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

 更新时间:2020年12月03日 12:00:15   作者:毛橘DD  
这篇文章主要给大家介绍了关于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语言中回调函数理解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++中的HTTP协议问题

    C++中的HTTP协议问题

    这篇文章主要介绍了C++中的HTTP协议问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • C++ std::any的模拟实现

    C++ std::any的模拟实现

    std::any是C++标准库中的一个类,std::any对象可以存储除单例等特殊情况外的任何类型的数据,本文主要介绍了C++ std::any的模拟实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • C语言中feof函数和ferror函数示例详解

    C语言中feof函数和ferror函数示例详解

    在C语言中feof函数用于检查文件流的结束标志,判断文件在读取时是否已经到达了文件的末尾,这篇文章主要给大家介绍了关于C语言中feof函数和ferror函数的相关资料,需要的朋友可以参考下
    2024-09-09
  • C++ opencv图像处理使用cvtColor实现颜色转换

    C++ opencv图像处理使用cvtColor实现颜色转换

    这篇文章主要为大家介绍了C++ opencv图像处理cvtColor实现颜色转换的实现示例代码,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • C语言实现冒泡排序算法的示例详解

    C语言实现冒泡排序算法的示例详解

    这篇文章主要介绍了C语言如何实现冒泡排序算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • C语言中字符的输入输出以及计算字符个数的方法详解

    C语言中字符的输入输出以及计算字符个数的方法详解

    这篇文章主要介绍了C语言中字符的输入输出以及计算字符个数的方法,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • C++九种排序具体实现代码

    C++九种排序具体实现代码

    这篇文章主要介绍了C++九种排序具体实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 解决scanf_s输入%d%c%d格式错误的问题

    解决scanf_s输入%d%c%d格式错误的问题

    这篇文章主要介绍了解决scanf_s输入%d%c%d格式错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • C++传值、传址、传引用的区别和选择小结

    C++传值、传址、传引用的区别和选择小结

    参数传递有传值、传址和传引用这三种,本文主要介绍了C++传值、传址、传引用的区别和选择小结,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • C语言实现翻译功能

    C语言实现翻译功能

    这篇文章主要为大家详细介绍了C语言实现简单的翻译功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01

最新评论