回调函数传参:函数指针做函数参数(回调函数)

目录

  • 背景
  • 回调函数是实现函数分层且单向依赖的好办法,使用函数指针运行
  • struct结构体回调函数代码更清晰
  • 简单理解回调函数
  • Demo
  • 其他回调函数博文

背景

这是我在实际工作中遇到的问题:

线程创建 第三个参数 函数指针
完全不管具体实现什么功能,把地址传过来,完全分层,黑盒子
涂鸦:那个接口有我解析的代码,也有mcu调用者的代码,耦合在一起了
要完全分层,双方代码要放在不同的 .c 文件里面,互不干扰。

回调函数是实现函数分层且单向依赖的好办法,使用函数指针运行

回调函数是实现函数分层且单向依赖的好办法,使用函数指针运行:
视频讲解【回调函数和函数指针】干货分享,彻底摆脱回调地狱


实际工作中很常见的一种方法是,额外去写一个注册/安装函数:

传递参数,底层给上层传递参数:


同时上层也可以给底层一个返回值,实现数据双向的携带:


总结:

struct结构体回调函数代码更清晰

参考:C/C++ struct 的回调函数使用技巧
地址:https://blog.csdn.net/u010333084/article/details/51339469?spm=1001.2014.3001.5502

回调函数是一个通过函数指针调用的函数。如果你把函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,我们就说这个函数是回调函数。可以作为函数参数传递哦。

使用struct 回调函数可以使得代码更加清晰明了.

1.定义回调函数的原型


typedef int STRU_FU;STRU_FU sfun1(int a, const char *b){printf("fun1  a = %d , b = %s \n",a,b);return a;
}STRU_FU sfun2(int a, void *b,float c){printf("fun2  a = %d , b = %f \n",a,c);return a;
}STRU_FU sfun3(int a, char b,long c){printf("fun3  a = %d , *b = %ld \n",a,c);return a;
}

2. 定义的struct的回调函数

struct fun_ops{ //定义回调函数structSTRU_FU (*fun1)(int a, char *b); //注册参数STRU_FU (*fun2)(int a, void *b,float c);STRU_FU (*fun3)(int a, char b,long c);
};

3. 注册回调函数

struct fun_ops fuops = {//注册初始化函数指针的函数.fun1 = sfun1,.fun2 = sfun2,.fun3 = sfun3,
};

4.完整的代码

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>typedef int STRU_FU;STRU_FU sfun1(int a, const char *b){printf("fun1  a = %d , b = %s \n",a,b);return a;
}STRU_FU sfun2(int a, void *b,float c){printf("fun2  a = %d , b = %f \n",a,c);return a;
}STRU_FU sfun3(int a, char b,long c){printf("fun3  a = %d , *b = %ld \n",a,c);return a;
}struct fun_ops{ //定义回调函数structSTRU_FU (*fun1)(int a, char *b); //注册参数STRU_FU (*fun2)(int a, void *b,float c);STRU_FU (*fun3)(int a, char b,long c);
};struct fun_ops fuops = {//初始化函数指针的函数.fun1 = sfun1,.fun2 = sfun2,.fun3 = sfun3,
};int main(int argc,  char* argv[])
{int g;struct fun_ops *ops = NULL;if(argc < 2){printf("please input 1 or 2 or 3 for test fun \n");return -1;}if(strcmp(argv[1], "1") == 0){ops = &fuops;g =1;printf("fun1 \n");ops->fun1(111,"fun1");//调用回调}else if( !strcmp(argv[1], "2")){ops = &fuops;g= 2;printf("fun2 \n");ops->fun2(2222,"fun2",3333);}else{ops = &fuops;g = 3;printf("fun3 \n");ops->fun3(1212,'y',9999999);}
}

简单理解回调函数

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。

在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发回调事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件

通过上面的例子我们有了以下几点概念

  • 主函数:相当于整个程序的引擎,调度各个函数按序执行

  • 回调函数:一个独立的功能函数

  • 中间函数(通用):一个介于主函数和回调函数之间的函数,登记回调函数,通知主函数,起到一个桥梁的作用

在中间函数调用回调函数的时候,我们需要把回调函数当作参数来传递,那么就需要用到函数指针,下面以一个例子来详细了解。

Demo

#include <stdio.h>//回调函数1  不同的调用者提供 类似多态
int callBack1(int x)
{return x*2;
}
//回调函数2  不同的调用者提供 类似多态
int callBack2(int x)
{return x/2;
}
//中间函数(通用)      //函数指针
int calc(int b,int (* func)(int))   //func把函数当作参数来进行传递
{return 100+func(b);
}int main()
{int a=10;int q=calc(2,callBack1);//注册:把函数赋值给函数指针的操作就是函数注册printf("%d\n",q);int p=calc(4,callBack2);//注册&调用回调函数printf("%d\n",p);return 0;
}

运行结果:

分析一下代码流程

  • 1、主函数需要调用回调函数

  • 2、中间函数登记回调函数

  • 3、触发回调函数事件

  • 4、调用回调函数

  • 5、响应回调事件

其他回调函数博文

c语言回调函数的使用及实际作用详解

C语言回调函数详解(全网最全)

回调函数是什么,如何使用以及函数的注册

C语言 | 嵌入式重点知识之回调函数

在函数中调用函数,有点象递归,递归调用的是自己。

回调函数 —— 借助中间通用函数(形参里有函数指针,实现函数注册)调用不同的回调函数 (多态/分层)相关推荐

  1. 在C++中调用DLL中的函数(2)

    本文转自:http://blog.sina.com.cn/s/blog_53004b4901009h3b.html 应用程序使用DLL可以采用两种方式: 一种是隐式链接,另一种是显式链接.在使用DLL ...

  2. c语言中结构体头文件是什么,函数形参里有结构体指针,为什么在头文件生

    满意答案 lam950 2017.04.08 采纳率:59%    等级:8 已帮助:913人 C语言用结构体指针作函数参数 这种方式比用结构体变量作函数参数效率高,因为无需传递各个成员的值,只需传递 ...

  3. 函数指针--Nginx和Redis中两种回调函数写法

    1.Nginx和Redis中两种回调函数写法 #include <stdio.h>//仿Nginx风格 //结构外声明函数指针类型 typedef void (*ngx_connectio ...

  4. 【C 语言】字符串模型 ( strstr-while 模型 | 抽象函数模型 | 业务子函数接口定义要点 | 形参指针间接赋值 | 返回值状态 | 形参指针处理 | 形参指针判空 | 形参返回值 )

    文章目录 前言 一.业务子函数接口定义要点 二.完整代码示例 前言 字符串开发模型 : strstr-while/do-while 模型 : 在 字符串 中 查找 子串特征 ; 两头堵模型 : 两个指 ...

  5. T-SQL里数据库工程师都不知道的秘密之SQL Server自定义函数UDF

    T-SQL SQL Server UDF自定义函数概念与案例实战 函数的定义 这里的函数指的是用户自定义函数(UDF)全名为(user-defined function),以下简称为函数. 它是数据库 ...

  6. python函数定义中参数列表里的参数是_python-函数(def)参数 及参数解构 变量 知识整理...

    函数 python 函数 由若干语句组成的语句块.函数名称.参数列表构成,他是组织代码的最小单元 完成一定的功能 函数的作用: 结构化编程对代码的最基本的封装,一般按照功能组织一段代码 封装的目的是为 ...

  7. 函数的定义和形参/实参

    1,函数:我们定义好一个事情,等想用的时候直接拿出来就行了,代码不用每次都写,节省无用功,(就好比把一次性做好的红烧肉放到冰箱里,什么时候想吃,就拿出来吃就好了,不用再费时费力去做了) 函数的官方定义 ...

  8. python函数定义中参数列表里的参数是_详解Python函数中参数带星号是什么意思

    函数的参数使用除了常规的位置参数和关键字参数外,还支持可变个数的函数参数,这种支持可变个数的参数方法称为参数收集,对应的参数称为收集参数. 一.参数收集的定义 Python的函数支持可变不定数量的参数 ...

  9. python函数调用时的实参和形参之间传递_python 函数(实参与形参、传递参数)...

    函数 什么是函数?函数是带名字的代码块,用于完成具体的工作.写出一个函数后,就可以一直调用. 定义函数,函数的基本组成: 1.1 向函数传递参数 向函数中传递任意参数,这样打印出的结果就可以根据自己的 ...

最新文章

  1. 当程序出Bug时,程序员最喜欢说的30句话
  2. java 覆盖和隐藏_Java覆盖和隐藏2
  3. 虚拟局域网vlan实验报告_自动化已非原来的自动化:看虚拟局域网技术应用到罗克韦尔的DCS...
  4. 没有终结点在侦听可以接受消息的_【大卫聊股】2019.05.05 周末重要消息分析及下周一走势预判...
  5. 如何将Pcm格式的音频文件转换成Wave格式的文件
  6. django20:BBS网页设计/注册功能/验证码代码
  7. node模块函数图解
  8. 编写批处理文件编译.Net工程
  9. dns 主从 windows
  10. shell逻辑判断和-a区别
  11. GC类型以及不同类型GC的搭配 1
  12. 能打开pdf格式的软件
  13. STM32+多片AD7705+双通道采集热电偶
  14. 竞赛|全球物联网数据创新大赛
  15. vue使用html2canvas jspdf实现pdf下载导出功能
  16. 福建师范大学2022年2月课程考试《计算机应用基础》作业考核试题
  17. Office在线预览及PDF在线预览的实现方式
  18. python的matplotlib画饼状图
  19. I2C总线3.3V与5V双向电平转换电路
  20. 10进制转37进制c语言程序,十进制数37转换成二进制数是( )。A.(100001)2B.(100101)2C.(101001)2D.(110001)2_考题宝...

热门文章

  1. 修正discuz发帖首次换行无效的问题
  2. Android 布局以及优化资料汇总
  3. maven打包指定main函数
  4. 编译Ruby2.0 问题解决
  5. TypeScript Generics(泛型)
  6. spring-在配置文件中配置DAO时直接引用DataSource
  7. 百度2011大会见闻:百度开始推出耀主页
  8. 数字阅读体验的平台距离我们还有多远?
  9. HALCON示例程序classify_image_class_mlp.hdev如何使用MLP分类器分割RGB图像
  10. 【数据结构】——冒泡排序、插入排序、选择排序