参考:《C专家编程》
C语言声明解读优先级规则
- 从最左边的标识符(名字)开始,然后按优先级顺序读取
- 优先级从高到低依次是:
a. 声明中被括号括起来的部分
b. 后缀操作符:()表示这是一个函数,[]表示这是一个数组
c. 前缀操作符:*表示指向xx的指针 - 如果const和(或)volatile后面紧跟类型说明符(如int,long等),那么它作用于类型说明符(即作用右边);其他情况下,const和(或)volatile作用于它左边紧邻的指针星号
规则是参考《C专家编程》,下面实例的解析来自我个人,有问题请指正。
简单举例
int *f();
// 从f开始,因为()优先级高于*,所以f是一个函数,返回int指针
int (*f)();
// 从f开始,因为和*被括起来了,所以f首先是一个指针。然后是一对括号,表示这个指针指向一个函数
// 这个函数要返回一个int值。因此,f是一个函数指针
int *(*f)();
// 类似上面,f是函数指针,但是这次的返回值是一个指向int的指针
int *f[];
// []比*的优先级高,所以f首先是一个数组,然后到*,表示数组的元素是指向int的指针
int (*f[])();
// []比*的优先级高,所以f首先是一个数组,它的元素的类型是指针;其次是(),表示这些
// 指针是指向返回int的函数。总结: f是一个数组,其元素类型是函数指针,它指向的函数返回值是int
int *(*f[])();
// 从f开始,先结合[],所以f是数组。然后是f左侧的*,表示f的元素的类型是指针。随后是()的优先级高于
// 最左侧的*,所以f的元素类型是函数指针,它指向的函数返回指向int的指针
复杂举例
char * const *(*next)();
从左往右第一个变量名是next,next左侧的*表示这是一个指针;
(*next)作为一个整体来看,先结合右侧的(),表示这是一个函数,因此next是一个指向函数的指针;
随后是(*next)左侧的*,表示next指向的函数,返回的是一个指针;
再看const,根据第3条,要结合左侧的指针,因此这个函数返回的指针,指向的是一个类型为char的常量指针
(常量指针就是指向的变量不能变,但是变量本身的值可以变)
总结就是:
next是一个指针,它指向一个函数,该函数返回另一个指针,这个指针指向一个类型为char的常量指针
char *(* c[10])(int **p);
从左往右第一个变量名是c,所以从c开始;
[]的优先级高于*,所以c是一个数组,但是数组元素都是指针;
由于括号出现,因此把(* c[10])看成一个整体,左侧的*优先级低于右侧的括号,所以先结合括号;
因此c[10]的元素的类型是函数指针,它们指向的函数的参数是int **p,返回值是char *。