对于 char * const *(*next)(); 这种数据类型分析起来特别麻烦,在这里先捋一下

# 规则

A. 声明先从名字开始读取,然后按照优先级顺序依次读取.
B. 优先级从高到低:

  1. 声明中被括号括起来的部分
  2. 后缀操作符:
    • fun() 中的 () 代表是一个函数;
    • arr[][] 表示这是一个数组
  3. 前缀: *ptr 表示 "指向 xx 的指针"

C. 如果使用 constvolatile , 紧跟类型说明符,则作用于类型说明符号;其他情况下作用于左边紧邻的 *

# 例子

举个例子 char * const *(*next)();
适用规则:

  1. A: 变量名位 next , 且被 () 运算符包含
  2. B1: 变量名被 () 括号内部是 (*arr) 代表其是指针
  3. B: 在 *() 之间决定
  4. B2: B2 规则告诉我们优先级较高的是 () , 所以 得出 next() 先结合是一个指向函数的指针,所以得出 "next 是一个函数指针,指向返回... 的函数"
  5. B3: 处理 * , 得出指针内容
  6. C: char * const , const 右边没有跟随类型符,所以解释为 "指向字符串的常量指针", 指针不可改变

综上,next 是 "一个指针,指向一个函数,该函数的返回一个指针,返回的指针为一个指向 char 型数据类型的常量指针"
下图是 C 语言函数定义的规则图解
图示_源于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

大道五十,天衍四十九,人遁其一!