【问题标题】:What's the use of multiple asterisks in the function call?函数调用中多个星号有什么用?
【发布时间】:2012-08-24 21:58:05
【问题描述】:

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

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++ 中都允许这样做?

【问题讨论】:

  • 为了 C 混淆代码竞赛而明确允许。
  • 可能原始编码员是按代码字符而不是按行付费
  • @TomTanner 你甚至不能在星号之间添加换行符吗?那真的很棒;)
  • 您可以在其中放置任意数量的空白区域

标签: c++ c function-pointers dereference function-call


【解决方案1】:

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

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

等等。

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

【讨论】:

    【解决方案2】:

    为什么在 C 和 C++ 中都允许这样做?

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

    6.3.2.1 - 4

    函数指示符是具有函数类型的表达式。除了 当它是 sizeof 运算符或一元 & 运算符的操作数时, 类型为“函数返回类型”的函数指示符是 转换为具有“函数指针”类型的表达式 返回类型''。

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

    6.5.3.2 - 3

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

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


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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案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
        

        就这样继续下去……

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-24
          • 2021-09-21
          相关资源
          最近更新 更多