Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注+收藏,欢迎欢迎~~
💥个人主页:小羊在奋斗
💥所属专栏:C语言
本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为同样是初学者的学友展示一些我的学习过程及心得。文笔、排版拙劣,望见谅。
4、函数指针数组
5、转移表
4、函数指针数组
在上篇文章中我们又学了一个新的指针类型——函数指针类型,那学了函数指针,你是否还记得我们还学过指针数组呢?指针数组是一个数组,数组元素是相同类型的指针变量。那我们是不是也可以将相同类型的函数指针变量存到一个指针数组内呢?答案是可以的。
存放函数指针变量的数组就叫做函数指针数组,函数指针数组出现的意义我就不多说了,跟其他类型数组的作用一样。
来看下面的示例:
#include <stdio.h>
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 (*pf1)(int, int) = add;
//int (*pf2)(int, int) = sub;
//int (*pf3)(int, int) = mul;
//int (*pf4)(int, int) = div;
int (*pf[4])(int, int) = { add, sub, mul, div };//函数指针数组
return 0;
}
可以看到,函数指针数组能避免我们需要多个相同函数指针类型变量创建时的繁琐。
为了验证上面创建的函数指针数组,我们来遍历上面的数组,将数组内所有的函数指针指向的函数都使用一遍:
可以看到我们通过数组内对应下标的元素找到相应的函数地址,再进行函数调用完成了相关的操作,得到了我们预期的结果。
值得注意的是,不要忘了数组内存放的是相同类型的元素。如果这些函数的参数个数、参数类型、函数的返回值类型有差异,则不能存到同一个函数指针数组中。
5、转移表
我们学了函数指针数组有什么用呢?函数指针数组的用途就是接下来我们要学习的转移表。
在介绍转移表之前,我们先来完成一个能实现计算器功能的小程序。
#include <stdio.h>
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("******* 0.exit ******\n");
printf("******* 1.add 2.sub ******\n");
printf("******* 3.mul 4.div ******\n");
printf("*****************************\n");
}
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("请输入两个操作数:");
scanf("%d %d", &x, &y);
ret = add(x, y);
printf("结果是:%d\n", ret);
break;
case 2:
printf("请输入两个操作数:");
scanf("%d %d", &x, &y);
ret = sub(x, y);
printf("结果是:%d\n", ret);
break;
case 3:
printf("请输入两个操作数:");
scanf("%d %d", &x, &y);
ret = mul(x, y);
printf("结果是:%d\n", ret);
break;
case 4:
printf("请输入两个操作数:");
scanf("%d %d", &x, &y);
ret = div(x, y);
printf("结果是:%d\n", ret);
break;
case 0:
printf("退出计算器\n");
break;
default:
printf("选择错误,请重新选择!\n");
break;
}
} while (input);
return 0;
}
上面的程序还不能实现更多的计算功能,比如 &、^、|、~、>>、<< 等,想要增加更多的功能,我们不仅要写更多的自定义函数,还要增加更多的 case 语句,实现起来有点繁琐,完成后将得到一个代码量比较大的小程序。那有没有什么办法既能实现计算器的功能,代码量又没有那么大,想增加别的功能的时候也不麻烦呢?
我们可以用刚学的函数指针数组来将四个自定义函数统一管理起来,通过数组下标访问对应的元素来实现函数调用,这样代码量就能大大减少。不仅如此,我们想增加某些功能的时候只需要做两步,第一步写好对应的自定义函数,第二步增大数组的大小后再将函数名存到数组中就完成了。我们去掉了 switch 语句用 if—else 分支来判断我们选择。具体代码实现如下:
#include <stdio.h>
#define N 5
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("******* 0.exit ******\n");
printf("******* 1.add 2.sub ******\n");
printf("******* 3.mul 4.div ******\n");
printf("*****************************\n");
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
int ret = 0;
int (*pf[N])(int, int) = { 0, add, sub, mul, div }; //多加一个数字0,为了让下标对应
do // 0 1 2 3 4
{
menu();
printf("请选择:");
scanf("%d", &input);
if (input > 0 && input < N)//使用if判断代替多条case语句
{
printf("请输入两个操作数:");
scanf("%d %d", &x, &y);
ret = pf[input](x, y);
printf("结果是:%d\n", ret);
}
else if (0 == input)
{
printf("退出计算器!\n");
}
else
{
printf("选择错误,请重新选择!\n");
}
} while (input);
return 0;
}
我们在上面的代码中创建了一个函数指针数组,通过数组来访问相应的函数,有一点跳转的意思。而我们上面代码中写的函数指针数组,就是一个转移表。 什么是转移表呢?
在C语言中,转移表是一个包含指向函数或变量的指针的数组。通过使用转移表,可以实现一种灵活的方式来实现条件分支和函数调用。转移表通常用于实现状态机或分派表等功能。通过在转移表中存储函数指针,可以根据条件或索引值来动态选择要执行的函数,从而提高代码的灵活性和可维护性。
如果觉得我的文章还不错,请点赞、收藏 + 关注支持一下,我会持续更新更好的文章。