“C/C++ 复杂类型声明规则” 将分为两节。第一节介绍螺旋法则声明规范,第二节介绍const的修饰关系。
本节主要解决以下问题:
1 | const int *a; // a可变嘛? *a可变嘛? |
这两节内容,我都尝试以一种不用死记硬背,而是理解的方式去掌握。
本文参考自【初中生也能看懂的C/C++类型声明规则教学,很简单的!】 https://www.bilibili.com/video/BV1mB4y1L7HB/ 。里面通过一些例子介绍了螺旋法则和对const关键词的判读。我将在此基础上加上我对其的解释,使其变得更加通俗易懂。
基本解决思路:const 只修饰右边最近的东西。
例如const r
, 说明r
这个变量是const的,不能动。const *r
,意为const (*r)
,说明*r
,r指向的东西,是const的。r自身可以变化。
再例如,const int r
, 说明这个int是const的。这个整数是常量。r
是一个整型常量。
举一些例子:
例子1
1 | int const a1 = 5; |
在这里,两个其实是等价的。对于第一个,a1
被const修饰了,所以a1
不能变。a1
是一个整型变量。所以连起来,a1
是一个常量整型变量。对于第二个,可以理解成a2
是一个const int,a2
是一个常量整型变量。
所以,不同的声明形式,意义可能相同。
例子2
1 | int const *p1 = &a1; |
在这里,两个其实也是等价的。对于第一个,*p1
被const修饰了,所以*p1
不能变。即p1
指向的是一个整型常量。对于第二个,可以理解成p2
指向一个const int,p2
指向的是一个常量整型变量。对于这两个来说,p1
p2
自己可以变,但是他们指向的不能变。
一个声明里的多个const,意义可能相同。例如:
1 | const int const *p3 |
这个例子里虽然有两个const,但其实还是只修饰了一个*p3
。p3
自身没有被const修饰,可以变。
例子3
1 | int *const r2; |
在这里,r2
直接被const修饰,所以r2
不能变。r2
指向一个int,那个int没有额外修饰,所以那个int是可以变的。总之,r2
是不能变的,但是r2
指向的int是可以变的。
例子4
1 | const int *const r3; |
在这里,r3
直接被const修饰,所以r3
不能变。r3
指向一个const int,那个int没有额外修饰,所以那个int是可以变的。总之,r3
是不能变的,r3
指向的int也不可以变的。
例子5
1 | const int **r5; |
r5
指向一个指向int的指针。这个被指向的指针指向的int是被const所修饰的。所以r5
可以变,r5
指向的那个(指向int的指针)也是可以变的,但是r5
指向的指针指向的int没得变。
例子6
1 | int const * const * const r6; |
上面那个例子的升级版。r6
指向一个指向int的指针。r6
被const修饰,r6
不能变。r6
指向的(指向int的指针)被const修饰,即*r6
不能变。r6
指向的指针指向的int,**r6
也被const修饰,也不能变。