C 中左值與右值

2021-08-14 04:15:25 字數 2719 閱讀 3772

讓我們先看看一些常見的左值和右值舉例:

int var = 6;          // var is a lvalue

const int var = 6;    // var is a (nonmodifiable) lvalue

char str = "hello, world"; // str is a (nonmodifiable) lvalue

"hello, world";       // the expression is string literal,

//so it's a rvalue

string("hello, world"); // the expresion is a (modifiable) rvalue

對於每乙個表示式,其要麼

是乙個左值(lvalues),要麼是乙個右值(rvalue)。

左值這個概念最初**於賦值語句:e1 = e2;,這裡要求左運算元e1是乙個(可修改的)左值。現在,左值這個概念的含義已不侷限於此。而右值是相對於左值出現的,非左即右。

雖然左值和右值的內涵和外延有了很大變化,但仍滿足這條規則:右值只能出現在賦值運算子的右邊,不能出現在它的左邊。

乙個左值對應於(refer to)乙個物件或者函式(注:函式不是物件)[注1

]。右值的型別總是完整型別或者void型別。注意兩點:(1)void型別(非完整型別)是右值;(2)當右值的型別不是void型別時,其必須是完整型別,因為需要計算它的值。由此可知,非void的非完整型別是左值。

c++中的左值和右值

1.   概念

變數和文字常量都有儲存區,並且有相關的型別,區別在於變數是可定址的;

1>資料值,儲存在某個記憶體位址中,也稱右值(rvalue),右值是被讀取的值(read value),文字常量和變數都可被用於右值。

2>位址值,即儲存資料值的那塊記憶體位址,也稱左值(lvalue),文字常量不能被用作左值。

2 . 問題

給表示式加上括號: ++a--

結果 ++(a--)

這個表示式是非法的,因為前增量操作要求乙個可修改的左值,而 "a--" 不是左值(即右值)

3 . 前增量和後增量的區別

早期的c語言教材,for迴圈語句通常寫成:

for(int i=0;i<10;i++)

而現在多為:

for(int i=0;i<10;++i)

兩者有區別嗎?

a++ 即是返回 a的值,然後變數 a 加 1,返回需要產生乙個臨時變數類似於

++a 則為:

顯然,前增量不需要中間變數,效率更高。

注1:物件型別為非函式、非引用、非void的型別;左值所對應的物件不一定實際存在。例如:char* p; *p這個左值所對應的物件目前是不存在的。

部分右值表示式也可以對應物件。例如,那些呼叫建構函式和呼叫那些返回類物件的函式的表示式,這些表示式可以呼叫相應物件的成員函式,但這些表示式是右值(此時,該右值可能是可修改的右值)。

如果在左值被計算時還沒有指定乙個物件,那麼該計算行為是未定義的。例如:char* p;此時計算*p的結果是未知的。

函式呼叫是左值,當且僅當返回型別是引用。

[注2]

在任何時候,當乙個左值出現在需要右值的地方,左值會被轉換成右值

。[注3]

注3:當左值型別t為非函式、非陣列型別時,左值可以被轉換為右值。如果t是非void的非完整型別,那麼此時左值不應該被轉化為右值來使用;如果該左值所對應的物件不是型別t的物件,也不是由t派生的型別的物件,或者該物件沒有被初始化,那麼發生這種轉換的程式將產生未定義行為。

如果t是非類型別,那麼轉換得到的右值的型別是t的cv-qualified版本;否則,右值型別是t。

左值所對應的物件所包含的值就是右值的結果。 在發生這種轉換時,左值的值並不是一定被計算。例如:當運算子sizeof的運算元發生這種轉換時,並不需要訪問左值的值,因為該運算子不需要計算它的運算元。

左值分為可修改的左值(modifiable)和不可修改的左值(nonmodifiable)。

如果要修改乙個物件,該物件必須是左值;例外情況是,類型別的右值也可以在某些情形下修改它所對應的物件。例如,函式呼叫返回的類是右值,但可以呼叫其成員函式修改該物件。

由const限定的表示式不可以被修改;除非這是乙個類型別,並且擁有mutable成員,那麼該mutable成員可以被修改。

非類型別的右值總是由cv-qualifiers限定,類型別的右值可以沒有cv-qualifiers。

部分內建運算子需要左值運算元。例如,所有內建賦值運算子要求它們的左運算元是乙個左值(此時還是乙個可修改的左值)。

部分內建運算子需要右值運算元,並且產生右值。例如,一元運算子和二元運算子「+」要求運算元為右值,並且它們產生的結果也為右值。

部分內建運算子和函式呼叫產生左值。例如,如果e是乙個指標型別的表示式,那麼*e是乙個左值表示式(注:*運算子的運算元是左值,產生乙個左值)。又如,函式 int& f();產生乙個左值,因此f()的呼叫是乙個左值表示式。

如果乙個程式試圖通過乙個左值的非下列型別去訪問儲存在物件中的值,那麼該行為是未定義的。

注2:自定義運算子是函式,這類運算子是否需要或者產生左值取決於它們的引數和返回值型別。

C 中左值與右值

讓我們先看看一些常見的左值和右值舉例 int var 6 var is a lvalue const int var 6 var is a nonmodifiable lvalue char str hello,world str is a nonmodifiable lvalue hello,wo...

c 左值與右值

在學c 過程中,左值與右值的概念是一道繞不過去的坎,因此就想寫一些自己的理解。左值 lvalue 與右值 rvalue 是c 語法中的術語 terms 第一次看到這兩個詞的時候,很自然就認為在乙個表示式中,在等號左邊的就是左值,在等號右邊的就是右值。如果你們第一次看到這兩個詞也這麼認為的話,那我要恭...

C 左值與右值

左值 lvalue 和右值 rvalue 是 c c 中乙個比較晦澀基礎的概念,不少寫了很久c c 的人甚至沒有聽過這個名字,但這個概念到了 c 11 後卻變得十分重要,它們是理解 move forward 等新語義的基礎。左值與右值這兩概念是從 c 中傳承而來的,在 c 中,左值指的是既能夠出現在...