回调函数

 

了解回调函数之前我们先来了解函数指针,函数的入口和变量一样,也是写进内存的,使用时会被压进栈,这说明可以和对变量一样,用一个指针指向函数,这种指针称之为函数指针。

函数指针:

例如:void (*fp)(char *s)。使用typedef 转换 typedef void (*Func)(int);写法是   返回类型(*新类型)(参数表),define进行替换时也是这种写法。由上可知,Func就是一个参数是int,返回值是void的函数的指针。

例子:

//宏定义
typedef void(*FP)(char *s);
//声明
void Islog( char *s);

int application_start( void )
{
     OSStatus err = kNoErr;
     FP fp; //通常使用宏FP来声明一个函数指针fp
     fp = Islog;//将Islog的函数入口地址付给fp
     fp("hello world !");//函数指针fp实现函数调用
     return err;
}

void Islog( char *s){
     app_log(" s:%s",s);
}

函数指针还可以变身成为函数数组指针,极其方便

例如:


#include <stdio.h>
 
int add(int x , int y){
    return x + y;
}
 
int sub(int x , int y){
	return x - y;
}
 
int mul(int x ,int y){
    return x * y;
}
 
int div(int x ,int y){
    return x / y;
}
 
int main(){
	int select , op1 , op2 ;
	int result = 0;
    int (*arr[5])(int x, int y) = {0 , add , sub , mul , div};	//函数指针数组
    printf(" 请输入你的选项 :\n");
    printf("**** 1 . 加法   2. 减法 ****\n");
    printf("**** 3 . 加法   4. 减法 ****\n");
    scanf("%d", &select);
    printf("请输入两个操作数: ");
    scanf("%d %d", &op1 , &op2);
    result =  (*arr[select])(op1, op2);
    printf("结果是 : %d\n", result);
    return 0;

例二:

//宏定义
typedef void(*FP)( char *s,int count);
//声明
void Islog1( char *s,int count);
void Islog2( char *s,int count);
void Islog3( char *s,int count);

int application_start( void )
{
     OSStatus err = kNoErr;

  //void* Islog[] = {Islog1,Islog2,Islog3};//定义了指针数组,这里a是一个普通指针
  //Islog3[0] ("hello world !");//编译错误,指针数组不能用下标的方式来调用函数

     FP Islog[] = {Islog1,Islog2,Islog3};//定义一个函数指针的数组,这里的f是一个函数指针
     Islog[0] ("hello world!",1);
     Islog[1] ("hello world!",2);
     Islog[2] ("hello world!",3);
     return err;
}

void Islog1( char *s,int count){app_log(" s:%s and count:%d",s,count);}
void Islog2( char *s,int count){app_log(" s:%s and count:%d",s,count);}
void Islog3( char *s,int count){app_log(" s:%s and count:%d",s,count);}

回调函数:

回调函数,顾名思义,就是使用者自己定义一个函数,使用者自己实现这个函数的程序内容,然后把这个函数作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。函数是你实现的,但由别人(或系统)的函数在运行时通过参数传递的方式调用,这就是所谓的回调函数。

例如:

typedef void (*CallFunc)(char *s,int count);
//定义回调函数

void PrintText(char *s,int count){
     app_log("s:%s",s);
     app_log("count:%d",count);
}

//定义实现回调函数的“调用函数”
void CallprintfText(CallFunc callfunc,char *s,int count){
     callfunc(s,count);
}

int application_start( void )
{
     OSStatus err = kNoErr;
     CallprintfText(PrintText,"hello world!",1);
     return err;
}

回调函数与普通函数调用的区别:

1.回调函数作为参数传给另一个函数,所以我们在调用回调函数时,预先并不知道所调用的函数具体是哪个函数,因为我们调用的是一个参数,而普通函数是通过具体的函数名来调用,所有我们在调用普通函数时,预先知道要调用的是哪个函数

2.

  • 对普通函数的调用:调用程序发出对普通函数的调用后,程序执行立即转向被调用函数执行,直到被调用函数执行完毕后,再返回调用程序继续执行。从发出调用的程序的角度看,这个过程为“调用-->等待被调用函数执行完毕-->继续执行”

  • 对回调函数调用:调用程序发出对回调函数的调用后,不等函数执行完毕,立即返回并继续执行。这样,调用程序执和被调用函数同时在执行。当被调函数执行完毕后,被调函数会反过来调用某个事先指定函数,以通知调用程序:函数调用结束。这个过程称为回调(Callback),这正是回调函数名称的由来。

  • 回调函数与普通函数的区别在于调用者不同。普通函数的调用是直接或者间接由main函数发起的。回调函数由系统发起调用,与main函数无关。在STM32的HAL库中,回调函数由中断发起。实际上它们就是中断处理函数。

参考:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值