“C/C++ 复杂类型声明规则” 将分为两节。第一节介绍螺旋法则声明规范,第二节介绍const的修饰关系。这两节内容,我都尝试以一种不用死记硬背,而是理解的方式去掌握。
本文参考自【初中生也能看懂的C/C++类型声明规则教学,很简单的!】 https://www.bilibili.com/video/BV1mB4y1L7HB/ 。里面通过一些例子介绍了螺旋法则。我将在此基础上加上我对其的解释,使其变得更加通俗易懂。
螺旋法则:
第一步,找到变量名,如果没有变置名,找到最里面的结构
第二步,向右看,读出你看到的东西但是不要跳过括号
第三步,再向左看,读出你看到的东西,但是也不要跳过括号
第四步,如果有括号的话,跳出一层括号
第五步,重复上述过程,直到你读出最终的类型
举例1:
1 | int *v[5]; |
- 第一步:
1 | int *v[5]; |
如上,我们找到了v
是变量名。读作:v
是……
- 第二步,向右看,读出你看到的东西但是不要跳过括号。
1 | int *v[5]; |
[5]
意为是一个5个元素的数组。读作:v是一个五个元素的数组。
- 第三步,再向左看,读出你看到的东西,但是也不要跳过括号。
1 | int *v[5]; |
int *
意为每个东西是一个指向int的指针。读作:v
是一个五个元素的数组,数组每个东西指向一个int型指针。
- 第四步,如果有括号的话,跳出一层括号。
1 | int *v[5]; |
对于上面这个例子,无这一步。我们已经读完了:v
是一个五个元素的数组,数组每个东西指向一个int型指针。
我们可以验证一下我们理解正不正确。我们可以用下列的代码给v数组赋值:
1 | int a = 2023; |
g++编译通过且运行正确,可见我们的理解没有问题。
举例2
1 | int (*func)() |
- 第一步:
1 | int (*func)() |
如上,我们找到了func
是变量名。读作:func
是……
- 第二步:向右看,读出你看到的东西但是不要跳过括号。
向右边遇到括号了,不跳出括号,skip。
- 第三步,再向左看,读出你看到的东西,但是也不要跳过括号。
1 | int (*func)() |
单独一个*意为“指向”。读作:func
指向……
- 第四步,如果有括号的话,跳出一层括号。向右看。
1 | int (*func)() |
这样一组括号是函数的意思。括号内为空,说明这个函数没有参数。整个(*func)
的左边是int
,它是这个函数的返回值,是int
。读作:func
指向一个接收空参且返回值为int
的函数。
我们可以验证一下我们理解正不正确。我们可以用下列的代码用匿名函数给func
赋值:
1 | int (*func1)(); |
g++编译通过且运行正确,可见我们的理解没有问题。
总结&一个网站推荐
螺旋法则五步骤;
当读的时候,看到[]
意为一个数组, ()
意为是一个函数,那么在主体的左侧肯定配套还会有一个返回值(当然,这个返回值也可能是一个复杂复合类型)。 *
如果单独出现,意为指向,如果和类型出现,如int*
,那就可以理解为指向int。
这里顺便推荐一个可以辅助阅读的网站:https://cdecl.org/ 。这个网站可以将表达式翻译成人话(英语),帮助大家的理解。但是总体来说只要会了螺旋法则,啥声明都能理解确切含义。