函数指针数组
是什么?
函数指数组是存放函数指针的数组
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { int(*parr[4])(int, int) = { Add,Sub,Mul,Div }; return 0; }
上面是函数指针数组的一个应用,因为我们发现Add,Sub,Mul,Div这4个函数的参数和返回类型都一样,又因为函数名就表示函数的地址,所以我们把这4个函数的地址存放在函数指针数组parr里面。
书写小技巧:
我们书写函数指针数组时,先写上函数指针的形式,接着在名字后面加上数组的 [ ] 方括号,就可以完成对函数指针数组形式的书写。
有什么用?
我们来模拟实现一个计算器。
下面是最基础的实现方式
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void menu() { printf("****************\n"); printf("**1:Add 2:Sub**\n"); printf("**3:Mul 4:Div**\n"); } int main() { //int(*parr[4])(int, int) = { Add,Sub,Mul,Div }; menu(); int input = 0; int x = 0; int y = 0; int ret = 0; do { printf("请输入操作数\n"); scanf("%d", &input); switch (input) { case 0: printf("退出计算器\n"); break; case 1: printf("请输入两个操作数\n"); scanf("%d %d", &x, &y); ret = Add(x, y); printf("%d\n", ret); break; case 2: printf("请输入两个操作数\n"); scanf("%d %d", &x, &y); ret = Sub(x, y); printf("%d\n", ret); break; case 3: printf("请输入两个操作数\n"); scanf("%d %d", &x, &y); ret = Mul(x, y); printf("%d\n", ret); break; case 4: printf("请输入两个操作数\n"); scanf("%d %d", &x, &y); ret = Div(x, y); printf("%d\n", ret); break; default: printf("输入非法,请重新输入\n"); break; } } while (input); return 0; }
我们不难发现上述代码有两个明显的缺点
1、这种代码过于冗余,尤其是每个计算法则的内容,只有调用函数不一样,其余三行内容完全一致。
2、未来我们想在这个计算器里增加其他的运算法则,case语句会变的越来越多,里面的代码冗余现象也会越来越严重。
那如何去解决上述问题呢
那就需要我们的函数指针数组出马了!
int main() { //int(*parr[4])(int, int) = { Add,Sub,Mul,Div }; menu(); int input = 0; int x = 0; int y = 0; int ret = 0; do { printf("请输入操作数\n"); scanf("%d", &input); int (*parr[])(int, int) = { NULL,Add,Sub,Mul,Div };//保持下标与我们输入数字一致 if (input >= 1 && input <= 4) { printf("请输入两个数字\n"); scanf("%d %d", &x, &y); ret = parr[input](x, y); printf("%d\n", ret); } else if (input == 0) printf("退出计算器\n"); else printf("输入非法,请重新输入\n"); } while (input); return 0; }
注意当我们调用函数指针数组时,可以直接写数组名,然后后面括号写函数的参数。
不难看出,用函数指针数组求解不仅仅减少很多的代码量,也方便我们日后增加运算法则,直接在数组里面增加函数名即可。
指向函数指针数组的指针
相当于我们取了函数指针数组的地址进行存放,书写形式就是先写函数指针,接着再写函数指针数组,最后再写指向函数指针数组的指针。
int Add(int x, int y) { return x + y; } int main() { int(*p)(int, int);//先写函数指针 int(*p[])(int, int)=Add;//然后在名字后面加上[],就是函数指针数组 int (*( * pf)[])(int, int) = &p;//因为又是指针,所以再需要一个*,然后先把*和名字括起来 return 0; }
小技巧:
指针把*和名字去掉,剩下的就是指针指向的对象
数组把数组名和 [ ] 去掉,剩下的就是存放在数组中的类型。