当前位置:嗨网首页>书籍在线阅读

42-其他复杂的声明

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

14.13 其他复杂的声明

C允许用户自定义数据形式。虽然我们常用的是一些简单的形式,但是根据需要有时还会用到一些复杂的形式。在一些复杂的声明中,常包含下面的符号,如表14.1所示。

表14.1 声明时可使用的符号

| 符号 | 含义 | | :----- | :----- | :----- | :----- | | * | 表示一个指针 | | () | 表示一个函数 | | [] | 表示一个数组 |

下面是一些较复杂的声明示例:

int board[8][8];       // 声明一个内含int数组的数组
int ** ptr;            // 声明一个指向指针的指针,被指向的指针指向int
int * risks[10];       // 声明一个内含10个元素的数组,每个元素都是一个指向int的指针
int (* rusks)[10];     // 声明一个指向数组的指针,该数组内含10个int类型的值
int * oof[3][4];       // 声明一个3×4 的二维数组,每个元素都是指向int的指针
int (* uuf)[3][4];     // 声明一个指向3×4二维数组的指针,该数组中内含int类型值
int (* uof[3])[4];     // 声明一个内含3个指针元素的数组,其中每个指针都指向一个内含4个int类
                          型元素的数组

要看懂以上声明,关键要理解*、 ()[] 的优先级。记住下面几条规则。

1.数组名后面的 [] 和函数名后面的 () 具有相同的优先级。它们比 * (解引用运算符)的优先级高。因此下面声明的 risk 是一个指针数组,不是指向数组的指针:

int * risks[10];

2. []() 的优先级相同,由于都是从左往右结合,所以下面的声明中,在应用方括号之前, * 先与 rusks 结合。因此 rusks 是一个指向数组的指针,该数组内含10个 int 类型的元素:

int (* rusks)[10];

3. []() 都是从左往右结合。因此下面声明的 goods 是一个由12个内含50个 int 类型值的数组组成的二维数组,不是一个有50个内含12个 int 类型值的数组组成的二维数组:

int goods[12][50];

把以上规则应用于下面的声明:

int * oof[3][4];

[3]的优先级高,由于从左往右结合,所以 [3] 先与 oof 结合。因此, oof 首先是一个内含3个元素的数组。然后再与 [4] 结合,所以 oof 的每个元素都是内含4个元素的数组。说明这些元素都是指针。最后, int 表明了这4个元素都是指向 int 的指针。因此,这条声明要表达的是: oof 是一个内含3个元素的数组,其中每个元素是由4个指向 int 的指针组成的数组。简而言之, oof 是一个3×4的二维数组,每个元素都是指向 int 的指针。编译器要为12个指针预留存储空间。

现在来看下面的声明:

int (* uuf)[3][4];

圆括号使得*先与 uuf 结合,说明 uuf 是一个指针,所以 uuf 是一个指向3×4的 int 类型二维数组的指针。编译器要为一个指针预留存储空间。

根据这些规则,还可以声明:

char * fump(int);          // 返回字符指针的函数
char (* frump)(int);       // 指向函数的指针,该函数的返回类型为char
char (* flump[3])(int);    // 内含3个指针的数组,每个指针都指向返回类型为char的函数

这3个函数都接受 int 类型的参数。

可以使用 typedef 建立一系列相关类型:

typedef int arr5[5];
typedef arr5 * p_arr5;
typedef p_arr5 arrp10[10];
arr5 togs;    // togs 是一个内含5个int类型值的数组
p_arr5 p2;    // p2 是一个指向数组的指针,该数组内含5个int类型的值
arrp10 ap;    // ap 是一个内含10个指针的数组,每个指针都指向一个内含5个int类型值的数组

如果把这些放入结构中,声明会更复杂。至于应用,我们就不再进一步讨论了。