1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【C语言进阶深度学习记录】三十二 函数指针与使用函数指针实现回调函数

【C语言进阶深度学习记录】三十二 函数指针与使用函数指针实现回调函数

时间:2019-01-21 01:09:04

相关推荐

【C语言进阶深度学习记录】三十二 函数指针与使用函数指针实现回调函数

回调函数是非常重要的概念

文章目录

1 函数的类型2 函数指针2.1 函数指针的使用2.2 使用函数指针实现回调函数3 总结

1 函数的类型

跟以前学数组的时候是一样的,C语言中的数组是有自己的类型的。函数也是有自己的类型的。

函数的类型由返回值、参数的类型、参数的个数共同决定

比如函数int add(int i, int j);的函数类型是int (int, int)

在C语言中可以使用typedef为函数重命名,如下

typedef int f(int, int); // 定义f为函数类型int(int, int)typedef void p(int); // 定义p为函数类型void(int)

上面定义函数类型一会再后面写具体的代码就会明白。

2 函数指针

与数组指针很相似

函数指针用于指向一个函数函数名执行函数体的入口地址(这里与数组指针一样,数组名代表数组的入口地址)可以通过函数的类型定义函数指针:FuncType* pointer(例如上面定义的f,那么f* p; p指向函数类型为f的函数。)也可以直接定义(这种我们见到的比较多):type (*pointer)(parameter list)

上面:

FuncType 是一种函数类型(例如int (int, int))type是函数的返回类型pointer是函数指针parameter list 是函数的参数列表

2.1 函数指针的使用

下面代码是演示定义函数类型与如何使用函数指针的代码:

36-1.c:

#include <stdio.h>typedef int FUNC(int); //定义函数类型int t(int i){return i*i;}void f(){printf("Call f()....\n");}int main(){FUNC* pt = t; //定义函数指针ptvoid(*pf)() = &f; //定义函数指针pfprintf("pf = %p\n", pf);printf("f = %p\n", f);printf("&f = %p\n", &f);pf(); //一般这么用(*pf)(); //一般不这么用f();int k = pt(3);printf("k = %d\n", k);return 0;}

运行结果为:

上面代码比较简单,我们注意两点:

typedef int FUNC(int); //定义函数类型FUNC* pt = t; //定义函数指针ptvoid(*pf)() = &f; //定义函数指针pf函数名f代表函数的入口地址,&f代表函数的整个地址(类似于数组),所以在数值上f与&f是相等的。但是意义不一样。函数指针的使用:pf(); 或者 (*pf)(); 一般像前者那么使用

2.2 使用函数指针实现回调函数

如何使用C语言直接跳转到某个固定的地址开始执行?(不是goto)

使用回调函数,回调函数是一种很重要的思想。那么什么是回调机制呢?

回调机制原理: 调用者不知道具体事件发生时需要调用哪一个具体的函数(是不是与C++中的多态很像,是的C++中的多态原理就是这样)当具体的事件发生的时候调用者通过函数指针,调用具体的函数。(是不是很像C++中的虚函数指针)

回调机制中的调用者和被调用者没有依赖关系

上面的理论,看起来并不是很容易让人理解,下面直接上手写代码就知道什么是回调函数了。

代码 36-2.c

#include <stdio.h>typedef int (Fruit)(int); //定义Fruit为int(int)类型的函数 参数:吃多少克,返回值:获得多少能量void Eat(Fruit* fruit, int n){//函数指针fruit:指向吃什么水果的函数 参数n:吃多少克int ret = 0;printf("Eat...\n");ret = fruit(n); //获得多少能量printf("Increase : %d\n", ret);}int Apple(int n){//吃n克苹果获得ret克能量int ret = 0;int i = 0;for(i=0; i<n; i++){printf("Eat apple get energy : %d\n", 1);ret++;}return ret;}int Banana(int n){//吃n克香蕉获得ret克能量int ret = 0;int i =0;for(i=0; i<n; i++){printf("Eat banana get energy : %d\n",3);ret+=3;}return ret;}int Pear(int n){//吃n克梨子获得ret克能量int ret = 0;int i = 0;for(i=0; i<n; i++){printf("Eat pear get energy : %d\n",5);ret+=5;}return ret;}int main(){Eat(Apple, 5); //get 5 printf("\n");Eat(Banana, 2); // get 6printf("\n");Eat(Pear, 3); //get 15printf("\n");return 0;}

上述代码的意思是:吃水果获得能量。但是吃什么水果,只有在程序运行起来之后才知道。所以吃这个动作Eat函数的参数无法指定吃哪种水果只能使用函数指针作为Eat函数的参数,当程序运行起来时根据传进来的参数确定吃什么水果,以及获得多少能量

上述程序编译运行结果为:

分析:

上面代码主要的核心就在于函数指针的使用。一定要学会函数指针的定义使用。学会使用函数指针来实现回调函数

3 总结

学会定义函数类型学会使用函数类型定义函数指针学会使用函数指针实现回调机制

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。