左值是用來指明一個物件的表示式。最簡單的左值就是變數名稱。左值(lvalue)之所以稱為“左”(以首字母為 L,代表 left),是因為一個左值表示一個物件,它可以出現在賦值運算子(assignment operator)的左邊,例如“左表示式=右表示式”。
其他表示式(那些表示一個值但不指明一個物件的),被類似地稱為
右值(rvalue)。右值是可以出現在賦值運算子右邊而不是左邊的表示式。例如,常數和算術表示式。
從一個左值中必定可以解析出對應物件的地址,除非該物件是位欄位(bit-field)或者被宣告為暫存器儲存類。
生成左值的運算子包括下標運算子(subscript operator)[]和間接運算子(indirection operator)*,如下表所示(如果 array 已被宣告為陣列,而 ptr 被宣告為指標變數)。
表1 指標和陣列表示式可能是左值
表示式 |
是左值嗎 |
array[1] |
是;一個陣列元素是一個具有位置的物件 |
&array[1] |
否;此物件的位置,並非一個具有位置的物件 |
ptr |
是;此指標變數是一個具有位詈的物件 |
*ptr |
是;指標所指的地方是一個具有位置的物件 |
ptr+1 |
否;此加法產生一個新的地址值,但不是一個物件 |
*ptr+l |
否;此加法產生一個新的算術值,但不是一個物件 |
物件可以被宣告為常數。在這種情況下,該物件就不能位於賦值運算的左邊,儘管它是左值,如下面的例子所示:
int a=1;
const int b=2, *ptr=&a;
b=20; //錯誤:b被宣告為const int
*ptr=10; //錯誤:ptr被宣告為const int的指標
在這個例子中,表示式 a、b、ptr 和 *ptr 都是左值。但是 b 和 *ptr 是常數左值。因為 ptr 被宣告為指向 const int 的指標,不能使用它修改它所指向的物件。
賦值運算左邊的運算元,以及任何自增或自減運算子(++ 和 --)的運算元,不僅應該是左值,還應該是
可修改的左值。
可修改的左值,其型別不可以被宣告為限定符 const,並且可修改的左值
不能是陣列型別。如果可修改的左值所表示的物件是結構或聯合型別,那麼它的元素都不可以被宣告(不管是直接地或間接地)為具有限定符 const 的型別。