L值与C中的R值

use*_*172 5 c pointers memory-address dereference

我正在回答这本教科书中的教科书问题.

我正在学习C中的指针,并且遇到了l值和r值.根据我的理解:

l-values are values that are defined after they are executed (++x)
r-values are values that are not defined after they are executed (x++)
Run Code Online (Sandbox Code Playgroud)

这是正确的吗?

我想回答的问题(我的尝试):

a) Which of the following C expressions are L-Values?
   1.  x + 2 Not a L value
   2.  &x    Is a L value
   3.  *&x   Is a L value
   4.  &x + 2  Not a L value
   5.  *(&x + 2) Is a L value
   6.  &*y  Is a L value

b) Is it possible for a C expression to be a L-value but NOT a R-value? Explain
   I've read that a L value can be a R value but not vice versa. I can't think of an example of something being an L value but not a R value.

c) Is &(&z) ever legal in C? Explain
   Assuming this is not legal since a memory address doesn't have its own memory address?
Run Code Online (Sandbox Code Playgroud)

我接近了吗?谢谢

Kei*_*son 9

l值是在执行后定义++x的值()r值是在执行后未定义的值(x++)

不,那不对.

单词"左值"和"右值"(这就是C标准拼写它们的方式)有着悠久的历史.这些术语来自"左"的"l"和"右"的"r",指的是赋值的左侧和右侧.

在一些上下文中,表达可以或者评价其左值评价其右值.鉴于这些术语的定义,"rvalue"是您通常认为的表达式的值; 评估2+2收益率4.评估其左值的表达式意味着确定它所引用的对象.例如,给定:

int x;
x = 2 + 2;
Run Code Online (Sandbox Code Playgroud)

在赋值的右侧,2 + 2将评估其右值,屈服4,并且左侧将被评估其左值,这意味着确定它所引用的对象.(评估表达式的rvalue ; x不使用先前存储的值(如果有).)

C标准对它们的定义不同.在C中,左值不是值; 这是一种表达方式.具体而言,引用2011 ISO C标准,第6.3.2.1节:

左值是表达式(具有比空隙之外的对象类型),该潜在指定的对象; 如果左值在评估时未指定对象,则行为未定义.

(添加"潜在"一词来涵盖案例,例如*ptr,ptr指针对象;如果ptr == NULL那时当前*ptr没有指定一个对象,但它仍然是一个左值.你总是可以在编译时确定给定的表达式是左值还是不是.早期版本的C标准对左值有不确定的定义.)

因此,C语言中的左值基本上是指定对象的表达式.您可以将其视为可以出现在作业左侧的表达,尽管这并不完全准确; 例如,const对象的名称不能在赋值的LHS上,但它仍然是左值.(正如您所看到的,确定左值的精确且一致的定义可能很棘手.)

既不是x++也不++x是C中的左值.

C标准不使用rvalue这个术语,而是在一个脚注中提到它:

有时被称为"rvalue"的内容在本国际标准中被描述为"表达的价值".

因此,当C定义术语时,左值是一种表达式(C源代码中存在的东西),但是右值是评估表达式的结果(在程序执行期间存在的东西).

(C++有不同的规则,以及其他几个类似左值的东西,包括glvalues等等.我不会在这里讨论.)