一、计算器的一般实现
请看如下代码:
void menu()
{
printf("******************************\n");
printf("****** 1.加法 2.减法 *****\n");
printf("****** 3.乘法 4.除法 *****\n");
printf("****** 5.退出程序 *****\n");
printf("******************************\n");
printf("请选择:");
}
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 a, b;
int input = 0;
int ret = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
printf("输入两个操作数\n");
scanf("%d %d", &a, &b);
ret = Add(a, b);
printf("ret=%d\n", ret);
break;
case 2:
printf("输入两个操作数\n");
scanf("%d %d", &a, &b);
ret = Sub(a, b);
printf("ret=%d\n", ret);
break;
case 3:
printf("输入两个操作数\n");
scanf("%d %d", &a, &b);
ret = Mul(a, b);
printf("ret=%d\n", ret);
break;
case 4:
printf("输入两个操作数\n");
scanf("%d %d", &a, &b);
ret = Div(a, b);
printf("ret=%d\n", ret);
break;
case 5:
printf("退出程序\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
通过简单的do-while循环,switch-case语句以及函数就可以模拟一个能够进行加、减、乘、除整型运算的计算机程序。但我们会发现,频繁的通过switch-case语句会使代码显得冗余,那么我们将考虑用函数指针数组简化代码。
下面,我将介绍什么是函数指针数组。
二、函数指针数组
指针是用来存放地址的,那么函数指针数组顾名思义就是“把函数的地址存放到一个数组当中”,那么这个数组就叫函数指针数组,形如:int (*parr[3])()。这里的3代表有三个函数的地址被存放在这个数组当中,int表示整型,*p为指针,arr为数组名。
有了函数指针数组的概念后,我们将用函数指针数组去简化上述代码,代码如下:
void menu()
{
printf("******************************\n");
printf("****** 1.加法 2.减法 *****\n");
printf("****** 3.乘法 4.除法 *****\n");
printf("****** 5.退出程序 *****\n");
printf("******************************\n");
printf("请选择:");
}
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 a, b;
int input = 0;
int ret = 0;
int(*p[5])(int x, int y) = { NULL,Add,Sub,Mul,Div };//转移表
do
{
menu();
scanf("%d", &input);
if (input <= 4 && input >= 1)
{
printf("请输入两个操作数:\n");
scanf("%d %d", &a, &b);
ret = (*p[input])(a, b);
printf("ret=%d\n", ret);
}
else if (input = 5)
{
printf("退出计算器\n");
}
else
printf("输入错误,请重新输入");
} while (input);
return 0;
}
我们在上述代码中引入了
int(*p[5])(int x, int y) = { NULL,Add,Sub,Mul,Div };
此代码将函数的地址保存在了数组当中,当我们当我们想要调用某一个函数时就可以通过访问地址找到该函数,为了保证数组下标与菜单中的数字保持一致,将函数指针数组的第一个元素置为空指针NULL。
当我们知道函数指针数组的概念后,是不是可以通过函数指针调用函数呢,我想答案时肯定的。于是我们又有了另一种写法。
三、回调函数
什么是回调函数,简单来说就是通过函数指针调用的函数,改进上述代码:
void menu()
{
printf("******************************\n");
printf("****** 1.加法 2.减法 *****\n");
printf("****** 3.乘法 4.除法 *****\n");
printf("****** 5.退出程序 *****\n");
printf("******************************\n");
printf("请选择:");
}
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 ret = 0;
int x, y;
printf("请输入两个操作数\n");
scanf("%d %d", &x, &y);
ret = pf(x, y);
printf("ret=%d\n", ret);
}
int main()
{
int a, b;
int input = 0;
int ret = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
calc(Add);
break;
case 2:
calc(Sub);
break;
case 3:
calc(Mul);
break;
case 4:
calc(Div);
break;
case 5:
printf("退出程序\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
总结:
通过这三段代码,我们简单的认识了函数指针数组,以及回调函数,由于作者能力有限,欢迎各位指正。