表达式不能自加减?

如下程序段

int x = 3, y = 4, z = 5;
cout << &(++x);
cout << x+++++y;
cout << &(x++);
cout << ++x++;
cout << ++x+++y+++z << endl;

(假设每条cout语句独立运行)求输出结果,思考一下吧

.

.

.

...

...

好了,看结果

第一个cout输出地址0x6dfee4

第二个cout报错 "lvalue required as increment operand"

第三个cout报错 "lvalue required as '&' operand"

第四个cout报错 "lvalue required as increment operand"

第五个cout报错 "lvalue required as increment operand"

这里从一连串的自增运算符开始说起。

首先自增运算符的操作数operand必须是能够存储数据的变量,而不是常量数

这就牵扯到前缀自增与后缀自增的区别了

前缀自增是先自增,再将变量代入表达式计算

后缀自增是先将值代入表达式计算,再自增(注意这里说的是将值代入,而不是将变量代入)

后缀自增/自减运算符优先级高于前缀自增/自减的一块空间。

因此,我们对这四个程序一一分析。

第一个表达式是&(++x),先执行++x,x值自增1后返回变量x,对变量x取地址,没有任何问题 

第三个表达式是&(x++),先将x的值代入表达式,此时相当于&3,很明显这个操作是不被允许的,只能对变量变量取地址

第二个表达式是x+++++y,由于编译器在判断表达式中的运算符时采用的是贪心算法,故x+++++y相当于((x++)++)+y,先执行x++,后缀自增,将x的值3代入表达式,此时相当于3++,常量不能自加减,出错。

第四个表达式是++x++,由于后缀自增运算符高于前缀自增,故该表达式相当于++(x++),先执行x++,将x的值3代入表达式,此时相当于++3,常量不能自加减,出错。

第五个表达式是++x+++y+++z,根据贪心算法,该表达式相当于(++x++) + (y++) + z,看到了吧,第一个括号里的++x++和第四个表达式一样,报错。

了解了吗?那看一下下面这个表达式:

cout << x+++y+++z++ << endl;

输出结果?

...

...

...

12,理解了吗?没有的话再来分析一下

x+++y+++z++,根据贪心算法,该表达式相当于(x++) + (y++) + (z++),括号里的内容均为后缀自增,故分别将他们的值3,4,5代入表达式,此时相当于3+4+5,结果是12哦,随后x值自增为4,y值自增为5,z值自增为6

ok,相信到这里,理解的差不多了吧,现在回到我们的正文:表达式不能自加减?

在上述第四个cout中的表达式++x++中,很多人给出的报错解释是 ++(x++),x++为表达式,表达式不能自加减。

但是现在细想起来,真的是这样吗?如果表达式真的不能自加减,那看一下下面这个程序:

cout << ++(x+=1) << endl;

同样是表达式,我只不过把x++替换成了x+=1,程序正常输出为5,真的是表达式不能自加减吗?

好了,再返回看上面一开始我就提到的报错信息,几乎每一个报错原因都是左值lvalue,而不是表达式expression。前文也提到过一个表达式中的左值必须是一块可以存储数据的存储空间,而我们在分析中发现我们给出的“左值”都是没有存储空间的常量(在自增运算符中的操作数就相当于左值了)。

这个++(x+=1)之所以运行成功,就是因为x+=1执行后返回的是x而不是x的值。

所以,别再说什么表达式不能自加减了,一个简单的例子就可以推翻这句话,真正的原因还是要多思考才是。

posted @ 2019-10-15 23:37  _程序兔  阅读(451)  评论(0编辑  收藏  举报