案例:c++
功能:能够根据用户输入的命令完成相应的功能;程序员
例如: 用户输入 hello 完成输出 hello的功能。数组
用户输入 hi 完成输出 hi 的功能。ide
通常的写法可能会写两个函数来实现 输出 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 函数中开一百个分支来完成判断???idea
额,对于一个程序员来说,这多是一个 bad idea!咱们是否是能够只写一个函数就能够完成主函数的功能呢?答案是确定的。spa
第二种方案:指针
首先咱们须要一个数组来把全部的命令所有存放到里面,只是须要的时候咱们再从数组里面找,而后把相应的命令与功能绑定到一块儿。所以咱们能够定义一个结构体,里面存放一个 cmd 命令 和 一个cmd 命令相对应的功能函数,而这个函数应该为一个函数指针,当咱们使用此函数的时候,让系统本身调用此函数。code
1 //定义一个函数指针 2 typedef void (*callback)(void); 3 //定义命令结构体 4 typedef struct cmd{ 5 char name[10]; //命令的名字 6 callback func; //与命令相对应的函数指针 7 }cmd_t;
而后定义一个命令数组:blog
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语言实现了多态的功能。
多态:基类的同一调用,在不一样的子类上有不一样的表现。通俗一点讲就是:根据不一样的类型实现不一样的功能。
而此时,咱们无需关心用户的输入的是什么。就能够完成相应的功能。