码迷,mamicode.com
首页 > 其他好文 > 详细

解释复杂声明符

时间:2016-04-30 00:52:37      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:

在解释复杂声明符时,方括号和圆括号(即,标识符右侧的修饰符)优先于星号(即,标识符左侧的修饰符)。 方括号和圆括号具有相同的优先级并且都是从左到右关联。 在完全解释声明符之后,将应用类型说明符以作为最后一步。 通过使用圆括号,您可以重写默认关联顺序和强制实施特定解释。 但是,绝不要单独在标识符名称两边使用圆括号。 这可能会被错误解释为参数列表。

解释复杂声明符的一个简单方法是通过下列 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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!