理解函数指针和回调函数

这篇具有很好参考价值的文章主要介绍了理解函数指针和回调函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

理解

函数指针

指向函数的指针。比如:

理解函数指针的伪代码
void (*p)(int type, char *data); // 定义一个函数指针p
void func(int type, char *data); // 声明一个函数func
p = func; // 将指针p指向函数func
p(1,"test"); // 调用方式1
(*p)(1,"test"); // 调用方式2

回调函数和回调

比如,B把自己函数cbkFunc()的地址告诉A,A在运行过程中执行cbkFunc()。则
回调函数:指B的函数cbkFunc();
注册回调函数:指B把函数cbkFunc()的地址告诉A;
回调:指A在运行过程中执行cbkFunc()。

code

  • 无头文件.h
  • 为了方便模块A和B写在了一个.c文件中
  • 打印log的函数见参考博客[3],可以直接替换为printf()
FunctionPointTest.c
/*
 * 理解函数指针和回调函数
 *
 * 假设需求:A要进行某项运动,有开始、正在做、结束3个状态,
 * B需要关注这3个状态
 *
 * 实现方案:A提供一个回调函数注册接口,在程序开始运行时,
 * B向A注册回调函数,A以回调函数的形式通知B
 *
 * 为了简便A和B写在一个文件里
 */

#include "D:\MyFiles\MyLog\WindowsC\mylog.h"
#include <stdio.h>
#include <windows.h>

// A和B的共同定义,一般是A的一个头文件,B会包含这个头文件:
typedef enum ENUM_EVENT {
	E_EVENT_START,
	E_EVENT_DOING,
	E_EVENT_FINISH,
} EnumEvent;
typedef void (*EVENT_CBK)(EnumEvent type, char *data);
int regEventCbk(EVENT_CBK cbk);

// A的实现
#define TAGA "[MODULE_A]"
static EVENT_CBK gSendEvent = NULL;
int regEventCbk(EVENT_CBK cbk) {
	if (cbk == NULL) {
		return -1;
	}
	gSendEvent = cbk;
	LOGI("%s{有人注册了回调函数:%X, 地址:%p}", TAGA, *gSendEvent, gSendEvent);
	return 0;
}
void doing() {
	gSendEvent(E_EVENT_DOING, "进行中..."); // 调用方式1
	Sleep(1000);
}
void runA() {
	LOGI("%s{我是A}", TAGA);
	if (gSendEvent == NULL) {
		LOGW("%s{B不关心我}", TAGA);
		return;
	}
	(*gSendEvent)(E_EVENT_START, "我开始了哟"); // 调用方式2
	doing();
	(*gSendEvent)(E_EVENT_FINISH, "我好了");
}

// B的实现
#define TAGB "[MODULE_B]"
long long int gAStart = 0;
long long int gAFinish = 0;
void eventStartHandler(char *data) {
	gAStart = GetTickCount();
	LOGI("%s{A:%s}{%lld}", TAGB, data, gAStart);
}
void eventDoingHandler(char *data) {
	LOGI("%s{A:%s}", TAGB, data);
}
void eventFinishHandler(char *data) {
	long long int aDurS = 0;
	gAFinish = GetTickCount();
	LOGI("%s{A:%s}{%lld}", TAGB, data, gAFinish);

	aDurS = (gAFinish - gAStart)/1000;
	LOGI("%s{A %llds}", TAGB, aDurS);
	if (aDurS < 10) {
		LOGI("%s{A 真快}", TAGB);
	}
}
void onEvent(EnumEvent type, char *data) {
	switch (type) {
		case E_EVENT_START:
			eventStartHandler(data);
		break;
		case E_EVENT_DOING:
			eventDoingHandler(data);
		break;
		case E_EVENT_FINISH:
			eventFinishHandler(data);
		break;
		default:
		break;
	}
}
void careA() {
	LOGI("%s{我的回调函数地址:%p}", TAGB, onEvent);
	regEventCbk(onEvent);
}
void runB() {
	LOGI("%s{我是B}", TAGB);
	careA();
}




int main() {
	LOGI("{start}");
	runB();
	runA();
	return 0;
}

运行结果

理解函数指针和回调函数

可优化点

.

参考博客

[1] https://zhuanlan.zhihu.com/p/162578969
[2] https://blog.csdn.net/zhou8201/article/details/100700479
[3] https://blog.csdn.net/qq_31300101/article/details/130190026?spm=1001.2014.3001.5502文章来源地址https://www.toymoban.com/news/detail-418831.html

到了这里,关于理解函数指针和回调函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c语言函数指针和指针函数的区别,以及回调函数的使用。

    函数指针 是什么,函数指针本质也是指针,不过是指向函数的指针,存储的是函数的地址。 指针函数 是什么,指针函数其实就是返回值是指针的函数,本质是函数。 函数指针是如何定义的呢,如下 这里 * pfun 需要 加括号 ,否则定义为了指针函数。 指针函数的定义如下: 下面

    2024年02月11日
    浏览(45)
  • C/C++面向对象(OOP)编程-回调函数详解(回调函数、C/C++异步回调、函数指针)

    本文主要介绍回调函数的使用,包括函数指针、异步回调编程、主要通过详细的例子来指导在异步编程和事件编程中如何使用回调函数来实现。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:C/C++精进之路 🎀CSDN主页 发狂的小花 🌄人生秘诀:学习的本质就是极致

    2024年02月03日
    浏览(39)
  • C生万物 | 剖析函数指针经典应用 —— 回调函数

    不懂函数指针的老铁可以先看看这篇文章【指针函数与函数指针】,上车,准备出发🚗 回调函数就是一个通过【函数指针】调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数

    2024年02月04日
    浏览(51)
  • 【再识C进阶2(中)】详细介绍指针的进阶——函数指针数组、回调函数、qsort函数

    💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖        在这一篇博客中,我们要认识并理解 函数指

    2024年02月09日
    浏览(45)
  • 【C语言】——指针五:转移表与回调函数

    1.1、转移表的定义      在之前的学习中,我们学习了 函数指针数组 (详情请看【C语言】——指针四:字符指针与函数指针变量),在最后。我曾问到:函数指针数组有什么用呢?别急,本文给大家细细道来。      函数指针数组常常被用在 转移表 中,那转移表是

    2024年03月26日
    浏览(41)
  • 【C进阶】回调函数(指针进阶2,详解,小白必看)

    目录 6. 函数指针数组 6.1简单计算器 6.2函数指针数组实现计算器 7. 指向函数指针数组的指针(仅作了解即可) 8.回调函数 8.1关于回调函数的理解​编辑 8.1.1用回调函数改良简单计算器 8.2qsort库函数的使用 8.2.1冒泡排序 8.2.2qsort的概念 8.3冒泡排序思想实现qsort          这篇文

    2024年02月14日
    浏览(38)
  • 【C++】多态 ⑧ ( 验证指向 虚函数表 的 vptr 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 )

    对比 定义了 虚函数 的类 与 没有定义虚函数的类 的大小 , 其它成员都相同 , 定义了虚函数的类多出了 4 字节 , 多出的 4 字节就是 vptr 指针占用的内存空间 ; \\\" 虚函数表 \\\" 由 C++ 编译器 负责 创建 与 维护 , 被 virtual 修饰的 虚函数 , 会自动 被 C++ 编译器 存储到 \\\" 虚函数

    2024年02月06日
    浏览(38)
  • C 语言高级3--函数指针回调函数,预处理,动态库的封装

    目录 1.函数指针和回调函数 1.1 函数指针 1.1.1 函数类型 1.1.2 函数指针(指向函数的指针) 1.1.3 函数指针数组        1.1.4 函数指针做函数参数(回调函数)  2.预处理 2.1 预处理的基本概念 2.2 文件包含指令(#include) 2.2.1 文件包含处理  2.2.2 #incude和#include\\\"\\\"区别 2.3 宏定义 2.3.1 无参

    2024年02月14日
    浏览(38)
  • 【C语言】指针的进阶(二)—— 回调函数的讲解以及qsort函数的使用方式

    目录 1、函数指针数组 1.1、函数指针数组是什么?  1.2、函数指针数组的用途:转移表 2、扩展:指向函数指针的数组的指针 3、回调函数 3.1、回调函数介绍  3.2、回调函数的案例:qsort函数 3.2.1、回顾冒泡排序  3.2.1、什么是qsort函数? 函数指针数组 是什么?首先主语是 数

    2024年02月07日
    浏览(43)
  • c语言中回调函数的理解和使用

    返回总目录 回调函数是通过函数指针实现的。可以将调用者和被调用者进行解耦,通过一个函数指针可以关联不同的函数实现,实现前提是函数指针和函数实现的参数类型一致,用户通过把需要调用函数的指针作为参数传递给一个函数进行实现,可以实现个功能模块之间的解

    2024年02月15日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包