如何理解c语言中的回调函数

(24) 2023-10-11 09:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说如何理解c语言中的回调函数,希望能够帮助你!!!。

在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。

这段话不是那么好理解,不同语言实现回调的方式有些许不同。其实可以这样理解,回调就是在一个函数中调用另外一个函数

如何理解c语言中的回调函数_https://bianchenghao6.com/blog__第1张

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

下面是两个函数指针的声明

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

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

如何理解c语言中的回调函数_https://bianchenghao6.com/blog__第2张

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

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

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

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

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

如何理解c语言中的回调函数_https://bianchenghao6.com/blog__第3张

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

可以看到,它的第三个参数是一个函数指针,传入两个没有定义指针指向的类型的参数ab,返回一个整型值。实际上这里使用了回调函数。通过回调函数,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;
}

如何理解c语言中的回调函数_https://bianchenghao6.com/blog__第4张

// 定义回调函数
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语言中的回调函数_https://bianchenghao6.com/blog__第5张

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

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复