C++ 中一个标识符配合着各种修饰界定符,使得标识符的本意不那么直观一眼就能看出,甚至需要仔细分析,才能知道该标识符的具体你含义。

比如:

void (*signal(int, void (*fp)(int)))(int);

其中 signal 是什么?

螺旋法则

对于如何进行变量的辩识,有个非官方的 “顺时针/螺旋法则(Clockwise/Spiral Rule)” 可用来帮助辩识。

该法则的内容,简单来说,为了搞清楚一个未知标识符的含义,我们可以:

  1. 从我们需要判定的标识符开始,顺时针画圈,遇到如下符号时,用对应的语义替换:
  • [x][] => 容量为 x 的数组或数组
  • (type1,type2...) => 接收 type1type2... 的函数,返回值为(待定)
  • * => 指向(类型待定)的指针
  1. 重复上面的步骤直到语句中所有符号都被遍历过。
  2. 始终优先解析括号括起来的部分。

实地演练

一个简单的示例

先从一个简单的开始,判定如下语句中 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 入参。
  • 最后,遇到 voidsignal 返回值指向的这个函数的返回值为空。

最后捋一下 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 如前所述,标识函数体内不修改实例。

相关资源

C++ 变量判定的螺旋法则的更多相关文章

  1. Python的程序结构[3] -> 变量/Variable[1] -> LEGB 法则

    LEGB法则 / LEGB Rule LEGB 变量搜索顺序 ---- 来源于<Python学习手册>/ Learning Python Page 419 ---- Python 的变量名 ...

  2. JavaScript 基础——使用js的三种方式,js中的变量,js中的输出语句,js中的运算符;js中的分支结构

    JavaScript 1.是什么:基于浏览器 基于(面向)对象 事件驱动 脚本语言 2.作用:表单验证,减轻服务器压力 添加野面动画效果 动态更改页面内容 Ajax网络请求 () 3.组成部分:ECM ...

  3. Python学习之变量的作用域

    学习地址:http://www.jianshu.com/p/17a9d8584530 1.变量作用域LEGB 1.1变量的作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空 ...

  4. Python基本语法_变量作用域LEGB

    目录 目录 软件系统 变量的作用域 高级语言对数据类型的使用过程 作用域的产生 作用域的类型 Llocal局部作用域 Eenclosing嵌套作用域 Gglobal全局作用域 Bbuilt-in内置作 ...

  5. 17.3.20---python的变量作用域

    1---变量的作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域.Python的作用域是静态的,在源代码中变量名被赋值的位置决 ...

  6. 如何阅读复杂的C类型声明

    阅读复杂的C类型声明,通常采用右左法则,也就是Clockwise/Spiral Rule (顺时针/螺旋法则). 本文将首先介绍工具(cdecl)(个人比较偏好使用工具提高学习和工作效率),然后中英文 ...

  7. OPEN CASCADE Multiple Variable Function

    OPEN CASCADE Multiple Variable Function eryar@163.com Abstract. Multiple variable function with grad ...

  8. ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave由于鼠标移动速度过快导致问题解决办法

    记录两个项目开发中遇到的问题,一个是ECharts外部调用保存为图片操作,一个是workflow工作流连接曲线onmouseenter和onmouseleave事件由于鼠标移动过快触发问题. 一.外部 ...

  9. java编程基础知识及常见例题

    ⒈标识符: 只能包含数字.字母.下划线.$,并且不能以数字开头.语义直观规范 驼峰法则: 如:方法名.变量名采用驼峰法则 帕斯卡命名法: 如: 类.接口.枚举采用帕斯卡命名法包名:网址倒写,com.网 ...

随机推荐

  1. idea实现第一个springboot程序

    1.环境准备 JDK:1.8 Apache Maven: 3.6.1 IntelliJ IDEA 2019.1.3 x64 SpringBoot 1.5.9.RELEASE:1.5.9: 1.1.MA ...

  2. 从 View 的四个构造方法说起

    View 类的四个构造函数 写过自定义 View 的都知道,View 有四个构造函数,一般大家都知道第一个构造方法是简单的在代码中new View 的时候调用的,第二个构造方法使用最广泛,是对应的生成 ...

  3. Codeforces 1009E

    题意略. 思路: 比如现在n = 11.那么我们观察a[1.....n]的出现次数: a[1]:2 ^ 10 + 10 * 2 ^ 9 a[2]:2 ^ 9 + 9 * 2 ^ 8 a[3]:2 ^ ...

  4. 栅格数据的批量镶嵌(附Python脚本)

    栅格数据的批量镶嵌(附Python脚本) 博客小序:在数据处理的过程中,会遇到需要大量镶嵌的情况,当数据较多时手动镶嵌较为麻烦,自己最近对分省的DEM数据进行镶嵌,由于利用python进行镶嵌较为方便 ...

  5. Oracle在VMware虚拟机安装的配置

    我是在VMware虚拟机上安装的Oracle , 我只说说我踩过的几个坑吧. VMware的虚拟网络编辑器 仅主机模式相当于在你的主机和虚拟机之间建立了一个局域网,里面只有你的主机和虚拟机 可以通过D ...

  6. SCRUM术语

    http://www.scrumcn.com/agile/scrum-knowledge-library/scrum.html#tab-id-2 Scrum: Scrum无对应中文翻译 Agile: ...

  7. Educational Codeforces Round 48 D Vasya And The Matrix

    EDU #48 D 题意:给定一个矩阵,已知每一行和每一列上数字的异或和,问矩阵上的数字是多少,不存在则输出NO. 思路:构造题,可以考虑只填最后一行,和最后一列,其中(n,m)要特判一下.其他格子给 ...

  8. CodeForces 988 F Rain and Umbrellas

    Rain and Umbrellas 题意:某同学从x=0的点走到x=a的点,路上有几段路程是下雨的, 如果他需要经过这几段下雨的路程, 需要手上有伞, 每一把伞有一个重量, 求走到重点重量×路程的最 ...

  9. 高可用的K8S集群部署方案

    涉及到的内容 LVS HAProxy Harbor etcd Kubernetes (Master Worker) 整体拓补图 以上是最小生产可用的整体拓补图(相关节点根据需要进行增加,但不能减少) ...

  10. Erlcron分析学习

    介绍 Erlcron实现类似Linux下面的cron的计划任务. 源码下载地址:https://github.com/erlware/erlcron 原理 Erlcron进程监控树 ecrn_cron ...