从两个例子分析C语言的声明
在读《C专家编程》一书的第三章时,书中谈到C语言的声明问题,《C专家编程》这本书只有两百多页,却花了一章的内容去阐述这个问题,足以看出这个问题的重要性,要想透彻理解C语言的声明问题仅仅看书是远远不够的,需要平时多实践并大量阅读别人写的代码。下面借鉴《C专家编程》书中的两个例子来说说这个问题,以下很多内容是摘自《C专家编程》的第55页-79页。
在C语言中,声明的形式和使用的形式相似,这种用法可能是C语言的独创,K & R也承认"C语言声明的语法有时候会带来严重的问题"。C语言的声明存在的最大问题是你无法以一种人们所习惯的自然方式从左到右阅读一个声明。下面看一个例子:
char * const *(*next)();
如果在第一眼就能看出这个声明要表达的意思,那么证明你的C语言功底已经到了一定的程度。《C专家编程》一书中给出的识别步骤为:
1)从变量名next开始,并注意到它直接被括号括住;
2)所以先把括号里的东西作为一个整体,得出"next”是一个指向....的指针;
3)然后考虑括号外面的东西,在星号前缀和括号后缀之间做一个选择;
4)根据C语言声明的优先级规则(后面会给出),优先级较高的是右边的函数括号,所以得出"next"是一个函数指针,指向一个返回...的函数;
5)然后,,处理前缀"*",得出指针所指的内容;
6)最后,把"char * const *"解释为指向字符串的常量指针。
把上述结果加以概括,这个声明表示"next是一个指针,它指向一个函数,这个函数返回另一个指针,该指针指向一个类型为char的常量指针"。这个问题便迎刃而解了.
下面再看一个例子:
char *(* c[10])(int **p);
首先,从变量名c开始,然后处理后缀"[]",表明c是一个数组,接着处理前缀"*",表示c是一个指针数组。然后处理后面的括号,表明数组c中的指针类型是指向一个函数的指针,并且这个函数的参数有且仅有一个:为指向指针的指针,该函数的返回值为一个指向字符串的指针。归纳在一起,为:
"c是一个数组[0...9],它的元素类型是函数指针,其所指向的函数返回值是一个指向字符串的指针,并且把一个指向指针的指针作为唯一的参数"。
以下是《C专家编程》一书中提到的C语言声明的优先级规则,摘自第64页。