函数指针表达式
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个int
s作为参数并返回一个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
是一个指向以两个int
s 作为参数并返回一个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
作为参数并返回一个指向以两个int
s 作为参数并返回int
的函数的函数的函数。所以f
返回类型与其参数返回类型相同。本来可以更简单的:
using ftype = int(*)(int,int);
ftype f( ftype a);
【讨论】:
请注意,C++ 使用引用扩展此 C 语法的方式似乎并未遵循此模式。例如。int &x;
将 x
声明为对 int
的引用,但这并不意味着 &x
具有 int
类型(它实际上具有 int*
类型)。因此,只有当您的声明中没有引用时,这一切都是正确的。
Arhhh 引用是怪物:具有指向对象语义的 const 指针。【参考方案4】:
a
是f1
唯一参数的名称;当您删除它时,您可以使用https://cdecl.org/ 来破译整个声明:
将 f1 声明为函数(指向函数 (int, int) 返回 int 的指针) 返回指向函数的指针 (int, int) 返回 int
所以f1
是一个函数。它接受一个函数指针(称为a
)并返回一个函数指针。
这两个函数指针都用于接受两个 int
s 并返回一个 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
【讨论】:
以上是关于函数指针表达式的主要内容,如果未能解决你的问题,请参考以下文章