我所理解的回调函数

 
   如果函数A的指针作为函数B的一个参数,在函数B中利用该指针调用函数A,则此时的A可以叫做回调函数。B就是调用者。
在C语言中一般用typedef来为回调函数定义别名(参数名)。
别名通过宏定义typedef来实现(这种typedef用的比较少),不是简单的宏替换。可以用作同时声明指针型的多个对象。
如当我们用
char *pa,pb;
这样定义后,pa是一个char型指针,但pb是一个char型字符。如需都定义为char型指针,我们可以这样来实现。
typedef char* BOTHchar;
BOTHChar pa,pb;

如此定义以后,pa和pb都是char型指针。BOTHChar可以看作char*使用。下文可见typedef的妙用。


先看一个回调函数的例子:

#include<stdio.h>
typedef int (*CallBack)(char *p);    
/*这一段不好理解,如果像上文一样定义CallBack Function,替换掉写成int (*Function)(char *p),
这就是定义一个函数指针,返回值为int */    //函数 ACall,ACall这个函数的地址后面作为实参传到 (*Function)(char *p)中。
int ACall(char *p)
{
printf("ACall回调打印出字符%s!\n", p);   
return 0;
}
//函数 CCall,CCall这个函数的地址后面也作为实参传到 (*Function)(char *p)中。
int CCall(char *p)
{   
printf("CCall回调打印出字符:%s\n”,  p);   
return 0;
}
// 执行回调函数,方式一:通过命名方式,这里pCallBack可以看做是CallBack的别名
int call(CallBack pCallBack, char *p)
{   
printf("call 直接打印出字符%s!\n", p);   
pCallBack(p);   
return 0;
}
// 执行回调函数,方式二:直接通过方法指针    
int call2(char *p, int (*ptr)())  //或者用int call2(char *p, int (*ptr)(char *)),同时ptr可以任意取名
{
printf("==============\n", p);    
(*ptr)(p);
}
int main()
{   
char *p = "hello";
call(ACall, p);   
call(CCall, p);
call2(p, ACall);   
call2(p, CCall);
return 0;
}

这个例子说明了回调函数如何进行定义和调用。其实质就是函数指针的应用。

再看另外一个回调函数:
#include <stdio.h>
typedef void (*callback)(char *);
void repeat(callback function, char *para)
{
function(para);
function(para);
}

void hello(char* a)
{
     printf("Hello %s\n",(const char *)a);
}

void count(char *num)
{
     int i;
     for(i=1;i<(int)num;i++)
          printf("%d",i);
     putchar('\n');
}

int main(void)
{
     repeat(hello,"Huangyi");
     repeat(count, (char *)4);
}
 
本例中回调函数的参数按什么类型解释由调用者(即repeat)规定,实现者(即hello,count)就是一个void *指针,实现者只负责将这个指针转交给回调函数,而不关心它到底指向什么数据类型。调用者知道自己传的参数是char *型的,那么在自己提供的回调函数中就应该知道参数要转换成char *型来解释(如(char *)4强制类型转换)。

回调函数功能:

提供统一的接口以及事件的通知。所谓提供统一接口或者事件的通知即:当发生某一事件或者出现某一个状态之后必定会进行某种操作。但是这个操作又不能写死,不同的环境不同的程序会有不同的实现,也就是说提供接口的人不想把逻辑写死,而是由调用接口的人来实现逻辑。这也就是回调函数的主要功能。


Reference:
[1].http://my.oschina.net/kaixindewo/blog/16320
[2].http://learn.akae.cn/media/ch24s05.html
[3].http://blog.csdn.net/feiyinzilgd/article/details/6110811
[4].http://www.cppblog.com/SpringSnow/archive/2008/12/07/68770.aspx
[5].《C Traps and Pitfalls》. (PS:这是一本好书) Page15~19



转载于:https://my.oschina.net/lvyi/blog/183072

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值