行 int *(*(x[3])())[5]; 是什么意思?在 C 中做什么?

what does the line int *(*(x[3])())[5]; do in C?

这是我第一次在 Stack Overflow 上提问,所以如果我做错了什么或不够具体,请随时告诉我。 我已经用 C 编写微控制器大约 4 年了。几天前,我参加了一个电子比赛。许多问题之一是 C 代码行

int *(*(x[3])())[5];

确实如此。这是我记得的那条线。括号可能在其他位置,但我认为是这条线。

我的猜测是 x 是一个函数指针数组,我们取第四个元素并取消引用它。然后在不传递参数的情况下执行此功能。返回值似乎是指向一个数组的指针,我们取消引用该数组一次以获取第一个元素的地址。然后我们选择该数组的第 6 个元素。我不知道 int 是干什么用的...

非常感谢您回答我的问题,祝您有愉快的一天。

使用cdecl:

$ cdecl
cdecl> explain int *(*(x[3])())[5]
declare x as array 3 of function returning pointer to array 5 of pointer to int

就是上面cdecl写的

阅读像这样的多毛声明的方法是找到最左边的标识符并找出路,记住以下优先规则:

*a[n]      -- a is an array of pointer
(*a)[n]    -- a is a pointer to an array
*f()       -- f is a function returning a pointer
(*f)()     -- f is a pointer to a function

应用这些规则,我们得到

        x             -- x is a
        x[3]          -- 3-element array of
       (x[3])()       -- function returning
      *(x[3])()       -- pointer to
     (*(x[3])())[5]   -- 5 element array of
    *(*(x[3])())[5]   -- pointer to
int *(*(x[3])())[5];  -- int

如所写,此声明无效;你不能有函数类型的数组。我想应该是这样的

int *(*(*x[3])())[5];

其中 x 是一个 指针数组 函数返回指向 int 指针数组的指针。

当您无法访问为您翻译声明的工具时,您可以记住这三个经验法则

  1. 共有三个基本原子(不包括类型名称)

    Atom [n] 转换为 Array (n elements) of .
    Atom () 转换为 函数返回 .
    Atom * 转换为 指向 的指针。

  2. 标识符开始向移动,遇到原子就翻译。

  3. 一个封闭的括号1或行尾反转解析方向。

1表示)向右移动,向左移动( .


下面是int *(*(x[3])())[5]超级迂腐的翻译

  • 从标识符开始,x
    翻译:x 是
    解析:int *(*(-[3])())[5]
    方向:右

  • 找到原子,[3].
    翻译:x 是
    的一个数组(有 3 个元素) 解析:int *(*(---)())[5]
    方向:右

  • 找到),反方向。
    翻译:x 是
    的数组(有 3 个元素) 解析:int *(*(----())[5]
    方向:.

  • 找到(,反方向。
    翻译:x 是
    的数组(有 3 个元素) 解析:int *(*-----())[5]
    方向:.

  • 找到原子().
    翻译:x 是一个数组(有 3 个元素) 函数返回
    解析:int *(*-------)[5]
    方向:右

  • 找到),反方向。
    翻译:x 是一个函数数组(包含 3 个元素)返回
    解析:int *(*--------[5]
    方向:.

  • 找到原子* 翻译:x 是函数返回 指向
    的一个数组(有 3 个元素) 解析:int *(---------[5]
    方向:左.

  • 找到(,反方向 翻译:x 是一个函数数组(包含 3 个元素),返回指向
    的指针 解析:int *----------[5]
    方向:.

  • 找到原子[5] 翻译:x 是一个函数数组(有 3 个元素)返回一个指针 **到一个数组(有 5 个元素)**
    解析:int *------------
    方向:右

  • 行尾,反向。 翻译:*x 是一个函数数组(有 3 个元素),返回指向 *
    数组(有 5 个元素)的指针 解析:int *------------
    方向:.

  • 找到原子 *。 翻译:*x 是一个函数数组(包含 3 个元素),函数返回一个指向数组(包含 5 个元素)的指针,该数组包含 * 指向
    的指针 解析:int -------------
    方向:左.

  • 找到类型名称 int。 翻译:x 是一个函数数组(有 3 个元素),函数返回指向指向 ints[= 的指针数组(有 5 个元素)的指针122=] 解析:-----------------
    方向:左.

翻译:x 是一个函数数组(有 3 个元素),返回一个指向指向 ints[= 的指针数组(有 5 个元素)的指针175=].


您还可以尝试删除括号:

int **(x[3]())[5] 转换为 x 是一个函数数组(有 3 个元素)返回一个数组(有 5 个元素)指针指向 ints.

int **x[3]()[5] 转换为 x 是一个函数数组(有 3 个元素)返回一个指针数组(有 5 个元素)指向 ints.
同上!

当然这很容易出错,我在写这个答案时cdecl手头有!