C语言中的类型说明是特别丰富的,不同的组合有不同的意义。比如说数组指针,指针数组,函数指针,指针函数,他们的样子都长得差不多,如果不能掌握如何去分析他们,靠死记的话,就很难灵活应用。现在慢慢的学习如何分析C语言的声明吧。
int a;
可以说声明了一个int型变量a,也可以说是把a声明为一个in型变量,在这里,这两句话的意思是一样的,所表达出的效果也是一样的。但是,在更复杂一点的C语言声明中,它们之间的区别可能会大相径庭了。下面再看一个吧。
int *a[3];
先稍微变一下型 int* a[3];
因此可以说是i声明了一个nt*型的数组,它的名字是a,即指针数组。再看它的兄弟:
int (*a)[3];
先看 int *a; 这条语句声明了,a是一个指针,它指向int型,也可以说声明了一个指向int型的指针a.
在C语言中,对于 int(*a)[3],()的优先级最高,因此先读()里面的,所以a是一个指针,它还带了个后缀[3],因此,说这个指针是指向一个int型数组的 。也可以换种说法声明了一个指向int型数组的指针a。
对于函数指针或者是指针函数,采用同样的方法可以对它进行分析,因此,到此,对于这两对容易混淆的兄弟,应该可以区分了。
上面,我们应该注意到了,在分析一个C语言的声明时,从左至右或者从右至左,它所表达的意思和作用似乎都是一样的。那么再看下面的:
char * const *(*next)();
看到这样的一个复杂的声明,有点感觉不知道从哪里开始读。从左往右,感觉不对,从右往右感觉还是不对。对于它,我是这样分析的:
先找到标识符next,由()的优先级最高,因此先读()里面的,知道next是一个指针。然后,在(*next)的前后,有一个前缀*和后缀(),那么先读哪一个呢?(),可以这样认为,在声明中,后缀总是比前缀要先读,也可以这样认为,()比*的优先级要高。因此说(*next)是一个指针,即函数指针。最后看它前面,char * const,这个const它作用于谁呢,是*还是char呢?应该是*,因为,在C语言的声明中,紧邻在const和volatile的*,始终是修饰*的,所以说是一个指向char型的常量指针。
整理一下:next是一个指针,它指向一个函数,该函数返回另一个指针,该指针指向一个类型为cahr的常量指针
最后,用《C专家编程》里的话,总结一下,如何分析C语言的声明:
A 声明从它的名字开始读取,然后按照优先级顺序依次读取
B 优先级从高到低依次是:
B.1 声明中被括号括起来的那部分
B.2后缀操作符:括号()表示这是一个函数,而方括号[]表示这个一个数组
B.3前缀操作符:星号*表示“指向……的指针”
C 如果const和(或)volatil关键字的后面紧跟类型说明符(如int ,long等),那么,它作用于类型说明符。在其他情况下,const和(或)volatile关键字作用于它紧邻的指针星号