函数指针在linux内核和c语言开发中用的非常多,而且在设计操作系统的时候也会用到,因此这里将详细讲解函数指针。既然函数指针也是指针,那函数指针也占用4个字节(32位编译器)。下面以一个简单的例子说明:
#include int add(int a,int b){ return a+b;}int main(int argc, char **argv){ int (*p)(int,int); p=add; printf(add(10,20)=%d\n,(*p)(10,20)); return 0;} 函数指针的解引操作与普通的指针有点不一样,对于普通的指针而言,解引只需要根据类型来取出数据即可,但函数指针是要调用一个函数,其解引不可能是将数据取出,实际上函数指针的解引本质上是执行函数的过程,只是这个执行函数是使用的call指令并不是之前的函数,而是函数指针的值,即函数的地址。其实执行函数的过程本质上也是利用call指令来调用函数的地址,因此函数指针本质上就是保存函数执行过程的首地址。
为了确认函数指针本质上是传递给call指令一个函数的地址,下面用一个简单例子说明:
上面是编译后的汇编指令,可以看到,使用函数指针来调用函数时,其汇编指令多了如下:
0x4015e3 mov dword ptr [esp+0xc],0x4015c00x4015eb mov eax,dword ptr [esp+0xc]0x4015ef call eax 分析:第一行mov指令将立即数0x4015c0赋值给寄存器esp+0xc的地址内存中,然后将寄存器esp+0xc地址的值赋值给寄存器eax(累加器),然后调用call指令,此时pc指针将会指向add函数,而0x4015c0正好是函数add的首地址,这样就完成了函数的调用。细心的读者是否发现一个有趣的现象,上述过程中函数指针的值和参数一样是被放在栈帧中,这样看起来就是一个参数传递的过程,因此可以看到,函数指针最终还是以参数传递的形式传递给被调用的函数,而这个传递的值正好是函数的首地址。
从上面可以看到函数指针并不是和一般的指针一样可以操作内存,因此作者觉得函数指针可以看作是函数的引用申明。
DSP虚拟I2C软件包的应用设计案例
台积电研发3nm工艺遇阻
Agilent安捷伦E8364A网络分析仪E8364B
NVIDIA收购ARM,加速了RISC-V在边缘AI的神经网路方面的应用
摩托罗拉Edge +揭示了带有打孔的精美瀑布显示屏
函数指针的使用简述
纳芯微推基于“Adaptive OOK”新一代增强型数字隔离芯片NSi82xx系列
2023开放原子全球开源峰会参会指南
分享使用 LTspice 进行电源电路设计的技巧
小米官方发微 19号的新机不止一款将会有一款屏幕指纹新机一同发布
苹果三星Fitbit在可穿戴健康设备领域做了哪些布局
电瓶修复技术:充电器最土但有效的方法是什么
教你如何计算MOS管的开关电路(一)
从零开始入门 | Kubernetes 中的服务发现与负载均衡
称重传感器激励电压
伟大的工程之芯片制造
影像仪设备用途有哪些?
美国加大政策补贴 各大厂商竞相开发直管萤光灯驱动IC
Matter 1.0正式发布,智能家居行业迎来大一统?
日本第一家,本田将推L3自动驾驶Legend