1.声明的构成
声明的核心是:声明器(declarator),所谓declarator,就是标识符及与它组合在一起的指针、函数括号和数组下标等,如下图所示:
数量 |
c语言中的名字 |
c语言中的表现形式 |
零个或多个 |
指针 |
*const volatile *volatile * *const *volatile const |
有且只有一个 |
直接声明器 |
标识符、标识符(参数)、标识符[下标]、(标识符)
|
零个或一个 |
初始化 |
= 初始值
|
一个完整的声明由下表中的各个部分组成:
数量 | c语言中的名字 | c语言中的表现形式 |
至少一个类型说明符 | 类型说明符 存储类型 类型限定类型 |
void char short int long signed
|
有且只有一个 | 直接声明器 |
参见上面的定义
|
零个或多个 | 更多声明器 |
,声明器
|
一个 | 分号 | ; |
2.理解c语言的优先级规则
优先级规则:
A. 声明从它的优先级规则开始,然后按照顺序依次读取;
B. 优先级从高到低依次是:
b.1 声明中被插号括起来的那部分
b.2 后缀操作符:括号()表示这是一个函数,而[]表示这是一个数组
b.3 前缀操作符:星号*表示“指向…的指针”
C. 如果const和(或)volatile关键字的后面紧跟着类型说明符(如int, long),那么它作用于类型说明符;在其它情况下,它作用于它左边紧邻的星号。
下面是对优先级规则的一种解释
步骤号 | 如果阅读 |
1.取最左边的标识符 | 表示“标识符是” |
2.查看标识符右边的的下一个符号,如果是方括号 | 对于每一对,表示“…的数组” |
3.如果是一个左括号 | 到右括号为止的内容,表示“返回…的函数” |
4.如果左边的符号是一个左括号 | 这个左括号把已经声明的内容组合在一起,直到遇见对应的右括号,然后从第2步重新开始 |
5.如果左边的符号是下述之一:const、volatile、* | 继续向左边读符号,直到不是那3个符号为止。如果符号是const,表示“只读”;如果是volatile,表示“volatile”;如果是*,表示”指向…的指针”。然后重复从第4步。 |
6.剩下的符号形成声明的基本类型 | 剩余的符号可一起阅读 |
举例说明如下:
char *(* c[10])(int **p);
剩余的声明 | 步骤 | 结果 |
char *(* [10])(int **p) | 第1步 | 标识符是c |
char *(* )(int **p) | 第2步 | 表示 c是一个含有10个元素的数组,元素类型是… |
char *()(int **p) | 第5步 | 表示 c是一个含有10个元素的数组,其元素类型是指向…的指针 |
char * (int **p) | 第4步 | 表示 c是一个含有10个元素的数组,其元素类型是指向…的指针 |
char * | 第3步 | 表示 c是一个含有10个元素的数组,其元素类型是指向函数的指针,这个函数接收一个指针的指针作为参数 |
char | 第5步 | 表示 c是一个含有10个元素的数组,其元素类型是指向函数的指针,这个函数接收一个指针的指针作为参数,返回一个指向…的指针 |
第6步 | 表示 c是一个含有10个元素的数组,其元素类型是指向函数的指针,这个函数接收一个指针的指针作为参数,返回一个指向字符的指针 |