前言
最近在复习指针和数组,发现之前没写过利用函数指针数组来实现计算器的博客,所以今天就来写一下。
引入
先来复习一下函数指针和函数指针数组的知识
函数指针
语法格式:
(函数返回类型) (*pf)(函数各个参数的类型) = 函数名
例子
#include<stdio.h> int Add(int x, int y) { return x + y; } int main() { int x = 2; int y = 3; int (*pfAdd)(int, int) = Add; int ret = (*pfAdd)(x, y); printf("%d\n", ret); return 0; }
函数指针数组
在格式上,只需要写成如下即可
(函数返回类型) (*pf[数组元素个数])(函数各个参数的类型) = 函数名;
原始版(不使用函数指针数组)
思路
如果不使用函数指针数组的话,可以直接用switch语句,输入数字,找到对应的运算,一直循环运算,直到决定停止循环
代码
void menu() { 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; int y = 0; int ret = 0; do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: printf("请输入2个操作数:"); scanf("%d %d", &x, &y); ret = Add(x, y); printf("ret = %d\n", ret); break; case 2: printf("请输入2个操作数:"); scanf("%d %d", &x, &y); ret = Sub(x, y); printf("ret = %d\n", ret); break; case 3: printf("请输入2个操作数:"); scanf("%d %d", &x, &y); ret = Mul(x, y); printf("ret = %d\n", ret); break; case 4: printf("请输入2个操作数:"); scanf("%d %d", &x, &y); ret = Div(x, y); printf("ret = %d\n", ret); break; case 0: printf("退出计算器\n"); break; default: printf("选择错误, 重新选择\n"); break; } } while (input); return 0; }
缺点
我们可以发现,当我们想增加计算器的功能时,比如按位与、按位或、左移、右移这些操作时,我们会增大switch语句的代码量,看起来很复杂
并且,我们可以发现,每一条case语句中,都有大量的重复的语句:
printf("请输入2个操作数:"); scanf("%d %d", &x, &y); printf("ret = %d\n", ret);
简化版(使用函数指针数组)
思路
当我们使用函数指针数组的时候,就可以大大减少代码量
具体就是创建一个函数指针数组,把需要用到的函数存在里面,想调用时,直接通过下标,即可调用这个函数
代码
void menu() { 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; int y = 0; int ret = 0; do { menu(); printf("请选择:>"); scanf("%d", &input); int (*pfArr[])(int, int) = {NULL, Add, Sub, Mul, Div}; if (0 == input) { printf("退出计算器\n"); } else if (input >= 1 && input <= 4) { printf("请输入2个操作数:"); scanf("%d %d", &x, &y); ret = pfArr[input](x, y); printf("ret = %d\n", ret); } else { printf("选择错误,重新选择!\n"); } } while (input); return 0; }
进阶版
我们可以用回调函数来进一步简化上面这段代码
void menu() { 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; int y = 0; int ret = 0; printf("请输入2个操作数:"); scanf("%d %d", &x, &y); ret = pf(x, y); printf("ret = %d\n", ret); } int main() { int input = 0; do { menu(); printf("请选择:>"); 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 0: printf("退出计算器\n"); break; default: printf("选择错误, 重新选择\n"); break; } } while (input); return 0; }
结语:
对于通过C语言来简单实现计算器的介绍到这里就结束了,顺带着复习了一下指针,我们下篇文章见~