首先声明如果你对int (*a)[10], char* const (*next());已经了解,就不要看了,一个声明是没什么意思的,这篇文章只是想阐述下C语言是怎么解析它的声明。
声明里面可以包括的元素有:类型说明符(int, void, char,struct...),存储类型extern, static, register, 类型限定符(const, volatile), 变量名(标识符), 符号(*,圆括号和中括号);
总体原则是,找到标识符(即是我们平时叫的变量名),从右向左解析;
具体步骤如下:
1. 找到声明中最左边的标识符,去掉标识符 => 变量是叫“标识符”
2. 查看标识符右边的下一个符号,如果是方括号,取出可能的大小,去掉方括号 =>是一个数组。
3. 查看标识符右边的下一个符号,
如果是左圆括号,取出可能的参数,一直到右括号 => 是一个函数
4. 查看标识符左边的符号,如果是左括号,找到对应的右括号,并把括号中的声明组合在一起。回到第2步重新开始执行。
5. 查看标识符左边的符号,如果是const, volatile,*, 继续向左读直到不是这三个类型为止。重复第4步。 =>解释为const, volatile,指向什么的指针
6. 剩下的符号一并读入 =>static unsigned int
你可能想问这几步就可以解决了? 是的,这就是所谓的神奇解码环。
下面我来随便验证下这个算法:
先来个简单的
int (*a)[10] 和 int* a[10];
声明式 步骤 执行结果
int (*a)[10] 第1步 找到最左边的标识符a,表示a是一个…
int (*)[10] 第2,3步 不匹配
int (*)[10] 第4步 匹配(,直接读到),包括*,表示a是一个指向…指针.Step2
int [10] 第2步 匹配[10],表示a是一个指向..size=10的数组的指针
int 第3,4,5 不匹配
结束 第6步 表示a是一个指向int数组的指针
int* a[10] 第1步 a是一个
int* [10] 第2步 a是一个…size=10的数组
int* 第3步 不匹配
int 第4步 匹配,a是一个存放着指针,size=10的数组
int 第5步 匹配,a是一个存放着int指针,size=10的数组
大家看的出两个声明的结果是一个是指针,一个是数组。
int a1[10];
int a2[20];
int (*b)[10];
int* c[10];
a[0] = 10;
b = &a2; //报错,cannot convert from 'int (*)[20]' to 'int (*)[10]'
b = &a1; //b是指向size=10的数组的指针
c[0] = &a1[0]; //c是一个数组,里面存放的是指针,指针指向int;
(未完待续)