本文主要讲解如果实现回调,特别是在封装接口的时候,回调显得特别重要,我们首先假设有两个程序员在写代码,A程序员写底层驱动接口,B程序员写上层应用程序,然而此时底层驱动接口A有一个数据d需要传输给B,此时有两种方式:
   1、A将数据d存储好放在接口函数中,B自己想什么时候去读就什么时候去读,这就是我们经常使用的函数调用,此时主动权是B。
   2、A实现回调机制,当数据变化的时候才将通知B,你可以来读取数据了,然后B在用户层的回调函数中读取速度d,完成OK。此时主动权是A。
很明显第一种方法太低效了,B根本就不知道什么时候该去调用接口函数读取数据d。而第二种方式由于B的读取数据操作是依赖A的,只有A叫B读数据,那么B才能读数据。也即是实现了中断读取。
那么回调是怎么实现的呢,其实回调函数就是一个通过函数指针调用的函数。如果用户层B把函数的指针(地址)作为参数传递给底层驱动A,当这个指针在A中被用为调用它所指向的函数时,我们就说这是回调函数。
注意:是在A中被调用,这里看到尽管函数是在B中,但是B却不是自己调用这个函数,而是将这个函数的函数指针通过A的接口函数传自A中了,由A来操控执行,这就是回调的意义所在。
下面就通过一个例子来演示
首先写A程序员的代码

//-----------------------底层实现A-----------------------------
typedef void (*pcb)(int a); //函数指针定义,后面可以直接使用pcb,方便
typedef struct parameter{
int a ;
pcb callback;
}parameter; void* callback_thread(void *p1)//此处用的是一个线程
{
//do something
parameter* p = (parameter*)p1 ;
while()
{
printf("GetCallBack print! \n");
sleep();//延时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 = ;
p->callback = callback; //创建线程
pthread_t thing1;
pthread_create(&thing1,NULL,callback_thread,(void *) p);
pthread_join(thing1,NULL);
}

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

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

//-----------------------应用者B-------------------------------
void fCallBack(int a) // 应用者增加的函数,此函数会在A中被执行
{
//do something
printf("a = %d\n",a);
printf("fCallBack print! \n");
} int main(void)
{
SetCallBackFun(,fCallBack); return ;
}

运行程序会看到

先会打印A程序的                 printf("GetCallBack print! \n");
然后等待3秒钟才会打印应用者B的 printf("fCallBack print! \n");

C语言面试题分类->回调的更多相关文章

  1. C语言面试题分类->指针

    有关指针的经典面试题 C语言为何如此长寿并实用?C++为什么有那么多精彩?指针可以说是C/C++中的灵魂所在,虽然早期中pascal也有指针,但是和C/C++比起来不是一个级别的.今天为大家深入浅出的 ...

  2. C语言面试题分类->链表

    链表的创建,清空,插入,删除 typedef int (* __compfunc)(const void *, const void *); //Traverse list. Fast macro t ...

  3. C语言面试题分类->字符串处理

    1.strlen:计算字符串长度(不包含'\0') 实现想法:遍历字符串,直到'\0'结束 #include<stdio.h> #include<stdlib.h> #incl ...

  4. C语言面试题分类->排序算法

    1.选择排序. 每次将最小的数,与剩余数做比较.找到更小的,做交换. 时间复杂度:O(n²) 空间复杂度:O(1) 优缺点:耗时但内存空间使用小. void selectSort(int *p,int ...

  5. C语言面试题分类->位运算

    1.不用临时变量交换两个整数. a = a ^ b; b = a ^ b; a = a ^ b; 2.实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如9的二进制是1001,则输出2. i ...

  6. C语言面试题分类->宏定义

    1.写一个“标准”宏,这个宏输入两个参数并返回较小的一个 答:#define MIN(x, y) ((x)<(y)?(x):(y))//注意x,y要加括号,因为x,y如果有复合运算会出现问题. ...

  7. 嵌入式开发—C语言面试题

    嵌入式开发—C语言面试题 源地址:http://blog.csdn.net/xdx2ct1314/article/details/7358929   1. 用预处理指令#define 声明一个常数,用 ...

  8. C语言面试题汇总之一

    C语言面试题汇总之一 1.static有什么用途?(请至少说明两种) l 限制变量的作用域: 设置变量的存储域. 2.引用和指针有什么区别? 引用必须被初始化,指针不必: 引用初始化以后不能被改变,指 ...

  9. 12个有趣的C语言面试题

    摘要:12个C语言面试题,涉及指针.进程.运算.结构体.函数.内存,看看你能做出几个! 1.gets()函数 问:请找出下面代码里的问题: #include<stdio.h> int ma ...

随机推荐

  1. RandomShuffleQueue

    一.几个函数 RandomShuffleQueue类 __init__(self, capacity, min_after_dequeue,dtypes, shapes=None,names=None ...

  2. uni-app 在input获取焦点(弹出软键盘后收起软键盘),页面不下滑,留下下方空白

    加入收起软键盘时让页面回正 uni.pageScrollTo({ scrollTop: 0, duration: 0 });

  3. 前端angular使用crypto-js进行加密

    首先下载大包 npm install crypto-js 然后下载ts版本的包 npm install --save @types/crypto-js 接着在头部导入crypto-js模块 impor ...

  4. 学习笔记_J2EE_SpringMVC_02_注解配置

    SpringMVC注解配置 1.测试环境: 名称 版本 备注 操作系统 Windows10 专业版1809X64   WEB服务器 Tomcat 8.5 X64   浏览器 Google Chrome ...

  5. 2018-2019-2 网络对抗技术 20165328 Exp6 信息收集与漏洞扫描

    目录 实验要求 基础问题回答: 实验过程: 各种搜索技巧的应用及DNS IP注册信息的查询 基本扫描技术 漏洞扫描--使用OpenVAS 实验感想 实验要求 (1)各种搜索技巧的应用 (2)DNS I ...

  6. sqlserver给用户配置存储过程查看权限

    对应的数据库->安全性->用户名右键属性-->安全对象-->指定所有对象-->选择服务器,里边有一个 查看定义(view any definition) 选项,勾上.

  7. Helm - Kubernetes服务编排的利器

    Helm介绍 在Kubernetes中部署容器云应用(容器或微服务编排)是一项有挑战性的工作,Helm就是为了简化在Kubernetes中安装部署容器云应用的一个客户端工具.通过Helm能够帮助开发者 ...

  8. python连接mysql数据库读取数据

    #-*- coding:utf-8 -*- #Author:'Lmc' #DATE: 2019/4/28/0028 上午 11:22:47 #FileName:test.PY import pymys ...

  9. Docker 学习5 Docker容器网络

    一.内核网络名称空间 1.可通过ip netns进行操作 [root@localhost /]# ip netns help Usage: ip netns list ip netns add NAM ...

  10. css处理事件透过、点击事件透过

    // 执行一些动作... $("#myModal2").css("pointer-events","none"); // 执行一些动作... ...