为什么该代码由于错误而无法编译:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
cout << ++(i++) << " " << i << endl;
return 0;
}
虽然该代码确实编译:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
cout << (++i)++ << " " << i << endl;
return 0;
}
我不明白。从我的角度来看,编译第一个块是非常合理的。表达式++(i ++)只是意味着取i,递增和输出,然后再增加它。
我不是在询问int溢出中的未定义行为。在撰写问题时我根本不知道r和l值,我不在乎为什么++我被认为是l值,但i ++不是。
答案 0 :(得分:6)
这是因为post增量和pre增量运算符返回不同类型的值。后增量的结果是所谓的'rvalue',意味着它不能被修改。但预增量需要一个可修改的值来增加它!
另一方面,预增量的结果是左值,这意味着它可以通过后增量安全地修改。
以上规则的原因是后增量需要返回对象的值,就像应用增量之前一样。顺便说一下,这就是为什么一般情况下,在非内置对象上使用后增量被认为比预增量更昂贵。
答案 1 :(得分:2)
简而言之,不同之处在于,在C ++中,您可以使用任何偶数个加号(仅限于编译器限制)作为前缀增量运算符,如下所示
++++++++++++++++i;
并且后增量运算符只有两个加号
i++;
后缀增量运算符返回一个值(C ++标准,5.2.6增量和减量)
1后缀++表达式的值是其值 操作数即可。 [注意:获得的值是原始值的副本 - 后注]
前缀增量运算符在递增后返回其操作数(C ++标准,5.3.2增量和减量)
1 ... 结果是更新的操作数;这是一个左值 ......
在C语言中与C ++相反,你也可以使用前缀增量运算符仅对对象应用两个加号。:)因此,C编译器会为这样的表达式发出错误
++++++++++++++++i;
答案 2 :(得分:1)
当您使用clang编译它时,您会收到错误消息,说明这一切。
<source>:8:13: error: expression is not assignable
cout << ++(i++) << " " << i << endl;
从++运算符开始也许是件好事。实际上它是i = i + 1
的简写。现在,如果我们看一下postfix版本i ++,它会在标准中说它返回原始值的副本,并且side efect
它会增加原始值。
所以从(i ++)你得到rvalue并试图分配它,因为我们知道你不能分配到rvalue。