参诸文籍, 带你深入理解C/C++复杂指针声明
本文参考的相关文章已置于页脚
文章目录
一. 引言
大家是不是曾经遇到像int * (* (*fp1) (int) ) [10];
一样的复杂指针声明? 是不是看着这种声明表达式就头晕? 本文将结合C/C++运算符优先级
和右左原则
(即, The Right-Left Rule)引导你逐步理解C/C++的复杂指针声明.
Note:本文参考的相关文章已在页脚放出, 部分文章为英文版本.
二. C/C++ 运算符优先级
Note:此处仅展示本文可能涉及的运算符, 完整内容请参考微软文档 - C++ 内置运算符、优先级和关联性
- 指针声明:int *。
- 取址运算符:&。
- 间接访问运算符:*。
- 其他运算符: []、()。
- 这些运算符的优先级按照从高到低的顺序依次为:[] () * &
三. 简单表达式
int *p;
int **pp;
int *(*pp); // 等效于第二行, 因为*这种一元运算符本就是从右至左的结合顺序.
一. int *p;
*
为一元操作符
, 作用是声明一个指针.这个语句声明p是一个指向int类型的指针
, 有个问题需要弄清楚?是那一部分把p变成指针的呢?
- 是
int *
这个整体? - 是
*
?
答案是*
, *
会先和p
结合, 声明p
是一个指针, 至于p
指针指向的是什么类型的数据呢?由int
指定.我们在分析时一定要注意这一点, 还不懂的话, 稍后讲解右左原则时,会详细讲解.
二. int **pp;
因为类似于 *
和++
这样的一元运算符遵循从右至左的结合顺序(所以, int *(*pp);
的效果与int **pp;
一样), 所以int **pp;
可以这样理解.
-
- 右侧第一个
*
先与pp结合, 代表pp是一个指针.
- 右侧第一个
-
- 现在已经知道pp是一个指针了, 由于从右至左的结合顺序, 接下来右侧第二个
*
将代表p
指针所指向的类型, 即一个指针
, 那么这个pp指针所指向的指针指向的是什么类型呢?我们看到前面有个int
, 那就是pp
是一个指向指向int类型的指针的指针
, 我知道你可能有点头晕, 但你先别晕.
- 现在已经知道pp是一个指针了, 由于从右至左的结合顺序, 接下来右侧第二个
四. 解读 C 声明的“右左”规则[重要]
(一)、符号含义
*
:表示“指向……的指针”,且始终位于左侧。[]
:表示“……的数组”,始终位于右侧。()
:表示“返回……的函数”,始终位于右侧。
(二)、解读步骤
步骤 1
找到标识符,此为起始点。然后在心里默念“标识符是”,开始构建声明语句。
步骤 2
- 观察标识符右侧的符号。
- 若发现“()”,则知道这是一个函数的声明,此时表述为“标识符是函数返回……”。
- 若发现“[]”,则表述为“标识符是……的数组”。
- 持续向右侧推进,直到没有符号或者遇到右括号“)”。若遇到左括号,即使括号中间有东西,也视为“()”符号的开始部分。
步骤 3
- 观察标识符左侧的符号。
- 如果不是特殊符号(如上述提到的
*
、[]
、()
),直接表述出来。 - 如果是特殊符号,则按照符号含义表翻译为对应的英文表述。
- 如果不是特殊符号(如上述提到的
- 持续向左侧推进,直到没有符号或者遇到左括号“(”。
(三)、示例
(1)int *p[];
示例
- 找到标识符“p”,此时表述为“p 是”。
- 向右侧移动,遇到“[]”,变为“p 是数组的”。
- 向左侧移动,遇到“*”,变为“p 是数组的指针指向”。
- 继续向左侧移动,完成最终表述“p 是数组的指针指向 int”(或者表述为“p 是一个数组,其中每个元素的类型是指向 int 的指针”)。
(2)int *(*func())();
示例
- 找到标识符“func”,表述为“func 是”。
- 向右侧移动,遇到“()`,变为“func 是函数返回”。
- 向左侧移动,遇到“*”,变为“func 是函数返回指针指向”。
- 再次向右侧移动,变为“func 是函数返回指针指向函数返回”。
- 再次向左侧移动,变为“func 是函数返回指针指向函数返回指针指向”。
- 最后向左侧移动,完成最终表述“func 是函数返回指针指向函数返回指针指向 int”。
(3)int (*(*fun_one)(char *,double))[9][20];
示例
按照规则解读为“fun_one 是指针指向函数(该函数接收(char *,double)参数并返回指针指向大小为 9 的数组的大小为 20 的 int 数组)”。
Allright, 你应该已经知道怎么理解这些复杂指针声明了!请您老给个三连吧!!!
五. 相关文章
《理解C语言中指针的声明以及复杂声明的语法》
ByTimeShatter
(CSDN)《The "Right-Left" Rule》
ByRick Ord
《How to interpret complex C/C++ declarations》
By
Vikram A Punathambekar