对于 char * const *(*next)();
这种数据类型分析起来特别麻烦,在这里先捋一下
# 规则
A. 声明先从名字开始读取,然后按照优先级顺序依次读取.
B. 优先级从高到低:
- 声明中被括号括起来的部分
- 后缀操作符:
fun()
中的()
代表是一个函数;arr[]
的[]
表示这是一个数组
- 前缀:
*ptr
表示 "指向 xx 的指针"
C. 如果使用 const
或 volatile
, 紧跟类型说明符,则作用于类型说明符号;其他情况下作用于左边紧邻的 *
号
# 例子
举个例子 char * const *(*next)();
适用规则:
- A: 变量名位
next
, 且被()
运算符包含 - B1: 变量名被
()
括号内部是(*arr)
代表其是指针 - B: 在
*
和()
之间决定 - B2: B2 规则告诉我们优先级较高的是
()
, 所以 得出next
和()
先结合是一个指向函数的指针,所以得出 "next 是一个函数指针,指向返回... 的函数" - B3: 处理
*
, 得出指针内容 - C:
char * const
,const
右边没有跟随类型符,所以解释为 "指向字符串的常量指针", 指针不可改变
综上,next 是 "一个指针,指向一个函数,该函数的返回一个指针,返回的指针为一个指向 char 型数据类型的常量指针"
下图是 C 语言函数定义的规则图解
# 表格化
上面的方式只能说是逻辑化,看上去还是不够清晰。我打算按着编译原理的角度结合上面图来列一个表格,按着上面的规则,就列一个表就可以推断出结果.
声明字符串 | 采取的步骤 | 结果 |
---|---|---|
char * const *(*next)(); | 1 | 表示 next是... |
char * const *(* )(); | 2,3 | 不匹配,转到下一步。表示 next是... |
char * const *(* )(); | 4 | 不匹配,转到下一步. |
char * const *(* )(); | 5 | 与 * 号匹配。表示 指向...的指针 |
char * const *( )(); | 4 | "(" ")" 匹配,转到第 2 步 |
char * const * (); | 2 | 不匹配,转到下一步 |
char * const * (); | 3 | 表示 返回...的函数 |
char * const * ; | 4 | 不匹配,转到下一步 |
char * const * ; | 5 | 表示 指向..的指针 |
char * const ; | 5 | 表示 只读的... |
char * ; | 5 | 表示 指向...的指针 |
char ; | 6 | 表示 char |
大道五十,天衍四十九,人遁其一!