在基于C的语言中,从右到左和从左到右的关联性会产生什么影响?

时间:2012-01-30 02:40:31

标签: c syntax operators language-design operator-precedence

我正在编写脚本语言,我想复制(非常标准化的)C order of operations.

我从来没有把握过作为一个正式概念的一件事,那就是结社性。为什么一些操作员组从左到右,其他从右到左?

有人可以举几个例子说明如果规则是从左到右或与它们相反的话,一行代码看起来会有什么不同吗?或者为什么关联性是它的方式,因为在我看来它只是一个随意的选择,但我认为他们有理由。

另外,请注意,我确实知道关联性意味着什么,我只是想不出任何从左到右(或反之亦然)优于其他选择的例子

4 个答案:

答案 0 :(得分:13)

在大多数情况下,每个操作员都具有对该操作员最有意义的关联性。

所有非赋值二元运算符都具有从左到右的关联性。这对于从左到右阅读英语的明显原因很有用,因此x + y + z的评估与阅读方式一致。此外,对于算术运算符,语义与我们对数学运算符的使用期望相符。

赋值运算符具有从右到左的关联性。从左到右的赋值将具有奇怪和意外的语义。例如,x = y = z会导致x的原始值yy的原始值为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不行。