首先,该表达式为错误表达式和未定义表达式。
该表达式的解析顺序:
++i++ ++ +i++ +i (1)
算入优先级的话运算顺序为:
(++((i++)++)) + (i++) + i (2)
因为编译器在解析字符串时总是向后寻找可能的有意义的串,所以,这个解析式不会被解释为
(++i++) + (++i++) + i (3)
(2)式中第一个i先后置++得到i++(因为后置++优先级比前置++高),是一个右值,这个中间表达式再
后置++就无法编译了,因为++运算符需要左值,而i++是右值(不信可以尝试在代码中写i++++,编
译器会告诉你++需要左值)。
另一方面,第一个(2)是一个标准未定义表达式, c语言有一套复杂的未定义表达式判别规则,该表达式
违反了“同一对象在两个序列点之间只能被修改1次”的标准定义表达式规则(2式中i被修改了4次)。标
准未定义表达式在不同的编译器下会得到不同的结果。
同样的原因(3)中的++i++导致无法编译。
加上括号使原表达式变成如下的形式:
((++i)++)+((++i)++)+i;
这次虽然可以通过编译(因为前置++产生左值),可是还是一个标准未定义表达式。
好的程序不能使用标准未定义表达式。
----------------------------------------------------------------
同样可分析出:
++i+++i+++i是错误的
它被解析为:
(++i++) + (i++) + i //YES
而不是:
(++i) + (++i) + (++i) //NO
处理(++i++)时会编译出错
---------------------------------------------------------------------------------------------------
这篇文章是我从网上找到了,看完后,颇有感悟,自以为对C掌握不错,看来差之千里。
只是文中一句,因为前置++产生左值
,看文章每次必须深究。
我而做了几个小实验,这句应该不对,前置++产生的也应该是右值
首先++++i,如果++i产生左值,而编译时gcc出错提示
需要左值?++i不是产生左值吗?
再来(++i)++;如果++i产生左值,而后置++需要左值
那这句应该没问题,但事实是:
还是需要左值,可见,前置++和后置++产生的都是右值。
实验有本文原作者实验不同,难道是编译器不同?也就是说这本就是一个未定义行为?
本人近日深陷C语言左值、右值问题不能自拔,望高手解决。