C语言中含自增运算符的表达式求值及标准合规性问询
C语言自增表达式与序列点的合规性问题
第一个代码案例
#include<stdio.h> int main() { int a=4; int b=4; int c= a++ < ++b? 1 : 0; printf ("%d",c); }
这段代码编译运行后输出1。已知三元运算符?处存在序列点,要求所有自增操作必须在该点前完成。这里++b是前缀自增,会在比较前完成自增,但a++是后缀自增,它的自增操作是在<比较之前还是之后执行?如果在比较前自增,a变成5,b变成5,5<5为假,c会被设为0;但实际输出1,说明a++是先用原值4参与比较,之后再完成自增。这种行为是否符合C语言规范?
第二个代码案例
#include<stdio.h> int main() { int a=4; int b=4; int d=2; int c= a++ + d < ++b + d? 1 : 0; printf ("%d",c); }
运行结果仍为1。同样,后缀自增a++需要在?前完成,但这是否能保证它的自增操作一定在<比较之后执行?
解答
根据C语言标准的定义:
- 后缀自增运算符
a++的求值结果是变量a的当前值,而a的自增操作(将新值存储回a)属于副作用,这个副作用必须在下一个序列点之前完成,但标准并未要求副作用必须在该表达式的求值结果被使用之前执行。 - 前缀自增运算符
++b的求值过程是先完成自增操作,再返回自增后的值,这是明确的定义。
针对第一个案例:a++的求值结果是4,用这个值和++b返回的5进行比较,4<5为真,所以c=1。a的自增操作(变为5)只要在?这个序列点之前完成即可,不需要在<比较前执行,完全符合规范。
针对第二个案例:a++的求值结果是4,加上d=2得到6;++b先自增到5,加上d=2得到7;6<7为真,所以c=1。a的自增操作同样只要在?序列点前完成即可,标准不限制它在加法或比较操作前执行,只要保证a++返回原值就合规。
结论:编译器的输出结果完全符合C语言规范,后缀自增的副作用仅需在序列点前完成,无需提前到子表达式的具体操作之前。
内容的提问来源于stack exchange,提问作者user2277550
相关产品推荐
相关产品推荐

