C 复杂指针声明

C 复杂指针声明,c,pointers,C,Pointers,我在cdecl.org中尝试了声明int*p()[],它说“将p声明为返回int指针数组的函数” 在我看来,声明的意思是“p是返回int指针的函数数组”,这没有任何意义。所以这个声明不应该被允许,对吗 我哪里做错了?这个声明确实不应该被允许;函数不能返回数组类型,也不能有函数类型的数组: 6.7.6.2数组声明器 约束 1除了可选的类型限定符和关键字static,[和]可以限定 表达式或*。如果它们分隔表达式(指定数组大小),则 表达式应为整数类型。如果表达式是常数表达式,则应 具有大于零的值元

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

在我看来,声明的意思是“p是返回int指针的函数数组”,这没有任何意义。所以这个声明不应该被允许,对吗


我哪里做错了?

这个声明确实不应该被允许;函数不能返回数组类型,也不能有函数类型的数组:

6.7.6.2数组声明器 约束

1除了可选的类型限定符和关键字
static
[
]
可以限定 表达式或
*
。如果它们分隔表达式(指定数组大小),则 表达式应为整数类型。如果表达式是常数表达式,则应 具有大于零的值元件类型不得为不完整或功能 类型。可选类型限定符和关键字
static
只能在 声明具有数组类型的函数参数,然后仅在最外层 数组类型派生。
...
6.7.6.3函数声明器(包括原型)

约束

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

重点补充。我不知道为什么cdecl没有在这个问题上返回某种错误

如果需要返回指向数组指针的函数,可以编写

int (*p())[N];
int (*p[N])();
int *(*p())[N];
这解析为

      p         -- p is a
      p()       -- function returning
     *p()       -- pointer to
    (*p())[N]   -- array of 
int (*p())[N];  -- int
      p        -- p is an
      p[N]     -- array of
     *p[N]     -- pointer to
    (*p[N])()  -- function returning
int (*p[N])(); -- int
如果需要函数指针数组,可以编写

int (*p())[N];
int (*p[N])();
int *(*p())[N];
解析为

      p         -- p is a
      p()       -- function returning
     *p()       -- pointer to
    (*p())[N]   -- array of 
int (*p())[N];  -- int
      p        -- p is an
      p[N]     -- array of
     *p[N]     -- pointer to
    (*p[N])()  -- function returning
int (*p[N])(); -- int
如果您想要一个返回指向指针数组的指针的函数,您可以编写

int (*p())[N];
int (*p[N])();
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
后缀
[]
()
的优先级高于一元
*
,因此:

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   )()
       |
       V
T (*  a[N] )();
如果需要指向函数的指针数组,请使用函数指针声明器

T (*f)();
并用数组声明符替换
f

T (*  a  )[N];
      |
      V
T (* f() )[N];
T (*   f   )()
       |
       V
T (*  a[N] )();
从这里,您应该能够读取(并生成)更复杂的类型


cdecl是一个很好的工具,但一旦您了解了C声明语法的真正工作原理,就不需要它了。

您可能想了解一下。以及如何使用类型别名(带
typedef
)来简化函数指针声明。如果数组由指针传递给函数,它们可能返回数组。@manuel hoelzl,这毫无意义。cdecl.org的解释是正确的,但也是不允许的。函数不能返回数组。你的解释不正确。您的描述将适用于
int*p[]()
。提示:
p()
是一个函数,
p[]
是一个数组。“返回int的函数指针数组”应该是
int(*p[])()cdecl如何将其声明为“返回一个int数组”。如果我们有一个像int*a[10]这样的简单声明,我们将其读作“10个整数指针的数组,而不是'a'返回10个整数指针的数组”。所以int*f()[10]也应该被理解为f是10个整数指针的函数,这是没有意义的。@SagarP:同样,
cdecl
不应该返回任何东西,但“这不是一个合法的声明。”。但是,它们如下所示-后缀
()
[]
具有相同的优先级,并且它们从左到右绑定
f()[10]
解析为
(f())[10]
-“
f
是一个返回数组的函数”。同样,C不允许函数返回数组类型,所以想知道为什么cdecl会这样解释它是浪费时间的。