目录

背景和基本概念(含与C++回调对比)

函数指针最一般的用法

函数指针结合回调

源码打包


背景和基本概念(含与C++回调对比)

毕业也有10个月了,加上实习已经工作14个月了,感觉这一年多的板砖生涯学到了很多的东西。同样本人对函数指针又有了新的认识。原因是这个月在某平台上进行二次开发,发现这里面有很多的callback!这个callback并不是C++里的callback,而是C语言的Callback。

估计是开发这个平台的人喜欢C语言的Callback,而不喜欢C++的Callback。

这里我简单说明下我对这两种Callback体会:

在我这边的项目中,我接触过2种不同的回调!

一种是C语言的,他的回调方式是使用函数指针。通常会有一个注册函数,把要回调的函数注册进去,之后就通过函数指针进行调用,这种是我最近才接触到的。

还有一种回调是C++的回调。这个在项目里面接触得比较多,毕竟现在我就是C++开发工程师(虽然有时候也做Java和DBA的工作),这种回调感觉比C语言的回调更加的灵活。这种一般是类继承的概念,一般用纯虚类使用纯虚函数充当接口(也有用一般的类,用虚函数做接口的),用虚函数的特点使用父类指针调用子类对象。感觉C++的回调,还是比C语言灵活的。

下面将说明下C语言中函数指针结合回调函数的用法;

函数指针最一般的用法

下面给出函数指针最一般的用法,估计稍微学过C语言语法的学生都会使用:

#include <stdio.h>int Sum(int a, int b){return a + b;
}int main(int argc, int **argv){int (*pFun)(int a, int b);pFun = Sum;printf("Sum=%d\n", pFun(100, 200));getchar();return 0;
}

运行截图如下:

但这样的函数指针并不能提现他真正方便的地方!

下面说下他正在方便的地方!

函数指针结合回调

这里其实可以把函数指针理解为变量,如下代码:

int (*fun1)(char);
int *(*fun2)(char);
int (*fun3[])(char);
int *(*fun4[])(char);typedef int(*pProcFun)(char);
pProcFun pFun1;
pProcFun pFun3[];
pProcFun *pFun3ptr;
pProcFun pFun2;
pProcFun pFun4[];
pProcFun *pFun4ptr;

如下最基础的,模块注册,模块管理,根据函数指针回调的例子!

运行截图如下:

程序结构如下:

源码如下:

FirstModule.h

#pragma once
#include "stdef.h"
#include "moduleAdmin.h"int InitFirstModule();

moduleAdmin.h

#pragma once#include "stdef.h"typedef enum tagMODULE_SETS  //SETS表示这是枚举集合
{MY_ALL_MODULE = 0,MY_READ_MODULE = 1,MY_WRITE_MODULE = 2,MY_INVALID_MODULE = 0xffff}MODULE_SETS_E; //E表示enumtypedef int(*pProcFun)();typedef struct tagMoudleData  //一般带有管理的结构体在C语言中都是tagXXXX
{int iModule;       //每个模块唯一IDpProcFun pFun;
}MOUDLE_DATA_S;     //一般在结构体结尾都加S,代表struct;int RegisterProc(int iModule, pProcFun pFun);
int ExcuteAllModule();

SecondMoudle.h

#pragma once#include "stdef.h"
#include "moduleAdmin.h"int InitSecondModule();

stdef.h

#pragma once#include <stdio.h>
#include <Windows.h>#define OK 0
#define ERR -1

FirstModule.cpp

#include "FirstModule.h"int FirstModuleProc(){printf("Hello I am First Module\n");return OK;
}int InitFirstModule(){RegisterProc(MY_WRITE_MODULE, FirstModuleProc);return OK;
}

main.cpp

#include "stdef.h"
#include "FirstModule.h"
#include "SecondModule.h"DWORD WINAPI MyThread(){while(1){ExcuteAllModule();Sleep(1000);}
}int TestFunPtr(){InitFirstModule();HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThread, NULL, 0, NULL);Sleep(3000);InitSecondModule();Sleep(3000);TerminateThread(hThread, 0);CloseHandle(hThread);return OK;
}int main(int argc, int *argv[]){TestFunPtr();getchar();return 0;
}

moduleAdmin.cpp

#include "moduleAdmin.h"#define MAX_PROC 100int g_iProCnt = 0;    //全局的前面加一个g
MOUDLE_DATA_S FunList[MAX_PROC] = {0};int RegisterProc(int iModule, pProcFun pFun){if(g_iProCnt == MAX_PROC){return ERR;}FunList[g_iProCnt].iModule = iModule;FunList[g_iProCnt].pFun = pFun;g_iProCnt++;return OK;
}//调用注册的函数
int ExcuteAllModule(){for(int i = 0; i < g_iProCnt; i++){FunList[i].pFun();}return OK;
}

SecondModule.cpp

#include "SecondModule.h"int SecondModuleProc(){printf("Hello I am Second Module\n");return OK;
}int InitSecondModule(){RegisterProc(MY_READ_MODULE, SecondModuleProc);return OK;
}

源码打包

下载地址:

https://github.com/fengfanchen/CAndCPP/tree/master/CfunctionPtrAndCallBack

C语言工作笔记-对函数指针的进一步认识(与回调函数结合使用,并且对比C++的回调)相关推荐

  1. C++工作笔记-对二级指针的进一步理解(函数的参数使用二级指针,从而操作原数据)

    二级指针不仅仅可以表示一个二维表(在邻接表里面用得比较多)! 当参数是一级指针的时候得到了是指向了同一个地址! 但参数是二级指针却有不同的效果! 如下代码: main.cpp #include< ...

  2. C++工作笔记-对二级指针的进一步理解(获取调用者的地址)

    一般的项目中,如果要获取调用者参数的地址可以考虑使用二级指针. 程序运行截图如下: 源码如下: #include <iostream> #include <conio.h> u ...

  3. c++ 函数指针_进化论——从函数指针到被结构封装的函数指针及参数的应用举例...

    ↑↑↑ 点击上方公众号名称关注,不放过任何转变的机会. ✎ 编 者 悟 语 借口再小也会瓦解人的意志. 文 章 导 读 今天带大家用下函数指针,然后将函数指针和函数参数封装到结构体中,接着将数据用动态 ...

  4. 使用 typedef 定义函数指针,更优雅的使用函数指针

    简介 关于函数指针的介绍,这里就不做过多说明了,不了解的同学可以看看这篇博客: https://blog.csdn.net/afei__/article/details/80549202 使用 typ ...

  5. 【C语言学习笔记】26. 指针(3)指向指针的指针、传递指针给函数

    前言 指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链.通常,一个指针包含一个变量的地址.当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置. ...

  6. C++工作笔记-简单工厂模式基础(用静态类传入函数指针,再进行调用)(仿大佬代码)

    代码如下: #include <iostream> using namespace std;typedef void(*LPFUNCTION)(int data); void regist ...

  7. C++_类和对象_对象特性_空指针访问成员函数_用法和问题解决---C++语言工作笔记050

    然后我们再来看空指针访问成员函数,实际上在c++中null指针也是可以访问成员函数的, 有些人可能会觉得奇怪,不用奇怪. 去看看代码,去写个person类 写个showClassName()方法,打印 ...

  8. C++提高部分_C++函数模板_基本用法---C++语言工作笔记081

    在c++中用到的主要技术,一个是面向对象,一个是 就是泛型编程,而泛型编程的主要实现技术就是利用模板技术实现的.可以看到c++提供了两种模板机制,一种是函数模板,一种是类模板, 我们这里先说,函数模板 ...

  9. C语言学习笔记----4(指针)

    文章目录 指针深入介绍 指针类型 二级指针 字符指针 指针数组 数组指针 函数指针 函数指针数组 函数指针数组指针 回调函数 总结 指针深入介绍 众所周知,亚里士多德1撑起了古希腊科学.哲学的半壁江山 ...

最新文章

  1. 开发自己的山寨Android注解框架
  2. SQL Server不能启动
  3. 《UNIX环境高级编程(第3版)》——1.7 出错处理
  4. redis6.0中的多线程
  5. AC日记——斗地主(dfs)
  6. easy mysql_GitHub - aleafs/easymysql: mysql client in cluster, based on node-mysql
  7. Linux集群服务知识点总结及通过案例介绍如何实现高性能web服务(三)
  8. 【PKUWC2018】Minimax【线段树合并】
  9. 美团点评DBProxy读写分离使用说明
  10. Ubuntu 在终端下使用命令行打开pdf文件
  11. 区块链技术的发展现状_区块链的现状及其发展趋势
  12. SolarWinds 供应链攻击中的第四款恶意软件及其它动态
  13. python app逆向_python之app逆向破解data参数中的PassWord DES加密无填充
  14. sql server book
  15. Windows10安装ubuntu18.04双系统教程(双硬盘)
  16. 阿里一位 70 后程序员、架构师的 26 个职场感悟
  17. Android 版本4.12 微信,安卓4.12微信下载
  18. 【建站教程】网站引用三方图片遇到简单防盗链referer的处理办法
  19. 减法公式运算法则_数学加减法运算和运算法则
  20. CSGO地图制作常见问题

热门文章

  1. ASP.Net防止页面刷新重复提交
  2. 程序猿,该在一个公司呆多久?
  3. 内向的人怎样改善人际关系
  4. 拜年+红包,都有份儿!
  5. CSS裸奔节,一个被遗忘的前端节日!
  6. 作为一名程序员,我站在人生的十字路口
  7. 位置问题_改变铸件浇注入水位置,能解决哪些问题?
  8. ffmpeg 转换flv压缩大小_使用ffmpeg进行视频文件转换成FLV整理
  9. 机器学习 | 距离计算
  10. 摸鱼也要讲究方法:工作学习中玩手机并不能缓解无聊和疲劳