我正在编写脚本语言,我想复制(非常标准化的)C order of operations.
我从来没有把握过作为一个正式概念的一件事,那就是结社性。为什么一些操作员组从左到右,其他从右到左?
有人可以举几个例子说明如果规则是从左到右或与它们相反的话,一行代码看起来会有什么不同吗?或者为什么关联性是它的方式,因为在我看来它只是一个随意的选择,但我认为他们有理由。
另外,请注意,我确实知道关联性意味着什么,我只是想不出任何从左到右(或反之亦然)优于其他选择的例子
答案 0 :(得分:13)
在大多数情况下,每个操作员都具有对该操作员最有意义的关联性。
所有非赋值二元运算符都具有从左到右的关联性。这对于从左到右阅读英语的明显原因很有用,因此x + y + z
的评估与阅读方式一致。此外,对于算术运算符,语义与我们对数学运算符的使用期望相符。
赋值运算符具有从右到左的关联性。从左到右的赋值将具有奇怪和意外的语义。例如,x = y = z
会导致x
的原始值y
和y
的原始值为z
。在表达式完成后,预计所有三个变量都具有相同的值。
前缀一元运算符具有从右到左的关联性,这是有道理的,因为最先评估最接近操作数的运算符,因此在~!x
中,首先计算!x
,然后{{1应用于结果。真的,真的奇怪的是前缀运算符应用了从左到右的关联性:说~
意味着评估~!x
然后应用~x
来实现结果与我们对表达的看法完全相反(或者,至少,大多数人对表达的看法......)。
答案 1 :(得分:6)
示例:
5 - 4 - 3
(5 - 4) - 3 = -2 // left association is correct
5 - (4 - 3) = 4 // right is incorrect
a == b == c // What does this equal?
// It is common to have == be non-associative because of this.
x = y = z
x = (y = z) // right association is correct, sets x and y
(x = y) = z // left is incorrect, does not set y
大多数操作员从数学继承他们的关联性。按位可以看作算术运算符,因此具有左关联性。
一元是正确联想的,因为它以这种方式分组:
~!-x = ~(!(-(x)))
除非是后缀,否则另一种方式没有多大意义。
答案 2 :(得分:2)
棘手的运算符是取幂(例如:python中的**,R中的^,haskell)。大多数语言,解析器等都将3 ** 3 ** 3
视为3 ** (3 ** 3)
。我个人认为这是正确的解释,但最近注意到octave和matlab都将其计算为(3 ** 3) ** 3
。
这不是C中的问题,因为它没有取幂运算符。相反,您调用pow
函数并且必须明确说明pow(3,pow(3,3))
或pow(pow(3,3),3)
。
答案 3 :(得分:0)
累积的结果通常就是答案。
然而,>>和<<必须是它们的方式或构造如12<< 2>> 3不行。