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

目录
  • 函数指针数组
    • 函数指针数组的定义
    • 函数指针数组的使用
    • 转移表
    • 回调函数
    • 指向函数指针数组的指针
  • 总结

函数指针数组

//整型数组 - 存放整型变量
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.指向函数指针数组的指针

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

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

总结

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

(0)

相关推荐

  • C语言进阶:指针的进阶(2)

    目录 数组指针 数组指针的定义 &数组名和数组名 数组指针的使用 反面用例 正面用例 Example 类型辨别方法 总结 数组指针 由前面的例子,不难得出,数组指针是指向数组的指针,是指针而非数组. 数组指针的定义 char ch = 'w'; char* pch = &ch;//字符地址存放在字符指针中 int a = 10; int* pint = &a;//整型地址存放在整型指针中 float f = 0.0; float* pf = &f;//浮点型地址存放在浮点型

  • C语言进阶:指针的进阶(3)

    目录 数组传参和指针传参 一维数组传参 二维数组传参 一级指针传参 二级指针传参 总结 数组传参和指针传参 实践之中不免会碰到数组和指针作函数参数而如何设计形参的问题. 一维数组传参 一维数组传参,下列接收方式是否可行呢? //1. void test(int arr[]) {} //2. void test(int arr[10]) {} //3. void test(int* arr) {} int main() { int arr[10] = { 0 }; test(arr); retur

  • 手把手带你搞懂C语言指针

    目录 前言 一.概念 1.*指针 2.&取址 二.指针修饰符 1.const 常量指针 2.volatile 特征指针 3.typedef 别名指针 三.指针运算 1. ++ -- + - 2.[] 标签访问 四.指针逻辑操作 总结 前言 自学笔记,没有历史知识铺垫(省略百度部分),C语言指针的使用 一.概念 1.*指针 指针: 内存资源的地址指针 变量:存放指针的盒子 32位操作系统中,其大小位32bit,即4个字节,64位为64bit,即8个字节,与指针数据类型无关 指针的数据类型: 表示指

  • C语言进阶:指针的进阶(1)

    目录 指针进阶 字符指针 字符指针的作用 字符指针的特点 指针数组 指针数组的定义 指针数组的使用 总结 指针进阶 我们在初阶时就已经接触过指针,了解了指针的相关内容,有: 指针定义:指针变量,用于存放地址.地址唯一对应一块内存空间. 指针大小:固定32位平台下占4个字节,64位8个字节. 指针类型:类型决定指针±整数的步长及指针解引用时访问的大小. 指针运算:指针解引用,指针±整数,指针-指针,指针关系运算. 本章节在此基础上,对C语言阶段指针进行更深层次的研究. 字符指针 字符指针,存入字符

  • C语言进阶:指针的进阶(4)

    目录 函数指针 函数指针的定义 函数指针的类型 函数指针的使用 Example 总结 函数指针 函数指针的定义 整型指针存放整型的地址:数组指针存放数组的地址:那么类比可得,函数指针存放函数的地址. 显然,函数指针指向函数,存放函数的地址.搞懂函数指针,先了解函数的地址. &函数名或函数名代表函数地址,与&数组名和数组名略有不同,&函数名和函数名完全一致. 函数的地址必然要放到函数指针里,函数指针的类型该如何写呢?(以Add函数为例) //整型指针 int* pa = &a

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

    目录 函数指针数组 函数指针数组的定义 函数指针数组的使用 转移表 回调函数 指向函数指针数组的指针 总结 函数指针数组 //整型数组 - 存放整型变量 int arr[10]; //字符数组 - 存放字符变量 char ch[5]; //指针数组 - 存放指针变量 int* arr[10]; //函数指针数组 - 存放函数指针 int(*pfar[10])(int, int); 指针数组存放指针变量,函数指针数组存放函数指针,故元素类型为函数指针类型. 函数指针数组的定义 int Add(in

  • C语言 指针数组进阶详解

    目录 指针与数组中的sizeof与strlen sizeof strlen 数组名 1.一维数组 整型数组 字符数组 指针数组 2.二维数组 指针笔试题 笔试题1 笔试题2 笔试题3 笔试题4 笔试题5 前言:指针与数组的知识往往让我们无法给自己定位,似乎是懂了,但真的碰上了又一言难尽.接下来有一些关于指针与数组的知识和例题讲解,来看看你对指针和数组到底有多了解吧! 指针与数组中的sizeof与strlen sizeof sizeof值关注占用空间的大小,单位是字节,不关注元素的类型,是一个操作

  • C语言从基础到进阶全面讲解数组

    目录 1.基础知识 2.数组的分类 2.1按元素类型分类 2.2按维数分类 3.数组定义和初始化 3.1 一维数组 3.2 二维数组 4.数组元素的引用方法 5.字符数组的定义 1.基础知识 C语言中使用数组表示多个连续的同类型的存储位置 使用数组表示多个连续存储位置的时候只需要一个名字,这个名字代表所有这些存储位置的整体 每一个存储位置有一个自己的编号,最前边的存储位置的编号是0,向后依次递增,最后一个存储位置的编号是个数减一,这个编号叫做下标 决不可以使用超过范围的下标 使用名称和下标就可以

  • C语言实现飞机游戏(进阶版)的示例代码

    目录 前言 一.代码重构 二.新式子弹代替激光 三.优化敌方战机 四.增加积分模块 五.更好的清屏功能 前言 没有学习函数,以上功能都在main()中实现是有点痛苦的.在学了函数之后会模块化重构相应的游戏,大家经历过上面的痛苦才能真正理解函数的好处.如果只是被动地学习语法知识,做些简单的算法题,是很难体会到函数封装的重要性的. 我们前面制作的用c语言实现一个最简单的飞机游戏但存在如下缺陷: 可能会遇到子弹运动时无法输入 键盘控制比较卡 不按键时敌人不会自动移动等问题,且敌人只出现一次 屏幕图标闪

  • 老生常谈C语言中指针的使用

    目录 前提 一.指针基础 1.1变量指针 1.2数据指针 1.3指针的本质 1.4指针数组 1.5指针的移动 1.5Scanf函数的解释 二.指针的进阶玩法 2.1二维指针 2.2结构体指针 结语 前提 指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分.指针也就是内存地址,指针变量是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同.有了指针以后,不仅可以对数据本身,也可以对

  • C语言的指针类型详细解析

    指针存储了内存的地址,同时指针是有类型的,如int*,float*,那么,一个自然的猜想就是指针变量应该存储这两方面的信息:地址和指针类型,比如,就像下面的结构体: 复制代码 代码如下: struct pointer{    long address;    int type;} 举个例子:打印sizeof(int*),值为4,可见4字节是存储内存地址用的,反过来就说明指针并没有存储类型信息的地方,那么指针的类型信息存放在哪儿呢?下面剖析一段简单的代码. 复制代码 代码如下: // ma.cpp

随机推荐