理解C语言声明的优先级规则

时间:2022-02-09 22:19:01

C语言的声明有时会很长,让人感到恐惧。这里描述了一种方法,用通俗的语言把声明分解开来,分别解释各个组成部分。

理解C语言声明的优先级规则的步骤

  1. 声明从它的名字开始读起,然后按照优先级顺序依次读取。

  2. 优先级从高到低依次是:

    • 声明中被括号括起来的那部分

    • 后缀操作符:
      括号()表示这是一个函数,
      方括号[]表示这是一个数组

    • 前缀操作符:星号*表示“指向…的指针”

  3. 如果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

参考:

  1. 《The C Programming Language中文版(第2版.新版)》
  2. 《C专家编程》
  3. dcl工具