“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修饰,也不能变。