回调函数(入门篇)

2023-11-06

首先,我们回忆一下,标准库函数printf是如何被我们调用的。

    1. 包含库函数所在的头文件   #include <stdio.h>
  	2. 调用printf,例如printf("Hello World");
  	3. 编译、运行,屏幕上输出了Hello World。搞定!

很好,我们就是这样调用标准库函数的。现在,假设有另外一个库函数myLib_ancient_times,它在被调用时,需要传入一个函数指针。

myLib_ancient_times(funPtr_modern_times);

奇妙的事情发生了,我们可以穿越了。

图解回调函数

提问:“传送门”是指什么?
答案:函数指针,指向函数funPtr_modern_times。

下面回归主题,什么是回调函数。答对了,就是“传送门”!
图解回调函数

输了这么多,是否感觉有那么一点点明白回调函数是什么了?接下来,我们通过实现一个计算器来更进一步理解回调函数。

目标:
实现一个计算器,可以实现正整数的加减乘除四则运算。
分析:
1. 输入的取值范围:0~9、+、-、*、/、=或回车
2. 输出:四则运算的计算结果,只显示整数部分

实现代码示例:

	#include <stdio.h>
	
	//calculator_lib.h
	typedef void (* calculator_callback_function)
	(
	    int    operator,
	    void * buf,
	    int    buf_len
	);
	
	calculator_callback_function cal_cb;
	
	typedef enum{
	    ADD,
	    SUB,
	    MUL,
	    DIV
	}cal_ind_e;
	
	typedef struct{
	    int res;
	}cal_ind_content_t;
	
	
	void cal_init(calculator_callback_function);
	
	//calculator_lib.c
	void cal_init(calculator_callback_function cb)
	{
	    cal_cb = cb;
	}
	
	void cal()
	{
	    int a,b;
	    char op;
	    cal_ind_content_t cal_ind;
	    
	    while(scanf("%d", &a)){
	        scanf(" %c", &op);
	        scanf("%d", &b);
	        
	        switch(op)
	        {
	            case '+':
	                cal_ind.res = a + b;
	                cal_cb(ADD, &cal_ind, sizeof(cal_ind));
	                break;
	            case '-':
	                cal_ind.res = a - b;
	                cal_cb(SUB, &cal_ind, sizeof(cal_ind));
	                break;
	            case '*':
	                cal_ind.res = a + b;
	                cal_cb(ADD, &cal_ind, sizeof(cal_ind));
	                break;
	            case '/':
	                cal_ind.res = a / b;
	                cal_cb(SUB, &cal_ind, sizeof(cal_ind));
	                break;
	            default:
	                printf("ERROR: Not supported operation.\n");
	                break;
	        }
	    }
	}
	
	//app.c
	void app_cal_cb(int op, void * buf, int buf_len)
	{
	    int res = *( (int*)buf );
	    printf("%d\n", res);
	}
	
	int main()
	{
	    int a,b;
	    char op;
	    
	    cal_init(app_cal_cb);
	    cal();
	
	    return 0;
	}

示例中,calaulator_lib模块通过回调函数将计算结果传递给了app模块。app模块通过回调函数实现了打印计算结果的功能。

在实际应用中,回调函数应用十分普遍,希望本文可以帮助你更好地理解回调函数。

练习:库函数qsort()是一个回调函数使用的例子。请使用qsort实现对一组数据的升序、降序排列。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

回调函数(入门篇) 的相关文章

  • Maven创建Web项目时如何设置JDK的版本

    使用命令 mvn Dwtpversion 1 0 eclipse eclipse 之后 导入的项目 Project Facet 的 java 还是 1 4 而当前使用的 Eclipse 上的设置是高于1 4版本 此时可以通过设置pom插件来
  • Java VisualVM 插件地址,安装Visual VM插件,修改下载插件地址使插件可以直接在JVisualVM中进行下载

    Java VisualVM 插件地址 打开Java VisualVM检查更新插件时 默认的连接连不上 通过浏览器访问之后发现默认的服务器已经404 新地址已经迁移到github 下面这个地址里面有不同版本jdk对应的插件中心地址 https
  • 2003-2019年上市公司治理水平(含原始数据和具体计算过程stata代码)

    2003 2019年上市公司治理水平 1 数据来源及数据说明在压缩包内 2 时间跨度 2003 2019年 3 区域范围 3669家上市公司 4 指标说明 该指标计算的方法的do文件以及参考文献都放在文件中 有需要的小伙伴可以自取 运用主成
  • __declspec(dllexport)与__declspec(dllimport)

    区别 他们都是DLL内的关键字 即导出与导入 他们是将DLL内部的类与函数以及数据导出与导入时使用的 dllexport是在这些类 函数以及数据的申明的时候使用 用他表明这些东西可以被外部函数使用 即 dllexport 是把 DLL中的相
  • Idea Git 已提交代码版本回滚

    本文主要记录在 Idea 中 如何通过 Git 回滚本地仓库和远程仓库代码版本 一 提交本地仓库代码回滚 1 模拟提交到本地仓库 模拟一次提交 提交到本地仓库 未提交到远程仓库 本地仓库 有 远程仓库 无 2 复制提交版本号 复制你想回到的
  • Unity 3D 碰撞体(Collider)

    在游戏制作过程中 游戏对象要根据游戏的需要进行物理属性的交互 因此 Unity 3D 的物理组件为游戏开发者提供了碰撞体组件 碰撞体是物理组件的一类 它与刚体一起促使碰撞发生 碰撞体是简单形状 如方块 球形或者胶囊形 在 Unity 3D
  • 面渣逆袭:分布式十二问,万字图文详解

    大家好 我是老三 不管今年金三银四如何 面渣逆袭系列继续 这期我们来看看分布式 分布式理论 1 说说CAP原则 CAP原则又称CAP定理 指的是在一个分布式系统中 Consistency 一致性 Availability 可用性 Parti
  • DS18B20测量温度

    文章目录 一 DS18B20读取温度步骤 二 初始化复位时序 2 发送一个字节 二 读取数据 1 读取一个Bit 2 读取一个字节 三 启动温度转换 四 判断转换完成 五 读取温度 程序地址 一 DS18B20读取温度步骤 一般在使用DS1
  • 【算法练习】最多等和不相交连续子序列

    200分 题目描述 给定一个数组 我们称其中连续的元素为连续子序列 称这些元素的和为连续子序列的和 数组中可能存在几组连续子序列 组内的连续子序列互不相交且有相同的和 求一组连续子序列 组内子序列的数目最多 输出这个数目 输入描述 第一行输
  • 计算机显卡设置方法,显卡在哪里设置 显卡设置方法【详细介绍】

    电脑中最重要的地方就是显示了 因为电脑cpu的高度运算和计算数据都是因为显卡在一直工作 所以很好的显卡设置能让我们的电脑使用和运行上更加完美 很多人会问那么显卡在哪里设置呢 怎么设置才好呢 想知道就和小编一起看下来吧 显卡在哪里设置 1 显
  • 怎么能跳过苹果服务器降级系统,苹果ios11手机怎样将系统降级?简单三步即可完成降级!...

    近日 苹果偷偷开启了降级通道 那些想降级回iOS 10的小伙伴现在有机会了 那么iPhone手机如何降级 下面为大家带来iOS 11降级教程 一起来看看 iOS 11降级教程 iPhone 5 5S 6 6S 7系列机型的老版本固件 苹果都
  • Android dp px ppi pt等概念的理解

    做Android开发过程中 总会用到px dp pt等概念 下面对它们代表的意义以及互相之间的关系做简单的介绍 目录 1 px 2 ppi 3 pt 4 dp 5 Android获取屏幕状态信息 1 px 像素 就是一个颜色点 一个像素点
  • 深度学习基础------前向传播与反向传播

    当前 深度学习已经应用到很多领域 无人驾驶汽车 黑科技以及图像分类等等 这些前沿的科技也面临许多挑战 如无人驾驶汽车需要进行物体的检测 行人的检测 标志的识别以及速度识别等等 图像分类已经成为一项重要技术 它是计算机视觉的核心任务 其困难之
  • 客户端启动耗时分析:基于Qt、C++的Windows应用程序

    客户端的启动作为所有交互的开端 经常被拿来进行分析 比较和优化 其中讨论比较多的就是启动耗时 本文整理了一些基于Qt C 的Windows客户端的启动耗时问题和分析经验 1 背景 客户端启动影响用户体验 启动耗时变久经常是由于工程师本身经验
  • Vue学习笔记总结

    目录 Vue的安装 1 官网下载 2 CDN 3 NPM Vue实例 1 创建实例 2 数据与方法 3 钩子函数 模板语法 1 插值 2 指令 计算属性 1 初识计算属性 2 计算属性缓存 vs 方法 3 计算属性 vs 侦听属性 4 计算
  • 解决CSGO出现加载某些地图时,进入载入界面闪退游戏的问题

    关于这个问题 我经过steam技术客服的回复后 关键问题在于 我的内存不够用 导致游戏在加载地图资源的时候 内存溢出 导致游戏崩溃 你可以用WIN X在事件查看器 windows日志 应用程序 中看到csgo崩溃的时候留下的错误信息 关于这
  • 原码、反码、补码、移码的作用

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 原码 反码 移码 补码的概念 二 深入理解原码和补码的转换 前言 因为一直不是很清楚原码反码的运算和符号位的关系 故想借此机会一举打好计算机数据表示与处理
  • 灰灰-1081-检查密码

    本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能 该网站要求用户设置的密码必须由不少于6个字符组成 并且只能有英文字母 数字和小数点 还必须既有字母也有数字 输入格式 输入第一行给出一个正整数 N 100 随后 N 行 每行给
  • 视频人脸识别和图片人脸识别的关系

    首先解释下视频人脸识别和图片人脸识别的区别 视频人脸识别是基于视频流进行人脸识别 用户的感觉就是直接在视频中就可以识别出人脸 而图片人脸识别 是用户直接上传图片 输出识别结果 图片人脸识别可以描述为 给定某一场景下的静态图象或者动态序列 根
  • ESP32 之 ESP-IDF 教学(十九)—— 在工程或组件中嵌入二进制数据

    本文章 来自原创专栏 ESP32教学专栏 基于ESP IDF 讲解如何使用 ESP IDF 构建 ESP32 程序 发布文章并会持续为已发布文章添加新内容 每篇文章都经过了精打细磨 通过下方对话框进入专栏目录页 CSDN 请求进入目录 O

随机推荐

  • 均值方差分析与风险资产组合

    文章目录 引言 对均值和方差的解释 资产组合的均值方差特性 小结 引言 在前面的文章中 初步介绍了债券和股票的价值评估方法 从中可以看见 用什么样的贴现率来估计未来现金流的现值 是资产定价的关键 在引入不确定性后 贴现率的确定变得更加困难
  • 三极管NPN和PNP的区别

    三极管NPN和PNP的区别 NPN和PNP三极管 其中n表示在高纯度硅中加入磷 指取代一些硅原子 并且在电压的刺激下所产生的自由电子进行导电 而p主要是加入硼取代硅 以此来产生大量的空穴利于导电 两者主要电源极性不同外 其他原理都是一样的
  • 打印出1-10000之间的所有对称数(如121,1331,2442)

    自己想的 for var i 0 i lt 10000 i fn i function fn num var n num toString if n length lt 2 return var prev n substring 0 Mat
  • cesium加载倾斜摄影模型全流程

    ContextCapture构建倾斜摄影模型 先打开ContextCapture Engine软件 这个是Master运行的必要软件 1 打开ContextCapture Master 新建工程 2 影像 添加影像 检查影像文件 3 导入位
  • 最小栈的实现

    实现一个栈 要求实现Push 出栈 Pop 入栈 Min 返回最小值 要求时间复杂度为O 1 可以借助两个栈来解决这个问题 一个栈用来存放栈的数据 其栈顶元素即为当前栈的 另外一个用来存放当前栈的最小元素 具体实现方法如下 首先定义该栈 t
  • 流体动力学控制方程(详细推导)

    CFD建立在流体力学基本控制方程 连续性方程 动量方程 能量方程的基础上 这些方程式任何流动都必须遵守的3个基本物理学原理 这三个方程是这些原理的数学描述 质量守恒定律 牛顿第二定律 能量守恒定律 全部CFD都是基于这些方程的 在开展研究之
  • 解决8080端口被占用导致报错的问题

    win R 输入cmd 回车 输入指令 netstat ano findstr 8080 找到端口对应 输入 taskkill pid 7244 f
  • Original error: gsmCall method is only available for emulators

    在夜神模拟器执行报错 self driver make gsm call 5551234567 GsmCallActions CALL 意思是gsmCall这个命令不支持 只支持下面这些命令 selenium common exceptio
  • Linux和Windows之间传输文件sftp命令

    将win10中的文件 上传到linux系统 Dos中的sftp命令 在dos窗口中输入 sftp cent 10 xx xx 43 根据提示输入用户的密码 在sftp中输入 put hadoop 2 8 5 tar gz home cent
  • Python+Vue计算机毕业设计银行助学贷款管理系统0o571(源码+程序+LW+部署)

    该项目含有源码 文档 程序 数据库 配套开发软件 软件安装教程 项目运行环境配置 Python3 7 7 Django Mysql5 7 pip list HBuilderX Vscode也行 Vue Pychram社区版 项目技术 Dja
  • Python Pandas 图形绘制(一):折线图,柱状图

    Pandas 图形绘制 一 折线图 柱状图 一 折线图 Line Chart 1 1 默认绘制折线图 df plot 1 2 绘制多条折线 二 柱状图 Bar Chart 2 1 垂直柱状图 df plot bar 2 2 叠加柱状图 st
  • 安全测试-优秀测试工程师必备的4项安全测试方法!

    用您5分钟时间阅读完 希望能对您有帮助 一 安全性测试 1 安全性测试方法 测试手段可以进行安全性测试 目前主要安全测试方法有 1 静态的代码安全测试 主要通过对源代码进行安全扫描 根据程序中数据流 控制流 语义等信息与其特有软件安全规则库
  • Couldn‘tparse bundle asset‘“D: \vue\cy_ gw2\dist\js \chunk- vendors.js1Analyzerwi 11usemodule

    报错信息 Couldn tparse bundle asset D vue cy gw2 dist js chunk vendors js1Analyzerwi 11usemodule 报错截图 报错原因 未安装less和less load
  • 从React源码来学hooks是不是更香呢

    本文将讲解 hooks 的执行过程以及常用的 hooks 的源码 hooks 相关数据结构 要理解 hooks 的执行过程 首先想要大家对 hooks 相关的数据结构有所了解 便于后面大家顺畅地阅读代码 Hook 每一个 hooks 方法都
  • 2D平面上的二连杆机器臂反向运动模拟(matlab代码示例)

    2D平面上的二连杆机器臂反向运动模拟 matlab上先下载 robotics system toolbox工具箱 robot rigidBodyTree DataFormat column MaxNumBodies 3 L1 1 the l
  • opencv+python物体检测【03-模仿学习】

    仿照练习 原文链接 步骤一 准备图片 正样本集 正样本集为包含 识别物体 的灰度图 一般大于等于2000张 尺寸不能太大 尺寸太大会导致训练时间过长 负样本集 负样本集为不含 识别物体 的任何图片 一般大于等于5000张 尺寸比正样本集稍大
  • Egg 使用 Sequelize

    npm install save egg sequelize mysql2 在 config plugin js 中引入 egg sequelize 插件 exports sequelize enable true package egg
  • 人工智能与教育融合的文献总结

    一般来说 人工智能与教育融合 首先要重塑教育理念 这是实现 教育 人工智能 的前提 格物斯坦提示 越是科技发达 越需要人性的支撑 教育的本质也是一种能力 生命和智能反映的是个体能力 这是亘古不变的科学原理 人工智能的观点来源于人们对于人工计
  • 数字型字符串千分位加逗号

    在数字型字符串千分位加逗号 param str return public static String addComma String str boolean neg false if str startsWith 处理负数 str str
  • 回调函数(入门篇)

    首先 我们回忆一下 标准库函数printf是如何被我们调用的 1 包含库函数所在的头文件 include