5

我刚刚了解到以下事实:

  • 前缀递增 (++var_name) 的结果是 C 中的 R 值(至少,我确信它不是 C 中的 L 值),但它是 C++ 中的 L 值。

  • 后缀增量 (var_name++) 的结果是 C 中的 R 值(至少,我确信它不是 C 中的 L 值)。在 C++ 中也是如此(它说结果是纯右值)。

我在 VS2010(.cpp 和 .c)和 Ubuntu(gcc 和 g++)中检查了这些。

在 C++ 标准http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf的 p.109 (5.3.2) 中,它是这样写的

前缀 ++ 的操作数通过加 1 来修改,或者如果它是 bool 则设置为 true(不推荐使用此用法)。操作数应为可修改的左值。操作数的类型应为算术类型或指向完全定义的对象类型的指针。结果是更新的操作数;它是一个左值,并且...

在第 101 页,(5.2.6)

后缀 ++ 表达式的值是其操作数的值。...结果是一个prvalue。结果的类型是操作数类型的 cv 非限定版本。另见 5.7 和 5.17。

(虽然我不知道 R 值和 prvalue 之间的区别)。

至于 C 标准http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf,前缀 ++ 在 6.5.3.1 中描述,后缀在 6.5.2.4 中,但从描述,我无法得到明确、明确的答案。

我想知道使它们成为 R 值或 L 值的原因。我所知道的是

We can assign a value to a (modifiable) L-value, for example, a variable name. R-value is a value of an expression.

但我不知道为什么后缀 ++ 不是 C 和 C++ 中的 L 值,以及为什么前缀 ++ 不是 C 中的详细信息。(我看到类似“后缀 ++...store...in一个临时地址,然后......”,但我还是不明白)。

另一个问题是为什么前缀 ++ 在 C 和 C++ 中是不同的?使前缀 ++ 成为 L 值(在 C++ 中)有很多优点?如果是这样,为什么C不改变这个?(除了向后兼容性之外的其他原因,或者至少为什么改变它会导致很多问题)。

4

2 回答 2

1

C 和 C++ 是不同的语言。C++ 有运算符重载,而 C 没有。++运算符,无论是前缀还是后缀,都是可以在 C++ 中重载的运算符。C++ 也有引用,而 C 没有。

在 C 中,++ii++都产生一个不是左值的值。这是可取的,否则您可能会通过尝试在相同的序列点边界内修改相同的标量而与未定义的行为发生冲突。

深思:在 C 中,逗号运算符也会产生一个不是左值的值,因此要“删除” lvalueness,您可以这样做:

(0, lvalue)
于 2014-08-15T00:43:45.017 回答
0

的确如此

  • 预递增/递减运算符(++var 或 --var)产生一个左值(即一个可修改的对象)

  • 后递增/递减运算符(var++ 或 var--)产生一个右值(即一个临时对象)。

考虑以下带有预递增/递减运算符的代码

{

int i = 0;

int* pi = &(++i);

}

没关系,因为实际上它的伪代码是

i = i+1; // pre increment i

int* pi = &i; // then evaluate its address and assign it to pi 

现在考虑相同的代码,但使用后递增/递减运算符以及编译器接受此无效代码的后果

{

int i = 0;

int* pi = &(i++); // Not OK !! because it is a temporary variable

}

它的伪代码是

int i = 0;

int tmp = i; // compiler creates a temporary variable to save value of i

int* pi = &tmp; // then would take the address of a temporary variable 

i = i + 1; 
于 2017-07-04T12:00:40.630 回答