🤔 今天回顾C++ 时候 发现遇到关于const的变量类型(底层const 顶层const 常量指针 指针常量 常量引用…)又有点懵懵的了,然后又仔细复盘了一下 最后整理了一下 也方便记忆
文章目录
- 引入
- 顶层const和底层const
- 顶层const
- 底层const
- 总结一下
- 一些练习
引入
首先明确一下C/C++中的基本类型
在C/C++中,分为常量,变量,字面量三大类。
🍎常量,简单而言,就是数据类型前面加了const 的 ;
比如 const int a=2;
🍌变量,就是正常的数据类型 比如,int a=0; float a=3.2;
🍊 字面量,就是用的各种字符串,数字,比如上面我提到的 2,0,3.2等。
另,要再讲讲指针变量这个东西。
指针变量也就只是一个数据类型而已,和int float等一样,int类型里面存储的是整型变量,float是浮点型,而指针变量存储的是变量的地址而已,我们可以通过对指针进行一系列操作,来对这个地址上的变量的值进行更改。具体可以看看这篇blog
指针与数组
顶层const和底层const
而本文的const变量 就是 “常量”的类型,由这个常量可以引入顶层const 和底层const。
顶层const
所谓顶层const 就是一般的各种数据类型前面加上了const。对于任何数据类型都适用 算术类型 类 指针等。如:
const int a=2;
const float b=3.2;
int* const p=&a;//p是一个const变量,是一个int*类型的;也就是这是一个int类型的常量指针(从右往左读)
这种类型的const 被成为顶层const。可以这样理解,这种类型的数据的值,一旦初始化就不可更改(所以叫顶层嘛)。具体的,一旦定义了a 这个整型常量,a就不可更改了;定义了p这个指针常量(挺好记忆的,就是这个指针变量的值是一个常量,一经初始化地址不可更改),由于指针变量的值就是地址,所以p的值,也就是p指向的地址就不可更改了;
同时 int cosnt 和const int 类似的都是一个东西,所以不用太纠结。它们都是定义一个常量类型。
底层const
所谓顶层const 与指针 引用等复合类型部分相关。也就是我们常见的指向常量的指针,和 常量引用(可以类比指向常量的指针 ,简称常量指针)。
不管是常量指针还是常量引用,它们都只负责一件事:仅仅要求不能用于改变所指对象的值,而没有规定那个对象的值不能通过其他途径改变。
举个栗子🌰
比如,我用了这个指针变量,这个指针变量就不能用于改变所指对象的值,但是指针变量本身的地址是可以改变的,至于这个对象是不是const没关系,只是说不能用这个指针变量改变了。常量引用也是一样的意思。
具体一点
int i=0;
const int j=3;
const int *p =&j;
const int *p2=&i;
上面两个都是合法的,只是说,不能通过指针变量去更改j和i的值了,但是指针指向的地址可以后面再变化。
总结一下
🌿
顶层const 可以理解为很普通的常量类型,在各个变量之前加一个const
底层const 与指针 引用等复合类型部分相关。
由这两组cosnt 催生出了指针常量(顶层const) 和常量指针(底层const),前者,由于是顶层const,所以一旦初始化之后就不能够更改指针变量的值,也就是地址。而后者,仅仅要求不能用于改变所指对象的值
一些练习
这些练习选于C++ Primer
const int v2= 0;int v1 = v2;
int *pl = &v1,&r1 = v1;
const int *p2 = &v2, *const p3 = &i,&r2 = v2;
//判断下面的语句是否合法,声明如上。
rl = v2;
pl = p2;
p2 = pl;
pl = p3;
p2 = p3;
🌈下面进行逐步的分析。
1️⃣rl是int类型的变量,v2是顶层const,简单理解为int类型的常量。
rl=v2,合法,就是一个简单的赋值操作。
2️⃣p1是int类型的指针,p2是底层const(也就是常量指针),p1=p2,可以这么理解,把p2的值(也就是p2指向的地址)赋值给p1的值(p1指向的地址)。但是我们知道p2是一个底层const,不能用于改变指向的值,也就是说既然选择用了p2这样的数据类型,那么其指向的地址的值默认不能随意被改变,从而起到一个保护的作用。而p1 是一个普通的指针变量,可以随意改变指向地址的值。所以把p2赋值给p1是不安全的行为,是不合法的。
3️⃣ 如果要把p1赋值给p2,最多就是p1指向的地址的值不能用p2进行随意更改了,变得更安全了,所以是合法的。
4️⃣ p3 即const int *const p3=&i;是顶层const也是底层const,和上面的同理,如果pl=p3 那么pl就可以改变p3 所指的值和地址了。
5️⃣ p2 = p3; 这是合法的。p2得到了p3指向的地址,不能进行更改,而p3恰好也是一个底层const,其所指向的地址值不允许被更改,所以是合法的。
🌈ok ,完结 看到这里点个赞吧 ~~ 如有错误,欢迎批评指正。