C | 函数指针

280 阅读5分钟

函数指针是 C 语言中一种非常重要的概念,它允许程序员将函数作为参数传递给其他函数,或者将函数作为返回值返回给调用者。在本文中,我们将深入探讨 C 语言中的函数指针,包括其定义、用法和示例。

1 函数指针的定义

在 C 语言中,函数指针是指向函数的指针变量。它与指向其他数据类型的指针类似,但是它指向的是一个函数,而不是一个变量。函数指针的定义方式如下:

return_type (*function_name)(parameter_list);

其中

  • return_type 表示函数的返回值类型
  • function_name 是指针变量的名称
  • parameter_list 是函数参数列表。

例如,下面的代码定义了一个函数指针 pfunc,指向一个返回值为 int,参数为 intchar 的函数:

int (*pfunc)(int, char);

2 函数指针的用法

函数指针可以用来实现回调函数和动态函数调用等功能。下面是一些常见的用法:

2.1 回调函数

回调函数是一种常见的编程技巧,它允许将一个函数作为参数传递给另一个函数,在某个事件发生时调用该函数。例如,我们可以定义一个 qsort 函数来对数组进行排序,它接受一个函数指针作为参数,用于比较两个元素的大小。

void qsort(void *base,
           size_t nitems,
           size_t size,
           int (*compar)(const void *, const void *)
          );

其中,compar 参数就是一个函数指针,用于比较两个元素的大小。

2.2 动态函数调用

函数指针可以用于动态地调用函数,这在编写插件和动态库等程序中非常有用。例如,我们可以使用函数指针来实现一个简单的插件系统,允许在运行时加载并调用插件中的函数。

2.3 函数指针作为返回值

函数指针也可以作为函数的返回值,这在某些场合下非常有用。

例如,我们可以定义一个函数 get_operation,它接受一个操作符作为参数,返回一个函数指针,该函数指针可以执行相应的操作。

int (*get_operation(char op))(int, int) {
    if (op == '+') {
        return add;
    } else if (op == '-') {
        return sub;
    } else if (op == '*') {
        return mul;
    } else if (op == '/') {
        return div;
    } else {
        return NULL;
    }
}

看一个经典的 signal 函数原型:

void (*signal(int sig, void (*func)(int)))(int);

该函数接受两个参数:一个整数 sig 表示要处理的信号,以及一个指向函数的指针 func,该函数将处理信号 sig

函数的返回类型是一个指向函数的指针,指向的函数接受一个整数参数并返回 void 类型。

因此,该函数可以被解释为:

  • signal 是一个函数,它接受两个参数:

    • sig:整数类型,表示要处理的信号
    • func:指向函数的指针,该函数将处理信号 sig
  • signal 函数返回一个指向函数的指针,该函数接受一个整数参数并返回 void 类型,该函数将作为处理信号 sig 的处理程序。

3 函数指针的示例

3.1 示例 1

下面是一个使用函数指针的简单示例,它实现了一个求和函数 sum 和一个求积函数 ``prod`,并且允许用户选择要执行哪个函数:

#include <stdio.h>

int sum(int a, int b) {
    return a + b;
}

int prod(int a, int b) {
    return a * b;
}

int main() {
    int a = 10, b = 20;
    int choice;

    printf("Enter your choice:\n");
    printf("1. Sum\n");
    printf("2. Product\n");
    scanf("%d", &choice);

    int (*pfunc)(int, int);

    if (choice == 1) {
        pfunc = sum;
    } else if (choice == 2) {
        pfunc = prod;
    } else {
        printf("Invalid choice\n");
        return 1;
    }

    printf("Result: %d\n", pfunc(a, b));

    return 0;
}

在上面的示例中,我们首先定义了两个函数 sumprod,它们分别计算两个整数的和和积。然后,我们在 main 函数中提示用户选择要执行哪个函数,然后根据用户的选择将函数指针 pfunc 指向相应的函数。最后,我们调用 pfunc 执行所选的函数,并输出结果。

在运行程序时,输出如下:

Enter your choice:
1. Sum
2. Product
2
Result: 200

这表明我们成功地使用函数指针执行了求积函数,并得到了正确的结果。

3.2 示例 2

以下是一个示例,定义了一个名为 get_function 的函数,该函数根据传入的参数返回不同的函数指针:

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

int (*get_function(int choice))(int, int) {
    if (choice == 1) {
        return add;
    } else if (choice == 2) {
        return subtract;
    } else {
        return NULL;
    }
}

int main() {
    int a = 10, b = 20;
    int choice;

    printf("Enter your choice:\n");
    printf("1. Add\n");
    printf("2. Subtract\n");
    scanf("%d", &choice);

    int (*pfunc)(int, int);
    pfunc = get_function(choice);

    if (pfunc == NULL) {
        printf("Invalid choice\n");
        return 1;
    }

    printf("Result: %d\n", pfunc(a, b));

    return 0;
}

在上面的示例中,我们定义了两个函数 addsubtract,它们分别计算两个整数的和和差。然后,我们定义了一个名为 get_function 的函数,该函数根据传入的参数返回不同的函数指针。最后,在 main 函数中,我们使用用户的输入调用 get_function 函数,将返回的函数指针存储在 pfunc 变量中,并使用它来调用所选的函数,并输出结果。

在运行程序时,输出如下:

Enter your choice:
1. Add
2. Subtract
2
Result: -10

这表明我们成功地使用了返回函数指针的函数,并且成功调用了所选的函数。

4 总结

本文介绍了 C 语言中函数指针的定义、用法和示例。函数指针是一种强大的编程工具,可以实现回调函数、动态函数调用等功能,并且可以作为函数的返回值。掌握函数指针的使用方法,可以使我们的程序更加灵活、高效。