您的位置:首页 > 编程语言 > C语言/C++

C++ 变量判定的螺旋法则

2019-09-25 23:47 2041 查看

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

比如:

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

其中

signal
是什么?

螺旋法则

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

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

  1. 从我们需要判定的标识符开始,顺时针画圈,遇到如下符号时,用对应的语义替换:
  • [x]
    []
    => 容量为
    x
    的数组或数组
  • (type1,type2...)
    => 接收
    type1
    type2
    ... 的函数,返回值为(待定)
  • *
    => 指向(类型待定)的指针
  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
    入参。
  • 最后,遇到
    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
      如前所述,标识函数体内不修改实例。

    相关资源

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: