当前位置: 首页 > news >正文

C 回调函数的两种使用方法

        对回调(callback)函数的一点粗陋理解,在我小时候,隔壁村有家月饼小作坊(只在中秋那段时间手工制作一些月饼出售,后来好像不做了),做出的月饼是那种很传统很经典的款式,里面有红绿丝、冰糖以及芝麻(好像也只做这一种),曾经跟着大人进去过一次,里面有张木头制作的月饼模子,原来花瓣状的月饼是用它压出来的啊,我们的回调函数(指针)就是这张月饼模子。功能是制作月饼(函数返回值),配料(参数)是面粉和油以及馅料。假如这个作坊一共有3个工人,每个工人负责一种馅料(五仁、豆沙、蛋黄)月饼,他们都需要这张月饼模子来制作自己的月饼,换句话说,他们都要提供同样类型的参数(配料)并得到同样类型的结果(月饼),至于具体的里子和做法(函数实现)必须得他们个人定,在实际生产(程序流程)中,这仨工人按各自节奏准备好自己的物料(函数实现),当在需要制作月饼时(调用回调函数),将配料往模子里这么一压,哟嘿,糯和和的月饼制作出来了。

        这一天当中,不同的师傅拿这个模子(回调函数指针)按自己的方法(函数具体实现)塞入配料(参数)压出了不同口味的月饼,不知道有没有越描越糊涂的嫌疑。

        下面再简单说说两个比较常见的用法。

例子一

一般使用(理解概念)
#include<stdio.h>int Callback_1(char *m) // Callback Function 1
{printf("Hello, this is Callback_1 %s\n", m);return 0;
}int Callback_2(char *n) // Callback Function 2
{printf("Hello, this is Callback_2 %s\n", n);return 0;
}int Callback_3(char *t) // Callback Function 3
{printf("Hello, this is Callback_3 %s\n", t);return 0;
}int Handle(int (*Callback)(char *), char *val)
{printf("Entering Handle Function. \n");Callback(val);printf("Leaving Handle Function. \n");
}int main()
{printf("Entering Main Function. \n");Handle(Callback_1, "wuren");Handle(Callback_2, "dousha");Handle(Callback_3, "danhuang");printf("Leaving Main Function. \n");return 0;
}

        上面的代码中,月饼模子就是int (*Callback)(char *),返回值是int(月饼),参数是char *(配料),三个师傅各自的秘密配方及手法分别是int Callback_1(char *m)、int Callback_2(char *n)、int Callback_3(char *t),这个int Handle(int (*Callback)(char *), char *)函数就是标准的工艺流程。在制作时(主函数内部调用),我们让师傅们轮流来操作,一号师傅拿起"wuren"配料制作出了五仁月饼,二号师傅拿起“dousha”配料制作出了豆沙月饼,三号师傅拿起"danhuang"配料制作出了蛋黄月饼。返回情况如下。

例子二

结构体使用(使用拓展)
#include <stdio.h>typedef struct
{int w;int h;int (*callback)(void*, void*);    
}St_Rect;int area(int w, int h)
{if(w && h){return w*h;}else{printf("area:invalid para!\n");return -1;}}int perimeter(int w, int h)
{if(w && h){return 2*(w + h);}else{printf("perimeter:invalid para!\n");return -1;}
}int empty(int w, int h)
{printf("w=%d,h=%d\n", w, h);return 0;
}void main(void)
{St_Rect rect;int choose = -1;printf("please input w\n");scanf("%d", &rect.w);printf("please input h\n");scanf("%d", &rect.h);printf("please input choose result\n");scanf("%d", &choose);switch(choose){case 0:rect.callback = area;break;case 1:rect.callback = perimeter;break;default:rect.callback = empty;break;}int result = rect.callback((int *)rect.w, (int *)rect.h);printf("the result is %d\n", result);
}

        这段代码则是回调函数的另外一种用法,很多实际项目上应该都比较常见。比如一家研发金融产品的公司,他们的客户有人行、建行、农行等等国内外银行以及其他机构,其中这家公司的一款清分机市场销量挺nice,吸引了更多的客户来购买,但是不同的客户有不同的需求(清分数据的处理逻辑),之前只有几家客户的情况下还可以通过类似if else、switch case这样的方法来实现不同客户的需求,随着客户数量的增加,再这么干不是不可以,但你能忍受代码里有这么多的条件语句吗,而且代码整体看起来码商也不高。此时我们就可以考虑用回调(第一种使用方法的升级用法),共用同一套架构,初始化时给予不同的函数实现。上面的代码例子也是基于此种场景,我们来看看。

        我们定义了一个矩形结构体,成员变量有宽度w、高h以及一个我们的回调函数指针int (*callback)(void*, void*),这个函数指针等同于保存一个(函数)地址的变量,而且这个回调函数有两个无类型的参数void*,无类型方便我们后面拓展使用。主函数内,我们让使用者分别输入宽度和高度值,并在最后让使用者选择是生成矩形面积结果呢还是矩形周长结果。其中的switch语句相当于初始化过程,确定最终的客户方案,最后开始了我们的回调过程,并返回我们选择的方案结果。

        大家在日常工作学习中如有类似需求可以参考一二,如果还有其他用法,欢迎告知讨论!

相关文章:

C 回调函数的两种使用方法

对回调&#xff08;callback&#xff09;函数的一点粗陋理解&#xff0c;在我小时候&#xff0c;隔壁村有家月饼小作坊&#xff08;只在中秋那段时间手工制作一些月饼出售&#xff0c;后来好像不做了&#xff09;&#xff0c;做出的月饼是那种很传统很经典的款式&#xff0c;里…...

医院云HIS系统源码,二级医院、专科医院his系统源码,经扩展后能够应用于医联体/医共体

基于云计算技术的B/S架构的HIS系统&#xff0c;为医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。 系统利用云计算平台的技术优势&#xff0c;建立统一的云HIS、云病历、云LIS&#xff0…...

NineData云原生智能数据管理平台新功能发布|2024年3月版

数据库 DevOps - 大功能升级 SQL 开发早期主要提供 SQL 窗口&#xff08;IDE&#xff09;功能&#xff0c;在产品经过将近两年时间的打磨&#xff0c;新增了大量的企业级功能&#xff0c;已经服务了上万开发者&#xff0c;覆盖了数据库设计、开发、测试、变更等生命周期的功能…...

java Web 疫苗预约管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 疫苗预约管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使…...

Qt5.14.2 揭秘Qt日志神器高效诊断程序潜在隐疾

对程序员而言&#xff0c;代码中的bug往往如同无影无踪的隐疾&#xff0c;影响着程序的健康运行。而及时有效的诊断手段则是治疗这些隐疾的良药。今天&#xff0c;我们将一窥Qt日志框架QLoggingCategory的神奇功效&#xff0c;探究它如何为你的Qt应用程序构筑坚实的诊断防火墙。…...

Mac上设置环境变量PATH

一、配置文件有哪些 在Mac系统中&#xff0c;环境变量的配置文件主要包括以下几个&#xff1a; 文件名称描述/etc/paths系统级别的配置文件&#xff0c;系统启动时会加载它。/etc/profile系统级别的配置文件&#xff0c;所有用户登录时都会读取该文件。~/.bash_profile用户级别…...

Redis 全景图(1)--- 关于 Redis 的6大模块

这是我第一次尝试以长文的形式写一篇 Redis 的总结文章。这篇文章我想写很久了&#xff0c;只是一直碍于我对 Redis 的掌握没有那么的好&#xff0c;因此迟迟未动笔。这几天&#xff0c;我一直在看各种不同类型的 Redis 文章&#xff0c;通过阅读这些文章&#xff0c;引发了我对…...

Lambda表达式,Stream流

文章目录 Lambda表达式作用前提函数式接口特点 语法省略模式和匿名对象类的区别 Stream流思想作用三类方法获取方法单列集合(Collection[List,Set双列集合Map(不能直接获取)数组同一类型元素(Stream中的静态方法) 常见的中间方法终结方法收集方法 Optional类 Lambda表达式 作用…...

Apache Hive的基本使用语法(一)

一、数据库操作 创建数据库 create database if not exists myhive;查看数据库 use myhive; desc database myhive;创建数据库并指定hdfs存储 create database myhive2 location /myhive2;删除空数据库&#xff08;如果有表会报错&#xff09; drop database myhive;…...

Python爬虫详解:原理、常用库与实战案例

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言引言&#xff1a;一、爬虫原理1. HTTP请求与响应过程2. 常用爬虫技术 二、P…...

搭建跨境电商电商独立站如何接入1688平台API接口|通过1688API接口采集商品通过链接搜索商品下单

接口设计|接口接入 对于mall项目中商品模块的接口设计&#xff0c;大家可以参考项目的Swagger接口文档&#xff0c;以Pms开头的接口就是商品模块对应的接口。 参数说明 通用参数说明 参数不要乱传&#xff0c;否则不管成功失败都会扣费url说明……d.cn/平台/API类型/ 平台&…...

【GlobalMapper精品教程】073:像素到点(Pixels-to-Points)从无人机图像轻松生成点云

文章目录 一、工具介绍二、生成点云三、生成正射四、生成3D模型五、注意事项一、工具介绍 Global Mapper v19引入的新的像素到点工具使用摄影测量原理,从重叠图像生成高密度点云、正射影像及三维模型。它使LiDAR模块成为已经功能很强大的的必备Global Mapper扩展功能。 打开…...

论文复现1:Mobilealoha

abstract:从人类演示中进行的模仿学习在机器人技术中表现出了令人印象深刻的表现。然而,大多数结果都集中在桌面操作上,缺乏一般有用任务所需的移动性和灵活性。在这项工作中,我们开发了一种用于模仿双手且需要全身控制的移动操纵任务的系统。我们首先推出 Mobile ALOHA,这…...

pycharm复习

目录 1.基础语法 2.判断语句 3.while循环 4.函数 5.数据容器 1.基础语法 1.字面量 2.注释&#xff1a; 单行注释# 多行注释" " " " " " 3.变量&#xff1a; 变量名 变量值 print&#xff1a;输出多个结果&#x…...

【SQLSERVER】批量导出所有作业或链接脚本

1.在Microsoft SQL Server Management Studio中选择–>视图(v)–>对象资源管理器详细信息(F7) 2.SSMS图形界面&#xff0c;左侧是“对象资源管理器”&#xff0c;右侧是“对象资源管理器详细信息”界面 3.左侧的“对象资源管理器”界面–>点击“SQLSserver代理”–…...

函数参数缺省和内联函数【C++】

文章目录 函数参数缺省函数参数缺省的条件和要求 内联函数内联函数的工作原理内联函数的定义方法内联函数的要求解决方法&#xff1a;直接在.h中定义内联函数的函数体 内联函数再Debug模式下默认是不展开的 函数参数缺省 顾名思义&#xff1a;可以少传一个/多个参数给函数&…...

javaWeb城市公交查询系统的设计与实现

一、选题背景 随着低碳生活的普及&#xff0c;人们更倾向于低碳环保的出行方式&#xff0c;完善公交系统无疑具有重要意义。公交是居民日常生活中最常使用的交通工具之一&#xff0c;伴随着我国经济繁荣和城市人口增长&#xff0c;出行工具的选择也变得越来越重要。政府在公共…...

企业案例:金蝶云星空对接旺店通·企业版

某知名化妆品企业&#xff0c;主要专注于化妆品&#xff0c;护肤品等研发&#xff0c;销售&#xff0c;生产于一体化的企业。企业的业务模式涉及比较广&#xff0c;有2B,2C和国内外电商领域。由于对内部业务流程的连贯性和数据的准确性比较关注。财务系统用的金蝶云星空&#x…...

wpsword求和操作教程

wpsword求和怎么操作&#xff1a; 1、首先&#xff0c;单纯的数据是无法求和的&#xff0c;所以我们必须要“插入”一个“表格” 2、接着将需要求和的数据填入到表格中。 3、填完后&#xff0c;进入“布局”选项卡。 4、然后打开其中的“公式” 5、在其中选择求和公式“SUM”并…...

Android 手机部署whisper 模型

Whisper 是什么? “Whisper” 是一个由OpenAI开发的开源深度学习模型,专门用于语音识别任务。这个模型能够将语音转换成文本,支持多种语言,并且在处理不同的口音、环境噪音以及跨语言的语音识别方面表现出色。Whisper模型的目标是提供一个高效、准确的工具,以支持自动字幕…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...

云原生安全实战:API网关Envoy的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口&#xff0c;负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...