background image

C语言中怎样理解三目运算符(条件运算符)的右结合性?

  

对于表达式 --a == b++ ? a++ : b++
当然是先判断--a 

 

是否等于 b++ ,然后决定执行后面的哪个表达式。

问题:但是它的又结合性体系那在哪里呢?为什么不把这个表达式中所有的自加自减

运算先执行完,然后再执行条件判断呢?

解析:这里涉及了C中的优先级、结合性、求值顺序。结合性只有在相同优先级的运算

符间才起作用,比如a+b*c,+与*优先级不同,这里根本不用去管结合性。而a+b+c则
需要进行结合性考虑了,如果+为左结合性,那么应该理解为:(a+b)+c,如果+为右结
合性,那么应该理解为a+(b+c),当然了,我们已经知道+为左结合性了。对于?:,在C中
与它优先级相同的只有它自己,因此只有连续的?:才会体现出它的右结合性,即a?b:c?
d:e中,根据右结合性可知应理解为a?b:(c?d:e)。显然,上述问题中是体现不出这种结合
性来的。

再者,还有一个求值顺序的问题,a?b:c中,C语言规定先对a求值,非零则对b求值

并作为该表达式的值,为零则对c求值并作为表达式的值,并且b和c中有且仅有一个会被
求值。对于题目中的就应该是:先进行(--a == b++)的求值,根据是否为零,会对(a+
+)或(b++)进行求值。说白了,也就是只有两种可能性:可能性1:先算(--a == b++),
再算(a++);可能性2:先算(--a == b++),再算(b++)。至于(--a == b++)中到底是
先算--a 还是b++则仅从C语言这个角度是无法判别的,这是个实现问题,如果要想写出
健壮的可移植的代码就应该避免这种表述.总结一下,就是先看优先级,次看结合性,有
的求值有序,有的则无序。

实际上,一条语句中出现多次同一个变量的自增或自减是不合规范的,因为这种写法

出现的结果是不确定的,根据编译器而定。a++表示语句执行后 a = a + 1,到底有多后?
有 2 个 a++怎么办?这都是编译器内部机制的问题。真正好的程序员是避免这种情况的。