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.0void 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; }
如下图所示,被通过函数指针调用的函数叫做回调函数,回调函数即使第三方调用调用函数的参数也在其中被调用。
若想在调用函数中随条件变化而调用不同的函数,就必须使用回调函数的方法:调用函数中使用函数指针,指向不同函数。回调函数在大型工程中显得非常方便。
![C语言进阶:指针的进阶(5)](https://img.it610.com/image/info11/b21de8db8da34b2885c2ff1e6824643f.jpg)
文章图片
指向函数指针数组的指针
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.指向函数指针数组的指针
![C语言进阶:指针的进阶(5)](https://img.it610.com/image/info11/9f89944b6d294d0c8d2ee5500072b8e2.jpg)
文章图片
从后往前看,指向函数指针数组的指针去掉*和指针名就是函数指针数组的类型,函数指针数组去掉*和指针名就是函数指针类型,函数指针去掉*和指针名就是函数类型。
在研究下去就没有必要了,指针放在数组里,数组被指针所指向……
总结 本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- 【生信技能树】R语言练习题|【生信技能树】R语言练习题 - 中级
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- 推荐系统论文进阶|CTR预估 论文精读(十一)--Deep Interest Evolution Network(DIEN)
- C语言解方程的根和判断是否是闰年
- C语言的版本比较
- 普通人进阶的三个过程-很多人都知道,但却本末倒置