参诸文籍, 带你深入理解C/C++复杂指针声明

参诸文籍, 带你深入理解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;可以这样理解.

    1. 右侧第一个*先与pp结合, 代表pp是一个指针.
    1. 现在已经知道pp是一个指针了, 由于从右至左的结合顺序, 接下来右侧第二个*将代表p指针所指向的类型, 即一个指针, 那么这个pp指针所指向的指针指向的是什么类型呢?我们看到前面有个int, 那就是pp一个指向指向int类型的指针的指针, 我知道你可能有点头晕, 但你先别晕.

四. 解读 C 声明的“右左”规则[重要]

(一)、符号含义

  • *:表示“指向……的指针”,且始终位于左侧。
  • []:表示“……的数组”,始终位于右侧。
  • ():表示“返回……的函数”,始终位于右侧。

(二)、解读步骤

步骤 1

找到标识符,此为起始点。然后在心里默念“标识符是”,开始构建声明语句。

步骤 2
  1. 观察标识符右侧的符号。
    • 若发现“()”,则知道这是一个函数的声明,此时表述为“标识符是函数返回……”。
    • 若发现“[]”,则表述为“标识符是……的数组”。
  2. 持续向右侧推进,直到没有符号或者遇到右括号“)”。若遇到左括号,即使括号中间有东西,也视为“()”符号的开始部分。
步骤 3
  1. 观察标识符左侧的符号。
    • 如果不是特殊符号(如上述提到的*[]()),直接表述出来。
    • 如果是特殊符号,则按照符号含义表翻译为对应的英文表述。
  2. 持续向左侧推进,直到没有符号或者遇到左括号“(”。

(三)、示例

(1)int *p[];示例
  1. 找到标识符“p”,此时表述为“p 是”。
  2. 向右侧移动,遇到“[]”,变为“p 是数组的”。
  3. 向左侧移动,遇到“*”,变为“p 是数组的指针指向”。
  4. 继续向左侧移动,完成最终表述“p 是数组的指针指向 int”(或者表述为“p 是一个数组,其中每个元素的类型是指向 int 的指针”)。
(2)int *(*func())();示例
  1. 找到标识符“func”,表述为“func 是”。
  2. 向右侧移动,遇到“()`,变为“func 是函数返回”。
  3. 向左侧移动,遇到“*”,变为“func 是函数返回指针指向”。
  4. 再次向右侧移动,变为“func 是函数返回指针指向函数返回”。
  5. 再次向左侧移动,变为“func 是函数返回指针指向函数返回指针指向”。
  6. 最后向左侧移动,完成最终表述“func 是函数返回指针指向函数返回指针指向 int”。
(3)int (*(*fun_one)(char *,double))[9][20];示例

按照规则解读为“fun_one 是指针指向函数(该函数接收(char *,double)参数并返回指针指向大小为 9 的数组的大小为 20 的 int 数组)”。

Allright, 你应该已经知道怎么理解这些复杂指针声明了!请您老给个三连吧!!!

在这里插入图片描述

五. 相关文章

  • 《理解C语言中指针的声明以及复杂声明的语法》By TimeShatter (CSDN)
  • 《The "Right-Left" Rule》By Rick Ord
  • 《How to interpret complex C/C++ declarations》By
    Vikram A Punathambekar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值