C++变量判定的螺旋法则示例详解
前言
C++ 中一个标识符配合着各种修饰界定符,使得标识符的本意不那么直观一眼就能看出,甚至需要仔细分析,才能知道该标识符的具体你含义。
比如:
void (*signal(int, void (*fp)(int)))(int);
其中 signal 是什么?
螺旋法则
对于如何进行变量的辩识,有个非官方的 “顺时针/螺旋法则(Clockwise/Spiral Rule)” 可用来帮助辩识。
该法则的内容,简单来说,为了搞清楚一个未知标识符的含义,我们可以:
1、从我们需要判定的标识符开始,顺时针画圈,遇到如下符号时,用对应的语义替换:
- [x] 或 [] => 容量为 x 的数组或数组
- (type1,type2...) => 接收 type1、type2... 的函数,返回值为(待定)
- * => 指向(类型待定)的指针
2、重复上面的步骤直到语句中所有符号都被遍历过。
3、始终优先解析括号括起来的部分。
实地演练
一个简单的示例
先从一个简单的开始,判定如下语句中 str 的含义:
+-------+
| +-+ |
| ^ | |
char *str[10];
^ ^ | |
| +---+ |
+-----------+
根据螺旋法则,如上面线图标识所示,
- 从 str 这个需要被判定的对象出发。
- 螺旋路径上第一次遇到的是 [ 左方括号,由此我们知道,str 是一个尺寸为 10 的数组。
- 继续旋转,遇到 *,所以 str 是一个尺寸为 10 的数组,数组元素为指针。
- 继续,遇到 ; 标识语句的结束。
- 再继续,遇到 char,所以 str 是一个尺寸为 10 的数组,数组元素为指向 char 类型的指针。
进阶
回到文章开头那个语句,来判定其中 signal 的含义。
+-----------------------------+
| +---+ |
| +---+ |+-+| |
| ^ | |^ || |
void (*signal(int, void (*fp)(int)))(int);
^ ^ | ^ ^ || |
| +------+ | +--+| |
| +--------+ |
+----------------------------------+
由螺旋法则画出如上的线图,进而可分析:
从要判定的 signal 出发首次遇到 ( 左括号,表示 signal 是一个函数,入参为 int 和 ...
此处需要需要进一步运用螺旋法则先确定 fp 的含义,才能进而确认 signal 这个函数的完整入参。所以从 fp 了发进行一次子螺旋。
因为需要优先解析括号括起来的部分,所以转一圈回来首次遇到的是 *,由此 fp 是一个指针。
继续解析 fp,遇到 (,所以 fp 是一个指向函数的指针,这个函数接收一个 int 类型的入参。
继续下去,遇到 void,所以 fp 是一个指向函数的指针,这个函数接收一个 int 类型的入参并且返回值为空。
至此完成了 fp 的解析,可以知道 signal 的类型为:
- 是一个函数,入参为:
- 一个 int 类型
- 一个指向函数的指针,这个函数接收一个 int 类型的入参并且返回值为空
路径跑到 signal 的螺旋中,遇到 *(紧邻 signal 左边),所以 signal 是
- 一个函数,入参为:
- 一个 int 类型
- 一个指向函数的指针,这个函数接收一个 int 类型的入参并且返回值为空
- 返回值为指针
再继续,遇到 (,接上面,返回值为指向另一函数的指针,被指向的这个函数接收一个 int 入参。
最后,遇到 void,signal 返回值指向的这个函数的返回值为空。
最后捋一下 signal 的完整类型为:接收一个 int,一个指向接收一个 int 并且返回值为空的函数的指针,这两个参数的函数,并且返回值为指向一个接收 int 型返回为空的函数...Orz。
成员函数的判定
螺旋施法没有给出在 const 参与的情况下的判定,不过因为 const 默认修饰紧邻其左边的元素,如果右边无元素,则修饰左边的元素。因此只需要将 const 和它修饰的元素作为整体来看,就还是可以使用螺旋法则的。
考察如下语句:
const int*const Method3(const int*const&) const;
当函数后面紧跟一个 const 时,表示该成员函数的作用域内 *this 是常量,即无法在该函数体内对所类的实体进行修改。
下面对上面的语句进行分析:
- 从 Method3 出发,遇到 (,所以 Method3 是一个函数,接收一个引用作为入参 const int*const& 部分。
- 该引用的类型是 const int*const,指向整形常量的常量指针。
- 继续遇到 *const,所以函数的返回值为常量指针。指针指向的类型为 const int 整形常量。
- 函数末尾的 const 如前所述,标识函数体内不修改实例。
相关资源
总结
以上就是我在处理客户端真实IP的方法,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。
- 斯坦福吴恩达团队公布最大医学影像数据集
- Rokid祝明铭:大腿我们不抱,人机交互产品形态未定 | 变局者
- 腾讯AI让二子,柯洁还是输了
- AI创业者的“英雄联盟”,腾讯AI加速器二期项目招募开启
- PyTorch发布一周年:盘点社区和工程大事件,后来者居上态势已显?
- 2018年AI如何发展?普华永道做出了8点预测 | 报告下载
- 不正之风!机器学习论文里都有哪四大投机取巧的写作手法?
- 前端写一个月的原生 Android 是怎样一种体验?
- 给人挖矿还不自知 电脑已变黑客肉鸡
- 反序列化漏洞屡被黑客利用,危害巨大,代码怎样写才安全?
- Mifa 主题微信编辑器
- Mifa GitHub Pages 主题
- Mifa Design:一个服务于 Markdown 的设计体系
- 未来机器人大脑将获取互联网知识自我学习
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Jenkins常用插件Copy Artifact的使用
- 聊聊dubbo-go的roundRobinLoadBalance
- 腾讯云录音文件识别请求和结果查询
- 【Kubernetes】kubectl top 如何使用
- js数组方法,常用数组Api的基本使用
- java jsp实现网络考试系统(mysql)
- 实操:数据万象语音转文字
- python智能图片识别系统(图片切割、图片识别、区别标识)
- 【Kubernetes】部署 metrics-server 后无法使用 top 命令
- 使用java计算数组方差和标准差
- jzy3D从入门到弃坑_2 使用jzy3D0.9画2D散点图
- jzy3D从入门到弃坑_3 使用jzy3D0.9画2D散点图--多条线条
- maven安装和应用
- 论文研读-多目标自适应memetic算法
- 一起来学matlab-matlab学习笔记13函数 13_1 函数返回值