函数指针需要加取地址符吗?

50
在C/C++中,如果我有以下函数:

```

void foo();
void bar(void (*funcPtr)());

这两个调用之间有区别吗:

bar(foo);
bar(&foo);

?


11
为增加混淆,bar(*foo);也等同于这两个表达式。 bar(***** foo);也是如此。 - Mike Seymour
4
我更喜欢使用&foo,因为这明确表明我想要一个函数指针,而不仅仅是忘记调用函数。 - sp2danny
3
请注意,方法指针不适用于此规则。它们需要显式的 & 符号。 - KeyC0de
1
很遗憾,这个问题被标记为重复,因为它实际上并不是。链接的问题假设和询问了“为什么”的原因,而这个问题避免了这种假设,不是问为什么,而是问是否需要一个“&”符号。链接到早期的问题的问题在于这个假设是错误的:正如Nikos所指出的那样,在获取非静态成员函数的指针时,必须使用“&ClassName::FunctionName”语法,因此需要使用“&”符号。 - Adrian Lopez
3个回答

45
不,没有区别,因为函数可以隐式转换为函数指针。 标准中的相关引用(N3376 4.3/1)如下所示: “函数类型T的左值可以转换为类型为‘指向T的指针’的prvalue。结果是函数的指针。”

2
这并非总是如此。在获取非静态成员函数的指针时,必须使用“&ClassName::FunctionName”语法,并且需要使用“&”符号。 - Adrian Lopez
@AdrianLopez,是的,但问题是关于自由函数而不是类成员函数。 - ForEveR

8
这两个调用有区别吗? 没有,它们没有区别。

2

bar(foo);被称为“短”版本

bar(&foo);是官方的写法

从功能上来说,两者没有区别,但第二种选项被大多数人认为是“良好的实践”,因为这样更明显地表明foo实际上是一个函数指针而不是一个实际的函数。

这与数组类似。如果你有:

int foobar[10]; 

那么 foobar 是一个 int *,但你也可以使用 &foobar 得到相同的结果。


11
我不同意你的"foobar"部分。如果定义为int foobar[10];,则foobar是一个int [10](包含10个整数的数组),但可以根据需要将其_隐式转换为_ int *(指向第一个整数的指针)("数组退化");特别地,sizeof foobar等于10 * sizeof(int),而不是sizeof(int*)。另外,&foobar是一个int (*)[10](指向包含10个整数的数组的指针),这完全是另一种类型(_不能_转换为int*)。 - gx_
4
但是你可以使用 &foobar[0](或者 &(foobar[0]))的写法,具有讽刺意味的是,它只是 &(*(foobar + 0)) 的一种简便写法,也就是 foobar + 0,其中 foobar 被隐式转换为指向其第一个元素的指针... - gx_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接