复杂的指针声明

时间:2017-10-20 20:27:35

标签: c pointers

我在cdecl.org中尝试了声明int * p()[],它说“声明p作为函数返回指向int的指针数组。”

根据我的说法,声明意味着“p是返回指向int的指针的函数数组”,这没有任何意义。那么这个宣言不应该被允许吗?

我哪里错了?

1 个答案:

答案 0 :(得分:1)

确实不应该允许这种声明;函数可能不返回数组类型,并且您可能没有函数类型的数组:

6.7.6.2数组声明符

约束

1除了可选的类型限定符和关键字static之外,[]可能会划界 表达式或*。如果它们分隔表达式(指定数组的大小),则 表达式应具有整数类型。如果表达式是常量表达式,它应该是 值大于零。 元素类型不应是不完整或函数 类型。可选的类型限定符和关键字static只能出现在 声明具有数组类型的函数参数,然后仅在最外层 数组类型推导。
...
6.7.6.3函数声明符(包括原型)

约束

1 函数声明符不应指定函数类型或数组的返回类型 类型。

C 2011 Online Draft

重点补充。我不知道为什么cdecl没有返回某种错误。

如果你想要一个返回指向数组的指针的函数,你就要写

int (*p())[N];

解析为

      p         -- p is a
      p()       -- function returning
     *p()       -- pointer to
    (*p())[N]   -- array of 
int (*p())[N];  -- int

如果你想要一个函数指针数组,你可以写

int (*p[N])();

解析为

      p        -- p is an
      p[N]     -- array of
     *p[N]     -- pointer to
    (*p[N])()  -- function returning
int (*p[N])(); -- int

如果你想要一个返回指向指针数组的指针的函数,那你就写了

int *(*p())[N];

读作

       p         -- p is a
       p()       -- function returning
      *p()       -- pointer to
     (*p())[N]   -- array of
    *(*p())[N]   -- pointer to
int *(*p())[N];  -- int

Postfix []()的优先级高于一元*,因此:

T *a[N];   // a is an array of pointer to T
T (*a)[N]; // a is a pointer to an array of T
T *f();    // f is a function returning pointer to T
T (*f)();  // f is a pointer to a function returning T

从这些规则开始,您可以使用替换来构建更复杂的声明。如果希望函数返回指向数组的指针,请执行

T (*a)[N];

并用函数声明符替换a

T (*  a  )[N];
      |
      V
T (* f() )[N];

如果需要指向函数的指针数组,请使用函数指针声明符

T (*f)();

并用数组声明符替换f

T (*   f   )()
       |
       V
T (*  a[N] )();

从这里开始,您应该能够阅读(并生成)更复杂的类型。

cdecl是一个很好的工具,但是一旦你了解了C语句的语法是如何工作的,你就不应该再需要它了。