在标准C语言文档中,运算符的结合性解释得不是很清楚。 一个完美的答案是:它是仲裁者,当多个运算符具有相同优先级时,决定先执行哪个运算符。
每个运算符都有一定的优先级,并且可以是左关联的或右关联的。 优先级决定了不带括号的表达式中操作数的“接近”程度。 例如,表达式a*b+c中,乘法运算符的优先级高于加法运算符,因此先执行乘法a*b,而不是加法b+c。
然而,许多运算符具有相同的优先级。 此时,运算符的结合性就发挥作用了。 如果表达式中存在多个具有相同优先级的运算符,则结合性将充当仲裁者来决定首先执行哪个运算符。 类似如下的表达式:
int a,b=1,c=2;
a=b=c;
我们发现这个表达式只有赋值符号,所以优秀的level无法帮助我们决定先执行哪个操作,是不是应该先执行b=c呢? 或者先执行a=b。 如果按前者,a=的结果是2; 如果按后者,a=的结果是1。
所有赋值运算符(包括复合赋值)都是右结合的,即首先执行表达式中最右边的运算,然后从右到左顺序执行。 这样,先将c赋值给b,然后将b赋值给a,a的最终值为2。同样,具有左结合性的运算符(如位运算符“&”和“|”)从左到右。
仅当表达式中出现两个或多个具有相同优先级的运算符时才使用结合性以消除歧义。 事实上,您会注意到所有具有相同优先级的运算符都具有相同的结合性。 必须如此,否则结合性仍然无法消歧。 如果在计算表达式的值时需要考虑关联性,最好将表达式分成两半或使用括号。
例子:
a=b+c+d
= 是右结合的,因此先计算 (b+c+d),然后将其分配给 a
+ 是左结合的,所以先计算 (b+c),然后计算 (b+c)+d
C 中的右结合运算符包括所有一元运算符以及赋值运算符 (=) 和条件运算符。 其他的则保持关联。
C 语言中有一些运算符指定 C 语言标准中表达式求值的顺序:
1:&& 和 || 指定从左到右求值,当可以确定整个表达式的值时就会停止,这通常称为短路。
2:条件表达式的计算顺序指定如下:
测试?exp1:exp2;
如果条件测试部分test非零,则计算表达式exp1,否则计算表达式exp2,并且保证仅计算exp1和exp2之一。
3:逗号运算符的求值顺序是从左到右,整个表达式的值等于最后一个表达式的值。 请注意,逗号“,”也可以用作函数参数的分隔符和变量定义的分隔符。 符号等。此时,表达式的求值顺序没有指定!
在判断表达式的计算顺序时,优先级高的先计算,优先级低的最后计算。 当优先级相同时,使用关联性,或者从左到右计算,或者从右到左计算。