函数指针表达式

Posted

技术标签:

【中文标题】函数指针表达式【英文标题】:Function pointer expression 【发布时间】:2018-01-13 12:53:54 【问题描述】:

所以我得到了以下表达式:

int (*f1(int(*a)(int, int))) (int, int);

我试图理解它,但它令人困惑。我发现“a”是一个指向带有 2 个参数(int,int)的函数的指针。 然后 f1 似乎是指向另一个接受 2 个 int 参数的函数的指针。 但令我困惑的是 f1 与 a 的关系。

有人可以给我一些提示或正确解释上述表达式的作用吗?

【问题讨论】:

请告诉我为什么人们使用函数指针编写 C++ 代码。 std::function 可用 这不是问题的重点。我有这条线,我正试图弄清楚它的含义,但我被卡住了。 cdecl.org 说:“将 f1 声明为函数(指向函数 (int, int) 返回 int)返回指向函数 (int, int) 返回 int 的指针” 另见:c-faq.com/decl/spiral.anderson.html How do I understand complicated function declarations? 的可能重复我确实看到这个问题是关于 C 的,而这个问题是关于 C++ 的,但这个问题没有任何 C++ 特定的内容。 【参考方案1】:

它将f1 声明为带有一个名为a 的单个参数的函数。参数类型和返回类型都是“指向带有两个int参数返回int的函数的指针”。


你是这样解析它的:

// f1 is...
      f1
// ...a function...
      f1(                 )
// ...with a single parameter called `a`, which is...
      f1(     a           )
// ...a pointer to...
      f1(    *a           )
// (skip parentheses)
      f1(   (*a)          )
// ...a function...
      f1(   (*a)(        ))
// ...with two `int` parameters...
      f1(   (*a)(int, int))
// ...returning an `int`. The `f1` itself returns...
      f1(int(*a)(int, int))
// ...a pointer to...
     *f1(int(*a)(int, int))
// (skip parentheses)
    (*f1(int(*a)(int, int)))
// ...a function...
    (*f1(int(*a)(int, int))) (        )
// ...with two int parameters...
    (*f1(int(*a)(int, int))) (int, int)
// ...returning an `int`.
int (*f1(int(*a)(int, int))) (int, int)

【讨论】:

【参考方案2】:

这是函数f1的声明,它接受一个参数a-一个指向函数的指针,它接受2个ints作为参数并返回一个int-并返回一个指向相同函数的指针输入。

用 typedef 分解它:

typedef int(*t)(int, int);

t f1(t a); //this is your declaration

【讨论】:

【参考方案3】:

C 中的技巧是将声明当作表达式来阅读。正是这种著名的对称性使 C 变得优雅。

如何阅读?遵循运算符优先规则:

    *a: 如果我取消引用变量a; (*a)(int,int): 然后用两个整数调用它; int (*a)(int,int):那我得到一个整数;

所以a 是一个指向以两个ints 作为参数并返回一个int 的函数的指针。

然后:

    f( int(*a)(int,int) ) 如果我使用参数 a 调用 f; *f( int(*a)(int,int) ) 然后我取消引用结果; (*f( int(*a)(int,int) )(int,int) 然后用 2 int 作为参数调用这个结果 int (*f( int(*a)(int,int) )(int,int) 我得到一个int

所以f 是一个以a 作为参数并返回一个指向以两个ints 作为参数并返回int 的函数的函数的函数。所以f 返回类型与其参数返回类型相同。本来可以更简单的:

using ftype = int(*)(int,int);
ftype f( ftype a);

【讨论】:

请注意,C++ 使用引用扩展此 C 语法的方式似乎并未遵循此模式。例如。 int &x;x 声明为对 int 的引用,但这并不意味着 &x 具有 int 类型(它实际上具有 int* 类型)。因此,只有当您的声明中没有引用时,这一切都是正确的。 Arhhh 引用是怪物:具有指向对象语义的 const 指针。【参考方案4】:

af1唯一参数的名称;当您删除它时,您可以使用https://cdecl.org/ 来破译整个声明:

将 f1 声明为函数(指向函数 (int, int) 返回 int 的指针) 返回指向函数的指针 (int, int) 返回 int

所以f1 是一个函数。它接受一个函数指针(称为a)并返回一个函数指针。

这两个函数指针都用于接受两个 ints 并返回一个 int 的函数。

下面是一个例子,可以看到这一切:

#include <iostream>

int passed(int x, int y)  std::cout << "passed\n"; return x * y; 
int returned(int x, int y)  std::cout << "returned\n"; return x + y; 

// a is redundant here, where we just declare f1:
int (*f1(int(*a)(int, int))) (int, int);

// but not here, where we define f1:
int (*f1(int(*a)(int, int))) (int, int)

    std::cout << "f1\n";
    int result_of_passed = a(10, 10);
    std::cout << result_of_passed << '\n';
    return returned;


int main()

    int x = f1(passed)(10, 10);
    std::cout << x << '\n';

输出:

f1
passed
100
returned
20

【讨论】:

以上是关于函数指针表达式的主要内容,如果未能解决你的问题,请参考以下文章

帮你捋值复杂指针(指针数组,数组指针 函数指针,函数指针数组)

函数指针表达式

类中函数指针调用函数

明显调用的表达式前的括号必须具有(指针)函数类型

函数指针

带括号的三元表达式在 C 中的函数指针声明中返回函数名称的基本原理