C语言的声明有时会很长,让人感到恐惧。这里描述了一种方法,用通俗的语言把声明分解开来,分别解释各个组成部分。
理解C语言声明的优先级规则的步骤
声明从它的名字开始读起,然后按照优先级顺序依次读取。
-
优先级从高到低依次是:
声明中被括号括起来的那部分
后缀操作符:
括号()表示这是一个函数,
方括号[]表示这是一个数组前缀操作符:星号*表示“指向…的指针”
如果const和(或)volatile关键字的后面紧跟类型说明符(如int,long等),那么它作用于类型说明符。在其他的情况下,const和(或)volatile关键字作用于它左边紧邻的指针星号。
例子1: char const (*next)();
适用规则 | 解释说明 |
---|---|
1 | 从变量名开始,next是… |
2.1 | 在把(*next) 作为一个整体,得出next是指向…的指针 |
2.2 | 读后缀(),得出是个函数,这个函数不带参数,所以next是指向函数的指针 |
2.3 | 读(*next) 前面的*,得出这个函数返回值是个指针 |
3 | 读char *const部分,const修饰的是指针,这是个指向char类型的常指针 |
连接在一起就是,next是一个指针,它指向一个函数,这个函数不带参数,它返回另外一个指针,这个指针指向char类型的常量指针。
例子2:char ( c[10])(int **p)
适用规则 | 解释说明 |
---|---|
1 | 从变量c开始 |
2.1 | 把(* c[10])作为一个整体 |
2.2 | 在这个整体里,读到[],所以c是一个包含10个元素的数组 |
2.3 | 数组的每个元素是个指针 |
2.2 | 读(int **p)的部分,这是个函数,参数是指向int的指针的指针 |
2.3 | 这个函数返回的是个指向char类型的指针 |
所以连接在一起就是,c是一个包含10个元素的数组,数组中的每个元素是个指向函数指针,该函数的声明是这样的,参数是指向int的指针的指针,返回值是指向char类型的指针。
例子3:void (*signal(int sig, void (*func)(int)))(int);
适用规则 | 解释说明 |
---|---|
1 | 先读void (*signal(…))(int),针对这部分,先从signal开始 |
2.1 | 把(*signal(…))当作一个整体 |
2.2 | signal是个函数 |
2.3 | 读signal前面的*,得出signal这个函数返回一个指针,该指针是指向函数的指针,函数原型是void f(int) |
在读(int sig, void (*func)(int))部分,这部分是signal的参数 |
所以连接在一起就是,signal是个函数,该函数带2个参数,int和一个函数的指针,该指针所指向的函数原型是void f(int)。signal这个函数的返回为函数的指针,该指针所指向的函数原型也是void f(int)。
虽然这样简洁,但是可读性太差。我们可以借助typedef来实现与上面声明等价的声明。
typedef void (*ptr_to_func) (int);
ptr_to_func signal(int, ptr_to_func);
ptr_to_func是一个函数指针,该函数接受int参数,返回值为void。signal是个函数,接受int和一个函数指针作为参数,返回值为ptr_to_func函数指针。
例子4: char (*(*x())[])()
适用规则 | 解释说明 |
---|---|
1 | 先把(*x())当成一个整体 |
2.2 | x是个函数 |
2.3 | 该函数返回一个指针 |
把已经处理的部分拿掉,换个新名称xx,得到char (*xx[])()` | |
2.2 | xx是个数组 |
2.3 | 数组的每个元素是个指针,该指针指向函数,函数的原型是 char f() |
所以连接在一起就是, x是个函数,函数返回一个指针,指针指向数组,数组的每个元素是个函数的指针,函数的原型是char f()。
《The C Programming Language》第5.12章有写一个dcl工具,它将C语言的声明转换为文字描述。源码我已经整理到我的github,在linux上执行下面的命令即可测试:
git clone git@github.com:rexnie/usefulC.git
cd src/tcpl/ch5/5-18
make
即可在当前目录下生成a.out, 执行该文件,得到:
./a.out
char (*(*x())[])()
x: function returning pointer to array[] of pointer to function returning char
参考:
- 《The C Programming Language中文版(第2版.新版)》
- 《C专家编程》
- dcl工具