C++变量判定的螺旋法则示例详解

 更新时间:2019年09月26日 08:24:02   作者:刘哇勇  
这篇文章主要给大家介绍了关于C++变量判定的螺旋法则,文中通过示例代码介绍的非常详细,对大家学习或者使用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的方法,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

相关文章

  • C语言之选择分支语句详解

    C语言之选择分支语句详解

    大家好,本篇文章主要讲的是C语言之选择分支语句详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • 详解编译器编译原理

    详解编译器编译原理

    这篇文章主要介绍了详解编译器编译原理的相关资料,需要的朋友可以参考下
    2017-06-06
  • C语言学籍管理系统源代码

    C语言学籍管理系统源代码

    这篇文章主要为大家详细介绍了C语言学籍管理系统源代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • 详解C++中普通旧数据(POD)的使用

    详解C++中普通旧数据(POD)的使用

    普通旧数据就是内存中的连续字节序列,是能够被“仅当作数据”处理的对象。这篇文章主要带大家了解一下C++中普通旧数据的定义与使用,感兴趣的可以了解下
    2023-03-03
  • c语言求出给定范围内的所有质数

    c语言求出给定范围内的所有质数

    本文主要介绍了c语言求出给定范围内的所有质数的小程序。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • C语言实现3*3数组对角线之和示例

    C语言实现3*3数组对角线之和示例

    今天小编就为大家分享一篇C语言实现3*3数组对角线之和示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • C语言实现简单的扫雷游戏操作

    C语言实现简单的扫雷游戏操作

    这篇文章主要为大家详细介绍了C语言实现简单的扫雷游戏操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • C++拷贝构造函数(深拷贝与浅拷贝)详解

    C++拷贝构造函数(深拷贝与浅拷贝)详解

    深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝
    2013-09-09
  • OpenGL实现边缘填充算法

    OpenGL实现边缘填充算法

    这篇文章主要为大家详细介绍了OpenGL实现边缘填充算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • C++深入讲解初始化列表的用法

    C++深入讲解初始化列表的用法

    这篇文章主要介绍了C++成员初始化列表,除了可以使用构造函数对类成员进行初始化之外,C++还提供了另外一种初始化的方法,叫做成员初始化列表。下面来看看文章的详细吧,需要的朋友可以参考一下
    2022-04-04

最新评论