C語言左值與右值詳解

2020-07-16 10:04:25
左值是用來指明一個物件的表示式。最簡單的左值就是變數名稱。左值(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 的型別。