C语言进阶:指针的进阶(5)

编辑: admin 分类: c#语言 发布时间: 2021-12-12 来源:互联网
目录
  • 函数指针数组
    • 函数指针数组的定义
    • 函数指针数组的使用
    • 转移表
    • 回调函数
    • 指向函数指针数组的指针
  • 总结

    函数指针数组

    //整型数组 - 存放整型变量
    int arr[10];
    //字符数组 - 存放字符变量
    char ch[5];
    //指针数组 - 存放指针变量
    int* arr[10];
    //函数指针数组 - 存放函数指针
    int(*pfar[10])(int, int);
    

    指针数组存放指针变量,函数指针数组存放函数指针,故元素类型为函数指针类型。

    函数指针数组的定义

    int Add(int x, int y) {//int(*)(int,int)
    	return x + y;
    }
    int Sub(int x, int y) {//int(*)(int,int)
    	return x - y;
    }
    int Mul(int x, int y) {//int(*)(int,int)
    	return x * y;
    }
    int Div(int x, int y) {//int(*)(int,int)
    	return x / y;
    }
    int main() {
    	//函数指针数组 - pfArr
    	int(*pfArr[4])(int, int) = { Add,Sub,Mul,Div };
    	return 0;
    }
    

    类型相同的函数,存放在同一个函数指针数组中。一般功能相似的函数,其类型也相同。

    函数指针数组的使用

    利用函数指针数组实现计算器,以简化调用过程。

    转移表

    //计算器实现1.0
    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 (*pfArr[10]) (int, int) = { 0,Add,Sub,Mul,Div };//数组下标和选项序号匹配
    	int input = 0;
    	int a = 0;
    	int b = 0;
    	do {
    		menu();
    		printf("请选择:>");
    		scanf("%d", &input);
    		if (0 <= input && input <= 4) {
    			if (input == 0) {
    				printf("退出游戏\n");
    				break;
    			}
    			else {
    				printf("请输入操作数\n");
    				scanf("%d %d", &a, &b);
    				printf("ret == %d\n", pfArr[input](a, b));
    				break;
    			}
    		}
    		else {
    			printf("输入错误\n");
    			break;
    		}
    	} while (input);
    	return 0;
    }
    

    函数指针数组实现不同选择情况下,通过函数地址“跳转”到不同的函数的功能。

    这样的函数指针数组成为转移表。(跳转功能)

    回调函数

    若不想舍弃switch语句,还可以这样简化代码3.0,代价为创建全局变量。若不想创建全局变量,可以使用2.0

    /******
    * 计算器实现
    * 2.0
    ******/
    void Calc(int (*pf)(int,int)) {
    	int a = 0;
    	int b = 0;
    	printf("请输入操作数:>");
    	scanf("%d %d", &a, &b);
    	printf("%d\n", pf(a, b));
    }
    int main() {
    	int input = 0;
    	do {		menu();
    		printf("请选择:>");
    		scanf("%d", &input);
    		switch (input) {
    		case 0:
    			printf("退出成功\n");
    			break;
    		case 1:
    			Calc(Add);
    			break;
    		case 2:
    			Calc(Sub);
    			break;
    		case 3:
    			Calc(Mul);
    			break;
    		case 4:
    			Calc(Div);
    			break;
    		default:
    			printf("请重新选择\n");
    			break;
    		}
    	} while (input);
    	return 0;
    }
    /******
    * 计算器实现
    * 3.0
    ******/
    int (*pfArr[10])(int, int) = { 0,Add,Sub,Mul,Div };
    int input = 0;
    void Call() {
    	int a = 0;
      int b = 0;
    	printf("请输入操作数:>");
    	scanf("%d %d", &a, &b);
    	printf("%d\n", pfArr[input](a, b));
    }
    int main() {
    	do {
    		menu();
    		printf("请选择:>");
    		scanf("%d", &input);
    		switch (input) {
    		case 0:
    			printf("退出成功\n");
    			break;
    		case 1:
    		case 2:
    		case 3:
    		case 4:
    			Call();
    			break;
    		default:
    			printf("请重新选择\n");
    			break;
    		}
    	} while (input);
    	return 0;
    }
    

    如下图所示,被通过函数指针调用的函数叫做回调函数,回调函数即使第三方调用调用函数的参数也在其中被调用。

    若想在调用函数中随条件变化而调用不同的函数,就必须使用回调函数的方法:调用函数中使用函数指针,指向不同函数。回调函数在大型工程中显得非常方便。

    在这里插入图片描述

    指向函数指针数组的指针

    int arr[10];
    int(*parr)[10] = &arr;//整型数组指针
    char(*pch)[10] = &ch;//字符数组指针
    //指向整型数组指针的指针
    int(*(*pparr))[10] = &parr;
    //指向字符数组指针的指针
    char(*(*ppch))[10] = &pch;
    
    //函数1.
    int Add(int x, int y) {
    	return x + y;
    }
    //函数指针2.
    int (*pf)(int, int) = Add;
    //函数指针数组3.
    int (*pfArr[10])(int, int) = { Add };
    //指向函数指针数组的指针4.
    int(*(*ppfArr)[10])(int, int) = &pfArr;
    

    前面已经交代,指针去掉*号和指针名,就是指向的变量类型;去掉指针名就是指针的类型。

    反过来,定义数组指针,需要得到指针所指向的数组的类型。1.先写出指针名,在其前面加*;2.写出数组的类型int()[10]

    定义指向函数指针数组的指针,依次写出如下内容:

    1.函数 —— 得到函数类型:int(int, int)

    2.函数指针 —— 得到函数指针类型:int(*)(int, int)

    3.函数指针数组 —— 得到函数指针数组的类型:int(*[10])(int, int)

    4.指向函数指针数组的指针

    在这里插入图片描述

    从后往前看,指向函数指针数组的指针去掉*和指针名就是函数指针数组的类型,函数指针数组去掉*和指针名就是函数指针类型,函数指针去掉*和指针名就是函数类型。

    在研究下去就没有必要了,指针放在数组里,数组被指针所指向……

    总结

    本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注海外IDC网的更多内容!

    【自由互联:韩国服务器 转载请保留连接】