深入理解C语言函数指针

C语言是一种广泛使用的编程语言,它提供了许多强大的功能,其中之一就是函数指针,函数指针是一种特殊的指针,它存储的是一个函数的地址,而不是一个变量的地址,通过函数指针,我们可以实现对函数的间接调用,从而实现更灵活、更高效的编程,本文将详细介绍C语言函数指针的概念、定义、使用方法以及注意事项。

函数指针的概念

函数指针是一种特殊的指针,它存储的是一个函数的地址,而不是一个变量的地址,当我们需要频繁地调用同一个函数时,可以使用函数指针来提高程序的运行效率,函数指针还可以用于实现回调函数、函数表等高级编程技巧。

函数指针的定义

在C语言中,我们可以通过以下方式定义一个函数指针:

1、返回类型 (*指针名)(参数列表);

2、typedef 返回类型 (*指针名)(参数列表);

我们可以定义一个指向返回类型为int、参数列表为(int, int)的函数的指针:

int (*func_ptr)(int, int);

c语言函数指针 c语言函数指针和指针函数

或者使用typedef简化定义:

typedef int (*FuncPtr)(int, int);
FuncPtr func_ptr;

函数指针的赋值与使用

1、给函数指针赋值:我们可以将一个函数的地址赋给一个函数指针,

int add(int a, int b) {
    return a + b;
}
int main() {
    int (*func_ptr)(int, int); // 定义一个函数指针
    func_ptr = add; // 将add函数的地址赋给func_ptr
    printf("%d
", func_ptr(1, 2)); // 输出3,表示func_ptr指向的是add函数
    return 0;
}

2、使用函数指针调用函数:我们可以通过函数指针来间接调用一个函数,

#include <stdio.h>
int subtract(int a, int b) {
    return a - b;
}
int multiply(int a, int b) {
    return a * b;
}
int divide(int a, int b) {
    return a / b;
}
void perform_operation(int (*op)(int, int), int a, int b) {
    printf("%d %s %d = %d
", a, op == add ? "+" : op == subtract ? "-" : op == multiply ? "*" : "/", b, op(a, b));
}
int main() {
    perform_operation(add, 1, 2); // 输出1 + 2 = 3
    perform_operation(subtract, 5, 3); // 输出5 - 3 = 2
    perform_operation(multiply, 4, 6); // 输出4 * 6 = 24
    perform_operation(divide, 9, 3); // 输出9 / 3 = 3,注意除数不能为0,否则会出错
    return 0;
}

注意事项

1、函数指针和数组、结构体等复合数据类型的指针不同,它们之间不能相互赋值,我们不能将一个数组指针赋值给一个函数指针,反之亦然。

2、函数指针可以指向任何返回类型为void或非可变参数的函数,如果一个函数有可变参数(如printf),则不能直接将其地址赋给一个函数指针,在这种情况下,我们需要使用可变参数列表来实现类似的功能。

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <errno.h> // for strerror() function in case of error reporting in logs or console outputs..etc..etc..etc..etc..etc..etc..etc..etc..etc..etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc...etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... etc.... et cetera and so on.....................................................................................................................................................................................................................................................................................................and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on and so forth and so on