【C】——C利用回調函數實現多態


案例:

  功能:可以根據用戶輸入的命令完成相應的功能;

  例如: 用戶輸入  hello   完成輸出 hello的功能。

        用戶輸入  hi   完成輸出 hi 的功能。

一般的寫法可能會寫兩個函數來實現 輸出 hello 和 hi 的功能,然后在根據用戶輸入的字符串與 hello 和 hi 比較,然后執行相應的函數。代碼如下:

 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!我們是不是可以只寫一個函數就可以完成主函數的功能呢?答案是肯定的。

第二種方案:

  首先我們需要一個數組來把所有的命令全部存放到里面,只是需要的時候我們再從數組里面找,然后把相應的命令與功能綁定到一起。因此我們可以定義一個結構體,里面存放一個 cmd 命令 和 一個cmd 命令相對應的功能函數,而這個函數應該為一個函數指針,當我們使用此函數的時候,讓系統自己調用此函數。

1 //定義一個函數指針
2 typedef void (*callback)(void);
3 //定義命令結構體
4 typedef struct cmd{
5     char name[10];  //命令的名字
6     callback func;  //與命令相對應的函數指針
7 }cmd_t;

  然后定義一個命令數組:

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語言實現了多態的功能。

  多態:基類的同一調用,在不同的子類上有不同的表現。通俗一點講就是:根據不同的類型實現不同的功能。

  而此時,我們無需關心用戶的輸入的是什么。就可以完成相應的功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM