C++ 变量判定的螺旋法则
C++ 变量判定的螺旋法则
C++ 中一个标识符配合着各种修饰界定符,使得标识符的本意不那么直观一眼就能看出,甚至需要仔细分析,才能知道该标识符的具体你含义。
比如:
void (*signal(int, void (*fp)(int)))(int);
其中 signal
是什么?
螺旋法则
对于如何进行变量的辩识,有个非官方的 “顺时针/螺旋法则(Clockwise/Spiral Rule)” 可用来帮助辩识。
该法则的内容,简单来说,为了搞清楚一个未知标识符的含义,我们可以:
- 从我们需要判定的标识符开始,顺时针画圈,遇到如下符号时,用对应的语义替换:
[x]
或[]
=> 容量为x
的数组或数组(type1,type2...)
=> 接收type1
、type2
... 的函数,返回值为(待定)*
=> 指向(类型待定)的指针
- 重复上面的步骤直到语句中所有符号都被遍历过。
- 始终优先解析括号括起来的部分。
实地演练
一个简单的示例
先从一个简单的开始,判定如下语句中 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
如前所述,标识函数体内不修改实例。