C语言逻辑与一元运算符优先级疑问:为何未先执行所有自增操作?
为什么C语言里逻辑运算的短路求值会跳过高优先级的自增?
这个问题戳中了很多C语言学习者容易混淆的点——运算符优先级和求值顺序的区别,咱们一步步理清楚:
先看你给出的代码:
int a = 1, b = 2, c = 3, d; d = a++ && b++ || c++; printf("%d\n", c);
你已经观察到输出是3,原因是||的短路特性:当左边表达式为真时,右边的c++根本不会执行。那为什么优先级更高的++没有先全部执行呢?
核心误区:优先级≠求值顺序
很多人会误以为优先级高的运算符就一定会先执行,但其实:
- 运算符优先级决定的是表达式的语法结构——也就是各个运算符和操作数的绑定关系,相当于给表达式加括号,确定谁和谁是一组;
- 求值顺序则是编译器计算各个操作数和表达式的先后顺序,这在C语言里,只有部分运算符(比如
&&、||、?:、逗号运算符)有明确的左到右求值规定,其他大部分运算符的求值顺序是未定义的。
拆解你的表达式
按照优先级,++的优先级高于&&和||,所以你的表达式会被编译器解析成这样的结构:
d = ((a++) && (b++)) || (c++);
注意,这只是确定了各个操作数的绑定关系,不是说要先把a++、b++、c++都算完再处理逻辑运算。
接下来看逻辑运算符的求值规则:
- 先计算
&&左边的a++:后置自增,所以表达式的值是a原来的1(为真),然后a变成2; - 因为
&&左边为真,所以继续计算右边的b++:表达式的值是b原来的2(为真),b变成3; - 此时
((a++) && (b++))的结果为真,轮到||运算——C语言规定||只要左边为真,就直接返回结果,完全不会计算右边的表达式,所以c++根本没机会执行,c的值保持3不变。
再举个例子帮你区分
比如表达式int res = x++ * ++y;,优先级上++高于*,所以结构是res = (x++) * (++y);,但求值顺序呢?C语言并没有规定是先算x++还是先算++y,不同编译器可能有不同结果;但如果是int res = x++ && ++y;,C语言就明确规定先算x++,如果x++为假,++y就直接跳过。
所以回到你的问题:不是C语言不遵守优先级规则,而是优先级管的是“谁和谁一组”,而逻辑运算符的短路求值是“什么时候算哪一组”的问题,两者不冲突。
内容的提问来源于stack exchange,提问作者Krash
相关产品推荐
相关产品推荐

