zhangyunxin411 2026.9.5
1. 什么是函数指针
- 函数指针实际上就是一种指针,指向的是函数,比如:
int(*p)(int,int);// 表示指针p指向一个参数为(int, int),返回值为int的函数 - 函数指针怎么用,函数指针就是一种指针类型,要使用同样需要声明和定义:
intfun(inta,intb){...}int(*p)(int,int);p=fun; - 利用 typedef 对函数指针起别名,顺便归纳一下 typedef 的写法:总体上就是声明一个该类的对象,然后将变量名改为要起的别名就行:
那么同样的函数指针也能这么写,在之后的操作中,会发现这么写很方便:// 比如要给一般的变量、指针变量起别名inta;// 声明typedefintI;// 别名Iint*p;// 声明typedefint*POINT;// 别名POINTstructdata{inti;charc;}stu;// 声明typedefstructdata{inti;charc;}DATA;// 别名DATAint*array[10];// 指针数组typedefint*ARRAY[10];int(*array)[10];// 数组指针typedefint(*POINT)[10];typedefint(*FUN)(int,int);
接下来总结函数指针的主要用途:作为参数、作为返回值;
2. 函数指针作为参数
函数作为参数很常见,比如各种回调函数。只需要将一个函数指针作为参数传入,回调函数就可以调用不同的函数,比如:
voidfun1(){...}voidfun2(){...}voidcall_fun(void(*p)()){p();}call_fun(fun1);call_fun(fun2);``` #3.函数指针作为返回值 为什么要执行一个函数再让这个函数返回一个函数呢,有什么意义:主要意义有两个:1.可以根据输入参数/状态,动态决定要执行哪一个函数。当然你也可以用if-else实现,但是当状态/参数多的时候,代码会变得冗长;2.在面向对象编程中,有的函数被封装,此时通常会通过这种方法来,通过一个外部的函数接口来调用内部的私有方法; 对于1,给出下面的一个命令分发器的例子: ```c// -----命令对应的函数-----voidled_on(){printf("LED ON!");}voidled_off(){printf("LED OFF!");}voidmotor_run(){printf("MOTOR RUN!");}typedefvoid(*FUN)(void);#defineCMD_NUM3// -----两个用于维护的数组-----char*cmd_name[CMD_NUM]={"led on","led off","motor run"};FUN cmd_handel[CMD_NUM]={led_on,led_off,motor_run};// -----命令分发器代码-----FUNcmd_search(char*str){FUN p=NULL;inti=0;for(i=0;i<CMD_NUM;i++){if(strcmp(str,cmd_name[i])==0){p=cmd_handel[i];returnp;}}returnp;}intmain(){charstr[10];fgets(str,10,stdin);str[strcspn(str,"\n")]='\0';FUN p=cmd_search(str);if(p!=NULL)p();return0;}``` 在上面的例子中,命令分发器逻辑不需要修改,当增删命令时只需要修改两个数组即可;甚至数组和处理函数可以变成配置数据,程序启动时动态加载,实现在不重启系统的情况下,动态增删命令。