标签:
在解释复杂声明符时,方括号和圆括号(即,标识符右侧的修饰符)优先于星号(即,标识符左侧的修饰符)。 方括号和圆括号具有相同的优先级并且都是从左到右关联。 在完全解释声明符之后,将应用类型说明符以作为最后一步。 通过使用圆括号,您可以重写默认关联顺序和强制实施特定解释。 但是,绝不要单独在标识符名称两边使用圆括号。 这可能会被错误解释为参数列表。
解释复杂声明符的一个简单方法是通过下列 4 个步骤“从里到外”地读取它们:
从标识符开始并直接查找方括号或圆括号(如果有)的右侧。
解释这些方括号或圆括号,然后查找星号的左侧。
如果在任何阶段遇到一个右圆括号,请返回并将规则 1 和 2 应用于圆括号内的所有内容。
应用类型说明符。
以带有颜色区分的格式查看复制到剪贴板char *( *(*var)() )[10];
^ ^ ^ ^ ^ ^ ^
7 6 4 2 1 3 5
char *( *(*var)() )[10];
^ ^ ^ ^ ^ ^ ^
7 6 4 2 1 3 5
在此示例中,步骤是按顺序编号的,并且可以按如下方式解释:
标识符 var 声明为
指向以下内容的指针
返回以下内容的函数
指向以下内容的指针
包含 10 个元素的数组,这些元素分别为
指向以下内容的指针
char 值。
示例
--------------------------------------------------------------------------------
以下示例阐释了其他复杂声明并演示了圆括号如何影响声明的含义。
以带有颜色区分的格式查看复制到剪贴板int *var[5]; /* Array of pointers to int values */
int *var[5]; /* Array of pointers to int values */
数组修饰符的优先级高于指针修饰符,因此,var 将声明为数组。 指针修饰符将应用于数组元素的类型;因此,数组元素是指向 int 值的指针。
以带有颜色区分的格式查看复制到剪贴板int (*var)[5]; /* Pointer to array of int values */
int (*var)[5]; /* Pointer to array of int values */
在对 var 的此声明中,圆括号为指针修饰符赋予了高于数组修饰符的优先级,并且 var 被声明为指向包含 5 个 int 值的数组的指针。
以带有颜色区分的格式查看复制到剪贴板long *var( long, long ); /* Function returning pointer to long */
long *var( long, long ); /* Function returning pointer to long */
函数修饰符的优先级也高于指针修饰符,因此对 var 的此声明将 var 声明为返回指向 long 值的指针的函数。 该函数被声明为采用两个 long 值作为参数。
以带有颜色区分的格式查看复制到剪贴板long (*var)( long, long ); /* Pointer to function returning long */
long (*var)( long, long ); /* Pointer to function returning long */
此示例与前一个示例类似。 圆括号为指针修饰符赋予了高于函数修饰符的优先级,var 被声明为指向返回 long 值的函数的指针。 同样,该函数采用两个 long 参数。
以带有颜色区分的格式查看复制到剪贴板struct both /* Array of pointers to functions */
{ /* returning structures */
int a;
char b;
} ( *var[5] )( struct both, struct both );
struct both /* Array of pointers to functions */
{ /* returning structures */
int a;
char b;
} ( *var[5] )( struct both, struct both );
数组的元素不能是函数,但此声明演示了如何将指针数组声明为函数。 在此示例中,var 被声明为包含 5 个指向函数(返回具有两个成员的结构)的指针的数组。 函数的参数被声明为具有同一结构类型 both 的两个结构。 请注意,*var[5] 两边需要圆括号。 如果没有它们,声明将是对声明函数数组的非法尝试,如下所示:
以带有颜色区分的格式查看复制到剪贴板/* ILLEGAL */
struct both *var[5]( struct both, struct both );
/* ILLEGAL */
struct both *var[5]( struct both, struct both );
以下语句声明指针的数组。
以带有颜色区分的格式查看复制到剪贴板unsigned int *(* const *name[5][10] ) ( void );
unsigned int *(* const *name[5][10] ) ( void );
name 数组具有组织在一个多维数组中的 50 个元素。 这些元素是指向常量指针的指针。 此常量指针指向没有参数并返回指向无符号类型的指针的函数。
下一个示例是函数,该函数返回指向包含三个 double 值的数组的指针。
以带有颜色区分的格式查看复制到剪贴板double ( *var( double (*)[3] ) )[3];
double ( *var( double (*)[3] ) )[3];
在此声明中,函数将返回指向数组的指针,因为返回数组的函数是非法的。 在此处,var 被声明为一个函数,该函数返回了指向包含三个 double 值的数组的指针。 函数 var 将采用一个参数。 参数(如返回值)是指向包含三个 double 值的数组的指针。 参数类型由一个复杂 abstract-declarator 给定。 参数类型中的星号两边需要圆括号;如果没有圆括号,参数类型将是一个包含三个指向 double 值的指针的数组。 有关抽象声明符的讨论和示例,请参阅 抽象声明符。
以带有颜色区分的格式查看复制到剪贴板union sign /* Array of arrays of pointers */
{ /* to pointers to unions */
int x;
unsigned y;
} **var[5][5];
union sign /* Array of arrays of pointers */
{ /* to pointers to unions */
int x;
unsigned y;
} **var[5][5];
如上面的示例所示,指针可以指向另一个指针,数组可包含数组作为元素。 这里的 var 是一个包含五个元素的数组。 每个元素都是一个五元素指针数组,这些指针指向指向具有两个成员的联合的指针。
以带有颜色区分的格式查看复制到剪贴板union sign *(*var[5])[5]; /* Array of pointers to arrays
of pointers to unions */
union sign *(*var[5])[5]; /* Array of pointers to arrays
of pointers to unions */
此示例演示圆括号的放置如何更改声明的含义。 在此示例中,var 是一个五元素指针数组,这些指针指向联合的五元素指针数组。 有关如何使用 typedef 避免复杂声明的示例,请参阅 Typedef 声明。
请参见
--------------------------------------------------------------------------------
概念
声明和类型
© 2015 Microsoft Corporation。保留所有权利。
向 Microsoft 发送有关本主题的反馈。
标签:
原文地址:http://www.cnblogs.com/nfking/p/5447855.html