为什么使用函数名作为函数指针等价于将操作符的address-of应用于函数名? [英] Why is using the function name as a function pointer equivalent to applying the address-of operator to the function name?

查看:109
本文介绍了为什么使用函数名作为函数指针等价于将操作符的address-of应用于函数名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有趣的是,使用函数名作为函数指针等效于将操作符的地址应用于函数名

It's interesting that using the function name as a function pointer is equivalent to applying the address-of operator to the function name!

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,是明确的,无效旧代码,
并且可以是一个重要的速记。这个简写对于只提供一个外部名称的
包是有用的,它指定一个包含对象和函数指针的
结构:member
函数可以调用 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 $ c> 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.

这篇关于为什么使用函数名作为函数指针等价于将操作符的address-of应用于函数名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆