C语言指针相关知识(二)(函数指针,函数指针数组,回调函数)

函数指针

函数指针就是指向函数的指针,存放函数地址的指针。
&函数名就是取函数的地址。
&函数名 等价于 函数名 ,如下面的 &sum 和 sum,都能获取函数的地址:
函数地址
如何声明变量来接收函数指针?
int (*p)(int , int ) = &add;
声明函数指针
注意: C语言不会判断传递的参数是否正确,所以使用函数指针时一定要小心。
那对于 void test (char
c); 函数又如何声明?
可以参照上面写出:
void ( *pt ) ( char* ) = &test;
void 为函数返回值;
(char*):函数有一个 char* 型的参数

使用指针来调用函数:
指针调用函数

注意:上面不能写成 printf (“%d\n”, *p(6,3));
写成这样的话,就会先运算 p(6,3),再对运算出来的值解引用,发生错误。
下面是声明函数指针的其他例子:
int (*p1)(double); --------一个double参数,返回 int
void (*p2)(char*); --------一个char指针参数,无返回值
double* (*p3)(int , int); --------两个int参数,返回double指针

函数指针数组

函数指针数组:是一个数组,存放的是函数的指针。
函数指针数组声明:
函数返回值类型 (*p[数组的个数]) (函数参数1,函数参数2…) = {数组元素};
例如:int ( *p [2] ) (int , int ) = {add , sub};

int add(int a,int b)
{
	return a + b;
}
int sub(int a, int b)
{
	return a - b;
}

int main()
{
	int (*pa)(int, int) = &add;
	int (*ps)(int, int) = ⊂
	int (*p[2])(int, int) = {pa, ps};
	//或者
	int (*p[])(int, int) = {add, sub};
	return 0;
}

函数指针数组的使用场景:
假设需要一个程序实现计算器功能(加减乘除),用户输入数字1,2,3,4,来分别选择加减乘除功能计算。如果在不使用函数指针数组的情况下,我们就只能使用 switch case语句,用户输入一个数字,则跳转到相应的功能,如果这样,那每个case里都有部分相同的代码。并且后期添加其它功能时,则会非常麻烦。

对此,如果我们使用函数指针数组的话,则会非常简便。我们把每个函数的地址存储到数组里,用户输入多少,就调用下标为用户输入的数组。

#include <stdio.h>
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("----------0.exit---------\n");
	printf("----1.add-------2.sub----\n");
	printf("----3.mul-------4.div----\n");
}
int main()
{
	int input = 0;
	do
	{
		menu();
		int a, b = 0;
		//把下标为0的元素赋值成NULL,用户输入0就会退出,和上面菜单栏对应
		int (*p[5])(int, int) = {NULL,add,sub,mul,div};
		printf("请输入你的选择-> ");
		scanf("%d", &input);
		if (input >= 1 && input <= 4)
		{
			printf("请输入两个数-> ");
			scanf("%d %d", &a, &b);
			int res = (p[input](a, b));
			printf("%d\n", res);
		}
		else if (input == 0)
		{
			printf("程序退出!!!\n");
			break;
		}
		else
		{
			printf("选择错误,请重新选择\n");
		}

	} while (input);

	return 0;
}

在上面程序中,定义了5个大小的函数指针数组,实现退出和加减乘除,下标为0的值是null,用户输入0,根据判断就会退出程序,用户输入1,2,3,4分别执行加减乘除。

回调函数

函数指针可以作为另一个函数的参数来使用,回调函数就是一个通过函数指针调用的函数。
下面是一个调用函数生成随机数数组的函数案例:
rand_array 函数调用 get_rand 函数这个动作就叫回调,而 get_rand 就是回调函数。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//用一个函数指针变量来接收,被调用函数的返回值是int,无参
void rand_array(int* arr, int sz, int (*fun)(void))
{
	for (int i = 0; i < sz; i++)
	{
		arr[i] = fun();
	}
}
int get_rand(void)
{
	return rand()%100+1;
}
int main()
{
	srand((unsigned)time(NULL));
	int arr[6] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//get_rand作为参数被rand_array调用
	rand_array(arr, sz, get_rand);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);//输出5个1-100的随机值
	}
	return 0;
}

上面代码中,get_rand 是生成 1-100 随机数的函数,它作为参数被 rand_array 函数调用,所以 rand_array 函数用一个函数指针来接收。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值