后缀(前缀)增量,L值和R值(在C和C ++中)

时间:2014-01-25 14:30:30

标签: c++ c operators operand operands

我刚学到以下事实:

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

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

  •   

我在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-nonqualified版本。另见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.

但我不知道为什么postfix ++不是C和C ++中的L值,以及为什么前缀++不在C中。(我看到类似“postfix”的内容++ ...存储...在一个临时地址,然后......“,但我仍然没有得到它。”

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

2 个答案:

答案 0 :(得分:1)

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

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

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

(0, lvalue)

答案 1 :(得分:0)

确实

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

  • post increment / decrement运算符(var ++或var--)产生一个rvalue(即一个临时对象)。

考虑使用预增量/减量运算符

的代码
{

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 virtually 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; // the post increment happening only after the assignment !!!

我希望这有助于澄清一点;)