在Java中使用前递增和后递减的表达式值

huangapple go评论76阅读模式
英文:

Value of expression with pre-increment and post-decrement in Java

问题

考虑以下表达式:

int x = 5, y = 5, z;
z = y + x * y-- + ++x;

根据我的计算,由于 ++-- 的优先级高于 +,z 的值应为 40。

所以 z = 4 + 6 * 5 + 6 = 40

但实际运行代码得到的结果是 z = 36。Java 是如何得出这个结果的呢?
此外,这里的结合性(从右到左)起了什么作用?

英文:

Consider the following expressions:

int x = 5, y = 5, z;
z = y + x * y-- + ++x;

According to my calculations the value of z should be 40 considering ++ and -- have higher precedence than +.

So z = 4 + 6 * 5 + 6 = 40.

Running the code yields a result of z = 36. How does Java arrive at that result?
Also, what role does associativity (right to left) play here?

答案1

得分: 3

你必须从左到右进行解释,因此:

因此 z = y(5) + x(5) * y--(仍为5,因为递减将在之后应用) + ++x(这是6,因为增量在评估x之前应用)

结果为 36

英文:

You must interpret it from left to right, so :

so z = y(5) + x(5) * y--(still 5, since the decrement will apply afterwards) + ++x(which is 6 because the increment applies before the evaluation of x)

The result being 36.

答案2

得分: 1

运算符的优先级告诉您如何解析表达式。它不会告诉您任何关于求值顺序的信息。

有两种方法可以看待这个问题,您可以将其视为隐式大括号,也可以将其视为AST的外观。

如果您从使用大括号的角度来看,您会得到这个结果:

z = y + x * y-- + ++x;
<=> z = y + (x * (y--)) + (++x);
<=> z = 5 + (5 * 5) + 6 // y--此时仍为5(之后变为4),++x为6
<=> z = 5 + 25 + 6
<=> z = 36

如果您从AST的角度来看,您会得到

  +
 / \
y   +
   / \
  *   x++
 / \
x   y--

现在,如果您按照求值顺序(从左到右)遍历该AST,您会发现最左边的y仍然是5。在右侧的树上,我们再次有一个+号,它是乘法和++x的结果。乘法是5 * 5,因为此时y--仍然为5,之后变为4,而y为4。最后,++x为6,x之后变为6。综合起来,5 + 25 + 6 = 36。

AST始终按顺序进行评估,运算符的优先级告诉您AST的外观(底部是较强绑定的运算符,顶部是较弱绑定的运算符)。

英文:

Operator precedence tells you how to parse the expression. It doesn't tell you anything about evaluation order.

There are two ways to look at this, you can either look at it as implicit braces, or as how the AST looks like.

If you look at it through the PoV of using braces, you end up with this:

    z = y + x * y-- + ++x;
&lt;=&gt; z = y + (x * (y--)) + (++x);
&lt;=&gt; z = 5 + (5 * 5) + 6 // y-- is still 5 (4 afterwards), ++x is 6
&lt;=&gt; z = 5 + 25 + 6
&lt;=&gt; z = 36

If you look at it through the AST lens, you get

  +
 / \
y   +
   / \
  *   x++
 / \
x   y--

Now if you go through that AST in evaluation order (left-right), you see that the leftmost y is still 5. On the right tree, we have again a +, which is the result of the multiplication and ++x. The multiplication is 5 * 5, since y-- is still 5 at that point, and y is 4 afterwards. And finally, ++x is 6 and x is 6 afterwards. Putting together, 5 + 25 + 6 = 36.

The AST is always evaluated in-order, operator precedence tells you how the AST looks like (stronger binding operators at the bottom, weaker binding one at the top).

答案3

得分: 0

int x = 5, y = 5, z;
z = y + x * y-- + ++x;

在这个例子中,var--var++ 将会在 z 之后执行。而 --var++var 将会在 z 之前执行。在你的情况下:

z = 5 + 5 * 5 + 6 = 36

如果你将表达式改写为 z = y + x * --y + ++x,结果将是 z = 5 + 5 * 4 + 6 = 40

如果你将表达式改写为 z = y + x * y-- + x++,结果将是 z = 5 + 5 * 5 + 5 = 35

英文:
int x = 5, y = 5, z;
z = y + x * y-- + ++x;

In this example var-- and var++ will be executed after z. And --var and ++var will be executed before z. In your case

z = 5 + 5 * 5 + 6 = 36

If you rewrite your expression to z = y + x * --y + ++x it will be z = 5 + 5 * 4 + 6 = 40.

If you rewrite your expression to z = y + x * y-- + x++ it will be z = 5 + 5 * 5 + 5 = 35.

huangapple
  • 本文由 发表于 2020年9月16日 18:03:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/63917663.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定