【问题标题】:Can you explain the following C/C++ statement?你能解释一下下面的 C/C++ 语句吗?
【发布时间】:2009-11-06 12:51:36
【问题描述】:
void (*func)(int(*[ ])());

【问题讨论】:

标签: c++ c function-pointers


【解决方案1】:

阅读毛茸茸的声明符的一般过程是找到最左边的标识符并找出路,记住[]()*之前绑定(即*a[]是一个指针数组,而不是一个指向数组的指针)。由于参数列表中缺少标识符,这种情况变得更加困难,但同样,[] 绑定在 * 之前,所以我们知道 *[] 表示一个指针数组。

所以,给定

void (*func)(int(*[ ])());

我们将其分解如下:

       func                   -- func
      *func                   -- is a pointer
     (*func)(           )     -- to a function taking
     (*func)(     [ ]   )     --    an array
     (*func)(    *[ ]   )     --    of pointers
     (*func)(   (*[ ])())     --    to functions taking 
                              --      an unspecified number of parameters
     (*func)(int(*[ ])())     --    returning int
void (*func)(int(*[ ])());    -- and returning void

实际情况如下:

/**
 * Define the functions that will be part of the function array
 */
int foo() { int i; ...; return i; }
int bar() { int j; ...; return j; }
int baz() { int k; ...; return k; }
/**
 * Define a function that takes the array of pointers to functions
 */
void blurga(int (*fa[])())
{
  int i;
  int x;
  for (i = 0; fa[i] != NULL; i++)
  {
    x = fa[i](); /* or x = (*fa[i])(); */
    ...
  }
}    
...
/**
 * Declare and initialize an array of pointers to functions returning int
 */
int (*funcArray[])() = {foo, bar, baz, NULL};
/**
 * Declare our function pointer
 */
void (*func)(int(*[ ])());
/**
 * Assign the function pointer
 */
func = blurga;
/**
 * Call the function "blurga" through the function pointer "func"
 */
func(funcArray); /* or (*func)(funcArray); */

【讨论】:

  • +1 已经足够好了,请尝试解释如何阅读这些表达式和示例。
【解决方案2】:

这不是声明,而是声明。

它将func 声明为一个指向函数的指针,该函数返回void 并采用int (*[])() 类型的单个参数,它本身是一个指向返回int 并采用固定但未指定数量的参数的函数的指针。


cdecl 输出给你的小信:

cdecl> explain void (*f)(int(*[ ])());
declare f as pointer to function (array of pointer to function returning int) returning void

【讨论】:

  • “固定但未指定数量的参数” - 该问题也被标记为 C++,在这种情况下,第二种函数类型恰好采用零参数。
  • 在我回答之后,C++ 标签是由原始发帖人以外的人添加的。根据我的书,这一步太聪明了。
  • 天哪,这太狡猾了。永远不清楚当有人说“C/C++”时他们是否说过,因为他们认为两种语言的答案是相同的,因为他们认为两种语言的答案不同......
  • +1,我只是想解释一下为什么你说“指向指针的指针”而 cdecl 说“指针数组”:这是因为在函数中,声明为数组的参数变成了指针。就这样没有人说“嘿,你打错了”:)
【解决方案3】:

是的:

$ cdecl 解释 void (* x)(int (*[])()); 将 x 声明为指向函数的指针 (指向函数返回 int 的指针数组)返回 void

【讨论】:

  • 我不这么认为,cdecl 只是不喜欢func 这个名字。
  • Nahhhh ... 这是 cdecl 中的一个错误 :)
  • 它表明你被骗了,lulz(顺便说一句,这是一个很好的作弊,cdecl 很好 xD)
【解决方案4】:

void (*func)(blah); 是一个指向以blah 为参数的函数的指针,其中blah 本身就是int(*[ ])() 是一个函数指针数组。

【讨论】:

    【解决方案5】:

    【讨论】:

      【解决方案6】:

      Geordi 是一个 C++ 机器人,可以训练这个:

      <litb> geordi: {} void (*func)(int(*[ ])());
      <litb> geordi: -r << ETYPE_DESC(func)
      <geordi> lvalue pointer to a function taking a pointer to a pointer to a nullary function 
               returning an integer and returning nothing
      

      它可以做很多有用的事情,比如显示所有参数声明(实际上,这只是匹配原始C++ 语法规则名称):

      <litb> geordi: show parameter-declarations
      <geordi> `int(*[ ])()`.
      

      让我们反其道而行之:

      <litb> geordi: {} int func;
      <litb> geordi: make func a pointer to function returning void and taking array of pointer to 
             functions returning int
      <litb> geordi: show
      <geordi> {} void (* func)(int(*[])());
      

      如果你问它,它会执行你给它的任何东西。如果你受过训练但忘记了一些可怕的括号规则,你也可以混合使用 C++ 和 geordi 风格的类型描述:

      <litb> geordi: make func a (function returning void and taking (int(*)()) []) *
      <geordi> {} void (* func)(int(*[])());
      

      玩得开心!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-27
        • 1970-01-01
        • 2011-01-21
        • 1970-01-01
        • 2016-12-30
        • 1970-01-01
        • 1970-01-01
        • 2011-04-20
        相关资源
        最近更新 更多