试图让foo返回指向fun2的函数指针失败,求分析问题原因
问题分析与解决方案
你的代码核心问题在于函数指针的算术运算属于未定义行为,直接对函数指针f执行f+1操作不符合C标准,导致返回的指针无效,调用后触发异常,所以y没有输出。
为什么原代码不行?
C标准仅允许对指向对象(比如数组元素、结构体实例等)的指针进行合法算术运算。函数指针指向的是函数代码的起始地址,并非数组中的元素对象——即便f来自函数指针数组的元素,f的类型依然是int (*)(int,int)(函数指针),而非指向数组元素的二级函数指针int (**)(int,int)。对函数指针执行+1操作时,编译器无法确定正确的地址偏移量,最终得到的是无效指针,调用该指针会触发未定义行为(比如程序无响应、崩溃、无输出等)。
正确的实现方式
要实现通过指针算术获取数组中下一个函数指针的需求,需要让foo函数接收二级函数指针(指向函数指针数组元素的指针),这样才能合法进行指针运算。修改后的代码如下:
#include <stdio.h> // 修改参数为二级函数指针 int (*foo(int (**f)(int, int)))(int, int) { printf("hello"); return *(f + 1); // 取数组下一个元素的函数指针返回 } int fun1(int x, int y) { return x + y; } int fun2(int x, int y) { printf("hey"); return x * y; } int main() { int (*fun_ptr[2])(int, int); int x, y; fun_ptr[0] = &fun1; x = fun_ptr[0](4, 5); printf("%d\n", x); // 修正换行符写法 fun_ptr[1] = &fun2; // 传入指向fun_ptr[0]的二级指针 fun_ptr[0] = foo(&fun_ptr[0]); y = fun_ptr[0](4, 5); printf("%d", y); return 0; }
关键修改点
- 将
foo的参数类型从int (*f)(int,int)改为int (**f)(int,int),使其成为指向函数指针数组元素的指针。 - 调用
foo时传入&fun_ptr[0],而非fun_ptr[0],确保传递的是二级指针。 - 修正原代码中
printf("%d ",x)的换行符错误,改为标准的\n。
运行修改后的代码,会依次输出9、hello、hey、20,符合预期。
内容的提问来源于stack exchange,提问作者Abhirup
相关产品推荐
相关产品推荐

