参考文献

  • [1] C++回调函数的理解与使用
  • [2]同步调用、回调和异步调用的区别–举出的例子生动形象
  • [3]深入理解回调函数–这个比较好理解
  • [4] 回调函数 同步回调 异步回调
  • [5] 该博客对回调函数的讲解也非常明白

1. 什么是回调函数

回调函数就是通过函数指针调用函数。如果把函数的指针或者地址作为参数传递给另一个参数,当这个指针被用来调用其所指向的函数时,那么这就是一个回调的过程,这个被回调的函数就是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或者条件发生时由另外的一方调用的,用于对该事件或者条件进行响应。回调函数就是在两个独立函数或者独立类通信的通道。

2. 回调函数和普通函数的区别

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

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

两者实现上的区别:

3. 同步回调和异步回调的区别

  • 回调可以是同步也可以是异步
  • 同步可以是单线程也可以是多线程
  • 异步必须是多线程或多进程(每个进程可以是单线程) ==> 换句话说,异步必须依靠多线程或多进程才能完成

(1) 同步回调:把函数b传递给函数a。执行a的时候,回调了b,a要一直等到b执行完才能继续执行;

(2) 异步回调:把函数b传递给函数。执行a的时候,回调了b,然后a就继续往后执行,b独自执行。

4. 同步回调的实现

// C代码实现的同步回调函数
#include<stdio.h>
#include<string.h>// C函数:回调函数
int RemoteControl(char *actions[], int actions_len){printf("C函数被调用.    ==>  你朋友通过你开的 ***远程控制*** 操作你的电脑.\n");for(int i = 0; i < actions_len; i++){printf(">> %s\n", actions[i]);}printf("C函数返回.       ==>  处理完毕,退出远程的使用.\n");return 0;
}// B函数
int YourFriend(int rc(char *actions[], int actions_len)){// actions是提供的一些动作char *actions[] = {"右键计算机","选择属性","选择高级系统设置","... ..."};printf("B函数被调用.    ==>  你朋友收到你的求助.\n");rc(actions, 4); // 回调函数的执行printf("B函数返回.      ==>  你朋友向你反馈处理结果.\n");return 0;
}// A函数
int You(){printf("A函数启动.      ==>  你用电脑,遇到了问题.\n");printf("A函数调用B函数.  ==>  你向你朋友发起求助,同时提供 ***远程控制*** 给他.\n");YourFriend(RemoteControl);printf("A函数返回.    ==>  你出门办事.\n");return 0;
}int main(){char *msg[] = {"Hello", "World"};You();return 0;
}

程序运行输出结果如下

A函数启动.      ==>  你用电脑,遇到了问题.
A函数调用B函数.  ==>  你向你朋友发起求助,同时提供 ***远程控制*** 给他.
B函数被调用.    ==>  你朋友收到你的求助.
C函数被调用.    ==>  你朋友通过你开的 ***远程控制*** 操作你的电脑.
>> 右键计算机
>> 选择属性
>> 选择高级系统设置
>> ... ...
C函数返回.       ==>  处理完毕,退出远程的使用.
B函数返回.      ==>  你朋友向你反馈处理结果.
A函数返回.    ==>  你出门办事.

一个疑问:同步回调和普通函数的调用在栈上的执行顺序有什么区别?

5. 异步回调的实现

异步回调必定是多线程或者多进程的,不可能是单线程或者单进程的。

程序实例1:

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>/*C(回调)函数*/
int remote_control(char *actions[], int actions_len){printf("C函数被调用.     ==>  你朋友通过你开的 ***远程控制*** 操作你的电脑.\n");for(int i = 0; i < actions_len; i++){printf(">> %s\n", actions[i]);}printf("C函数返回.       ==>  处理完毕,退出远程的使用.\n");return 0;
}/*B函数*/
int your_friend(int rc(char *actions[], int actions_len)){char *actions[] = {"右键计算机","选择属性","选择高级系统设置","... ..."};printf("B函数被调用.     ==>  你朋友收到你的求助.\n");rc(actions, 4);printf("B函数返回.       ==>  你朋友向你反馈处理结果.\n");pthread_exit(0);
}/*A函数*/
int you(){printf("A函数启动.       ==>  你用电脑,遇到了问题.\n");printf("A函数调用B函数.  ==>  你向你朋友发起求助,同时提供 ***远程控制*** 给他.\n");pthread_t id;int thread_ret;thread_ret = pthread_create(&id, NULL, (void *)your_friend, remote_control);if(thread_ret){printf("Create pthread error!");return -1;}pthread_detach(id);printf("A函数返回.       ==>  你出门办事.\n");//为了在标准输出看到B函数打印的信息,先不返回.sleep(3);return 0;
}int main(void){char *msg[] = {"Hello", "world"};you();return 0;
}
// 另一种传参方式
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>struct callbackArgs{int (*callback_fun)(char *actions[], int actions_len);
} callback_args;/*C(回调)函数*/
int remote_control(char *actions[], int actions_len){printf("C函数被调用.     ==>  你朋友通过你开的 ***远程控制*** 操作你的电脑.\n");for(int i = 0; i < actions_len; i++){printf(">> %s\n", actions[i]);}printf("C函数返回.       ==>  处理完毕,退出远程的使用.\n");return 0;
}/*B函数*/
int your_friend(struct callbackArgs *input_function){char *actions[] = {"右键计算机","选择属性","选择高级系统设置","... ..."};printf("B函数被调用.     ==>  你朋友收到你的求助.\n");input_function->callback_fun(actions, 4);printf("B函数返回.       ==>  你朋友向你反馈处理结果.\n");pthread_exit(0);
}/*A函数*/
int you(){printf("A函数启动.       ==>  你用电脑,遇到了问题.\n");printf("A函数调用B函数.  ==>  你向你朋友发起求助,同时提供 ***远程控制*** 给他.\n");pthread_t id;int thread_ret;callback_args.callback_fun = remote_control;thread_ret = pthread_create(&id, NULL, (void *)your_friend, &callback_args);if(thread_ret){printf("Create pthread error!");return -1;}pthread_detach(id);printf("A函数返回.       ==>  你出门办事.\n");//为了在标准输出看到B函数打印的信息,先不返回.sleep(3);return 0;
}int main(void){you();return 0;
}

上述程序中,A函数相当于应用者;C函数是A函数创建的,但是并不在A函数中执行,而是作为回调函数向底层进行注册;B函数是底层的函数。

程序输出结果:

程序实例2:
假设有这样一个任务,A是底层,其产生的数据要给应用者B去使用,采用异步回调机制实现如以下两端程序所示:
A.cpp

//-----------------------底层实现A-----------------------------
typedef void (*pcb)(int a); //函数指针定义,后面可以直接使用pcb,方便
typedef struct parameter{int a ;pcb callback;
}parameter; void* callback_thread(void *p1)//此处用的是一个线程
{//do somethingparameter* p = (parameter*)p1 ;while(1){printf("GetCallBack print! \n");sleep(3);//延时3秒执行callback函数p->callback(p->a);//函数指针执行函数,这个函数来自于应用层B}
}//留给应用层B的接口函数
extern SetCallBackFun(int a, pcb callback)
{printf("SetCallBackFun print! \n");parameter *p = malloc(sizeof(parameter)) ; p->a  = 10;p->callback = callback;//创建线程pthread_t thing1;pthread_create(&thing1,NULL,callback_thread,(void *) p);pthread_join(thing1,NULL);
}
————————————————
版权声明:本文为CSDN博主「夏菠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiabodan/article/details/47999411

上面的代码就是底层接口程序员A写的全部代码,留出接口函数SetCallBackFun即可

下面再实现应用者B的程序,B负责调用SetCallBackFun函数,以及增加一个函数,并将此函数的函数指针通过SetCallBackFun(int a, pcb callback)的第二个参数pcb callback 传递下去。

B.cpp

//-----------------------应用者B-------------------------------
void fCallBack(int a)       // 应用者增加的函数,此函数会在A中被执行
{//do somethingprintf("a = %d\n",a);printf("fCallBack print! \n");
}int main(void)
{SetCallBackFun(4,fCallBack);return 0;
}
————————————————
版权声明:本文为CSDN博主「夏菠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiabodan/article/details/47999411

C++学习之回调函数相关推荐

  1. NodeJS学习笔记 —— 回调函数与callback hell

    什么是回调函数 编程分为两类:系统编程(system programming)和应用编程(application programming).所谓系统编程,简单来说,就是编写库:而应用编程就是利用写好的 ...

  2. JS中回调函数的写法

    <!DOCTYPE HTML>  <html> <head>   <meta charset="GBK" /> <title& ...

  3. JS回调函数(callback)

    在使用Jquery的时候,用到Callback(),回调函数的概念.而且很多. 比如: $.ajax({url:"test.json",type: "GET", ...

  4. js回调函数的理解(轉)

    js回调函数(callback)理解Mark!讲之前说一句function say(){alert(,,,,,,,,)}var say=function (){alert(,,,,,,,)}var s ...

  5. Node.js入门 - 回调函数

    本文自theprojectspot.com翻译而来,文章原作者为Lee Jacobson, 已经作者授权翻译用于非商业用途.原文地址:猛戳这里进入 如果你还没读过第一篇,先跑到这里去瞧一瞧,我保证你多 ...

  6. mysql.js回调函数_js回调函数(callback)

    Mark! js学习 不喜欢js,但是喜欢jquery,不解释. 自学jquery的时候,看到一英文词(Callback),顿时背部隐隐冒冷汗.迅速google之,发现原来中文翻译成回调.也就是回调函 ...

  7. JavaScript中的引用函数、调用函数和回调函数

    引用函数与调用函数的区别 引用函数与调用函数的差别与函数名称后是否附有括号()有关.函数引用只会单独出现,但函数调用则必定后随括号,很多时候还附有自变量. 举个例子 // 函数引用 代码一 funct ...

  8. c语言回调函数_C语言学习第26篇---函数与指针分析 回调函数

    函数类型的概念 1.C语言函数也是有类型的 2.函数类型由函数返回值,参数类型,参数个数共同决定 int add(int i,int j) 的类型是 int(int , int) 3.C语言中通过ty ...

  9. php回调函数求1+2+3+...+100的值_PHP全栈学习笔记6

    php能做什么,它是运行在服务器端的,web网站大部分数据都是存储在服务器上的,PHP就是用来处理这些存储在服务器的数据.跨平台,服务器可以是多种平台上的服务器,脚本语言,免费. wampserver ...

最新文章

  1. FreeBSD下安装配置Hadoop集群(三)
  2. 安装 Ruby 和 Rails 开发环境
  3. centos mysql 启动_MYSQL在centos上首次启动
  4. css --- flex:n的解析
  5. sql 如何设置行级锁_SQL Server 2016中的行级安全性
  6. linux下用grep命令根据文件内容进行关键字搜索[linux ubuntu grep] -转
  7. Mac使用minicom串口工具
  8. 电脑配置知识_电脑小知识:装机不求人!10 分钟电脑配置挑选速成攻略|硬盘|电脑|cpu|装机|固态硬盘|机械硬盘...
  9. android122 zhihuibeijing 新闻中心NewsCenterPager加载网络数据实现
  10. HDU 1196 ( Lowest Bit )
  11. 专业测试油耗的软件,油耗软件app哪个好_检测汽车油耗的软件_油耗记录软件车机版...
  12. JavaScript TypeScript 学习总结
  13. 软件开发未来五大技术趋势
  14. 计算机科学相关的期刊,计算机类期刊汇总(核心期刊,国家级期刊)
  15. 操作系统之哲学原理 第2版
  16. 6.0 深度学习图片常见转换操作
  17. 使用ROS和AprilTags进行相机定位(二维码定位全流程)
  18. Java GC 介绍
  19. 教你用Java来玩答题(百万英雄/冲刺大会等)
  20. 提交工程到git的分支上

热门文章

  1. 发那科机器人回原位置先上升_发那科机器人:参考位置设定方法
  2. Alibaba 官方微服务扛把子「SpringCloudAlibaba 全彩学习手册.PDF」,开源学习ing,
  3. java imageio处理图像_Linux geoserver调优之Java图像处理优化(原生JAI和ImageIO和java默认库相互转换)...
  4. esp8266连接机智云
  5. idea构建web项目-超详细教程
  6. oracle linux i386,在CentOS 5.5 i386 上安装 Oracle 10G XE
  7. CAN通信的用户层设计
  8. 万向区块链小课堂:超短文梳理区块链层级,字字珠玑
  9. java实现简单数独游戏
  10. 空间计量经济学与Stata操作