我不明白Java如何推进这个算术表达式
int x = 1;
int y = 1;
x += y += x += y;
System.out.println("x=" + x + " y=" + y);
使用Java我得到x = 4和y = 3.但在C,Perl,Php我得到x = 5和y = 3 在纸上我也得到x = 5和y = 3
答案 0 :(得分:9)
这显然是令人讨厌的部分:
x += y += x += y;
执行如下:
int originalX = x; // Used later
x = x + y; // Right-most x += y
y = y + x; // Result of "x += y" is the value stored in x
x = originalX + y; // Result of "y += x" is the value stored in y
所以:
x y
(Start) 1 1
x = x + y 2 1
y = y + x 2 3
x = originalX + y 4 3
重要的部分是在这里使用originalX
。复合赋值视为:
x = x + y
并且+
的第一个操作数在第二个操作数之前计算 ...这就是为什么它需要原始值为x
的原因而不是“最新的”。
如果左侧操作数表达式不是数组访问表达式,则:
首先,评估左侧操作数以生成变量。如果此评估突然完成,则赋值表达式出于同样的原因突然完成;不评估右侧操作数,也不进行赋值。
否则,保存左侧操作数的值,然后计算右侧操作数。如果此评估突然完成,则赋值表达式会因同样的原因而突然完成,并且不会发生任何分配。
如果有疑问,请参阅语言规范 - 并且绝不假设仅仅因为两种语言的行为不同,其中一种语言是“错误的”。只要实际行为符合每种语言的指定行为,一切都很好 - 但它确实意味着您需要了解您使用的每种语言的行为。
那就是说,你应该首先清楚地避免像这样的可怕代码。
答案 1 :(得分:-1)
从右到左开始
1. x += y gives x = 2, y = 1
2. y += ( x +=y ) gives x = 2, y = 3
3. x += ( y += x += y ) gives x = 4, y = 3
所以,这一切都是一致的