C/C++ 中的变量声明解读
复杂的 C/C++ 声明, 你只需要使用一条规则:
理解 C 语言声明的优先级:
A 声明从它的名字开始读取, 然后按照优先级顺序依次读取.
B 优先级从高到低依次是:
B. 1 声明中被括号括起来的那部分
B. 2 后缀操作符:
括号 () 表示这是一个函数, 而
方括号表示这是一个数组
B. 3 前缀操作符: 星号 * 表示 "指向 ... 的指针".
C 如果 const 和 (或) volatile 关键字的后面紧跟类型说明符 (如 int, long 等), 那么它作用 于类型说明符. 在其他情况下, const 和 (或) volatile 关键字作用于它左边紧邻的指针星号.
char * const *(*next)() ; // next 是一个指针, 这个指针指向一个无参的函数, 这个函数返回一个常指针, 这个常指针指向另一个 char *.
B. 2 和 B. 3 必会交替执行, 因为 C/C++ 中不能出现 var()[] 或 var[]() 或 var()(), 因此分析完一个标识符后的 ( 或 [ 时, 都会转向左边去寻找星号 *, 只有一种情况特例, 就是多维数组, 如: int *arr[10][10] ; 这种情况需要在标识符后面一直寻找中括号, 直到找完为止. 详情参见 C 语言语法所不能
对于上述 C 条件, 我个人有些补充:
如果 const 或 volatile 紧邻类型说明符, 则其修饰的就是类型说明符. 否则, const 紧邻星号 *, 则其修饰的是指针本身.
总结来说, 就是 const 是左结合的, 仅当 const 左边没有可修饰的符号时才进行右结合. 因为要考虑到如下情况:
int const *p ; // 此时在类型说明符 (int) 在 const 的前面, 所以是 (int const) *p, 即常指针. 等同于 int const *p ;
说的直白一些就是先找到标识符, 然后往右看, 直到看到 ')' 为止, 然后向左走, 跳过已读过的符号, 直到看到前面开括号对应的 '(' 为止. 我一直是这么做的. 例如:
10 9 8 7 3 1 2 6 5 4
char * const *(*next[10])(int const x) ;
- next 是一个标识符
- 这个标识符是一个是个元素的数组
- 这个数组存放的是指针, 这些指针指向函数
- 所指向的函数含有一个参数 x
- 这个参数是常量变量
- 这个参数类型是 int 型
- 这个函数返回一个指针
- 这个指针指向另一个指针
- 被指向的指针是指针常量
- 这个指针常量指向一个 char 型变量