有趣的是, 使用功能名称作为函数指针相当于应用的地址运算符函数名 !
这里的例子。
typedef bool (*FunType)(int);
bool f(int);
int main() {
FunType a = f;
FunType b = &a; // Sure, here's an error.
FunType c = &f; // This is not an error, though.
// It's equivalent to the statement without "&".
// So we have c equals a.
return 0;
}
使用的名字是我们已经知道的东西在阵列。 但你不能喜欢写东西
int a[2];
int * b = &a; // Error!
这似乎与语言的其他部分并不一致。 这是什么设计的原理是什么?
这个问题说明了这种行为,为什么它的语义。 但我感兴趣的是,为什么语言被这样设计的。
更有趣的是功能型可以隐式转换为参数时,指针本身,而是使用作为返回类型时,将不会被转换为指针本身!
例:
typedef bool FunctionType(int);
void g(FunctionType); // Implicitly converted to void g(FunctionType *).
FunctionType h(); // Error!
FunctionType * j(); // Return a function pointer to a function
// that has the type of bool(int).
既然你特别要求对这种行为的理由,这是我能找到的最接近的事情(从ANSI C90理文件- http://www.lysator.liu.se/c/rat/c3.html#3-3- 2-2 ):
3.3.2.2函数调用
可以使用函数指针或作为(*pf)()
或如pf()
后者构建体,在基础文档不认可,将出现在C一些本版本中,是明确的,没有无效旧的代码,并且可以是一个重要的速记。 简写为呈递只有一个外部名称,其指定一个完整的指针到对象S和功能结构包有用:成员函数可以被称为graphics.open(file)
,而不是(*graphics.open)(file)
。 功能代号的治疗可导致有些好奇,但有效的,句法形式。 鉴于声明:
int f ( ) , ( *pf ) ( ) ;
那么所有的下列表达式是有效的函数调用:
( &f)(); f(); (*f)(); (**f)(); (***f)(); pf(); (*pf)(); (**pf)(); (***pf)();
在每一行的第一个表达在前面的段落中讨论。 第二个是常规用法。 所有随后的表达式利用一个功能指示器的隐式转换的到的指针值,在几乎所有的表达上下文。 委员会认为没有真正的伤害在使这些形式; 取缔形式像(*f)()
同时仍允许*a
(用于int a[])
只是似乎更多的麻烦比它的价值。
基本上,加入功能指示器和函数指针之间的等价性,使使用函数指针更方便一点。
这是从C继承功能
在C语言中,它主要是允许的,因为还有别的不多函数的名称,其本身可能意味着。 所有你可以用实际功能做的是调用它。 如果你不调用它,你唯一可以做的就是把地址。 由于没有歧义,任何时间的函数名后面没有(
用于给函数的调用,该名称求函数的地址。
这实际上有点类似的语言的一个其它部分-的阵列的名称的计算结果为除了在一些相当有限的情况下数组的第一元素的地址(被用作操作数&
或sizeof
)。
由于C允许的话,C ++做的好,主要是因为同样的仍然是正确的:你可以用一个函数做的唯一的事情是把它或采取其地址,所以如果名字后面没有(
来表示一个函数调用,那么名称求毫不含糊的地址。
对于数组,存在当操作者的地址没有使用指针衰变:
int a[2];
int * p1 = a; // No address-of operator, so type is int*
int (*p2)[2] = &a; // Address-of operator used, so type is int (*)[2]
这是有意义的,因为数组和指针是不同类型的,并且可以例如以引用返回到阵列或通过引用数组函数。
然而,随着功能的,有什么其他类型的可能呢?
void foo(){}
&foo; // #1
foo; // #2
让我们想象一下,仅#2给出了类型void(*)()
会有什么类型&foo
是什么? 有没有其他的可能性。
文章来源: Why is using the function name as a function pointer equivalent to applying the address-of operator to the function name?