首页 > 编程笔记

C++函数指针(指向函数的指针)

在 C++ 中,函数也是有地址的。编译之后的函数,其实是一组指令的集合,这样一组指令在程序运行时存在于内存中,其起始地址就是该函数的地址,也称做函数的入口地址。

编写 C++ 程序时,可以用函数名来表示函数的地址,也可以在函数名之前加上取地址符号“&”表示函数的地址。

举个简单的例子:
int add(int a, int b) {
    return a + b;
}
add() 函数的地址可以用函数名add或者&add表示。

我们知道,指针可以用于存储变量的地址,它还可以用于存储函数的地址,这样的指针就称为函数指针。

存储函数入口地址的指针,也可以说成是指向函数的指针,它们是等价的。

函数指针也是一个变量,可以指向不同的函数。同时通过函数指针可以调用其指向的函数,从而使得函数调用更加灵活。

函数指针在 C++ 编程中有广泛的应用,比如回调函数、策略模式和表驱动方法。

函数指针的定义

定义一个函数指针,遵循以下格式:
返回值类型 (*函数指针名)(参数列表);
例如,定义一个指向返回值类型为 int、参数列表为 (int, int) 的函数指针:
int (*functionPtr)(int, int);
其中,functionPtr 就是函数指针的名称。注意,函数指针名两侧的括号不能省略,否则就变成了一个返回 int* 类型的函数声明。

可以在定义函数指针的同时为它赋初值,也可以在定义后再另行赋值。例如,令 functionPtr 指向上面的 add() 函数:
functionPtr = &add
或者更简洁地写成下面这种方式:
functionPtr = &add

函数指针的使用

使用函数指针调用函数同函数调用一样,只要在函数指针后面加上实参列表即可。

以下的 C++ 程序演示了如何使用函数指针。
#include <iostream>

// 两个简单的函数
int add(int a, int b) {
    return a + b;
}

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

int main() {
    // 声明一个返回类型为int,接受两个int参数的函数指针
    int (*functionPtr)(int, int);

    // 初始化函数指针
    functionPtr = add;

    // 使用函数指针调用函数
    int sum = functionPtr(2, 3);  // 输出应为5
    std::cout << "Sum: " << sum << std::endl;

    // 改变函数指针指向
    functionPtr = multiply;

    // 再次使用函数指针调用函数
    int product = functionPtr(2, 3);  // 输出应为6
    std::cout << "Product: " << product << std::endl;

    return 0;
}
运行结果为:

Sum: 5
Product: 6

函数指针作为参数

函数指针也可以作为其它函数的参数,例如:
#include <iostream>

// 定义两个简单的函数
int add(int a, int b) {
    return a + b;
}

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

// 定义一个函数,它接受一个函数指针作为参数
void execute(int (*funcPtr)(int, int)) {
    int result = funcPtr(2, 3);
    std::cout << "Result: " << result << std::endl;
}

int main() {
    // 使用add函数作为参数调用execute
    std::cout << "Executing 'add' function:" << std::endl;
    execute(add);

    // 使用multiply函数作为参数调用execute
    std::cout << "Executing 'multiply' function:" << std::endl;
    execute(multiply);

    return 0;
}
输出结果为:

Executing 'add' function:
Result: 5
Executing 'multiply' function:
Result: 6

在 main() 函数中,我们两次调用 execute() 函数,第一次传入 add() 函数,第二次传入 multiply() 函数,这样 execute() 函数就能动态地执行不同的操作。

函数指针作为返回值

函数指针也可以作为其它函数的返回值。例如:
#include <iostream>

// 两个简单的函数
int add(int a, int b) {
    return a + b;
}

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

// 一个函数,根据输入参数返回对应的函数指针
int (*selectFunction(char op))(int, int) {
    if (op == '+') {
        return add;
    }
    if (op == '*') {
        return multiply;
    }
    // 返回nullptr表示无效的操作符
    return nullptr;
}

int main() {
    // 根据输入参数获取函数指针
    int (*funcPtr)(int, int) = selectFunction('+');
   
    // 使用函数指针
    if (funcPtr != nullptr) {
        int result = funcPtr(3, 4);  // 输出应为 7
        std::cout << "Result: " << result << std::endl;
    } else {
        std::cout << "Invalid operator." << std::endl;
    }

    // 再次获取函数指针,这次使用乘法
    funcPtr = selectFunction('*');
   
    // 再次使用函数指针
    if (funcPtr != nullptr) {
        int result = funcPtr(3, 4);  // 输出应为 12
        std::cout << "Result: " << result << std::endl;
    } else {
        std::cout << "Invalid operator." << std::endl;
    }

    return 0;
}
执行结果为:

Result: 7
Result: 12

在这个例子中,有两个简单的函数 add() 和 multiply(),还有一个名为 selectFunction() 的函数,它接受一个字符(操作符)作为参数,并返回一个相应的函数指针。

selectFunction() 的返回类型稍微有些复杂,因为它自身返回一个函数指针。这里,int (*selectFunction(char op))(int, int)的意义是:selectFunction 是接受一个 char 参数、返回值类型为 int (*)(int, int)的函数。

main() 函数中调用 selectFunction() 返回的函数指针来计算结果,实现了动态地根据某些条件(这里是一个字符操作符)来选择要执行的函数,这是使用函数指针作为返回值的一个常见应用场景。

总结

函数指针是 C++ 编程中一个非常有用的特性,尤其在需要动态选择函数或实现回调时,正确使用函数指针可以让你的代码更加模块化和可维护。

推荐阅读