在什么是右值,左值,x值,左值和右值中有一个相当广泛的左值描述?,但这是面向c++的,我认为其中很多不适用于c。
我对左值的理解如下:
-
数组不是,但它们的下标值可以是,只要它们不是数组。例如:
int arr[3][2]; arr // no --> int[3][2] arr[1] // no --> int[2] arr[1][1] // yes --> int
-
结构可以直接或通过成员访问,如
.
或->
,只要它们不计算为数组。例如:struct Member {int id}; Member member = {.id=2}, *member_ptr = &member; member = {.id=3}; // ok member_ptr = &member; // ok member.id=3; // ok member_ptr->id=4; // ok
-
&
操作符的地址不能。例如:a = 7; b = &a; &b = &a; // invalid
-
*
操作符的值只要不是指向数组就可以int x[2][2] = {{1,2}, {3,4}}; *(x+1)=3; // not ok, evaluates to x[2] *(*(x+1)+1) = 3; // ok
除了更明显的情况,如做7=x
,有主要项目,我的理解是缺失的?或者上面有不正确的项目吗?
C标准在第6.3.2.1p1节中定义了左值:
左值是一个可能指定对象的表达式(对象类型不是
void
);如果左值在求值时没有指定对象,则该行为未定义。当说对象具有特定类型时,该类型由用于指定对象的左值指定。可修改的左值是不具有数组类型、不具有不完全类型、不具有const限定类型的左值,并且如果它是结构体或联合,则不具有任何具有const限定类型的成员(递归地包括所有包含的聚合或联合的任何成员或元素)。
这个定义包括数组,但是数组不是可修改的左值。
间接操作符*
的结果也是左值,因为它指向一个对象。如果结果对象是数组,这也适用。
数组下标操作符[]
也产生一个左值,因为x[y]
与*(x + y)
完全等价。
成员访问操作符.
和成员指针操作符->
的结果也是左值。
复合字面值也是左值。例如,下面是有效的:
int *p = (int [3]){1,2,3};
p[0] = 4;