文章目錄
- 1.函式指標
- 2.函式指標陣列
- 3.指向函式指標陣列的指標
- 4.回呼函式
1.函式指標
我們知道,整型指標是指向整型的指標;陣列指標是指向陣列的指標;以此類推,那么 函式指標就是指向函式的指標,
和其他指標一樣,在講解函式指標之前,首先明白這三點:
1.( )的優先級高于 *
2.定義一個變數是,除去變數名,剩下的就是它的變數型別
3.一個指標變數去除變數名和 * 剩下的就是指標指向的內容的型別
對于函式指標,舉個栗子:
#include<stdio.h>
int Add(int x, int y)
{
return x + y;
}
int main()
{
int(*p)(int, int) = &Add;//取出函式的地址放在函式指標p中
return 0;
}
此時的變數 p 就為一個函式指標變數,
那么如何定義函式指標的呢?圖示如下:

即定義一個函式指標時,指標的型別要與函式的型別一致,
例如
void test ( char* str ) 為一個函式,那么定義一個指向它的函式指標就為:
void ( * p ) ( char * )
補充說明一點:
對于陣列而言: 陣列名 != &陣列名
對于函式而言: 函式名 = &函式名( 規定)
那么如何使用函式指標呢?
看如下代碼:
int add(int x, int y)
{
return x + y;
}
int main()
{
int (*p)(int, int) = &add;
int ret = (*p)(3, 5);//對p解參考,然后再傳入引數即可
printf("%d\n", ret);
return 0;
}

即通過對函式指標解參考找到該函式,然后傳入引數就可實作函式的呼叫,
深入探究:
對于 int (*p)(int, int) = &add; 此行代碼,我們又知道 函式名 = &函式名,
那么代碼也可寫成 int (*p)(int, int) = add; 因為指標p中存放的為函式add的地址,所以我們就能這樣理解:p == add ,即 p 與函式名 add 為一回事,所以當我們呼叫函式時,可以寫:
add ( a , b ) == p ( a , b ) == (*p) ( a , b ) ---- 經過代碼驗證,輸入的結果一樣,
這樣一來,我們就知道了 ( *p ) ( 3, 5) 中的 解參考符號 * 是沒有任何意義的,在寫程式時,可寫可不寫,
2.函式指標陣列
我們知道,陣列是一個存放相同資料型別的空間,例如:
int arr[ 10 ] 為一個整型陣列,存放10個元素,每個元素 int 型整數
char* arr[ 10 ] 為一個指標陣列,存放10 個元素,每個元素為 char* 型指標
. . .
那么如果要將函式指標存放在一個陣列中,那么這個陣列就為函式指標陣列
如何定義函式指標陣列?例如:
定義 int (*parr[10])( int , int )
parr[10] 就為一個函式指標陣列,可以存放10個函式指標,每個函式指標的型別為 int (* )( int , int ) 型,
所以簡單來說,創建一個函式指標,只需要在原有的函式指標的形式下加上
[ ] 即可,例如:
存在函式指標:int (*p)(int, int) = &add
此時要創建一個存放指標 p 的陣列,那么函式指標陣列定義為:
int ( * parr[10] )( int , int )
該函式指標陣列能存放 10 個與指標p型別一樣的函式指標
函式指標陣列的應用:轉移表
舉個栗子:模擬計算器
int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
int mul(int x, int y)
{
return x * y;
}
int div(int x, int y)
{
return x / y;
}
int main()
{
int input = 1;
int (*p[5])(int, int) = { 0,add, sub, mul,div };
while (input)
{
printf("************************\n");
printf("** 1.add 2.sub **\n");
printf("** 3.mul 4.div **\n");
printf("************************\n");
scanf("%d", &input);
if (input >= 1 && input <= 4)
{
int i = 0;
int j = 0;
printf("請輸入運算元:");
scanf("%d %d", &i, &j);
int ret = (*p[input])(i,j);
printf("結果為:%d\n", ret);
}
else
{
printf("輸入錯誤!\n");
}
}
return 0;
}

這里就巧妙地運用了函式指標陣列,將運算的函式存放在函式指標陣列p中,
再通過陣列的下標找到相應函式,解參考后傳參就可呼叫相應函式,
相比于switch-case陳述句來每次呼叫函式,使用函式指標陣列更為方便,且代碼量相對少,避免代碼冗余,
3.指向函式指標陣列的指標
說明:
指向函式指標陣列的指標是一個 指標,
該指標指向一個 陣列 ,陣列的元素都是 函式指標 ;
如何定義?
void test(const char* str)
{
printf("%s\n", str);
}
int main()
{
void (*pfun)(const char*) = test;//函式指標 pfun
void (*pfunArr[5])(const char* str);//函式指標陣列 pfunArr
pfunArr[0] = test;
void (*(*ppfunArr)[10])(const char*) = &pfunArr;
//指向函式指標陣列 pfunArr 的指標 ppfunArr
return 0;
}
void ( * ( * ppfunArr )[10])(const char*) = &pfunArr; 即為指向函式指標陣列的指標 ppfunArr 的定義
對于指向函式指標陣列的指標的講解就不多說了,僅作了解即可,
4.回呼函式
所謂回呼函式就是一個通過函式指標呼叫的函式,如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標被用來呼叫其所指向的函式時,我們就說這是回呼函式,回呼函式不是由該函式的實作方直接呼叫,而是在特定的事件或條件發生時由另外的一方呼叫的,用于對該事件或條件進行回應,
舉個簡單的栗子:
void test2()
{
printf("Hello world!");
}
void test1(void (*p)()) //形參用函式指標接收,該指標指向 test2
{
p(); //呼叫函式指標
}
int main()
{
test1(test2); //將函式test2作為引數,即將函式test2的地址傳過去
return 0;
}

類似以上程式中函式的呼叫機制就很好的利用了回呼函式,
回呼函式的意義就在于可以通過一個函式從而實作多個函式的呼叫,可以有效的減少代碼冗余的出現,
回呼函式機制的運用在這里先不做說明,我會在下一篇博客中做具體詳解,
希望大家多多關注哦!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/294275.html
標籤:其他
上一篇:Microsoft Windows MHTML腳本代碼注入漏洞 (MS11-026) (CVE-2011-0096)

