0

考虑下面的 C 声明:

typedef char (* ( * (* ARR ) ( ) ) [8]) (int,int) ;    
ARR arr;

表示什么arr

4

3 回答 3

3

从最左边的标识符开始,然后记住它[]()在之前绑定*,因此*a[]是指针数组,是指向数组的指针,(*a)[]*f()返回指针的函数,(*f)()是指向函数的指针:

typedef                ARR                           -- ARR is a typedef for
                    (* ARR )                         -- a pointer
                    (* ARR ) ( )                     -- to a function
                ( * (* ARR ) ( ) )                   -- returning a pointer
                ( * (* ARR ) ( ) ) [8]               -- to an 8-element array
             (* ( * (* ARR ) ( ) ) [8])              -- of pointers
             (* ( * (* ARR ) ( ) ) [8]) (       )    -- to functions
             (* ( * (* ARR ) ( ) ) [8]) (int,int)    --   taking two int parameters
typedef char (* ( * (* ARR ) ( ) ) [8]) (int,int) ;  --   and returning char

所以

ARR arr;

声明arr为一个指向函数的指针,该函数返回一个指向 8 元素指针数组的指针,该指针指向返回 char 的函数。

这是一个在实践中会是什么样子的示例:

char f0(int a, int b) { ... }
char f1(int x, int y) { ... }
char f2(int g, int h) { ... }
...
char f7(int r, int s) { ... }

// funcArr is an *array* of pointers to functions, not a function
char (*funcArr[8])(int, int) = {f0, f1, f2, f3, ..., f7}; 

// func is a function that will return the funcArr array
char (*(*func())[8])(int,int) { return funcArr; }

arr = func;

char c = (*(*(*arr)())[i])(x,y);

所以,最后一行

  1. 取消引用arr
  2. 调用结果函数 ( func)
  3. 取消引用从 返回的指针func,这给了我们数组 ( funcArr)
  4. 在索引处找到函数指针i
  5. 取消引用指针给我们f0...f7
  6. 并调用结果函数

使typedef代码更具可读性的一种方法是分阶段进行:

typedef char CharFunc(int, int);
typedef CharFunc *CharFuncArray[8];
typedef CharFuncArray *ArrayFunc();

ArrayFunc *arr;

就个人而言,我不喜欢以这种方式做事,因为你如何从ArrayFunc *arr

char c = (*(*(*arr)())[i])(x,y);

而像这样的声明

char (*(*(*arr)())[8])(int,int);

告诉你应该如何使用arr

于 2012-11-29T12:49:12.487 回答
3

arr是一个pointer to a function returning pointer to an array of 8 pointers to a function which takes 2 int as an argument returning char

有关更多信息,请参阅使用顺时针/螺旋规则对复杂声明进行命名

于 2012-11-29T11:49:11.107 回答
2

arr是指向函数的指针,返回指向数组的指针 8 指向函数的指针,该函数将 2 个参数作为返回字符的 int。你肯定需要检查这个链接,它可以帮助你解码这些复杂的声明。

PS:我建议不要有这么复杂的声明。把它分成几部分。

于 2012-11-29T11:51:45.317 回答