37

我想不出函数调用中多个星号的任何实际用途:

void foo(int a, char b)
{

}

int main(void)
{
    (**************foo)(45, 'c');

    //or with pointer to function:
    void (*ptr)(int, char) = foo;
    (******ptr)(32, 'a');
}

为什么在 C 和 C++ 中都允许这个东西?

4

4 回答 4

43

C 和 C++ 中的标准转换之一是函数到指针的转换。当函数名出现在表达式中时,可以将其转换为指向该函数的指针。所以:

  • foo相当于&foo
  • *foo等价于*(&foo), 或foo
  • **foo等价于**(&foo), 或*foo, 或foo

等等。

这意味着您可以合法地*在函数名称前添加任意数量的名称,而不会改变其含义。不过,没有理由这样做。

于 2012-08-30T08:13:47.877 回答
40

为什么在 C 和 C++ 中都允许这个东西?

我不能代表 C++,但对于 C,至少函数指示符被转换为指针:

6.3.2.1 - 4

函数指示符是具有函数类型的表达式。除非它是 sizeof 运算符或一元 & 运算符的操作数,否则类型为“函数返回类型”的函数指示符将转换为类型为“<strong>指向函数返回类型的指针”的表达式。

应用间接运算符产生一个函数指示符:

6.5.3.2 - 3

一元 * 运算符表示间接。如果操作数指向一个函数,则结果是一个函数指示符

因此,无论您应用间接运算符多少次,您都会得到相同的结果:一个立即转换为指针的函数指示符。


在我看来,这样做几乎没有用处。

于 2012-08-30T08:01:30.590 回答
9

因为*操作员需要一个地址值。并且无论何时需要一个值(与对象或函数 glvalue 相对),左值到右值、函数到指针以及数组到指针的转换都应用于操作数。因此,当再次取消引用时,取消引用的函数会立即再次转换为指针。

这些要么从对象中读取值,要么产生一个指针值,分别指向数组或函数的开头。

这些取消引用的行除了为了它的 lulz 之外没有其他目的。

于 2012-08-30T08:00:14.430 回答
-4

我理解的方式是

* is a pointer to a memory address
& is the value at the Memory address

*foo means pointer to foo memory address
**foo means *(*foo) *(foo memory address) This is a different value from *foo

就这样继续下去……

于 2012-09-06T15:26:09.603 回答