为何typedef函数指针的测试代码无需&或*也能正常运行?
关于C语言函数指针的几个常见疑惑
1. 为什么typedef函数指针时不需要写*result()?
你可能混淆了两种合法的typedef方式:
- 第一种是直接typedef函数类型:
后续声明函数指针时,只需给这个类型加typedef int ResultFunc(int); // 定义的是「返回int、参数为int的函数」类型*:ResultFunc* func_ptr;,这和直接写int (*func_ptr)(int);完全等价。 - 第二种是直接typedef函数指针类型:
这时声明指针直接用typedef int (*ResultFuncPtr)(int); // 直接定义函数指针类型ResultFuncPtr func_ptr;即可。
你所说的「无需用*result()」,应该是用了第一种typedef方式——本质是把函数类型单独typedef,后续用指针时补*,这是C标准允许的写法,两种方式只是语法形式不同,效果完全一致。
2. 为什么赋值时不用&result,用了也能跑?
这是C语言的核心规则:函数名在表达式中(除了作为&的操作数,或是sizeof的操作数时),会被自动隐式转换成指向该函数的指针。
举个实际例子:
int result(int x) { return x+1; } // 以下三种赋值写法完全等价 func_ptr = result; // 函数名自动转为指针 func_ptr = &result; // 显式取函数地址,和上面效果一致 func_ptr = *result; // 解引用指针得到函数实体,但实体又会自动转成指针,最终结果不变
简单说,result、&result、*result在赋值给函数指针时,最终都会被编译器处理成同一个函数入口地址——这就是三种写法都能运行的原因。
3. 编译器的处理逻辑
编译器处理函数名时遵循以下逻辑:
- 看到单独的函数名(比如赋值语句右侧的
result),直接将其替换为该函数的入口地址(即指针值)。 - 看到
&result,由于函数本身就是代码块的入口,取它的地址本质就是直接获取这个入口地址,和函数名隐式转换的结果完全一致。 - 看到
*result,编译器先把result转成指针,解引用后得到函数实体,但这个实体又会立刻被隐式转换成指针——等于绕了一圈回到原点,最终结果还是同一个指针值。
这些都是C标准明确规定的行为,所有符合标准的C编译器都会按此处理。
内容的提问来源于stack exchange,提问作者DesertEaglePt50
相关产品推荐
相关产品推荐

