目录
一.概念
二.函数数组的用途:转移表
例子:计算器
法一:用switch来编写
代码
运行结果
对法一的改进(利用函数指针)
代码
法一的缺点
法二(利用函数指针数组)
代码
运行结果
数组是一个存放相同类型数据的存储空间,那我们已经学习了指针数组,比如︰
int *arr[10];
//数组每个元素是int *
那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?,看下图:
哪一个才是正确写法呢?
答案是:parr1。parr1先和[]结合,说明parr1是数组,数组的内容是什么呢﹖是int (*)()类型的函数指针。
#include
void mean()
{
printf("*********************\n");
printf("***1.add 2.sub****\n");
printf("***3.mul 4.div****\n");
printf("*******0.exit********\n");
printf("*********************\n");
}
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 input=0;
int x=0,y=0;
do
{
mean();
printf("请选择:>");
scanf("%d",&input);
switch(input)//这里的input就对应menu函数里面的选项
{
case 1:
printf("请输入两个操作数:>");
scanf("%d %d",&x,&y);
printf("%d\n",Add(x,y));
break;
case 2:
printf("请输入两个操作数:>");
scanf("%d %d",&x,&y);
printf("%d\n",Sub(x,y));
break;
case 3:
printf("请输入两个操作数:>");
scanf("%d %d",&x,&y);
printf("%d\n",Mul(x,y));
break;
case 4:
printf("请输入两个操作数:>");
scanf("%d %d",&x,&y);
printf("%d\n",Div(x,y));
break;
case 0:
printf("退出");
break;
default:
printf("选择错误\n");
break;
}
}while(input!=0);//用这个作为循环的条件
}
这里我们发现每一个case后面都有段相似的代码,那么我们可以在这一部分加以改进
#include
void mean()
{
printf("*********************\n");
printf("***1.add 2.sub****\n");
printf("***3.mul 4.div****\n");
printf("*******0.exit********\n");
printf("*********************\n");
}
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 Calc(int (*pf)(int,int))//利用函数指针去接受加减乘除四个函数
{
int x=0,y=0;
printf("请输入两个操作数:>");
scanf("%d %d",&x,&y);
printf("%d\n",pf(x,y));
}
int main()
{
int input=0;
int x=0,y=0;
do
{
mean();
printf("请选择:>");
scanf("%d",&input);
switch(input)//这里的input就对应menu函数里面的选项
{
case 1:
Calc(Add);
break;
case 2:
Calc(Sub);
break;
case 3:
Calc(Mul);
break;
case 4:
Calc(Div);
break;
case 0:
printf("退出");
break;
default:
printf("选择错误\n");
break;
}
}while(input!=0);//用这个作为循环的条件
}
其运行结果也是一样的
上面只有加减乘除四种功能,如果我们想继续增加功能的话,那我们就需要继续增加case的数目,一旦过多就很容易导致代码复杂,所以当功能比较多时我们就需要另一种更高效的方法。
#include
void mean()
{
printf("*********************\n");
printf("***1.add 2.sub****\n");
printf("***3.mul 4.div****\n");
printf("*******0.exit********\n");
printf("*********************\n");
}
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 input=0;
int x=0,y=0;
int (*pfarr[5])(int,int)={0,Add,Sub,Mul,Div};//这里要用5,且第一个为0是为了跟选项匹配
do
{
mean();
printf("请选择:>");
scanf("%d",&input);
if(input>=1&&input<=4)
{
printf("请输入两个操作数:>");
scanf("%d %d",&x,&y);
int ret=pfarr[input](x,y);
printf("%d\n",ret);
}
else if(input==0)
{
printf("退出\n");
}
else
{
printf("选择错误\n");
}
}while(input!=0);//用这个作为循环的条件
}
用函数指针数组去存函数,让函数成为数组中的元素,然后就像调用数组中的元素那样调用函数就可以了,这要那个就解决了当需要添加功能而增加case的问题,当我们需要增加功能时可以:如果需要增加就只需要再写一个函数,然后main函数再稍微改动一下就可以了
如图