函数指针和回调函数

文章目录

一.函数指针

1.什么是函数指针

  • 函数指针是指向函数的指针。在C语言和C++中,函数指针可以用来存储函数的地址,并且可以通过函数指针来调用函数。
  • 也可以作为函数的返回值。通过函数指针,可以实现回调函数和动态函数调用等功能。
  • 通过函数指针,可以实现回调函数和动态函数调用等功能。函数指针的类型由函数的参数和返回值类型来确定。函数指针在一些高级的编程技术中经常被使用,例如函数指针数组、函数指针作为结构体成员等。

2.函数指针的形式

在了解形式之前,我们需要知道一个小细节
自定义函数名和取地址函数名是等价的

c 复制代码
void test()
{
	return;
}
int main()
{
	printf("%p\n", test);
	printf("%p\n", &test);
}


所以我们书写就会有两种形式:

void (*pf1)() = &test;
void (*pf2)()= test;

如果函数需要传参,返回值,则括号里要表达形式

c 复制代码
int Add(int x, int y)
{
return x+y;
}
int (*pf3) (int x,int y)
//也可以省略x,y
int (*pf4) (int ,int )

3.函数指针的用途。

1.调用函数

通过直接解引用,并且传参就可以直接调用

c 复制代码
int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int (*pf1) (int, int) = Add;
	//直接调用
	printf("%d\n", Add(1, 8));
	//指针解引用
	printf("%d\n", (*pf1)(1, 8));
}

2.作为参数进行传递

虽然函数可以全局调用,但是有时候我们需要在程序运行时动态地确定调用哪个函数,或者需要将函数作为参数传递给其他函数。这时候就需要使用函数指针作为参数。

二.函数指针数组

函数指针数组是一个数组,其中的每个元素都是一个函数指针。函数指针数组可以用来存储多个函数的地址,从而可以根据需要动态地选择并调用不同的函数。

形式如下:

c 复制代码
void (*functions[2])() = {function1, function2};

我们接下来展示一段简易代码,利用函数指针数组做一个转移表实行计算器的部分功能:

c 复制代码
int Add(int x, int y)
{
	return x + y;
}
int Mul(int x, int y)
{
	return x * y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Div(int x, int y)
{
	return x / y;
}
int main()
{
	int x, y;
	int input = 1;
	//将函数封装进数组
	int(*p[5]) (int, int) = { NULL,Add,Mul,Sub,Div };
	//打印菜单
	do {
		printf("***************************\n");
		printf("***************************\n");
		printf("****0:退出   1:加法 ******\n");
		printf("****2:乘法  3:减法 ******\n");
		printf("****4:除法          ******\n");
		printf("***************************\n");
		printf("***************************\n");
		scanf("%d", &input);
		if (input<5&&input>0)
		{
			printf("请输入你要计算的数字x,y\n");
			scanf("%d %d", &x, &y);
			int ret =(p[input](x, y));//调用
			printf("结果是:%d\n",ret );
		}
		else break;


	} while (input);
	return 0;
}

由此我们可知相同参数和类型近似的函数可以通过函数指针数组分装使用

三.回调函数

回调函数是指在某个函数执行过程中,通过函数指针调用另一个函数的过程。通常情况下,回调函数作为参数传递给某个函数,并在该函数特定的条件下被调用。

回调函数通常用于实现一些灵活的、可定制的功能,例如事件处理、状态通知、数据处理等。通过回调函数,可以将特定的处理逻辑从原始函数中分离出来,使得原始函数具有更高的通用性和灵活性。
在c语言中有一个经典的库函数qsort,它的底层逻辑是快速排序,他需要用户自己实现比较部分函数

void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *));

四个参数分别为:

1.void *base:指向待排序数组的指针,即数组的首元素地址。
qsort 函数通过这个指针来访问待排序的元素。

2.size_t num:数组中待排序元素的个数。

3.size_t size:每个元素的大小(以字节为单位)。
由于 qsort 函数不知道数组中元素的具体类型,
因此需要通过 size 参数来确定每个元素的大小。

4.int (*compar)(const void *, const void *):指向比较函数的指针。
比较函数的原型必须是 int compar(const void *a, const void *b),
其中 a 和 b 是待比较的两个元素的指针。
比较函数需要根据实际的排序需求来定义,
返回值为负数表示 a 应该排在 b 前面,
返回值为正数表示 a 应该排在 b 后面,
返回值为 0 表示 a 和 b 相等。

展示一个简单排序:

c 复制代码
int compare(const void* a, const void* b)
{
	return *((int*)a) - *((int*)b);
}
int main()
{
	int arr[10] = { 2,5,7,4,6,1,5,0,9,7 };
	//排序
	qsort(arr, 10, sizeof(int), compare);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

不光是整形排序,void类型意味着可以兼容各种数据的排序。

本期的知识分享到此结束。希望三联支持一下博主!

相关推荐
番茄电脑全能王26 分钟前
《CS2》提示mss32.dll丢失的根源与应对策略。《CS2》提示mss32.dll丢失是什么原因?mss32.dll丢失怎么办?
网络·经验分享·游戏·电脑
计科土狗43 分钟前
前缀和与差分
c++·算法
十二测试录1 小时前
Jmeter自学【8】- 使用JMeter模拟设备通过MQTT发送数据
经验分享·测试工具·jmeter·程序人生·自动化
红色的山茶花1 小时前
YOLOv9-0.1部分代码阅读笔记-anchor_generator.py
笔记·深度学习·yolo
m0_748250032 小时前
【STM32】F103ZET6开发板----笔记01
笔记·stm32·嵌入式硬件
1101 11012 小时前
STM32-笔记16-定时器中断点灯
笔记·stm32·单片机
午言若2 小时前
MYSQL 架构
c++·mysql
旺旺大力包2 小时前
【 Git 】git 的安装和使用
前端·笔记·git
WPG大大通3 小时前
基于DIODES AP43781+PI3USB31531+PI3DPX1207C的USB-C PD& Video 之全功能显示器连接端口方案
c语言·开发语言·计算机外设·开发板·电源·大大通
羑悻的小杀马特4 小时前
【AIGC篇】畅谈游戏开发设计中AIGC所发挥的不可或缺的作用
c++·人工智能·aigc·游戏开发