函数指数组是存放函数指针的数组
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;
}
指针把*和名字去掉,剩下的就是指针指向的对象
数组把数组名和 [ ] 去掉,剩下的就是存放在数组中的类型。