【问题标题】:L value vs R value in CC中的L值与R值
【发布时间】:2014-11-25 14:21:36
【问题描述】:

我正在回答来自this textbook 的教科书问题。

我正在学习 C 中的指针,并且遇到了左值和右值。据我了解:

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++)

对吗?

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

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?

我接近了吗?谢谢

【问题讨论】:

  • 你为什么要标记这个c++
  • 顺便说一句,尽管 C 和 C++ 中的 值类别 具有几乎相同的最终效果,但它们通过非常不同的路径到达那里。不会有任何适用于两者的解释。像这样的问题需要选择一种语言。
  • @BenVoigt:我已经删除了 C++ 标签,因为 OP 说他正在学习 C。
  • (a) R, R, L, R, L, R (b) 否* (c) 否
  • 我发现C FAQ 条目在解释左值/右值时非常有用。

标签: c pointers memory-address dereference


【解决方案1】:

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

不,这不正确。

“左值”和“右值”这两个词(这是 C 标准对它们的拼写)有着悠久的历史。这些术语来自“左”的“l”和“右”的“r”,指的是作业的左侧和右侧。

在某些情况下,表达式可以对其左值求值对其右值求值。鉴于这些术语的定义,“右值”就是您通常认为的表达式的值。评估2+2 产生4。评估一个表达式的左值意味着确定它所指的对象。例如,给定:

int x;
x = 2 + 2;

赋值的右侧,2 + 2 将被评估为它的右值,产生4,而左侧将被评估它的左值,这意味着确定它所引用的对象。 (表达式的右值评估;之前存储在x 中的值,如果有的话,不使用。)

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

lvalue 是一个表达式(对象类型不是 void) 潜在地指定一个对象;如果左值不指定 评估对象时,行为未定义。

(添加了“可能”一词以涵盖*ptr 等情况,其中ptr 是指针对象;如果ptr == NULL*ptr当前指定对象,但它仍然是左值。您始终可以在编译时确定给定表达式是否为左值。早期版本的 C 标准对 lvalue 的定义存在缺陷。)

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

x++++x 在 C 中都不是左值。

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

本国际标准中有时称为“右值” 描述为“表达式的值”。

因此,正如 C 定义的术语,lvalue 是一种表达式(存在于 C 源代码中的东西),而 rvalue 是评估的结果一个表达式(在程序执行期间存在的东西)。

(C++ 有不同的规则,还有其他几类类似左值的东西,包括 glvalues 等等。这里我就不多说了。)

【讨论】:

  • C 标准不拼写右值(脚注除外)
  • @AnttiHaapala:是的,我在回答中说过。
猜你喜欢
  • 1970-01-01
  • 2011-01-30
  • 2011-08-31
  • 1970-01-01
  • 2019-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多