函數指針在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],0x4015c0
0x4015eb mov eax,DWORD PTR [esp+0xc]
0x4015ef call eax
分析:第一行mov指令將立即數0x4015c0賦值給寄存器esp+0xc的地址內存中,然后將寄存器esp+0xc地址的值賦值給寄存器eax(累加器),然后調用call指令,此時pc指針將會指向add函數,而0x4015c0正好是函數add的首地址,這樣就完成了函數的調用。細心的讀者是否發現一個有趣的現象,上述過程中函數指針的值和參數一樣是被放在棧幀中,這樣看起來就是一個參數傳遞的過程,因此可以看到,函數指針最終還是以參數傳遞的形式傳遞給被調用的函數,而這個傳遞的值正好是函數的首地址。
從上面可以看到函數指針并不是和一般的指針一樣可以操作內存,因此作者覺得函數指針可以看作是函數的引用申明。
-
Linux
+關注
關注
87文章
11411瀏覽量
212217 -
C語言
+關注
關注
180文章
7626瀏覽量
139535 -
函數指針
+關注
關注
2文章
57瀏覽量
3903
發布評論請先 登錄
相關推薦
C語言中指針函數和函數指針的概念及應用示例
ARM的函數指針、指針函數的區別和用法
求求你,不要再糾結指針了(2)——函數指針

評論