C语⾔运算符的结合性
在标准C语⾔的⽂档⾥,对操作符的结合性并没有做出⾮常清楚的解释。⼀个满分的回答是:它是仲裁者,在⼏个操作符具有相同的优先级时决定先执⾏哪⼀个。
每个操作符拥有某⼀级别的优先级,同时也拥有左结合性或右结合性。优先级决定⼀个不含括号的表达式中操作数之间的“紧密”程度。例如,在表达式a*b+c中,乘法运算的优先级⾼于加法运算符的优先级,所以先执⾏乘法a*b,⽽不是加法b+c。
但是,许多操作符的优先级都是相同的。这时,操作符的结合性就开始发挥作⽤了。在表达式中如果有⼏个优先级相同的操作符,结合性就起仲裁的作⽤,由它决定哪个操作符先执⾏。像下⾯这个表达式:
int a,b=1,c=2;
a=b=c;
我们发现,这个表达式只有赋值符,这样优秀级就⽆法帮助我们决定哪个操作先执⾏,是先执⾏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:&& 和 || 规定从左到右求值,并且在能确定整个表达式的值的时候就会停⽌,也就是常说的短路。
c语言中的逗号表达式
2:条件表达式的求值顺序是这样规定的:
test ? exp1 : exp2;
条件测试部分test⾮零,表达式exp1被求值,否则表达式exp2被求值,并且保证exp1和exp2两者之中只有⼀个被求值。
3:逗号运算符的求值顺序是从左到右顺序求值,并且整个表达式的值等于最后⼀个表达式的值,注意逗号','还可以作为函数参数的分隔符,变量定义的分隔符等,这时候表达式的求值顺序是没有规定的!
判断表达式计算顺序时,先按优先级⾼的先计算,优先级低的后计算,当优先级相同时再按结合性,或从左⾄右顺序计算,或从右⾄左顺序计算。