下面是详细讲解“C 函数指针与回调函数”的完整使用攻略:
函数指针
C 语言中,函数可以视为程序的一个模块,可以通过函数名来调用。但实际上,在 C 语言中函数的本质是作为一种数据类型存在的,具体而言,它是一种指针类型。
函数指针的声明
函数指针的声明需要指定它所指向的函数的返回值类型和参数类型。示例代码如下:
int (*pfn)(int, char);
上面的代码声明了一个名为 pfn
的函数指针,它指向一个参数为 int
和 char
类型、返回值为 int
类型的函数。
函数指针的赋值
函数指针可以指向任一类型、参数列表和返回类型都相同的函数。示例代码如下:
int func(int a, char b)
{
return a + b;
}
int (*pfn)(int, char);
pfn = func;
int result = pfn(123, 'A');
上面的代码中,函数 func
定义了一个参数为 int
和 char
类型、返回值为 int
类型的函数。接下来,声明了一个名为 pfn
的函数指针,将其赋值为 func
,然后通过函数指针调用 func
函数并返回结果。
函数指针作为参数
函数指针也可以作为函数的参数传递。示例代码如下:
int add(int a, char b)
{
return a + b;
}
int sub(int a, char b)
{
return a - b;
}
int calc(int (*pfn)(int, char), int a, char b)
{
return pfn(a, b);
}
int result1 = calc(add, 123, 'A');
int result2 = calc(sub, 123, 'A');
上面的代码中,定义了函数 add
和 sub
分别用于求和和求差,然后定义了函数 calc
,它接受一个函数指针、一个 int
类型的参数和一个 char
类型的参数,用于调用函数指针所指向的函数并返回结果。接下来,分别通过 calc
函数调用了 add
和 sub
函数,从而分别求出了加法和减法的结果。注意,在调用 calc
函数时,可以直接将函数名作为参数传递。
回调函数
回调函数是指函数指针所指向的函数作为参数传递进另一个函数,这个被调用的函数会在适当的时候调用回调函数。
回调函数的定义
定义回调函数需要按照被调用的函数的要求进行,具体而言,需要指定它的返回值类型和参数类型。代码示例如下:
void callback(int result)
{
printf("result = %d\n", result);
}
上面的代码中,定义了一个名为 callback
的函数,它接受一个 int
类型的参数,打印出函数计算的结果。
回调函数的使用
使用回调函数可以通过函数指针的方式来实现。示例代码如下:
void calc(int (*pfn)(int, char), int a, char b, void (*cb)(int))
{
int result = pfn(a, b);
cb(result);
}
int add(int a, char b)
{
return a + b;
}
calc(add, 123, 'A', callback);
上面的代码中,定义了一个名为 calc
的函数,它接受一个函数指针、int
和 char
类型的参数以及一个指向回调函数的函数指针。在函数内部,它首先调用函数指针所指向的函数来计算结果,然后再将计算结果传递给回调函数进行处理。在主函数中,定义了一个名为 callback
的回调函数,并将其传递给了 calc
函数,这样在 calc
函数内部在计算出结果后,会通过回调函数来进行打印输出。
示例说明
下面是两个示例说明:
示例 1:冒泡排序
下面的代码演示如何使用回调函数实现冒泡排序,其中的回调函数用于比较两个元素的大小。
#include <stdio.h>
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void bubble_sort(int arr[], int n, int (*cmp)(int, int))
{
int i, j;
for (i = 0; i < n - 1; i++)
{
for (j = 0; j < n - i - 1; j++)
{
if (cmp(arr[j], arr[j+1]) > 0)
{
swap(&arr[j], &arr[j+1]);
}
}
}
}
int cmp(int a, int b)
{
return a - b;
}
void print(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {3, 1, 4, 2, 5};
int n = sizeof(arr) / sizeof(int);
bubble_sort(arr, n, cmp);
print(arr, n);
return 0;
}
示例 2:事件回调函数
下面的代码演示如何使用回调函数实现事件机制,其中的回调函数用于处理事件。
#include <stdio.h>
typedef void (*callback_t)(void);
void register_event(callback_t cb)
{
printf("register event\n");
cb();
}
void handle_event(void)
{
printf("handle event\n");
}
int main()
{
register_event(handle_event);
return 0;
}
上面的代码中,通过定义 callback_t
类型来声明回调函数的函数指针类型,然后定义函数 register_event
,它接受一个回调函数作为参数,在函数内部打印出注册事件的信息,然后调用回调函数。在主函数中,定义了一个名为 handle_event
的函数作为事件回调函数,然后将其传递给 register_event
函数注册事件,在 register_event
函数内部,将会打印出注册事件的信息,并调用事件回调函数 handle_event
进行事件处理。