一、背景

首先看下如下代码,这个定义是放在头文件的,在程序中tCdrvCallbackFkt也定义了另一个变量,而且括号后面还跟定义了几个变量,不理解这个定义。

typedef void (PUBLIC *tCdrvCallbackFkt) (tCDrv_Handle CdrvHandle_p,
tCDrv_Event Event_p,
LPARAM pArg_p,
DWORD dwParam_p);

最近在跟别人的代码,要更改别人的代码,所以必须是理解每一行代码的意义和如何使用,遇到关于函数指针的使用,还有回调函数的使用。通过查资料来理解下定义的这个函数指针。

二、函数指针的使用

先不去看上面定义的这个函数指针,从最基本的模型理解起:

int (*p)();

上面定义p为一个指向函数的指针变量,函数返回值为整形。定义时要注意最后的空括号表示指针变量所指的是一个函数。

下面例子说明下,通过代码的注释进行理解。

#include"stdio.h"

typedef void(*p)(char* s);    //定义了一个函数指针类型

void str(char* s);

int main()
{
p test; //定义一个函数指针test
test=str; //将str函数的入口地址赋给test,即指针取地址
test("Hello World\n"); //函数指针test调用str函数,即函数指针取str函数里边的内容
return 0;
} void str(char* s)
{
printf("%s",s);
}

再来看typedef void (PUBLIC *tCdrvCallbackFkt) ()其实就是自命名定义了一个函数指针的类型,这样方便对其它函数指针的定义。

三、回调函数的使用

有了函数指针的基础后,看下如何使用回调函数,回调函数,就是使用者自己定义一个函数,使用者只管实现自己程序的内容而不用去管怎样被调用,然后把这个函数作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。函数是你实现的,但由别人(或系统)的函数在运行时通过参数传递的方式调用,这就是所谓的回调函数。简单来说,就是由别人的函数运行期间来回调你实现的函数。下面例子说明,看代码注释理解:

#include"stdio.h"

typedef void(*p)(char* s);       //定义了一个函数指针类型

void str(char* s);               //函数声明

void Mycallback(p test,char* s)  //实现回调函数调用的函数,对于p test也可以写成 void(*test)(),此函数只管去实现调用,程序里边具体怎样实现不用管
{
test(s);
} int main()
{ Mycallback(str,"Hello"); //回调函数在主程序中实现调用,对于调用回调函数人来说只需要去理解调用的函数传入那些参数就好,不管函数里边内容的具体实现
return 0;
} void str(char* s) //自己定义的回调函数,对于回调函数来说只管去实现程序内容
{
printf("%s",s);
}

四、参考文档

http://qiaopeng688.blog.51cto.com/3572484/1727246

http://www.cnblogs.com/ioleon13/archive/2010/03/02/1676621.html

http://blog.chinaunix.net/uid-8318378-id-2032233.html

by 羊羊得亿

2017-05-19 ShenZhen

C语言之函数指针、回调函数的使用的更多相关文章

  1. C语言笔记 08_函数指针&回调函数&字符串&结构体&位域

    函数指针 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调用函数.传递参数. 函数指针变量的声明: / ...

  2. typedef void(*Fun) (void)是什么意思 函数指针(回调函数) 和函数对象总结

    https://blog.csdn.net/FreeApe/article/details/49124043 bool (*pf)(const string &,const string &a ...

  3. delphi 中的函数指针 回调函数(传递函数指针,以及它需要的函数参数)

    以下代码仅仅是测试代码:delphi XE7 UP1 interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.V ...

  4. C#委托与C语言函数指针及函数指针数组

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  5. C/C++回调方式系列之一 函数指针和函数回调模式

    一.函数指针 1. 函数的定义 return_type function_name(parameter list) { function_body } return_type: 返回值,函数一定有返回 ...

  6. c语言的函数指针和函数指针数组的简单demo

    今天,简单记录一下,函数指针和函数指针数组的使用,废话不多说,直接贴上代码,里面有详细的注释,方便以后查阅. #include <cstdio> #include <Windows. ...

  7. Delphi 函数指针(函数可以当参数)

    首先学习: 指向非对象(一般的)函数/过程的函数指针 Pascal 中的过程类型与C语言中的函数指针相似,为了统一说法,以下称函数指针.函数指针的声明只需要参数列表:如果是函数,再加个返回值.例如声明 ...

  8. Day8 函数指针做函数参数

    课堂笔记 课程回顾         多态 virtual关键字 纯虚函数 virtual func() = 0;         提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...

  9. C++中类成员函数作为回调函数

    注:与tr1::function对象结合使用,能获得更好的效果,详情见http://blog.csdn.net/this_capslock/article/details/38564719 回调函数是 ...

  10. C++中 线程函数为静态函数 及 类成员函数作为回调函数

    线程函数为静态函数: 线程控制函数和是不是静态函数没关系,静态函数是在构造中分配的地址空间,只有在析构时才释放也就是全局的东西,不管线程是否运行,静态函数的地址是不变的,并不在线程堆栈中static只 ...

随机推荐

  1. vue28-2.0-过滤器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. caioj1443:第k小的数Ⅲ

    [传送门:caioj1443] 简要题意: 给出一颗n个点的树,给出每个点的权值,再给出n-1条边,有m个询问,每个询问输入x,y,k,输出第x节点到第y节点的路径上第k大的点 题解: 这是一道主席树 ...

  3. Xml、Json序列化

    Xml序列化: public class XmlHelper { private static string XmlPath = Path.Combine(AppDomain.CurrentDomai ...

  4. beego简单的验证码实现以及验证

    /** * 程序 */package controllers import (    "github.com/astaxie/beego"    "github.com/ ...

  5. HDU2665 kth number 线段树做法

    题意:求区间第k小 思路: 线段树 每个节点上保存 当前区间已经排序好的序列 (归并一下就好了嘛 复杂度 O(l)的) 这样建树的时空复杂度都是 O(nlogn)的 对于 每次询问 二分一个答案 在树 ...

  6. SQL 2008 还原 SQL2005 备份文件 不成功的解决方法

    解决方法1:不要在数据库名字上点右键选择还原,而要是在根目录“数据库”三个字上点右键选择还原,然后再选择数据库,问题便可以解决,如果不行参照方法2 解决方法2:写sql语句处理: RESTORE DA ...

  7. Coderfroces 864 D. Make a Permutation!

    D. Make a Permutation! Ivan has an array consisting of n elements. Each of the elements is an intege ...

  8. Centos/RHEL :How to add,delete and display LVM tags

    1. 什么是LVM标签? 在你想开机启动时让逻辑卷被激活可用时,添加lvm标签是一个不错的选择.lvm标签允许那些被预先标记的实现这样的效果. 2. 配置文件 配置文件/etc/lvm/lvm.con ...

  9. Mark Sweep GC

    目录 标记清除算法 标记阶段 深度优先于广度优先 清除阶段 分配 First-fit.Best-fit.Worst-fit三种分配策略 合并 优点 实现简单 与保守式GC算法兼容 缺点 碎片化 分配速 ...

  10. 阿里&163 yum源

    站点:https://opsx.alibaba.com/mirror #阿里云base cat /etc/yum.repos.d/alibase.repo [rhel7] name=ali-base ...