6

根据此表++具有从右到左的关联性。所以,我运行这段代码:

int a = 5;
++a + ++a * ++a

并期望表达式是50(因为8 + 7 * 6,增量从右到左开始)。6 + 7 * 8但是该表达式由 Eclipse从左到右 ( ) 进行评估,并给出结果为62. 我对 Java 中的这种关联性很陌生,并且一定遗漏了一些明显的东西。请帮助我理解这种奇怪的行为。

编辑:谢谢你的回答,但我现在还有一个问题。从@bizclop 的代码和树答案中可以看出,很明显,关联++性无关紧要。那么, /的这种关联性是否有任何用例?++--

4

2 回答 2

13

这里混合了两种不同的东西:表达式解析和表达式求值。

让我们从表达式开始:++a + ++a * ++a。我们首先与它有什么关系?由于运算符+and*需要两个操作数并且++需要一个,我们必须弄清楚哪个操作数与哪个操作一起使用。这是表达式解析步骤,其中应用了优先级/关联性。

  1. ++具有最高优先级,因此我们可以将表达式重写为(++a) + (++a) * (++a)
  2. 接下来是*,所以我们可以再次添加括号:(++a) + ((++a) * (++a))
  3. 最后我们有+,是所有优先级中最低的,所以为了对称,我们可以这样写: ((++a) + ((++a) * (++a)))

请注意,我们可以将其巧妙地表示为一棵树:

   +
  / \
++   *
 |   | \
 a  ++ ++
     |  |
     a  a

所以这是我们基于优先级和关联性的评估树。

请注意,在这种情况下,关联性根本不重要,因为所有运算符都有不同的优先级。如果我们的表达式是4 - 1 - 3 + 2,那么使用关联性来达到(((4 - 1) - 3) + 2)+-具有相同的优先级就很重要了。

现在是下一步,评估。评估总是从左到右进行(即使对于分配,虽然规则有点古怪),但它使用我们刚刚构建的树从左到右进行。

  1. 所以首先我们开始评估+运算符,因为它在顶部。
  2. 然后我们向左下一层,因为我们评估运算符++a左侧的+(6)
  3. 然后我们向右走并开始评估*操作。
  4. 我们这样做的方式是评估第二个++a, (7)
  5. 然后是第三个++a (8)
  6. 然后我们将第 4 步和第 5 步的结果相乘(这是*评估的操作),(56)
  7. 最后我们将第 6 步的结果与第 2 步的结果相加(62)

......我们完成了。

TL;DR:优先级和关联性决定了括号的放置位置,但评估始终是从左到右的。

15.7. 评估令

Java 编程语言保证运算符的操作数看起来是以特定的评估顺序进行评估的,即从左到右。

于 2015-06-18T09:51:49.577 回答
3

这是因为乘法运算符*的优先级高于加法+运算符。

计算将是++a + (++a * ++a) = 6 + 7 * 8

于 2015-06-18T09:23:38.130 回答