关于c语言中回调函数的理解

前言

在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。
这段话不是那么好理解,不同语言实现回调的方式有些许不同。其实可以这样理解,回调就是在一个函数中调用另外一个函数。

在c语言中,回调是使用函数指针来实现的。 函数指针——顾名思义,是指向一个函数的指针。通常函数指针有两个方面的用途,一个是转换表(jump table),另一个是作为参数传递给一个函数。
下面是两个函数指针的声明

int(*f)(int,float);int*(*g[])(int,float);

前者把f声明为一个函数指针,它所指的函数接受两个参数,分别是一个整型值和浮点型值,并返回一个整型值。
后者把g声明为一个数组,数组的元素类型是一个函数指针,它所指向的函数接受两个参数,分别是一个整型值和浮点型值,并返回一个整型指针。

需要注意的是,简单声明一个函数指针并不意味着它马上就可以使用。和其他指针一样,对函数指针执行间接访问之前必须把它初始化为指向某个函数。下面的代码段说明了一种初始化函数指针的方法。

intf(int);int(*pf)(int) = f;

第 2 个声明创建了函数指针pf,并把它初始化为指向函数f。函数指针的初始化也可以通过一条赋值语句来完成。在函数指针的初始化之前具有f的原型是很重要的,否则编译器就无法检查f的类型是否与pf所指向的类型一致。

通过一个例子简单介绍回调函数的使用

大家应该都对c语言的库函数qsort有所了解,qsort声明如下

void qsort(void*base,size_tnitems,size_tsize,int(*compar)(constvoid*,constvoid*))

可以看到,它的第三个参数是一个函数指针,传入两个没有定义指针指向的类型的参数a,b,返回一个整型值。实际上这里使用了回调函数。通过回调函数,qsort可以在运行时调用用户定义的函数(底层代码调用在高层定义的子程序)。
这里我们设计一个简单的sort函数,来理解回调过程

1、定义函数指针

typedefint(*compar)(constint*a,constint*b);

2、自定义sort函数,为了简单,这里使用冒泡排序

int*sort(int*nums,intn, compar cmp){int*target =malloc(n*sizeof(int));if(!target) perror("Memory error");memcpy(target, num, n *sizeof(int));for(inti =0; i < n; i++) {for(intj = i+1; j < n; j++) {if(cmp(target[i], target[j]) >0) {target[i] ^= target[j] ^= target[i] ^= target[j];}}}returntarget;}

3、实现函数回调

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<errno.h>typedefint(*compar)(constint*a,constint*b);// 定义实现回调函数的"调用函数"int*sort(int*nums,intn, compar cmp){int*target =malloc(n*sizeof(int));if(!target) perror("Memory error");memcpy(target, num, n *sizeof(int));for(inti =0; i < n; i++) {for(intj = i+1; j < n; j++) {if(cmp(target[i], target[j]) <=0) {target[i] ^= target[j] ^= target[i] ^= target[j];}}}returntarget;}
// 定义回调函数intcmp1(inta,intb){returna < b;}intmain(intargc,charconst*argv[]){inta[10] = {1,4,3,1,10,4,5};int*x = bubble_sort(a,7, cmp1);for(inti =0; i <7; i++)printf("%d ", x[i]);printf("\n");return0;}

运行结果:

1
1 1 3 4 4 5 10

调用函数向其函数中传递int (*compar)(const int *a, const int *b);这是int cmp1(int a, int b)函数的入口地址,即PC指针可以通过移动到该地址执行int cmp1(int a, int b)函数,可以通过类比数组来理解。

实现函数调用中,函数调用了“调用函数”,再在其中进一步调用被“调用函数”。相比于主函数直接调用“被调函数”,这种方法为使用者,而不是开发者提供了灵活的接口。另外,函数入口可以像变量一样设定同样为开发者提供了灵活性。

总结

到此这篇关于c语言中回调函数理解的文章就介绍到这了,更多相关c语言中回调函数理解内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言模块回调Lua函数的两种方法

    lua和C通过虚拟栈这种交互方式简单而又可靠,缺点就是C做栈平衡稍微会多写一点代码. 今天分享学到的C模块回调Lua函数的两种方法,都是炒冷饭,大侠勿喷. 1. C保存函数对象 C模块可以通过注册表保存Lua里面的对象,等适当时候取出再调用即可. 复制代码 代码如下: static int lua_callback = LUA_REFNIL; static int setnotify(lua_State *L) {   lua_callback = luaL_ref(L, LUA_REGISTR

  • 详解C语言编程中的函数指针以及函数回调

    函数指针: 就是存储函数地址的指针,就是指向函数的指针,就是指针存储的值是函数地址,我们可以通过指针可以调用函数. 我们先来定义一个简单的函数: //定义这样一个函数 void easyFunc() { printf("I'm a easy Function\n"); } //声明一个函数 void easyFunc(); //调用函数 easyFunc(); //定义这样一个函数 void easyFunc() { printf("I'm a easy Function\n

  • C语言中的回调函数实例

    在C语言中一般用typedef来为回调函数定义别名(参数名). 别名通过宏定义typedef来实现,不是简单的宏替换.可以用作同时声明指针型的多个对象. 比如: 复制代码 代码如下: char *pa,pb://pa是一个char型指针,但pb是一个char型字符.我们可以这样来实现typedef char* PCHAR:PCHAR pa,pb://pa和pb都是char型指针 先看一个回调函数的例子: 复制代码 代码如下: #include<stdio.h> //方法指针的格式为:int (

  • 关于c语言中回调函数的理解

    前言 在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用.这一设计允许了底层代码调用在高层定义的子程序. 这段话不是那么好理解,不同语言实现回调的方式有些许不同.其实可以这样理解,回调就是在一个函数中调用另外一个函数. 在c语言中,回调是使用函数指针来实现的. 函数指针--顾名思义,是指向一个函数的指针.通常函数指针有两个方面的用途,一个是转换表(jump table),另一个是作为参数传递给一个函数. 下面是两个函数指针的声明 int(*f)(i

  • c语言中回调函数的使用以及实际作用详析

    目录 前言 一.通过这节课程你能掌握以下知识: 二.程序架构的核心理念和需求 三.回调函数的作用 1.输出型 2.输入型 四.掌握回调函数的程序编写 总结 前言 今天给大家讲一下芯片/模块厂家写SDK必须会使用的一种技术:回调函数. 回调函数这个知识点其实并不是很难,难是难在网上很多讲解回调函数的都说的太学术化了化了,一点也不亲民. 很多人即使知道怎么写回调函数也根本就搞不懂它们在实际产品中也有什么用,什么时候用. 所以这节课呢我们会以程序架构的需求为出发点,讲解回调函数是怎么满足它这个需求的.

  • C语言中回调函数的使用详情

    目录 1.程序架构 2.回调函数的作用 3.掌握回调函数的程序编写 4.回调函数在产品中的应用 下文将学习到; 程序架构的核心理念和需求 掌握回调函数的作用 掌握回调函数的程序编写 掌握回调函数在产品中的应用 1.程序架构 一个好的程序架构至少要达到以下要求: 硬件层和应用层的程序代码分开,相互之间的控制和通讯使用接口,而且不会共享的全局变量或者数组. 用专业术语描述就是可移植性.可扩展性. 在51单片机写程序时,基本上一个.c文件解决,包括寄存器配置,产品功能.到了stm32时,我们会把不同的

  • C语言中回调函数的含义与使用场景详解(2)

    目录 详解C语言中回调函数的含义与使用场景(2) 使用场景一(重定义): 使用场景二(扩展函数功能): 使用场景三(分层): 总结 详解C语言中回调函数的含义与使用场景(2) 引言:在上一篇文章中介绍了回调函数的概念与使用方法,本节将深入地介绍回调函数典型的使用场景.通过使用回调函数可以实现驱动和应用程序的分离解耦,让程序更加地灵活.也可以借助回调函数实现插入自定义代码.分层设计程序的思想. 使用场景一(重定义): 在统一的接口中,动态地改变一个函数的功能.该函数的功能可以是加载参数.或者执行运

  • C语言中回调函数和qsort函数的用法详解

    目录 回调函数 指向函数指针数组的指针 qsort(qulick sort)-库函数 回调函数 通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数. 回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应. 举例: #include<stdio.h> void menu() { printf("*************************

  • C语言中回调函数的含义与使用场景详解

    目录 举例 动态改变回调函数的实现的方法: 1)编译时直接赋值 2)运行时实现动态注册 3)作为函数参数传递到指定的函数内 总结 举例 在下述程序中函数 test2_cal() 中调用 函数指针 s_cal 指定的函数执行数值的计算.则 s_cal 指定的那些函数就可以看作一个回调函数. typedef int (*my_calculate_t)(int a, int b); static int cal_sum(int a, int b) { printf("now is sum\r\n&qu

  • 对js中回调函数的一些看法

    最近在忙公司android的项目,所以也就很少抽时间来写些东西了.刚闲下来,我就翻了翻之前看的东西.做了android之后更加感觉到手机端开发的重要性,现在做native App  和Web App是主流,也就是说现在各种基于浏览器的web app框架也会越来越火爆了,做js的也越来越有前途.我也决定从后端开发渐渐向前端开发和手机端开发靠拢,废话不说了,我们来切入正题"js的回调函数"相关的东西. 说起回调函数,好多人虽然知道意思,但是还是一知半解.至于怎么用,还是有点糊涂.网上的一些

  • 详解C语言中的函数、数组与指针

    1.函数:当程序很小的时候,我们可以使用一个main函数就能搞定,但当程序变大的时候,就超出了人的大脑承受范围,逻辑不清了,这时候就需要把一个大程序分成许多小的模块来组织,于是就出现了函数概念:   函数是C语言代码的基本组成部分,它是一个小的模块,整个程序由很多个功能独立的模块(函数)组成.这就是程序设计的基本分化方法: (1) 写一个函数的关键: 函数定义:函数的定义是这个函数的实现,函数定义中包含了函数体,函数体中的代码段决定了这个函数的功能: 函数声明:函数声明也称函数原型声明,函数的原

  • C++中回调函数(CallBack)的用法分析

    本文实例分析了C++中回调函数(CallBack)的用法.分享给大家供大家参考.具体分析如下: 如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过. 其错误是普通的C++成员函数都隐含了一个传递函数作为参数,亦即"this"指针,C++通过传递this指针给其成员函数从而实现程序函数可以访问C++的数据成员.这也可以理解为什么C++类的多个实例可以共享成员函数却-有不同的数据成员.由于this指针的作用,使得将一个CALL-BACK型的成员函数作为回调函数安装时

  • 浅析JS中回调函数及用法

    回调函数,什么是回调函数呢?很多初学者都不是很明白,感觉懵懵的,不理解,更不会用! 其实简单理解的话就是在一个函数执行完毕后,得到想要的特定数据后在去执行的函数,并没有性药中的那么高深! function getdata(callback){ //这里我们假设是从后端获取数据 setTimeout(function(){ //假设我们获取到数据info var info = { "id":1, "name":'张三' } //得到数据以后执行函数方法 callbac

随机推荐