一文详解函数指针与回调函数

嵌入式技术

1372人已加入

描述

函数指针与回调函数

函数指针是指向函数的指针变量。它允许我们将函数作为参数传递给其他函数或将函数作为返回值返回。函数指针的类型与所指向的函数的类型相匹配。

回调函数是一种通过函数指针来实现的机制。在使用回调函数的情况下,我们可以将一个函数的指针传递给另一个函数,然后在后者中调用该函数来完成特定的任务。回调函数常常用于事件处理、异步编程和插件架构等场景。

使用回调函数的一般流程如下:

  1. 定义一个函数,该函数将作为回调函数被调用。
  2. 定义另一个函数,该函数接受一个函数指针作为参数,用于指定回调函数。
  3. 在第二个函数中,根据需要调用传入的回调函数。

通过回调函数,我们可以将程序的控制权交给调用方,使得调用方可以根据特定的条件或事件来执行自定义的代码逻辑。这种机制提供了一种灵活的方式来扩展程序的功能和逻辑。

函数指针代码:

定义一个函数指针:

int(*func_ptr)(int,int);

定义一个函数计算两个整型数据的和:

int sum(int x,int y)
{
    return x+y;
}

定义一个函数计算两个整型数据的差:

int difference(int x, int y)
{
	return x-y;
}

定义一个函数计算两个整型数据的积:

int product(int x, int y)
{
	return x*y;
}

函数指针测试代码如下:

#include < stdio.h >

//定义三个函数,它们具有相同的形式参数和返回值

//sum计算两个数相加
int sum(int x, int y)
{
	return x+y;
}

//difference计算两个数相减
int difference(int x, int y)
{
	return x-y;
}

//product计算两个数相乘
int product(int x, int y)
{
	return x*y;
}

//主函数
int main(void)
{
    int(*func_ptr)(int,int);//定义有两个整数参数、返回值是整数的函数指针

	int a = 5;
	int b = 8;

	func_ptr = sum;                                  //将func_ptr分别指向函数sum
    printf("sum's address=%pn",sum);                //打印sum中存储的地址
    printf("func_ptr=%pn",func_ptr);                //打印func_ptr存储的值
    printf("%d+%d=%dn",a,b,sum(a,b));               //直接调用sum函数
    printf("%d+%d=%dn",a,b,func_ptr(a,b));          //通过func_ptr调用sum函数

    func_ptr = difference;                           //将func_ptr分别指向函数difference
    printf("difference's address=%pn",difference);  //打印difference中存储的地址
    printf("func_ptr=%pn",func_ptr);                //打印func_ptr存储的值
    printf("%d-%d=%dn",a,b,difference(a,b));        //直接调用difference函数
    printf("%d-%d=%dn",a,b,func_ptr(a,b));          //通过func_ptr调用difference函数

    func_ptr = product;                              //将func_ptr分别指向函数product
    printf("sum's address=%pn",product);            //打印product中存储的地址
    printf("func_ptr=%pn",func_ptr);                //打印func_ptr存储的值
    printf("%d*%d=%dn",a,b,product(a,b));           //直接调用product函数
    printf("%d*%d=%dn",a,b,func_ptr(a,b));          //通过func_ptr调用product函数

    return0; 
}

测试代码运行结果如下:

sum's address=00401500
func_ptr=00401500
5+8=13
5+8=13

difference's address=0040150D
func_ptr=0040150D
5-8=-3
5-8=-3

sum's address=00401518
func_ptr=00401518
5*8=40
5*8=40

回调函数代码:

定义一个函数,参数包含一个函数指针和两个整型数据:

//该函数有三个参数,函数指针func_ptr和整数a、b

int compute_func(int (*func_ptr)(int, int),int x, int y)
{
	return func_ptr(x,y);
}

定义一个函数指针:

int (*func_ptr)(int, int);

定义三个函数:

//定义三个函数,它们具有相同的形式参数和返回值

//sum计算两个数相加
int sum(int x, int y)
{
	return x+y;
}

//difference计算两个数相减
int difference(int x, int y)
{
	return x-y;
}

//product计算两个数相乘
int product(int x, int y)
{
	return x*y;
}

回调函数测试代码如下:

#include < stdio.h >

//定义三个函数,它们具有相同的形式参数和返回值
//sum计算两个数相加
int sum(int x, int y)
{
	return x+y;
}

//difference计算两个数相减
int difference(int x, int y)
{
	return x-y;
}

//product计算两个数相乘
int product(int x, int y)
{
	return x*y;
}

//自定义实现3乘以x+5乘以y
int my_func(int x, int y)
{
	return3*x+5*y;
}

//该函数有三个参数,函数指针func_ptr和整数a、b
//与sum、difference、product形式相同
int compute_func(int(*func_ptr)(int,int),int x,int y)
{
	return func_ptr(x,y); //直接返回func_ptr的调用结果
}


//主函数 
int main(void)
{
	int a = 5;
	int b = 8;

	//通过调用compute_func函数计算a和b的和、差、积
	printf("%d+%d=%dn",a,b,compute_func(sum,a,b));      
	printf("%d-%d=%dn",a,b,compute_func(difference,a,b));
	printf("%d*%d=%dn",a,b,compute_func(product,a,b));
    //通过调用compute_func函数计算3*a+5*b的值 
	printf("3*%d+5*%d=%dn",a,b,compute_func(my_func,a,b));

	return0;
}

测试代码运行结果如下:

//传入相同的参数不同的函数名得到不同的结果

5+8=13
5-8=-3
5*8=40
3*5+5*8=55

总结一下使用函数指针的好处:

  1. 可以动态选择函数:函数指针允许在运行时动态选择要调用的函数。这对于根据条件或配置来确定执行的函数非常有用。通过更改函数指针的指向,可以轻松地切换函数的行为,而无需修改调用它的代码。
  2. 可以实现回调机制:函数指针广泛应用于回调机制,使得可以将一个函数作为参数传递给另一个函数。这种机制可以在事件发生或特定条件满足时触发回调函数的执行,从而实现灵活的程序控制流。
  3. 扩展性和灵活性:函数指针提供了一种灵活的方式来扩展程序的功能和逻辑。通过使用函数指针,可以通过添加或修改指向不同函数的指针来实现新的行为,而无需更改现有的代码。
  4. 函数作为数据:函数指针使得函数可以像其他数据类型一样被操作和传递。这种能力使得可以将函数作为数据结构的一部分来处理,例如在数组、链表或树中存储函数指针。
  5. 接口抽象:函数指针可以用于实现接口抽象,将底层的具体实现与高层的接口分离。通过定义一组函数指针作为接口,可以使得不同的实现可以被动态地切换和替换,从而提高代码的可维护性和可扩展性。

函数指针提供了一种灵活和强大的机制,使得函数可以像其他数据一样被处理和传递,从而增强了程序的可扩展性、可维护性和灵活性。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分