第6.12章: 函数指针

English

概述

函数指针是指向函数而不是数据的指针。 函数指针让你能够:

在本章中,你将学到函数指针如何工作、如何声明它们、如何调用它们, 以及如何使用 ::fast_io::funcvw() 操纵器打印它们的地址。

1. 函数类型

函数根据其参数列表和返回类型而具有一个类型。


int add(int a, int b);

add 的类型是:


int(int, int)

这表示:“一个接受两个 int 并返回 int 的函数。”

2. 函数会退化为指针

正如数组会退化为指针一样,函数名也会退化为指向该函数的 指针。


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

int (*p)(int, int) = add; // function pointer

p 的类型是“指向接受两个 int 并返回 int 的函数的 指针”。

3. 通过函数指针调用

你可以像调用普通函数一样调用函数指针。


int result = p(3, 4);   // calls add(3, 4)

也可以写成:


int result = (*p)(3, 4); // equivalent

4. 把函数指针传给函数

函数指针可以用作参数类型。


int operate(int a, int b, int (*op)(int, int))
{
    return op(a, b);
}

用法:


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

::fast_io::io::println(operate(3, 4, add)); // 7
::fast_io::io::println(operate(3, 4, mul)); // 12

5. 用 using 别名提升清晰度

函数指针的语法很冗长。你可以用 using 别名来简化它。


using binary_op = int(*)(int, int);

int operate(int a, int b, binary_op op)
{
    return op(a, b);
}

这让代码更易读、更易维护。

6. 返回函数指针

函数可以返回函数指针。


binary_op choose(bool multiply)
{
    if(multiply)
        return mul;
    return add;
}

用法:


auto f = choose(true);
::fast_io::io::println(f(3, 4)); // 12

7. 函数指针数组

你可以把多个函数存入一个数组。


binary_op ops[2]{add, mul};

::fast_io::io::println(ops[0](3, 4)); // add
::fast_io::io::println(ops[1](3, 4)); // mul

这对跳转表、解释器和分派系统很有用。

8. 用 ::fast_io::funcvw() 打印函数地址

fast_io 库提供了一个名为 funcvw() 的特殊操纵器, 用来打印函数或函数指针的地址。这在调试、教学, 以及验证两个函数指针是否指向同一函数时极其有用。

示例:打印函数的地址


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

println(funcvw(add));

这会打印 add 函数的地址。

示例:打印函数指针的地址


int (*p)(int, int) = add;

println(funcvw(p));

这会打印 p 中存储的地址。它应当与为 add 打印的地址相同。

funcvw() 适用于:

9. 函数指针为何重要

函数指针在以下领域不可或缺:

它们也是更高级特性的基础,例如:

要点