函式指標,轉移表和回撥函式的理解
阿新 • • 發佈:2018-12-22
函式指標
函式指標顧名思義就是將函式看做一個指標,用一個指標來儲存函式的地址
函式指標的用法:
函式指標的正確寫法是 void (*p1)() 而 void *p2() 是無法存放函式指標的,因為這是返回值為指標的函式,p1先與*結合,說明p1是一個指標,指標指向一個函式,指向的函式無引數,返回值型別為void。具體用法如下例
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> void check(char *a, char *b, int(*cmp)(const char *, const char *)) { if ((*cmp)(a, b) == 0) //cmp指向庫函式strcmp(),呼叫cmp就是呼叫strcmp(),並且a和b作為引數 printf("相同\n"); else printf("不相同\n"); } int main(void) { char arr1[1024], arr2[1024]; int(*p)(const char *, const char *); //將庫函式strcmp的地址賦值給函式指標p //並且用限定符const保持呼叫後指標指向內容不變 p = strcmp; printf("請輸入兩個字串,然後進行對比\n"); scanf("%s", &arr1); scanf("%s", &arr2); check(arr1, arr2, p); return 0; }
函式指標陣列
函式指標陣列其實就是一組函式指標,兩個的關係就好比如整數和整形陣列,下面是函式指標陣列的正確寫法
int (*p[10])() p先與[]結合,說明p1是陣列,陣列的內容就是int (*)()型別的函式指標
轉移表
靈性運用轉移表可以讓我們的程式碼有更高的可維護性和可讀性,並減少我們的程式碼量,轉移表我個人理解就是將函式集中轉移到同一個地方,這樣就更加方便我們的閱讀和理解,舉個例子
如果不用轉移表實現一個計算器的功能,我們一般的做法就是定義四個函式int add(int a,int b),int sub(int a,int b),int mul(int a,int b),int div(int a,int b),然後用一個switch語句分別呼叫這四個函式,但是如果我們用轉移表就能減少工作量
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int add(int a, int b){ return a + b; } int sub(int a, int b){ return a - b; } int mul(int a, int b){ return a * b; } int div(int a, int b){ return a / b; } int main(){ int x, y; int choose=1; int ret = 0; int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; while (choose){ printf("請選擇您需要的操作,1:add 2:sub 3:mul 4:div 0:退出\n"); scanf("%d", &choose); if ((choose <= 4 && choose >= 1)){ printf("請輸入兩個整數\n"); scanf("%d %d", &x, &y); ret = (*p[choose])(x, y); } if (choose == 0){ printf("歡迎下次使用\n"); } else{ printf("輸入有誤\n"); } printf("ret=%d\n", ret); } return 0; }
回撥函式
回撥函式就是一個通過函式指標呼叫的函式。如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標被用來呼叫其所指向的函式時,我們就說這是回撥函式。而且回撥函式還有個特點,那就是回撥函式不是人為的主動呼叫,而是當某個特定時間或者條件發生時由另一方(作業系統或者第三方庫)呼叫,用於對該事件或條件進行響應
下面是具體的例子
int main(){
printf("hello world");
return 0;
}//一般的hello world程式
把它改成回撥函式形式
void print_text(){
printf("hello world");
}//這是回撥函式(被呼叫的函式)
void callback_function(void (*callbackfuct)()){
callbackfuct();
}//這是實現回撥函式的呼叫函式
//先在形參中定義函式指標,再從main函式中傳入函式的地址
//然後在呼叫函式執行時通過函式指標呼叫回撥函式
int main(){
callback_function(print_text);
//傳回調函式的地址給呼叫函式
return 0;
}
帶引數的回撥函式形式,原理和上面差不多
void print_text(char* s){
printf("%s",s);
}
void callback_function(void (*callbackfuct)(),char* s){
callbackfuct(s);
}
int main(){
callback_function(print_text,"hello world");
return 0;
}