计算机

函数指针

函数指针是指向函数的指针。 因为函数本身不能被复制或引用,所以当需要传入或者返回一个函数时,只能使用函数指针。

函数指针的操作

定义

定义函数指针的格式为:

ReturnType (*pf)(Type1, Type2, ...);

例如,定义一个接受两个整数、返回一个整数的函数指针:

int (*pf)(int, int);

赋值与调用

给函数指针赋值时,等号右边可以直接填函数名,函数会自动转化为指针,不必显式地取地址;利用函数指针调用时,也可以直接使用调用运算符(括号),不必显式地解引用。

例如:

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

int main()
{
    int (*pf)(int, int);
    pf = add; // 隐式转化为指针
    pf = &add;
    int ans = pf(1, 2); // 隐式转化为函数
    ans = (*pf)(1, 2);
}
bool cmp(int a, int b)
{
    return a > b;
}
int a[1005];

int main()
{
    sort(a + 1, a + n + 1, cmp); // cmp 隐式转化为指针
    return 0;
}

单独类型

对于形参为 Type1,返回值为 ReturnType 的函数,其指针的类型可以写为 ReturnType (*)(Type1)。这种类型可以用于强制类型转换或尾置返回值。

使用 using 可以定义函数本身和函数指针的类型别名。例如

using F = int(int*, int*); // F 是接受两个指针、返回一个整数的函数类型
using PF = int(*)(int*, int*); // PF 是函数指针

函数指针用作形参和返回值

定义与声明的形式仍然一致,只取决于后面接语句块还是接分号。

形参

函数指针用作形参时,类似于普通函数指针的定义方法。例如,一个函数 double_fx 接受函数指针 pf 和整型 x 为形参,则其定义为

int double_fx(int (*pf)(int), int x)
{
    return 2 * pf(x);
}

返回值

类型别名

返回值更加麻烦一些。如果直接应用类型别名,可以使语义更清楚:

using PF = int(*)(int, int);
PF f(double x);

直接返回

如果不使用类型别名,则要模仿函数指针的定义格式 ReturnType (*f)(Type1, ...),然后在 pf 处后面添上括号和形参列表,表示函数 f 的形参。

例如,这里定义 identity_constructor 函数,该函数接受 0 个参数,返回一个 int -> int 的函数:

int identity(int x)
{
    return x;
}
int (*identity_constructor())(int)
{
    return identity;
}

可以对比定义函数指针 pf 和定义返回函数指针的函数 f 的语句:

int (*pf)(int, int); // 定义函数指针
int (*f(double x))(int, int); // 接受一个 double 型形参 x,返回 (int, int) -> int 函数指针的函数

尾置返回值

需要使用上面提到的 函数指针 格式,或者使用函数别名。

auto f(double x) -> int(*)(int, int);
BEYOND THE ARTICLE

读完了,有什么想法?

阅读已保存的问答示例,并循着引用回到原文。

查看公开问答示例
— 本文完 — 返回文章列表