C语言中printf内变量自增输出与预期不符的原因咨询
为什么C语言中这两个printf的输出和预期不符?
嘿,这个问题其实踩中了C语言里一个非常经典的坑——函数参数的求值顺序是未指定行为,再加上自增运算符的副作用时机,才导致了和你预期不一样的结果。咱们一步步拆解来看:
首先先把你的代码贴出来方便对照:
#include <stdio.h> void f(int a, int b, double c){ printf("%d \n", a); printf("%d \n", b); printf("%f \n", c); } int main(void){ int i = 0, x = 7; float a = 2.25; f (x=5, x-7, a); printf("\n\n"); f (x = 6, x-7, a); printf("\n\n"); printf("%d %d\n",i, i++ ); printf("%d %d\n",i, ++i ); return 0; }
先看第一个异常的printf:printf("%d %d\n",i, i++ );
你预期输出0 0,但实际得到1 0,原因在于:
C语言标准没有规定函数参数的求值顺序——编译器完全可以选择先计算第一个参数,或者先计算第二个参数。在你的编译环境里,它优先计算了第二个参数i++:
i++是后置自增运算符:它会先返回变量当前的值(也就是0),然后再把i的值加1(此时i变成1)。- 等计算第一个参数
i的时候,i已经被自增成1了,所以最终输出就是1 0。
再看第二个异常的printf:printf("%d %d\n",i, ++i );
你预期输出1 1,实际得到2 2,逻辑和上面一致:
- 编译器还是优先计算了第二个参数
++i:前置自增运算符会先把i的值加1(从1变成2),然后返回修改后的值(2)。 - 接着计算第一个参数
i时,i已经是2了,所以输出就是2 2。
关键提醒:这种行为是未指定的
这里要划重点:这种参数求值顺序属于未指定行为——不同的编译器(甚至同一编译器的不同优化等级)可能会做出完全不同的选择,输出结果也会不一样。所以写C代码的时候,一定要避免在同一个函数调用里,对同一个变量同时进行“读取”和“修改”操作,这是非常危险的写法。
内容的提问来源于stack exchange,提问作者gokhan_ozeloglu
相关产品推荐
相关产品推荐

