为什么“a +++++ b”不能用gcc编译,但是“a +++ b”,“a ++ + ++ b”和“a +++ ++ b”可以?
可能重复:
请帮我理解C中的错误a +++++ b
这是示例代码,为什么“a +++++ b”无法编译,但其他人可以?
#include #include int main(int argc, char **argv) { int a = 0; int b = 0; int c = 0; c = a+++b; printf("a+++b is: %d\n", c); c = a = b = 0; c = a++ + ++b; printf("a++ + ++b is: %d\n", c); c = b = a = 0; c = a+++ ++b; printf("a+++ ++b is: %d\n", c); c = b = a = 0; c = a+++++b; // NOTE: Can not be compiled here. printf("a+++++b is: %d\n", c); return 0; }
这是因为a+++++b
被解析为a ++ ++ + b
而不是a ++ + ++ b
[C的标记化器是贪婪的]。 a++
返回一个右值,你不能在rvalue上应用++
,这样你就会得到那个错误。
a+++b; // parsed as a ++ + b a+++ ++b; // parsed as a ++ + ++ b
阅读有关最大蒙克规则的内容。
编译器是贪婪的,所以你的表达
a+++++b
将被理解为
a++ ++ +b
+
运算符级联…使用a+++++b
,在添加操作级联后没有要添加的l值(内存可寻址值)。
换句话说, a+++b
与(a++) + b
。 这是一个有效的操作。 对于a+++ ++b
也是如此,它等同于(a++) + (++b)
。 但是使用a+++++b
,你无法通过C-parser获得它。 对于解析器,它看起来像((a++)++) + b
,并且因为(a ++)返回一个temp,这不是一个可以通过++
运算符再次递增的l值。
# include # include int main(int argc, char **argv) { int a = 0; int b = 0; int c = 0; c = a+++b; printf("a+++b is: %d\n", c); c = a = b = 0; c = (a++)+(++b); printf("a++ + ++b is: %d\n", c); c = b = a = 0; c = (a++)+(++b); printf("a+++ ++b is: %d\n", c); c = b = a = 0; c = (a++)+(++b); printf("a+++++b is: %d\n", c); return 0; }