考虑
int a =10;
c = a/a; //c becomes 1.
c= a* + a/a ; //c becomes 1.
c= 5+ a* + a/a ; //c becomes 15.
c = ++a + a++ - --a - a-- + a * + a/a ; //c becomes 10.
有人可以告诉我上面的工作原理吗?特别是a *部分。第一个仅供参考。
答案 0 :(得分:1)
在这一行:
c= a* + a/a ;
+
是unary plus operator。所以它相当于
c = a * a/a;
变量a
为10,因此10 * 10/10
为10
,而非1
。然后...
c= 5+ a* + a/a;
相当于c = 5 + a * a/a
,因此c
现在为15
。然后
c = ++a + a++ - --a - a-- + a * + a/a ;
将增量更改a
预先增加到11
。将增量a++
增量增加到12
但产生旧值11
,到目前为止产生22
。然后Pre递减递减到11
,减法产生11
。接下来,后递减递减到10
但产生旧值11
,减法产生0
。我们已经知道a * + a/a
是什么,10
。
答案 1 :(得分:1)
让我们看看第三行。
c = a * + a / a;
没有后缀*
运算符(EXPR*
),但有一个中缀*
运算符(EXPR * EXPR
):乘法运算符。因此*
必须是乘法运算符。
前缀+
运算符(+EXPR
):一元加运算符。因此+
必须是一元加运算符。
以上相当于
c = (a * (+a)) / a;
(10 * (+a)) / a
(10 * (+10)) / a
(10 * 10) / a
100 / a
100 / 10
10
下一行EXPR * + EXPR
的情况完全相同。
c = 5 + a * + a / a
相当于
c = 5 + ((a * (+a)) / a)
5 + ((10 * (+a)) / a)
5 + ((10 * (+10)) / a)
5 + ((10 * 10) / a)
5 + (100 / a)
5 + (100 / 10)
5 + 10
15
最后一行EXPR * + EXPR
的情况完全相同。
c = ++a + a++ - --a - a-- + a * + a/a;
相当于
c = ((((++a) + (a++)) - (--a)) - (a--)) + ((a * (+a)) / a);
最后一行在同一表达式中使用和修改a
。在大多数语言中,此类代码的行为未定义,因为操作数评估顺序未定义。即使这样,理解何时将引用放在堆栈上与副本相对也是至关重要的,这会导致代码不佳。
在Java中,the order is defined,但在我的测试中实际上并非如此。让我们看看((++a) + (a++)) - (--a)
10
的初始值为a
。
使用从左到右的评估:
((++a) + (a++)) - (--a) [a=10]
(11 + (a++)) - (--a) [a=11]
(11 + 11) - (--a) [a=12]
22 - (--a) [a=12]
22 - 11 [a=11]
11
使用java
,你得到13.因此,我实际上不会显示你的最后一行是如何评估的。这将需要检查生成的字节代码,如果它甚至有效,它将显示它的可怕代码。