55

我的问题是一个非常简单的问题。

通常,在声明某个变量时,您会将其类型放在其前面,例如:

int a;

函数指针的类型可能类似于: int(*)(int,int),以防我们指向一个接受两个整数并返回一个整数的函数。但是,当声明这样一个指针时,它的标识符不在类型之后,比如:

int(*)(int,int) mypointer;

相反,您必须在中间写下标识符:

int(*mypointer)(int,int);

为什么会这样?抱歉,我知道这是一个令人尴尬的简单问题...

感谢大家的回复。作为

4

4 回答 4

32

我在回答为什么数组、指针和函数的 C 语法是这样设计的?,它基本上归结为:

语言作者更喜欢使语法以变量为中心而不是以类型为中心。也就是说,他们希望程序员查看声明并认为“如果我写表达式*func(arg),那将导致一个int;如果我写*arg[N],我会有一个浮点数”而不是“func必须是指向一个函数的指针并返回那个“。

维基百科上的C 条目声称:

Ritchie 的想法是在类似于它们使用的上下文中声明标识符:“声明反映使用”。

...引用 K&R2 的 p122。

于 2013-01-01T22:22:06.033 回答
24

这个结构反映了一个普通函数是如何被声明(和使用)的。

考虑一个正常的函数定义:

int foo (int bar, int baz, int quux);

现在考虑定义一个指向具有相同签名的函数的函数指针:

int (*foo) (int, int, int);

注意这两个结构如何相互镜像?这使得*foo更容易识别为函数指针而不是其他东西。

于 2013-01-01T22:21:57.657 回答
13

如果您正在处理一个函数(不是指向一个函数的指针),则名称也在中间。它就像:return-type function-name "(" argument-list ")" ...。例如, inint foo(int)int返回类型、foo名称和int参数列表。

指向函数的指针的工作方式几乎相同——返回类型,然后是名称,然后是参数列表。在这种情况下,我们必须添加 a*以使其成为指针,并且(因为*for a 指针是前缀)一对括号将 the 绑定*到名称而不是返回类型。例如,int *foo(int)这意味着一个名为 foo 的函数,它接受一个 int 参数并返回一个指向 int 的指针。为了让 * 绑定到foo,我们需要括号,给 int (*foo)(int).

当您需要指向函数的指针数组时,这会变得特别难看。在这种情况下,大多数人发现使用 typedef 作为指针类型最容易,然后创建该类型的数组:

typedef int (*fptr)(int);

fptr array[10];
于 2013-01-01T22:22:22.677 回答
9

我曾在某些地方看到函数指针声明为

int (*foo) (int a, int b);

在某些地方ab没有被提及,并且两者仍然有效。

所以

int (*foo) (int, int)

也是正确的。

我发现记住的一个非常简单的方法如下所述:

假设函数声明为:

int function (int a , int b);

Step1:只需将函数放在括号中:

int (function) (int a , int b);

Step2:*在函数名前加a并更改名称:

int (*funcPntr) (int a , int b);

PS:在这个答案中,我没有遵循命名约定等的正确编码指南。

于 2015-10-20T03:24:40.240 回答