为什么使用函数名作为函数指针等同于将地址运算符应用于函数名?
有趣的是,使用函数名作为函数指针相当于将地址运算符应用于函数名!
这是示例.
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;
}
使用名称是我们在数组中已经知道的东西.但是你不能写像
Using the name is something we already know in array. But you can't write something like
int a[2];
int * b = &a; // Error!
它似乎与语言的其他部分不一致.这种设计的原理是什么?
It seems not consistent with other parts of the language. What's the rationale of this design?
这个问题解释了这种行为的语义以及它为什么起作用.但我对为什么这样设计语言很感兴趣.
This question explains the semantics of such behavior and why it works. But I'm interested in why the language was designed this way.
更有趣的是,函数类型作为参数使用时可以隐式转换为指向自身的指针,但作为返回类型使用时不会转换为指向自身的指针!
What's more interesting is the function type can be implicitly converted to pointer to itself when using as a parameter, but will not be converted to a pointer to itself when using as a return type!
示例:
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):
Since you specifically ask for the rationale of this behavior, here's the closest thing I can find (from the ANSI C90 Rationale document - http://www.lysator.liu.se/c/rat/c3.html#3-3-2-2):
3.3.2.2 函数调用
3.3.2.2 Function calls
函数指针可以用作(*pf)()
或pf()
.后一种结构,未在基础文件中批准,出现在一些当前版本的 C,是明确的,不会使旧代码失效,并且可以是一个重要的速记.速记是有用的只提供一个外部名称的包,它指定一个充满指向对象和函数的指针的结构:成员函数可以被称为 graphics.open(file)
而不是(*graphics.open)(file)
.函数指示符的处理可以导致一些奇怪但有效的句法形式.鉴于声明:
Pointers to functions may be used either as (*pf)()
or as pf()
.
The latter construct, not sanctioned in the Base Document, appears in
some present versions of C, is unambiguous, invalidates no old code,
and can be an important shorthand. The shorthand is useful for
packages that present only one external name, which designates a
structure full of pointers to object s and functions : member
functions can be called as graphics.open(file)
instead of
(*graphics.open)(file)
. The treatment of function designators can
lead to some curious , but valid , syntactic forms . Given the
declarations :
int f ( ) , ( *pf ) ( ) ;
那么以下所有表达式都是有效的函数调用:
then all of the following expressions are valid function calls :
( &f)(); f(); (*f)(); (**f)(); (***f)();
pf(); (*pf)(); (**pf)(); (***pf)();
每一行的第一个表达式在前面已经讨论过段落 .二是常规用法.所有后续表达式利用函数的隐式转换指针值的指示符,几乎在所有表达式上下文中.委员会认为允许这些形式没有任何实际危害;取缔像 (*f)()
这样的形式,同时仍然允许 *a
(for int a[])
,只是看起来比它的价值更麻烦.
The first expression on each line was discussed in the previous
paragraph . The second is conventional usage . All subsequent
expressions take advantage of the implicit conversion of a function
designator to a pointer value , in nearly all expression contexts .
The Committee saw no real harm in allowing these forms ; outlawing
forms like (*f)()
, while still permitting *a
(for int a[])
,
simply seemed more trouble than it was worth .
基本上,增加了函数指示符和函数指针之间的等价性,使使用函数指针更加方便.
Basically, the equivalence between function designators and function pointers was added to make using function pointers a little more convenient.
相关文章