C 函数指针与回调函数

  • Post category:C

下面是详细讲解“C 函数指针与回调函数”的完整使用攻略:

函数指针

C 语言中,函数可以视为程序的一个模块,可以通过函数名来调用。但实际上,在 C 语言中函数的本质是作为一种数据类型存在的,具体而言,它是一种指针类型。

函数指针的声明

函数指针的声明需要指定它所指向的函数的返回值类型和参数类型。示例代码如下:

int (*pfn)(int, char);

上面的代码声明了一个名为 pfn 的函数指针,它指向一个参数为 intchar 类型、返回值为 int 类型的函数。

函数指针的赋值

函数指针可以指向任一类型、参数列表和返回类型都相同的函数。示例代码如下:

int func(int a, char b)
{
    return a + b;
}

int (*pfn)(int, char);
pfn = func;
int result = pfn(123, 'A');

上面的代码中,函数 func 定义了一个参数为 intchar 类型、返回值为 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');

上面的代码中,定义了函数 addsub 分别用于求和和求差,然后定义了函数 calc,它接受一个函数指针、一个 int 类型的参数和一个 char 类型的参数,用于调用函数指针所指向的函数并返回结果。接下来,分别通过 calc 函数调用了 addsub 函数,从而分别求出了加法和减法的结果。注意,在调用 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 的函数,它接受一个函数指针、intchar 类型的参数以及一个指向回调函数的函数指针。在函数内部,它首先调用函数指针所指向的函数来计算结果,然后再将计算结果传递给回调函数进行处理。在主函数中,定义了一个名为 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 进行事件处理。