如何解释这种运算符关联性?
Posted
技术标签:
【中文标题】如何解释这种运算符关联性?【英文标题】:How to explain this operator associativity? 【发布时间】:2015-06-18 09:21:15 【问题描述】:根据this table,++
具有从右到左的关联性。所以,我运行这段代码:
int a = 5;
++a + ++a * ++a
并期望表达式为50
(如8 + 7 * 6
,从右到左递增)。但表达式是由 Eclipse 从左到右 (6 + 7 * 8
) 计算的,结果为 62
。我对 Java 中的这种关联性很陌生,并且一定遗漏了一些明显的东西。请帮助我理解这种奇怪的行为。
编辑:感谢您的回答,但我现在还有一个问题。从@bizclop 的代码和树答案中可以看出,很明显++
的关联性并不重要。那么,++
/--
的这种关联性是否有任何用例?
【问题讨论】:
关联性 != 优先级。优先级优先,关联性仅用于解决运算符具有相同优先级的情况。 我想不出一个例子说明++
/--
运算符的关联性很重要,可能没有。
【参考方案1】:
这里混合了两种不同的东西:表达式解析和表达式求值。
让我们从表达式开始:++a + ++a * ++a
。我们首先与它有什么关系?由于运算符+
和*
需要两个操作数而++
需要一个,所以我们必须弄清楚哪个操作数与哪个操作对应。这是表达式解析步骤,其中应用了优先级/关联性。
++
具有最高优先级,因此我们可以将表达式重写为 (++a) + (++a) * (++a)
接下来是*
,所以我们可以再次添加括号:(++a) + ((++a) * (++a))
最后我们有+
,这是所有优先级中最低的,所以为了对称,我们可以写成:((++a) + ((++a) * (++a)))
请注意,我们可以将其巧妙地表示为一棵树:
+
/ \
++ *
| | \
a ++ ++
| |
a a
这是我们基于优先级和关联性的评估树。
请注意,在这种情况下,关联性根本不重要,因为所有运算符 有不同的优先级。如果我们的表达是
4 - 1 - 3 + 2
,它 使用关联性来达到(((4 - 1) - 3) + 2)
很重要,因为+
和-
具有相同的优先级。
现在是下一步,评估。评估总是从左到右进行(即使对于分配,虽然规则有点古怪),但它使用我们刚刚构建的树从左到右进行。
-
首先我们开始评估
+
运算符,因为它位于顶部。
然后,当我们评估 +
运算符左侧的 ++a
时,我们向左下一级,(6)
然后我们向右走并开始评估*
操作。
我们这样做的方式是评估第二个++a
,(7)
然后是第三个++a
(8)
然后我们将第 4 步和第 5 步的结果相乘(这是评估的 *
操作),(56)
最后我们将步骤 6 的结果添加到步骤 2 的结果中(62)
...我们完成了。
TL;DR:优先级和关联性决定了括号的放置位置,但评估始终是从左到右的。
15.7. Evaluation Order
Java 编程语言保证运算符的操作数似乎以特定的计算顺序进行计算,即从左到右。
【讨论】:
太棒了!正是我需要的。我将始终使用这种树方法评估所有表达式! 我还有一个问题,我为此编辑了问题。请看。【参考方案2】:这是因为乘法运算符*
的优先级高于加法运算符+
。
计算将是++a + (++a * ++a) = 6 + 7 * 8
【讨论】:
感谢您的回答!我还有一个问题,我为此编辑了问题。请看。以上是关于如何解释这种运算符关联性?的主要内容,如果未能解决你的问题,请参考以下文章