请求解析下述C语言代码的输出结果及运行流程
代码执行流程与输出解析
先贴出问题中的代码:
#include <stdio.h> void fun(int a, float b) { int c; c = a + b; printf("Value ----- c %d", c); } int main() { void (*foo) (int, int) = &fun; (*foo)(3,2); return 0; }
核心问题:函数指针类型不匹配
这段代码的关键问题在于函数指针foo的类型和目标函数fun的类型不匹配:
fun的参数是(int, float),但foo被声明为接受(int, int)的函数指针,这种赋值属于未定义行为(C标准不保证执行结果),但我们可以基于常见编译器的调用逻辑解释为什么输出3。
执行流程与输出原因
- 参数传递阶段:
调用(*foo)(3,2)时,因为foo被声明为接受两个int参数的指针,编译器会按int类型的大小(通常32位)把3和2依次压入栈中。 - 函数
fun的参数读取:
但fun的第二个参数是float类型,根据C语言的默认参数提升规则,float参数会被提升为double(通常64位)来传递。所以fun会从栈中读取64位的数据作为第二个参数b。
此时栈中对应位置的数据是int类型的2(32位0x00000002),剩下的32位是栈内的垃圾数据,组合成的64位值对应的double是一个极小的接近0的数(double的高位为0,指数部分为0,属于非规格化数,数值趋近于0)。 - 计算与输出:
c = a + b中,a是3,b是接近0的极小值,当把这个和转换为int类型时,小数部分会被截断,结果就是3。最后printf输出c的值为3。
重要提示
这种写法属于未定义行为,不同编译器、不同平台可能输出不同结果,甚至程序崩溃。实际开发中必须保证函数指针的类型与目标函数完全匹配。
内容的提问来源于stack exchange,提问作者Selvamuthukumaran
相关产品推荐
相关产品推荐

