为什么将函数名称用作函数指针等同于将address-of运算符应用于函数名称?

有趣的是,使用函数名称作为函数指针等同于将address-of运算符应用于函数名称!


这是例子。


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).


慕慕森
浏览 460回答 3
3回答

慕桂英546537

这是从C继承的功能。在C语言中,之所以允许使用它,主要是因为函数名称本身并不意味着什么。您可以使用实际功能做的就是调用它。如果您不打电话,唯一可以做的就是获取地址。由于没有歧义,因此只要函数名称后不带a (来表示对该函数的调用,该名称就等于该函数的地址。这实际上与语言的另一部分相似-数组的名称计算为该数组第一个元素的地址,除非在相当有限的情况下(用作&或的操作数sizeof)。由于C允许这样做,所以C ++也可以这样做,主要是因为这仍然适用:您只能对函数进行调用或获取其地址,因此,如果名称后面没有a (来表示函数调用,那么名称的计算结果就毫无歧义。

慕容森

对于数组,使用address-of运算符时没有指针衰减: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; // #1foo;  // #2假设只有#2给出了type void(*)(),那么类型将&foo是什么?没有其他可能性。
打开App,查看更多内容
随时随地看视频慕课网APP