最近几天在看K&R的《c程序设计语言》,看似薄薄的一本书,感觉要完全读下来(包括习题)还要下很大的功夫啊,今天看到第5章指针与数组中5.12节的复杂声明,文中给了一个示例程序来说明如何正确分析c语言的声明,比如说:
char (*(*x[3])())[5];
x: array[3] of pointer to function returning
pointer to array[5] of char.
第一行是一个声明,下面两行是对这个声明进行分析之后的解释,在给出整个示例程序之前,书中给出了一个简单的分析声明的语法形式并引用了附录作为参考。我翻来覆去看了几遍这个语法形式,还是没有搞懂怎么回事,但是我想起另一本c的经典书《c专家编程》有一章是专门讲如何分析c声明的语法的,于是我找来那本书看了一下,发现还是《c专家编程》讲的娓娓道来,通俗易懂啊。
下面我就结合自己的经验说明一下如何简单的分析c语言的声明:
第0步:沉着冷静,不要被多重嵌套的括号吓到(这个步骤熟练后可以省略:))
第1步:从左至右,找到第一个标识符。
第2步:查看标识符右边的符号,并确定是一个数组还是函数。
第3步:查看左边的符号。
第3步a:如果是左括号则将处理过的部分结合到一起直到遇到右括号作为标识符返回第2步。
第3步b:如果是const,volatile,*其中之一则继续向左直到不是这三个符号之一。
第4步:剩下的符号构成声明的基本类型。
我估计很多人已经头晕了,不知道上面什么意思,下面我结合上面的那个例子说明一下:
第1步:从左至右找到第一个标识符,那就是x。
第2步:查看标识符右边的符号是'[',所以x是一个具有3个元素的数组。
第3步:查看左边的符号,是'*',转至第3步b。
第3步b:说明数组中的元素都是指针,向左是左括号了,将这个左括号结合到对应的右括号(也就是(*x[3]))作为新的标识符返回第2步。
第2步:查看右边的符号是'(',说明指针是指向参数列表为空的函数的指针。
第3步:查看左边的符号,是'*', 转至第3步b。
第3步b:说明函数的返回值是指针,向左是左括号,将这个左括号结合到对应的右括号(也就是(*(*x[3])()))作为新的标识符返回第2步。
第2步:查看右边的符号是'[',所以是指向具有五个元素的数组的指针。
第3步:查看左边的括号,既不是a情况,也不是b情况,跳至第4步。
第4步:数组的类型为char。
所以以上的声明表示的是x是一个具有3个元素的数组,数组的每个元素都是一个指向函数的指针,函数的参数列表为空,返回值是指向一个具有5个元素的指针,元素的类型为char。
下面有两道习题,都是来自《c专家编程》的例子,答案在书中有,这里就不给出了:
char* const *(*next)();
char *(* c[10])(int **p);