什么是运算符的结合性,为什么它很重要?
对于操作符,结合性指的是当相同的操作符在一行中出现时,我们首先应用哪个操作符。在下面的示例中,设 Q
为该操作符。
a Q b Q c
如果Q
是左结合的,那么它会按照以下方式进行求值
(a Q b) Q c
如果它是右结合的,那么它会被评估为
a Q (b Q c)
这很重要,因为它改变了表达式的含义。考虑整数算术中的除法运算符,它是左关联的。
4 / 2 / 3 <=> (4 / 2) / 3 <=> 2 / 3 = 0
如果它是右结合的,那么它将被解析为未定义的表达式,因为您将会除以零。4 / 2 / 3 <=> 4 / (2 / 3) <=> 4 / 0 = undefined
有三种结合性:
数学中的结合律是指像加法(+)这样的运算符所具有的一种属性。该属性允许您重新排列括号而不改变语句的值,即:
(a + b) + c = a + (b + c)
在编程语言中,操作符的结合性(或者称为优先级)是一个属性,用于确定在缺少括号的情况下,具有相同优先级的操作符如何分组;即每个操作符的计算顺序。这可能在编程语言之间存在差异。简单!!
Left Associative means we evaluate our expression from left to right
Right Associative means we evaluate our expression from right to left
我们知道乘号(*)、除号(/)和取模运算符(%)具有相同的优先级,但根据结合性,答案可能会有所不同:
例如:我们有表达式:4 * 8 / 2 % 5
Left associative: (4 * 8) / 2 % 5 ==> (32 / 2) % 5 ==> 16 % 5 ==> 1
Right associative: 4 * 8 /(2 % 5) ==> 4 * ( 8 / 2) ==> 4 * 4 ==> 16
2%5
的计算结果是2
,而不是0
。 - Caleb Stanford这是同一优先级运算符的评估顺序。从左到右或从右到左的顺序很重要。
3 - 2 - 1
如果是从左到右,那么它就是
(3 - 2) - 1
如果它是从左到右的,那么它就是0。如果它是从右到左的,则为
3 - (2 - 1)
这是第二点。在大多数语言中,我们说减号运算符具有从左到右的结合性。
关于3-2-1
的情况可能看起来微不足道,如果说“当然,我们会从左到右进行计算”。但在其他情况下,比如在Ruby或NodeJS中进行计算:
$ irb
2.6.3 :001 > 2 ** 3 ** 2
=> 512
**
是“乘方”运算符。它的结合性是从右向左的。 2 ** (3 ** 2)
这个是2 ** 9
,即512
,而不是
(2 ** 3) ** 2
这是 8 ** 2
,即64
。
这是操作数与运算符绑定的顺序。基本上:
a - b + c
可能被计算为(假设-和+具有相同的优先级):
((a - b) + c) 或者,
(a - (b + c))
如果运算符是左结合的(立即绑定到左操作数),它将被计算为第一个。如果它们是右结合的,则将其计算为第二个。
如果你指的是运算符结合性:
它定义了表达式被解析的方式。它提供了一个标准,以便每个表达式都以相同的方式被解析。
这对于具有相同优先级的操作非常重要,当可能存在副作用时尤其重要。
大多数之前的示例都使用了常量。如果参数恰好是函数调用,那么调用的顺序可能由关联规则确定,当然这取决于您的编译器。如果这些函数具有副作用..
expr -> expr + term;
是左结合的,而expr -> term + expr
是右结合的。 - C--*
是左结合的,但/
是右结合的,那么a * b / c
会如何计算?这时就会产生矛盾。因此,我认为如果您想涵盖多个运算符,需要说“当具有相同优先级和结合性的运算符”才行。 - Johannes Schaub - litb