什么是回调函数?回调函数是函数指针的一种用法

百科   2025-02-07 13:59   北京  

一、什么是回调函数?

什么是回调函数?先看官方解释:在计算机程序设计中,回调函数(或简称回调,Callback=call then back,被主函数调用运算后会返回主函数),是指通过参数将函数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。


这段解释太过于官方了,我们抓住几个关键点:1.它是个函数;2.它被当做参数传递到其他代码,并且会被调用。总结一下:回调函数就是我们以参数的形式传给某个参数,然后这个回调函数会在未来某个时机被调用。


举个例子:我给了你一个手机,并且跟你说,你明天早上10点拿这个手机给我打电话,那么在这个场景里面,这个手机的功能就类似于回调函数,使用(调用)它的时机就是明天早上10点。


在我们写程序的时候,回调函数都有哪些应用场景呢?最经典的就是我们做一些异步操作的时候,比如在JavaScript里面发送网络请求的时候,伪代码如下:

在上面这段代码里面,我们给ajax函数传递了两个回调函数,一个是负责请求成功的时候调用,一个是负责请求失败的时候调用,这个例子再加上我上面的解释,应该就可以理解什么是回调函数了。


二、回调函数是这样的

在说回调函数之前,很有必要先说明一下 “函数指针” 这个概念,它是回调函数能够实现的重要基础。


1、函数指针

C语言中的灵魂:指针。指针的使用和变幻方式,真正的使用起来能让你眼花缭乱。下面是常见的指针的定义:

int *ptr1;char *ptr2;struct std *ptr3; // 结构体指针

函数指针:函数指针是指向函数的指针变量。简单理解是指向函数名的指针变量。函数指针既然是指向函数的,那么它就可以像函数一样,用于调用函数、传递参数等操作。函数指针的定义方式如下:

函数返回值类型 (* 指针变量名) (函数参数列表);
“函数返回值类型”:表示该指针变量可以指向具有什么返回值类型的函数;“函数参数列表”:表示该指针变量可以指向具有什么参数列表的函数。
举例如下:int (*func1)(void)int (*func2)(int,char,...)char (*func3)(int,char,...)......

从上面的演示可以看到,函数指针的定义就是将一个函数中的 “函数名” 改成“(* 指针变量名)”的方式,从而实现了一个函数指针的定义。

但是这里需要注意的是:“(* 指针变量名)”两端的括号是必须要有的,如果缺少了这对括号,那么这个定义的方式就会变为指针函数。如下:

int *func1(void)int *func2(int,char,...)char *func3(int,char,...)......这种就不是函数指针了,而是指针函数。两者差别是很大的。

特别需要需要注意的一点是:指向函数的指针变量没有 ++ 和 -- 运算。

对于函数指针,一般为了方便使用,我们会选择另外的一种定义方式:

typedef 函数返回值类型 (* 指针变量名) (函数参数列表);

比如:

typedef int (*Fun1)(int,...); typedef int (*Fun2)(int, int,...); typedef void (*Fun3)(void); typedef void* (*Fun4)(void*); ......

2.函数指针的使用方式

函数指针要怎么使用呢?例子:

因为函数名 Func 代表函数的首地址,所以经过赋值以后,指针变量 p 保存的就是Func的函数入口地址,即 p 就指向函数 Func() 代码的首地址。


为了加深函数指针的使用方式,看下面的一段代码:

#include <stdio.h>
int Max(int, int); //函数声明
int main(void){int a, b, c;int(*p)(int, int); //定义一个函数指针
p = Max; //把函数Max赋给指针变量p, 使p指向Max函数
printf("please enter a and b:");scanf("%d %d", &a, &b); c = (*p)(a, b); //通过函数指针调用Max函数printf("a = %d\nb = %d\nmax = %d\n", a, b, c);return 0;}
int Max(int x, int y) //定义Max函数{int z;if (x > y) z = x;else z = y;
return z;}

特别注意的是,因为函数名本身就可以表示该函数地址(指针),因此在获取函数指针时,可以直接用函数名,也可以取函数的地址。

3. 函数指针可以作为函数的参数来使用

函数指针变量本身也是一个变量,也可以作为某个函数的参数进行使用的。如下:

4.回调函数

回调函数:如果一个函数的指针(函数名或地址)作为参数传递给另外一个函数,当这个指针被用来调用其所指向的函数时,就说这个指针所指向的函数是一个回调函数。简明点说:回调函数不是直接调用该函数进行使用的,而是要通过另外的特定事件或者其他函数进行调用的。定义一个函数然后直接调用,都不能称为回调函数。

例程1:

例程2:

可以看出,MyHandle() 函数的参数有一个指针,在 main() 函数里调用MyHandle() 函数的时候,给它传入了函数Callback_1()、Callback_2()、Callback_3() 的函数名,这时候的函数名就是对应函数的指针,也就是说,回调函数其实就是函数指针的一种用法。

雨飞工作室
本着“让人有所知,让人有所思”的理念,带你游走在无人机及机器人、物联网领域,领略人间芳华,感受百味人生。
 最新文章