前言:
爲了方便查看博客,特意申請了一個公衆號,附上二維碼,有興趣的朋友可以關注,和我一起討論學習,一起享受技術,一起成長。
1. 函數指針的定義
函數的指針,它是一個指針,指向一個函數。
舉例:
A:char *(*func1)(char *p1,char *p2);
B:char * *func2(char *p1,char *p2);
C:char *func3(char *p1,char *p2);
解釋:
A:這裏 func1 不是函數名,而是一個指針變量,指向一個函數。這個函數有兩個指針類型的參數,函數的返回值也是指針。可以理解爲:(char *) 類型的指針變量 *func1 。
B:func2 是函數名,帶兩個參數,返回值爲 char ** 類型,是一個二級指針。
C:func3 是函數名,帶兩個參數,返回值爲 char * 類型。
2. 函數指針的運用
測試:
char *func(char *p1, char *p2)
{
int i = 0;
i = strcmp(p1,p2);
if (i == 0)
{
return p1;
}
else
{
return p2;
}
}
調用函數指針:
int main(void)
{
/*定義一個函數指針變量*/
char *(*pf)(char *p1, char *p2);
pf = &func;/*初始化,將函數的地址取出來*/
(*pf)("aa","bb");/*地址是個實際值*/
getchar();
return 0;
}
注:
//定義一個函數指針變量,(*pf) 括號不能省略
eg:int (*pf)funcx(int ,int)
3. *(int *)&p
void FuncPri(void)
{
printf("void func ! \r\n");
}
int main(void)
{
void (*pv)();
*(int *)&pv = (int)FuncPri;
(*pv)();
getchar();
return 0;
}
註解:
(1)void (*pv)():定義一個指針變量 pv,pv 指向一個函數,這個函數的參數和返回值都是 void。
(2)&pv:取指針 pv 本身的地址,在 32 位系統,它爲一個 32 位的二進制數。
(3)(int *)&pv:表示將地址強制轉換成指向 int 類型的數據。
(4)*(int *)&pv = (int)FuncPri:表示將函數的入口地址賦值給指針變量 pv。那麼 (*pv)() 就是表示對函數的調用。
函數指針的作用:
可以將實現同一功能的多個模塊統一起來標識,便於後期維護,系統結構更清晰,便於分層設計,利於系統抽象,降低耦合度,使接口與實現分開。
4. ((void() ())0) ()
分析:
(1)void (*)():一個函數指針,無返回值,無參數;
(2)(void(*) ())0:將 0 強制轉換成函數指針類型,0 是一個地址,即一個函數存在首地址爲 0 的一段區域內。
(3)((void() ())0):取 0 地址開始的一段內存內的內容,內容就是保存在首地址爲 0 的一段區域內的函數。
(4)((void() ())0) ():函數調用。
5. 函數指針與指針函數
對比 | 函數指針 | 指針函數 |
---|---|---|
實質 | 一個指針,一個變量,常用來調用函數 | 一個函數,返回值是指針類型的函數,有自己的函數體 |
格式 | 數據類型關鍵字 *Func(形參),eg:char *Func(void); | 數據類型關鍵字 (*指針名)(形參),eg:int (*pf)(int,int *); |
通過 typedef 關鍵字來統一命名函數指針:
形式:形式2:typedef 返回類型(*新類型)(參數表)
typedef int (*pFunc)(int, int); // 聲明一個函數指針類型
//返回值爲int類型,兩個參數爲 int 類型
參考: