8

我遇到了这个问题in this website,并在Eclipse中尝试过,但无法理解它们的评估方式。a + = a ++ * a ++ * a ++ in Java。它如何得到评估?

int x = 3, y = 7, z = 4; 

    x += x++ * x++ * x++; // gives x = 63 
    System.out.println(x); 

    y = y * y++; 
    System.out.println(y); // gives y = 49 

    z = z++ + z; 
    System.out.println(z); // gives z = 9 

根据网站的注释中,x + = X ++ * X ++ * X ++解析为X = X +((X + 2)*(X + 1)* X),其结果是正确的。我想我错过了这个运算符的优先级。

+0

'X + = 3 * 4 * 5; = 3 + 60 = 63'; 'y = 7 * 7 = 49','z = 4 + 5 = 9' – NullUserException

+6

为什么这会被投票结束为一个C++问题的重复? – NullUserException

+2

(我同意NullUserException - C/C++对于处理这个相同的结构有不同的*规则,但是它恰好在Java下很好定义,如果不是丑陋的话。) – 2012-11-13 22:08:27

回答

12

的Java表达式求值留给根据自己的优先级向右&。

int x = 3, y = 7, z = 4; 

x (3) += x++ (3) * x++ (4) * x++ (5); // gives x = 63 
System.out.println(x); 

y = y (7) * y++ (7); 
System.out.println(y); // gives y = 49 

z = z++ (4) + z (5); 
System.out.println(z); // gives z = 9 

后缀增量操作符只在变量被使用/返回后才增加变量。一切似乎都正确。

这是后缀增量操作的伪代码:

int x = 5; 
int temp = x; 
x += 1; 
return temp; 

从JLS 15.14.2(reference):

The value of the postfix increment expression is the value of the variable before the new value is stored.

+1

感谢你最后的声明:)使它变得简单了解如何评估++ x。在这个例子之前总是与++ x混淆。 – WilliamShatner

+0

'Java根据它们的优先级从左到右评估表达式'是一个矛盾的术语。 Java评估*操作数*从左到右; *运算符*按照运算符优先级和关联性的顺序进行评估。 – EJP

1

由于后增修改变量值取后和+ =在评估其右手侧之前评估其左侧,

x += x++ * x++ * x++; 

变得

tmp0 = x 

tmp1 = x 
++x 
tmp2 = tmp1 * x 
++x 
tmp3 = tmp2 * x 
++x 

x = tmp0 + x 
+0

你确定哟是否意味着左手边在右手边进行评估,因为我认为我知道对面? 代码分解是好的,除了最后一条语句x = tmp0 + x在x = 3时不会导致63. –

+0

否则它将是66而不是63. – Dan

2

后缀运算符x++意味着像 “给我x的值了,但增加以备将来参考”

因此,由order of operations and evaluation

x++ * x++ * x++

首先解释为

3 * 4 * 5(= 60)

然后添加到原来 3,得到63

原始值用于,因为它是在同一行,假若你写的是这样的:

int x = 3; 

int y += x++ * x++ * x++; 
x += y; 

x现在将是66,而不是63,因为在第二行中的x现在如图6所示,而不是它的原始3.

1

一元operato RS从左向右计算,所以第一个x++得到值x,第二个是(x+1)等而+ =计算根据在开始时的x值,所以加入x

5

无关,与的运算符优先级本身,只是评估的顺序。 两件事情知道这里:

  1. x++是后缀增量,所以x值递增后其被评估
  2. *评估右侧则左侧。

考虑到点2,表达式x++ * x++ * x++可以更具体地重写为x++ * (x++ * (x++))

整个表达式可以写成的程序:

a = x 
x += 1 
b = x 
x += 1 
c = a*b 
d = x 
x += 1 
return c*d 
+0

谢谢代码的破解帮助:) –

+0

+1,但带有挑剔:事实上,运算符优先级在任何地方都有效,在表达式或语句中有多个运算符:)前缀和后缀运算符比二元运算符具有更高的优先级,这就是为什么'x ++ * x ++'可以写**而不用括号**。你必须写'(x ++)*(x ++)'。没有运算符优先级和parens,只能从右到左发生,它可能意味着'x ++ *(x ++))'这可能是一个语法错误:没有LHS操作数用于* – quetzalcoatl

+0

好吧,够公平的。我的意思是,答案应该与postfix和prefix运算符的行为有关,而不是运算符的优先级,就像混合了不同优先级的许多运算符的表达式一样(例如,'x ++ * x ++ + x ++/x ++ ') –

2

由于增量操作++是变量x之后加入。这是一个后增量操作。这意味着,x在处理操作后递增。

In your example the expression would be: 
x += 3 * 4 * 5 
First the expression is added by 3 (x+=....) 
then the first x++ results in 3 
the second x++ results in 4 (because it was incremented before) 
and the third x++ results in 5. 

如果您希望变量递增之前执行的操作,你必须写++ X(预增量操作)