Java:pre-postfix运算符优先级 [英] Java: pre-,postfix operator precedences
问题描述
我有两个关于Java中运算符优先级的类似问题。
I have two similar questions about operator precedences in Java.
第一个:
int X = 10;
System.out.println(X++ * ++X * X++); //it prints 1440
根据甲骨文教程:结果,
后缀(表达式++,expr--)运算符具有比前缀(更高的优先级+ + expr, - expr)
According to Oracle tutorial:
postfix (expr++, expr--) operators have higher precedence than prefix (++expr, --expr)
所以,我想评估订单:
1) first postfix operator: X++
1.a) X++ "replaced" by 10
1.b) X incremented by one: 10+1=11
At this step it should look like: System.out.println(10 * ++X * X++), X = 11;
2) second POSTfix operator: X++
2.a) X++ "replaced" by 11
2.b) X incremented by one: 11+1=12
At this step it should look like: System.out.println(10 * ++X * 11), X = 12;
3) prefix operator: ++X
3.a) X incremented by one: 12+1=13
3.b) ++X "replaced" by 13
At this step it should look like: System.out.println(10 * 13 * 11), X = 13;
4) evaluating 10*13 = 130, 130*11 = 1430.
<但是Java似乎忽略了PRE / POST排序并将它们放在一个层面上。所以真正的顺序:
But Java seems to ignore PRE/POST ordering and puts them on one level. So the real order:
X++ -> ++X -> X++
导致答案为(10 * 12 * 12)= 1440的原因。
what causes the answer to be (10 * 12 * 12) = 1440.
第二个:
int a=1, b=2;
a = b + a++;
部分接受的回答:
到转让时, ++
已将 a
的值增加到 2
(因为优先级) ,所以 =
覆盖递增的值。
Part of accepted answer:
"By the time of assignment, ++
has already incremented the value of a
to 2
(because of precedence), so =
overwrites that incremented value."
好的,让我们一步一步看看:
OK, let's look step-by-step:
1) replacing "b" with 2
2) replacing "a++" with 1
3) incrementing "a" by 1 -> at this point a==2
4) evaluating 2+1 = 3
5) overwriting incremented value of "a" with 3
似乎一切都很好。
但是让我们对该代码做一点改动(将=替换为+ =)
Seems everything is fine. But let's make a little change in that code (replace "=" with "+=")
a += b + a++;
步骤1-4应与上述相同。
所以,在第4步之后我们有类似的东西:
steps 1-4 should be same as above. so, after step 4 we have something like that:
a += 3;
其中 a == 2
然后我想:好的, a = 2 + 3
,所以 a
应该 5
。但答案只是 4
And then I think: OK, a = 2+3
, so a
should be 5
. BUT the answer is only 4
我真的很困惑。我已经花了几个小时但仍然无法理解我的错误。
I'm really confused. I already spent couple of hours but still can't understand where I am wrong.
P.S。我知道,我不应该在实际应用中使用这种风格。我只是想了解我的想法有什么问题。
P.S. I know, that I shouldn't use this "style" in real applications. I just want to understand what is wrong in my thoughts.
推荐答案
混淆源于操作数是从左到右评估。 首先执行此操作,然后再注意操作员优先级/操作顺序。
The confusion stems from the fact that the operands are evaluated from left to right. This is done first, before any attention is paid to operator precedence/order of operations.
此行为在 JLS 15.7.2。在操作前评估操作数
所以 X ++ * ++ X * X ++
是第一个评估为 10 * 12 * 12
,如你所见,得到1440。
So X++ * ++X * X++
is first evaluated as 10 * 12 * 12
which yields, as you saw, 1440.
为了说服自己,请考虑以下因素:
To convince yourself of this, consider the following:
X = 10; System.out.println(X++ * ++X);
X = 10; System.out.println(++X * X++);
如果 X ++
先完成,那么 ++ X
秒,然后乘法,两者都应打印相同的数字。
If X++
were done first, then ++X
second, then multiplication, both should print the same number.
但它们不会:
X = 10; System.out.println(X++ * ++X); // 120
X = 10; System.out.println(++X * X++); // 121
那么这有什么意义呢?好吧,如果我们意识到操作数从左到右进行评估,那么它就非常有意义。
So how does this make sense? Well if we realize that operands are evaluated from left to right, then it makes perfect sense.
X = 10; System.out.println(X++ * ++X); // 120 (10 * 12)
X = 10; System.out.println(++X * X++); // 121 (11 * 11)
第一行看起来像
X++ * ++X
10 (X=11) * (X=12) 12
10 * 12 = 120
和第二个
++X * X++
(X=11) 11 * 11 (X=12)
11 * 11 = 121
那么为什么表中的前缀和后缀增量/减量运算符?
确实,在乘法之前必须执行递增和递减。但是这说的是:
Y = A * B++
// Should be interpreted as
Y = A * (B++)
// and not
Y = (A * B)++
正如
Y = A + B * C
// Should be interpreted as
Y = A + (B * C)
// and not
Y = (A + B) * C
操作数的评估的顺序仍然是左边的到右边。
It remains that the order of the evaluation of the operands occurs left-to-right.
考虑以下程序:
class Test
{
public static int a(){ System.out.println("a"); return 2; }
public static int b(){ System.out.println("b"); return 3; }
public static int c(){ System.out.println("c"); return 4; }
public static void main(String[] args)
{
System.out.println(a() + b() * c());
// Lets make it even more explicit
System.out.println(a() + (b() * c()));
}
}
如果参数已评估在他们需要的时候, b
或 c
将首先出现,另一个接下来,最后 A
。但是,该计划输出:
If the arguments were evaluated at the time they were needed, either b
or c
would come first, the other next, and lastly a
. However, the program outputs:
a
b
c
14
a
b
c
14
因为无论在等式中需要和使用它们的顺序如何,它们都是仍然评估从左到右。
Because, regardless of the order that they're needed and used in the equation, they're still evaluated left to right.
有用的阅读:
- What are the rules for evaluation order in Java?
- a += a++ * a++ * a++ in Java. How does it get evaluated?
- Appendix A: Operator Precedence in Java
这篇关于Java:pre-postfix运算符优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!