前言:本文主要内容是关于函数指针数组的,并且展示了函数指针数组的用途
1、函数指针数组
1、函数指针数组是什么?
函数指针数组是什么?首先主语是数组,数组是一个存放相同类型数据的存储空间。那我们已经学习了指针数组,比如:char* arr[5] ———— 字符指针数组,它是一个数组,存放的是字符指针。
int* arr[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;
}
int main()
{
//int (*pf1)(int, int) = Add;
//int (*pf2)(int, int) = Sub;
//int (*pf3)(int, int) = Mul;
//int (*pf4)(int, int) = Div;
//函数指针数组
//
int (*pfArr[4])(int, int) = {Add, Sub, Mul, Div};
//
return 0;
}
讲解 :pfArr先和[]结合所以是数组,剩下的是数组元素的类型int (*)(int, int) 。
名为pfArr的数组,数组长度为4。数组中的元素都是指向具有返回类型为int,参数类型为int和int的函数的指针。
换句话说,pfArr是一个长度为4的指针数组,每个指针指向一个接受两个int参数并返回int类型值的函数。所以pfArr是函数指针数组
1.2、函数指针数组的用途:转移表
用C语言实现一个计算器功能(加减乘除):
int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int div(int a, int b) { return a / b; } void menu() { printf("*******************************\n"); printf("****** 1.add 2.sub *****\n"); printf("****** 3.mul 4.div *****\n"); printf("****** 0.exit *****\n"); printf("*******************************\n"); } int main() { int input = 0; int a = 0; int b = 0; int ret = 0; do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: printf("请输入2个操作数:"); scanf("%d %d", &a, &b); ret = add(a, b); printf("%d\n", ret); break; case 2: printf("请输入2个操作数:"); scanf("%d %d", &a, &b); ret = sub(a, b); printf("%d\n", ret); break; case 3: printf("请输入2个操作数:"); scanf("%d %d", &a, &b); ret = mul(a, b); printf("%d\n", ret); break; case 4: printf("请输入2个操作数:"); scanf("%d %d", &a, &b); ret = div(a, b); printf("%d\n", ret); break; case 0: printf("退出计算器\n"); break; default: printf("选择错误,重新选择\n"); break; } } while (input); return 0; }
虽然能实现一个计算器功能,但是这个代码特别地冗余,重复的部分非常多,并且如果需要添加多一个功能是,又需要再添加多一个case,导致代码越来越长,重复部分也越来越多,这是非常不好的代码习惯,那有什么办法能够解决呢?
其实我们通过观察可以发现,这些函数有一些特点,就是除了函数名不同之外,返回类型以及参数类型都是一致的。
既然除了函数名不同之外其余都相同,那么是否就可以使用函数指针数组来改造一下代码?
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return a / b;
}
void menu()
{
printf("*******************************\n");
printf("****** 1.add 2.sub *****\n");
printf("****** 3.mul 4.div *****\n");
printf("****** 0.exit *****\n");
printf("*******************************\n");
}
int main()
{
int input = 0;
int a = 0;
int b = 0;
int ret = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
//创建一个函数指针数组
int (*pfArr[])(int, int) = { NULL,add,sub,mul,div };
//为了使数组下标与菜单序号对应起来,在0下标处放置一个NULL
if (input == 0)
{
printf("退出计算器\n");
}
else if (input >= 1 && input <= 4)
{
printf("请输入2个操作数:");
scanf("%d %d", &a, &b);
ret = pfArr[input](a, b); //下标访问数组中的函数并调用
printf("ret = %d\n", ret);
}
else
{
printf("选择错误,重新选择\n");
}
} while (input);
return 0;
}
在一个
do-while
循环中,首先调用menu
函数显示菜单选项。用户通过scanf
输入选项。根据用户输入的选项,在pfArr
数组中找到对应的函数指针,并调用它。这里使用了函数指针数组的技巧,使得根据用户输入的选项可以直接从数组中找到相应的函数,并进行调用。这样可以避免使用多个if
或switch
语句来处理不同的选项。
扩展:指向函数指针的数组的指针
创建变量的类型的时候最好是在原来的函数指针数组的基础上来修改比较好写
void (*pf)(const char*) = test;//pf是函数指针变量
void (*pfArr[10])(const char*);//pfArr是存放函数指针的数组
void (* (*p) [10])(const char*) = &pfArr;//p指向函数指针数组的指针