案例:html
功能:能夠根據用戶輸入的命令完成相應的功能;c++
例如: 用戶輸入 hello 完成輸出 hello的功能。程序員
用戶輸入 hi 完成輸出 hi 的功能。數組
通常的寫法可能會寫兩個函數來實現 輸出 hello 和 hi 的功能,而後在根據用戶輸入的字符串與 hello 和 hi 比較,而後執行相應的函數。代碼以下:ide
1 //回調函數的用處 2 #include <stdio.h> 3 #include <string.h> 4 5 void hello(void); 6 int my_strcmp(char* des, char* src); 7 void hi(void); 8 9 int main(void){ 10 char val[20] = {}; 11 while(1){ 12 gets(val); 13 if(!my_strcmp(val,"hello")){ 14 hello(); 15 } 16 else if(!my_strcmp(val,"exit")){ 17 break; 18 } 19 else if(!my_strcmp(val,"hi")){ 20 hi(); 21 } 22 } 23 return 0; 24 } 25 void hello(void){ 26 printf("hello\n"); 27 } 28 void hi(void){ 29 printf("hi\n"); 30 } 31 32 //字符串比較函數 33 int my_strcmp(char* des, char* src){ 34 while(*des){ 35 if(*des != *src) 36 return 1; 37 des++; 38 src++; 39 } 40 return *src - *des; 41 }
好像這樣寫也聽不錯的。能夠完美的完成需求。可是若是當命令再增長一個,咱們是否是就須要再寫一個功能函數,而後再增長一個分支。若是當某天命令加到上百個的時候咱們是否是也要在 main 函數中開一百個分支來完成判斷???函數
額,對於一個程序員來說,這多是一個 bad idea!咱們是否是能夠只寫一個函數就能夠完成主函數的功能呢?答案是確定的。idea
第二種方案:指針
首先咱們須要一個數組來把全部的命令所有存放到裏面,只是須要的時候咱們再從數組裏面找,而後把相應的命令與功能綁定到一塊兒。所以咱們能夠定義一個結構體,裏面存放一個 cmd 命令 和 一個cmd 命令相對應的功能函數,而這個函數應該爲一個函數指針,當咱們使用此函數的時候,讓系統本身調用此函數。code
1 //定義一個函數指針 2 typedef void (*callback)(void); 3 //定義命令結構體 4 typedef struct cmd{ 5 char name[10]; //命令的名字 6 callback func; //與命令相對應的函數指針 7 }cmd_t;
而後定義一個命令數組:htm
1 //聲明命令數組 2 const cmd_t cmd_tbl[] = { 3 {"hello",cmd_hello}, 4 {"hi",cmd_hi}, 5 {"exit",cmd_exit}, 6 };
跟命令相對應的函數爲:
1 static void cmd_hello(void){ 2 hello(); 3 } 4 5 static void cmd_hi(void){ 6 hi(); 7 } 8 9 static void cmd_exit(void){ 10 exit(0); 11 }
相對應的功能函數爲:
1 void hello(void){ 2 printf("hello\n"); 3 } 4 void hi(void){ 5 printf("hi\n"); 6 }
此時咱們還須要一個查找命令函數:
1 cmd_t* my_find(const char* val){ 2 int i; 3 for(i = 0; i < sizeof(cmd_tbl)/sizeof(cmd_tbl[0]); i++){ 4 if(!my_strcmp(val,cmd_tbl[i].name)){ 5 return &cmd_tbl[i]; 6 } 7 } 8 return 0; 9 }
此函數返回的是一個結構體指針,若沒有找到命令則返回0;
main 函數以下:
1 int main(void){ 2 char val[20] = {}; 3 cmd_t *cmd_ptr; 4 while(1){ 5 gets(val); 6 cmd_ptr = my_find(val); 7 if(cmd_ptr){ 8 cmd_ptr->func(); 9 } 10 else{ 11 printf("no cmd\n"); 12 } 13 } 14 return 0; 15 }
此時的代碼的可讀性就變得很高了,若是想添加另外一條命令的時候,main 函數根本不用動,只須要在命令數組中添加數組,而後添加一個命令相對應的功能函數就能夠了。 本身寫的函數不須要本身調用,而是根據用戶所輸入的信息調用相應的函數,以上結構體的函數成爲回調函數。正是由於回調函數的存在讓C語言實現了多態的功能。
多態:基類的同一調用,在不一樣的子類上有不一樣的表現。通俗一點講就是:根據不一樣的類型實現不一樣的功能。
而此時,咱們無需關心用戶的輸入的是什麼。就能夠完成相應的功能。