C/C++回调函数

来源:互联网 发布:java sha1加密解密 编辑:程序博客网 时间:2024/05/17 23:15
回调函数就像您随身带的BP机:告诉别人号码,在它有事情时Call您
    
    回调用于层间协作,上层将本层函数安装在下层,这个函数就是回调,而下层在一定条件下触发回调,例如作为一个驱动,是一个底层,他在收到一个数据时,除了完成本层的处理工作外,还将进行回调,将这个数据交给上层应用层来做进一步处理,这在分层的数据通信中很普遍。
    
    其实回调和API非常接近,他们的共性都是跨层调用的函数。但区别是API是低层提供给高层的调用,一般这个函数对高层都是已知的;而回调正好相反,他是高层提供给低层的调用,对于低层他是未知的,必须由高层进行安装,这个安装函数其实就是一个低层提供的API,安装后低层不知道这个回调的名字,但它通过一个函数指针来保存这个回调,在需要调用时,只需引用这个函数指针和相关的参数指针。
    
    其实:回调就是该函数写在高层,低层通过一个函数指针保存这个函数,在某个事件的触发下,低层通过该函数指针调用高层那个函数。回调在C语言中是通过函数指针来实现的,通过将回调函数的地址传给被调函数从而实现回调。因此,要实现回调,必须首先定义函数指针,请看下面的例子:
    
    void Func(char *s);// 函数原型
    
    void (*pFunc) (char *);//函数指针
    
    可以看出,函数的定义和函数指针的定义非常类似。
    
    一般的化,为了简化函数指针类型的变量定义,提高程序的可读性,我们需要把函数指针类型自定义一下。
    
    typedef void(*pcb)(char *);
    
    回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。
    
    被调函数的例子:
    
    例一:
    
    void GetCallBack(pcb callback)
    
    {
    
    /*do something*/
    
    }
    
    用户在调用上面的函数时,需要自己实现一个pcb类型的回调函数:
    
    void fCallback(char *s)
    
    {
    
    /* do something */
    
    }
    
    然后,就可以直接把fCallback当作一个变量传递给GetCallBack,
    
    GetCallBack(fCallback);
    
    如果赋了不同的值给该参数,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。
    
    例二:
    
    //Test.c
    
    #include <stdlib.h>
    
    #include <stdio.h>
    
    int Test1()
    
    {
    
    int i;
    
    for (i=0; i<30; i++)
    
    {
    
    printf(“The %d th charactor is: %c\n”, i, (char)(‘a' + i%26));
    
    }
    
    return 0;
    
    }
    
    int Test2(int num)
    
    {
    
    int i;
    
    for (i=0; i<num; i++)
    
    {
    
    printf(“The %d th charactor is: %c\n”, i, (char)('a' + i%26));
    
    }
    
    return 0;
    
    }
    
    void Caller1(void (*ptr)())      //指向函数的指针作函数参数
    
    {
    
    (*ptr)();
    
    }
    
    void Caller2(int n, int (*ptr)())    //指向函数的指针作函数参数,这里第一个参数是为指向函数的指针服务的,
    
    {                                                   //不能写成void Caller2(int (*ptr)(int n)),这样的定义语法错误。
    
    (*ptr)(n);
    
    return;
    
    }
    
    int main()
    
    {
    
    printf(“************************\n”);
    
    Caller1(Test1); //相当于调用Test2();
    
    printf(“&&&&&&************************\n”);
    
    Caller2(30, Test2); //相当于调用Test2(30);
    
    return 0;
    
    }
    
    以上通过将回调函数的地址传给调用者从而实现调用,但是需要注意的是带参回调函数的用法。要实现回调,必须首先定义函数指针。函数指针的定义这里稍微提一下。比如:
    
    int (*ptr)(); 这里ptr是一个函数指针,其中(*ptr)的括号不能省略,因为括号的优先级高于星号,那样就成了一个返回类型为整型的函数声明了
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 进口报关金额少报了怎么办 报关重量报少了怎么办 金额报多100倍怎么办 ems没扫描到单号怎么办 回国海关被税了怎么办 代购买错东西了怎么办 征信报告有逾期怎么办 evus信息填错了怎么办 清关一个月了该怎么办 清关一直不发怎么办 清关一个月了怎么办 香港ems到西安海关税怎么办 寄东西被海关扣留怎么办 天津港新舱单品名错误核销怎么办 移动手机不能用联通卡怎么办 移动手机联通卡网速卡怎么办 移动手机不支持联通4g怎么办 汽车分离轴承异响怎么办 至尊宝被冻结了怎么办 qq冻结了至尊宝怎么办 至尊宝没办法申诉怎么办 至尊宝qq被冻结怎么办 未满16岁怎么办手机卡 联想预装的office卸载怎么办 win10激活后无法启动怎么办 移动电话卡没用了没注销怎么办 快捷快递客服热线一直打不通怎么办 牛奶乳加钙咀嚼片吃多了怎么办 三生骗了我该怎么办 国珍产品新时代卡怎么办 三个月大的宝宝对眼怎么办 9月大婴儿眼睛对眼怎么办 30岁眼部有皱纹怎么办 才24岁眼部皱纹怎么办 被双开后以前的养老保险怎么办 尚赫辟谷期间来月经怎么办 保险公司给代理人奖金迟发怎么办 比亚迪f3烧机油怎么办 支付宝刷脸认证老失败怎么办 融e借没密码器怎么办 融e购不显示积分怎么办