为何f(25)与pf(25)等价?C语言函数名与指针疑问
关于C语言函数名与函数指针的疑问解答
先看示例代码:
int f(int); int (*pf)(int)=&f; int ans; ans=f(25); ans=(*pf)(25); ans=pf(25);
《C和指针》一书指出
f(25)与pf(25)等价,原因是调用函数时函数名f会被转换为指向该函数内存地址的函数指针,再通过函数调用运算符执行代码。这与原有认知相悖:
- 声明变量
int a并将其作为右值时,a直接标识内存位置并获取其中的值;为何函数名不直接标识函数的内存位置,而是要转为指针?- 若未声明指向函数的指针,函数名转换后的指针存储在哪里?
- 变量
a与&a的值不同,需通过*&a才能获取a的值,为何f(25)却与pf(25)等价?
为什么函数名调用要先转成指针?
这是C语言标准规定的语法规则:函数名在绝大多数表达式语境下(除了作为sizeof、&运算符的操作数时)会隐式转换为指向自身的函数指针,而函数调用运算符()的操作数要求是函数指针,不是函数本身。
变量和函数的本质逻辑不同:变量是存储数据的内存块,作为右值时直接取数据;但函数是存储指令的内存块,C语言设计时把函数调用的逻辑绑定到了指针上,这样不管是用函数名还是函数指针变量,调用逻辑都能统一,避免语法分裂。
函数名转换后的指针存在哪?
这个转换是编译阶段完成的,不会在运行时生成实际的指针变量存储在内存里。编译时编译器会直接把函数名替换成对应的函数入口地址,相当于硬编码到指令中,运行时CPU直接跳转到该地址执行,不需要额外存储指针。
为什么f(25)和pf(25)等价?
变量的逻辑是:a是变量值,&a是变量地址,*&a等价于a,因为*和&是互逆操作。但函数的规则有特殊设计:
- 写
f时,它自动转成&f(函数指针); - 对函数指针用
*,比如*pf,它又会自动转成函数本身,而函数本身又会再转成指针——所以(*pf)其实等价于pf; ()运算符不管操作数是函数名还是函数指针,都会先把操作数转成函数指针再执行调用。
简单说就是C语言给函数调用做了语法糖:不管你写的是函数名、&函数名、*函数指针还是直接用函数指针,最终都会被处理成函数指针来调用,所以f(25)、(*pf)(25)、pf(25)全都是等价的。
内容的提问来源于stack exchange,提问作者zhm
相关产品推荐
相关产品推荐

