C语言条件表达式(三目运算符)结合性问题

java筑基 · 2019-06-14 · 197 人浏览

在C语言标准中规定:条件表达式(三目运算符)的结合性是右结合,即自右向左结合




比如下面这条语句


int i = -2;

int n = ++i == 0 ? 99 : i == -1 ? 11 : 22;


问题是:n的值是多少?




一般理解,根据上面的表达式以及结合性,n的求值语句等价于


int n = ++i == 0 ? 99 : (i == -1 ? 11 : 22);


这时问题就出现了,有些人会对后面括号中的表达式先进行运算,得到结果为22,然后再计算整个表达式,最终得到的结果是 n = 22。




但是运行结果却是 n = 11,这是为什么呢?




究其原因,实际上就是将运算符的结合性与表达式的运算顺序这两个概念弄混了。




就上面这个语句来说,运算符的右结合性只是说明这个表达式等价于


int n = (++i == 0 ? 99 : i == -1) ? 11 : 22;

而不是


int n = (++i == 0 ? 99 : i == -1) ? 11 : 22;



结合性仅仅是定义了多个相同优先级的运算符和与之相关的操作数(操作符)的结合顺序,而并没有规定那个子表达式先运行。




换一种说法,结合性和优先级只是定义表达式的结构,当确定表达式运行时的行为时才需要表达式各部分的运算顺序。




C语言对于大多数的运算符没有规定运算顺序,只明确规定了条件表达式(三目运算符)、逻辑与 &&、逻辑或 || 以及逗号运算符的运算顺序(看到逻辑与&& 和 逻辑或 || 运算符是不是想到了什么?对,就是“短路求值”!)。




C语言对于条件表达式(三目运算符)的运算顺序规定为:条件表达式首先对条件部分求值,若条件部分为真,则对问号之后冒号之前的部分求值,并将求得的结果作为整个表达式的结果值,否则对冒号之后的部分求值并作为结果值。




再回到之前的问题看一下,了解了吧~~




总结一下:C语言编译器对于一个表达式进行编译处理时,首先需要确定表达式的结构,这时用到了运算符的优先级和结合性,然后再确定表达式运行时的行为(表达式各部分的运算次序)这里用到了运算符的运算顺序(求值顺序)。


这里需要理解的重点就是优先级、结合性、表达式各部分的运算顺序是不同的概念!




参考文章:【说说C语言运算符的“优先级”与“结合性”】 http://blog.csdn.net/steedhorse/article/details/5903974

--------------------- 

作者:GeekDonie 

来源:CSDN 

原文:https://blog.csdn.net/geekdonie/article/details/17173735 

版权声明:本文为博主原创文章,转载请附上博文链接!