c语言-函数指针

2024-01-09 11:47:42


前言

本篇文章介绍c语言中的函数指针以及函数指针的应用。


一、函数指针

函数指针:指向函数的指针。

在这里插入图片描述
函数在编译时分配地址。
&函数名 和 函数名代表的意义相同,都表示函数的地址。

1.1 函数指针定义

	int (* pf)(int,int);

int:表示函数指针指向的函数的返回值类型为int
pf:表示函数指针变量名
(int,int):表示函数指针指向的函数的参数类型
pf的类型:int(*)(int,int)

1.2 函数指针调用函数

	//写法一
	int ret1 = (*pf)(2,3); //通过对函数指针进行解引用
	//写法二
	int ret2 = pf(2,,3);  //函数指针调用函数的简写形式

1.3 函数指针代码分析

下面两段代码来自《c陷阱与缺陷》
代码一

	(* (void(*)()) 0)(); 

上面这行代码表示一次函数调用
void(*)() 表示函数指针类型
( void(*)() )0 表示将整型值0强制转换为函数指针类型
(* (void(*)()) 0)() 表示调用地址为0的函数

代码二

	void(* signal_func(int, void(*)(int)) )(int);

上面代码表示一次函数声明
函数名 signal_func
参数类型int和void(*)(int)
返回值类型 void(*)(int)

将代码进行简写

	typedef void(*SIGNALTYPE)(int); //将void(*)(int)函数指针类型重命名为SIGNALTYPE
	SIGNALTYPE signal_func(int, SIGNALTYPE);

二、函数指针数组

函数指针数组:存储函数指针的数组
函数指针数组的定义形式:

	ret_type(* parr[array_size])(param_type);

ret_type: 函数指针数组中每个元素返回值类型
parr: 函数指针数组名
array_size: 数组长度
param_type: 函数指针数组中每个元素的参数类型

应用场景:

  1. 当有多个返回类型相同,参数类型相同的函数时,可将这多个函数用函数指针数组存储
  2. 函数指针数组可以实现跳转功能,称作转移表

下面通过一个简单实现计算器功能的例子说明函数指针数组的使用。

//加
int add(int x, int y)
{
	return (x + y);
}
//减
int sub(int x, int y)
{
	return (x - y);
}
//除
int div(int x, int y)
{
	assert(y);
	return (x / y);
}
//乘
int mul(int x, int y)
{
	return (x * y);
}
void menu(void)
{
	printf("********************\n");
	printf("** 1 加法 2 减法 **\n");
	printf("** 3 乘法 4 除法 **\n");
	printf("** 0 退出        **\n");
	printf("********************\n");
}
int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	//函数指针数组
	int(*parr[])(int, int) = {NULL, add, sub, mul, div};
	int length = sizeof(parr) / sizeof(parr[1]);
	do{
		menu();
		printf("请选择>");
		scanf("%d", &input);
		if (0 == input)
		{
			printf("退出程序!\n");
		}
		else if (input >= 1 && input <= (length - 1))
		{
			printf("请输入两个操作数>");
			scanf("%d %d", &x, &y);
			ret = parr[input](x,y);//通过函数指针调用
			printf("结果为:%d\n",ret);
		}
		else
		{
			printf("输入不正确!\n");
		}
	} while (input);

	return 0;
}

三、指向函数指针数组的指针(数组指针)

指向函数指针数组的指针,其实就是数组指针
定义形式:

	ret_type(*(*pparr)[array_size])(param_type);

ret_type: 函数指针数组中每个元素返回值类型
pparr: 指向函数指针数组的指针变量名
array_size: 数组长度
param_type: 函数指针数组中每个元素的参数类型

四、回调函数

回调函数指通过函数指针调用的函数
当把一个函数的地址作为参数传递给另一个函数,另一个函数通过这个地址调用函数,这个函数就是回调函数。
回调函数不是由函数的实现方直接调用,即不直接通过使用函数名调用,而是在特定事件或条件时由另外的一方通过函数指针调用,用于对该事件或条件进行响应。

修改上面的例子,利用回调函数实现:

//参数为函数指针
void calculator(int(* pfunc)(int,int))
{
	int x = 0;
	int y = 0;
	int ret = 0;
	printf("输入两个操作数>");
	scanf("%d %d", &x, &y);
	ret = pfunc(x, y);
	printf("结果为:%d\n", ret);
}

int main()
{
	int input = 0;
	do {
		menu();
		printf("请选择>");
		scanf("%d", &input);
		switch (input)
		{
		case 0:
			printf("退出程序!\n");
			break;
		case 1:
			calculator(add);//将加法函数的地址传递
			break;
		case 2:
			calculator(sub);//将减法函数的地址传递
			break;
		case 3:
			calculator(mul);//将乘法的地址传递
			break;
		case 4:
			calculator(div);//将除法的地址传递
			break;
		default:
			printf("输入不正确!\n");
			break;
		}
	} while (input);

	return 0;
}

总结

本篇文章介绍了函数指针的使用、函数指针数组的使用、指向函数指针数组的指针的定义、以及介绍了回调函数的定义以及使用。

文章来源:https://blog.csdn.net/pyc68/article/details/135419524
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。