函数指针
来源:互联网 发布:港澳资讯点金手软件 编辑:程序博客网 时间:2024/06/06 05:00
回调函数
1、函数类型基础
函数三要素:名称、参数、返回值
C语言中的函数有自己特定的类型
C语言中通过typedef为函数类型重命名
typedef type name(parameter list)
typedef int f(int, int);
typedef void p(int);
函数指针
函数指针用于指向一个函数
函数名是执行函数体的入口地址
1)可通过函数类型定义函数指针:FuncType* pointer;
2)也可以直接定义:type(*pointer)(parameter list);
pointer为函数指针变量名
type为指向函数的返回值类型
parameterlist为指向函数的参数类型列表
#include <stdio.h>typedef int Func(int, int);typedef int (*PFunc)(int, int);int add(int a,int b){ return a + b;}int main(int argc, char* argv[]){ PFunc func = add; int res = func(1, 2); printf("res = %d\n",res); Func *f = add; res = (*f)(1, 2); printf("res = %d\n",res); return 0;}
2、函数指针做函数参数
指针做函数参数pk函数指针做函数参数
回忆指针做函数参数
一级指针做函数参数、二级、三级
函数指针做函数参数
当函数指针做为函数的参数,传递给一个被调用函数,
被调用函数就可以通过这个指针调用外部的函数,这就形成了回调
int add(int a, int b);void libfun(int (*pDis)(int a, int b));int main(void){ libfun(add); return 0;}int add(int a, int b){return a + b;}void libfun(int (*pDis)(int a, intb)){ int a, b; a = 1; b = 2; printf("%d", pDis(a, b));}
现在这几个函数是在同一个文件当中
假如
int libfun(int (*pDis)(int a, intb))
是一个库中的函数,就只有使用回调了,通过函数指针参数将外部函数地址传入
来实现调用
函数add的代码作了修改,也不必改动库的代码,就可以正常实现调用
便于程序的维护和升级
3、函数指针正向调用
函数指针做函数参数,调用方式
被调用函数和主调函数在同一文件中(用来教学,没有任何意义)
2、函数指针做函数参数
被调用函数和主调函数不在同一个文件中、模块中。
难点:理解被调用函数是什么机制被调用起来的。框架
框架提前设置了被调用函数的入口(框架提供了第三方模块入口地址的集成功能)
框架具备调用第三方模块入口函数
练习
typedef int (*EncDataFunc)(unsignedchar *inData,int inDataLen,unsigned char *outData,int*outDataLen,void *Ref, int RefLen);
int MyEncDataFunc(unsigned char*inData,int inDataLen,unsigned char *outData,int *outDataLen,void*Ref, int RefLen)
{
int rv = 0;
char *p = "222222222222";
strcpy(outData, p);
*outDataLen = strlen(p);
return rv;
}
int Send_Data(EncDataFuncencDataFunc, unsigned char *inData, int inDataLen, unsigned char*outData, int *outDatalen)
{
int rv = 0;
if (encDataFunc != NULL)
{
rv = encDataFunc(inData,inDataLen, outData, outDatalen, NULL, 0);
if (rv != 0)
{
printf("func encDataFunc()err.\n");
return rv;
}
}
return rv;
}
int main()
{
int rv = 0;
EncDataFunc encDataFunc = NULL;
encDataFunc = MyEncDataFunc;
// 第一个调用
{
unsigned char inData[2048];
int inDataLen;
unsigned char outData[2048];
int outDatalen;
strcpy(inData, "1111");
inDataLen = strlen(inData);
rv = encDataFunc(inData,inDataLen,outData, &outDatalen, NULL, 0);
if (rv != 0)
{
printf("edf err .....\n");
}
else
{
printf("edf ok \n");
printf("%s \n",outData);
}
}
{
unsigned char inData[2048];
int inDataLen;
unsigned char outData[2048];
int outDatalen;
strcpy(inData, "3333");
inDataLen = strlen(inData);
rv = Send_Data(MyEncDataFunc,inData, inDataLen, outData, &outDatalen);
if (rv != 0)
{
printf("func Send_Dataerr:%d", rv);
return rv;
}
printf("%s \n",outData);
}
getchar();
}
4、函数指针反向调用
回调函数
利用函数指针实现的一种调用机制
具体任务的实现者,可以不知道什么时候被调用
回调函数是利用函数指针实现的一种调用机制
回调机制原理
当具体事件发生时,调用者通过函数指针调用具体函数
回调机制的将调用者和被调函数分开,两者互不依赖
任务的实现和 任务的调用 可以耦合 (提前进行接口的封装和设计)
需要重新审视dll和其他第三方厂商接口之间的关系
动态库可以集成第三方厂商的业务功能
动态库(框架)不经常改动,能兼容后来的业务模型,2010年写的代码能调用2020写的代码,用到多态
动态库和第三方业务模型模块之间 松耦合
//动态库变成框架需要做的工作
//1 第三方业务入口传进来(回调函数的入口地址传进来)
//2 加密解密 业务模型抽象
//实现动态库 加密解密业务模型抽象
通过定义函数指针类型;函数指针做函数参数实现
- 指针函数 函数指针
- 函数指针/指针函数
- 指针函数&函数指针
- 函数指针 指针函数
- 函数指针 指针函数
- 指针函数,函数指针
- 函数指针,指针函数,
- 指针函数,函数指针
- 函数指针 指针函数
- 函数指针、指针函数
- 指针函数&函数指针
- 函数指针 指针函数
- 函数指针 指针函数
- 函数指针&指针函数
- 指针函数 函数指针
- 指针函数 &函数指针
- 函数指针&指针函数
- void指针 函数指针
- chrome浏览器默认浏览方式变成了“移动端”的浏览方式,怎么恢复pc端浏览?
- jetbrains 所有产品的历史版本下载
- asp.net web api http put delete , iis 返回400.0 找不到错误的解决办法.
- NDK和JNI的使用
- Qt中条件编译或者叫编译开关
- 函数指针
- C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)
- 3分独享阅信短信大礼包,申请即送500条
- Python编码错误
- Fuel部署OpenStack过程及原理介绍
- C++11 并发指南六( <atomic> 类型详解二 std::atomic )
- 从SVN上checkout下来的工程报linker错误
- linux常用快捷键大全
- 序列模式PrefixSpan算法介绍