C语言----函数指针与回调函数

  • 一.定义

    回调函数是指 使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。函数是你实现的,但由别人(或系统)的函数在运行时通过参数传递的方式调用,这就是所谓的回调函数。简单来说,就是由别人的函数运行期间来回调你实现的函数。C语言中回调函数主要通过函数指针的方式实现。

  • 二.代码

#include <stdio.h>

void testCallbackFun(void* Param)
{
	printf("[Info]--Enter Function:%s\n", __FUNCTION__);
}

void FAN_ALERTSetCallbackFunc (void (* CallbackFunction)(void* Param),void* Param)
{
	printf("[Info]--Enter Function:%s\n", __FUNCTION__);
	CallbackFunction(Param);
}

int main()
{
	FAN_ALERTSetCallbackFunc(testCallbackFun, NULL);

	return 0;
}
  • 三.运行结果 

  • 四.总结

(此部分转自https://blog.csdn.net/yuexiang321/article/details/52658947

int Max_Int(int a, int b)   //声明一个函数
{
	return (a>b)?a:b;
}

int (*pFun)(int a, int b);    //声明函数指针,此时函数指针没有指向任何函数

pFun = Max_Int; //使函数指针指向Max_Int函数

int max;
int m = 5;
int n = 8;
max = (*pFun)(m,n);                //使用函数指针引用Max_Int函数
max = pFun(m,n);                   //与上一句效果完全相同
printf(“The max value is %d\n”, max);    //print ‘8’

1、更高级的声明方式:

1)使用typedef声明函数指针。

我们可以使用typedef来声明函数,以使代码的可读性更强。

typedef bool(*pCopySDMMC2Mem)(int, unsigned int, unsigned short, unsigned int*, bool);


通过之前的介绍,我们可以知道,此函数指针可以指向“返回bool型,带int, unsigned int, unsigned short, unsigned int*, bool型参数” 的函数。

借此声明,我们可以像声明变量那样同时创建多个函数指针。

pCopySDMMC2Mem  pf1, pf2;


2)使用define来定义函数指针

#define CopySDMMCtoMem(z,a,b,c,e)(((bool(*)(int, unsigned int, unsigned short, 
        unsigned int*, bool))(*((unsigned int *)0xD0037F98)))(z,a,b,c,e))

2.函数指针的两个典型应用

1)将函数作为参数传递给函数(此部分转自https://blog.csdn.net/yuexiang321/article/details/52658947)

相信,大家中学的时候都学过积分这个鬼东西。不知道还记不记得积分最原始的计算方法。对,没错,无限细分,求面积。好的。我们接下来就给大家一个应用函数指针有关积分计算的例子。直接贴出代码。

#include <stdio.h>  
   
//Calculate用于计算积分。一共三个参数。第一个为函数指针func,指向待积分函数。二三参数为积分上下限  
double Calculate(double(*func)(double x), double a, double b)  
{  
    double dx = 0.0001;//细分的区间长度  
    double sum = 0;  
    for (double xi = a+dx; xi <= b; xi+=dx)  
    {  
       double area = func(xi)*dx;  
       sum +=area;  
    }  
    return sum;  
}  
   
double func_1(double x)  
{  
    return x*x;  
}  
   
double func_2(double x)  
{  
    return x*x*x;  
}  
   
void main()  
{  
    printf("%lf\n", Calculate(func_1, 0, 1));  
    printf("%lf\n", Calculate(func_2, 0, 1));  
}  

2)引用不在代码段中的函数

此功能在嵌入式系统中经常使用。我们知道,我们写的用户程序的code是存放在代码段中的,在嵌入式系统中,一般情况下是存放在flash中的。什么叫不在代码段中的函数?很多微控制器在出厂前会将一些功能函数(系统函数)固化在rom中(类似于PC机中的BIOS),如Flash擦写功能,Flash Copy功能。而我们写的代码是不认识这些函数的,不能直接使用函数名调用。所以,当我们想在用户程序中调用这些系统函数时,就只能使用函数指针的方式,通过将系统函数的入口地址传给函数指针,来达到调用rom中程序的目的。这些系统函数一般都会在官方手册中给出功能,返回值类型和参数列表。

下面是从三星的S5PV210_applicationnote中截取的一个系统函数。
 

从上我们可以分析出,此系统函数的入口地址为0xD0037F98。返回bool型,带有int, unsigned int, unsigned short, unsigned int*, bool型五个参数。实际使用时,我们可以如下调用:

// 实际使用时
pCopySDMMC2Mem p1 = (pCopySDMMC2Mem)0xD0037F98;
p1(x, x, x, x, x);

 传入五个合适的参数即可。

关于指针函数和函数指针的区别可以参考如下博客:

https://blog.csdn.net/luoyayun361/article/details/80428882

猜你喜欢

转载自blog.csdn.net/qq_31094099/article/details/88710042