C語言進階:指針的進階(5)
函數指針數組
//整型數組 - 存放整型變量 int arr[10]; //字符數組 - 存放字符變量 char ch[5]; //指針數組 - 存放指針變量 int* arr[10]; //函數指針數組 - 存放函數指針 int(*pfar[10])(int, int);
指針數組存放指針變量,函數指針數組存放函數指針,故元素類型為函數指針類型。
函數指針數組的定義
int Add(int x, int y) {//int(*)(int,int) return x + y; } int Sub(int x, int y) {//int(*)(int,int) return x - y; } int Mul(int x, int y) {//int(*)(int,int) return x * y; } int Div(int x, int y) {//int(*)(int,int) return x / y; } int main() { //函數指針數組 - pfArr int(*pfArr[4])(int, int) = { Add,Sub,Mul,Div }; return 0; }
類型相同的函數,存放在同一個函數指針數組中。一般功能相似的函數,其類型也相同。
函數指針數組的使用
利用函數指針數組實現計算器,以簡化調用過程。
轉移表
//計算器實現1.0 void menu() { printf("**********************************\n"); printf("***** 1.Add ****** 2.Sub *****\n"); printf("***** 3.Mul ****** 4.Div *****\n"); printf("************ 0.exit ************\n"); printf("**********************************\n"); } int main() { int (*pfArr[10]) (int, int) = { 0,Add,Sub,Mul,Div };//數組下標和選項序號匹配 int input = 0; int a = 0; int b = 0; do { menu(); printf("請選擇:>"); scanf("%d", &input); if (0 <= input && input <= 4) { if (input == 0) { printf("退出遊戲\n"); break; } else { printf("請輸入操作數\n"); scanf("%d %d", &a, &b); printf("ret == %d\n", pfArr[input](a, b)); break; } } else { printf("輸入錯誤\n"); break; } } while (input); return 0; }
函數指針數組實現不同選擇情況下,通過函數地址“跳轉”到不同的函數的功能。
這樣的函數指針數組成為轉移表。(跳轉功能)
回調函數
若不想舍棄switch語句,還可以這樣簡化代碼3.0,代價為創建全局變量。若不想創建全局變量,可以使用2.0
/****** * 計算器實現 * 2.0 ******/ void Calc(int (*pf)(int,int)) { int a = 0; int b = 0; printf("請輸入操作數:>"); scanf("%d %d", &a, &b); printf("%d\n", pf(a, b)); } int main() { int input = 0; do { menu(); printf("請選擇:>"); scanf("%d", &input); switch (input) { case 0: printf("退出成功\n"); break; case 1: Calc(Add); break; case 2: Calc(Sub); break; case 3: Calc(Mul); break; case 4: Calc(Div); break; default: printf("請重新選擇\n"); break; } } while (input); return 0; } /****** * 計算器實現 * 3.0 ******/ int (*pfArr[10])(int, int) = { 0,Add,Sub,Mul,Div }; int input = 0; void Call() { int a = 0; int b = 0; printf("請輸入操作數:>"); scanf("%d %d", &a, &b); printf("%d\n", pfArr[input](a, b)); } int main() { do { menu(); printf("請選擇:>"); scanf("%d", &input); switch (input) { case 0: printf("退出成功\n"); break; case 1: case 2: case 3: case 4: Call(); break; default: printf("請重新選擇\n"); break; } } while (input); return 0; }
如下圖所示,被通過函數指針調用的函數叫做回調函數,回調函數即使第三方調用調用函數的參數也在其中被調用。
若想在調用函數中隨條件變化而調用不同的函數,就必須使用回調函數的方法:調用函數中使用函數指針,指向不同函數。回調函數在大型工程中顯得非常方便。
指向函數指針數組的指針
int arr[10]; int(*parr)[10] = &arr;//整型數組指針 char(*pch)[10] = &ch;//字符數組指針 //指向整型數組指針的指針 int(*(*pparr))[10] = &parr; //指向字符數組指針的指針 char(*(*ppch))[10] = &pch; //函數1. int Add(int x, int y) { return x + y; } //函數指針2. int (*pf)(int, int) = Add; //函數指針數組3. int (*pfArr[10])(int, int) = { Add }; //指向函數指針數組的指針4. int(*(*ppfArr)[10])(int, int) = &pfArr;
前面已經交代,指針去掉*號和指針名,就是指向的變量類型;去掉指針名就是指針的類型。
反過來,定義數組指針,需要得到指針所指向的數組的類型。1.先寫出指針名,在其前面加*;2.寫出數組的類型int()[10]
定義指向函數指針數組的指針,依次寫出如下內容:
1.函數 —— 得到函數類型:int(int, int)
2.函數指針 —— 得到函數指針類型:int(*)(int, int)
3.函數指針數組 —— 得到函數指針數組的類型:int(*[10])(int, int)
4.指向函數指針數組的指針
從後往前看,指向函數指針數組的指針去掉*和指針名就是函數指針數組的類型,函數指針數組去掉*和指針名就是函數指針類型,函數指針去掉*和指針名就是函數類型。
在研究下去就沒有必要瞭,指針放在數組裡,數組被指針所指向……
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!