在看const相关内容的时候,对const的一些概念还存在部分疑惑,容易搞混,尤其是在变量声明这种情况下。
这篇博客就主要写一下const的相关。
const主要是用来表示一种值不能被改变的变量,也就是将变量变为常量的作用。
例如 const int a=1;
这时候再向a赋值,则会报错。a用const作为限定,则无法再对a进行复制。
a仅作为一个常量。
刚才是初始化的一般用法,我给变量a一个常量,同时用const作为限定符,这样就是一个基本的初始化。
下面是用变量初始化
int a=1;
const int b=a;
int c=b;
这里的初始化的写法可以得到几个结论。
变量在初始化时可以给常量赋值。
常量可以给变量赋值。
const一般只有在当前文件夹有效。
看个例子
const int a=123;
const int &b=a;
b=1;
int &c=a;
上面四条语句,1,2是正确的。第二句,用b对a进行引用,因为a是常量,所以对于a的引用,它本身也得是常量。
第三条语句是在b已经为a的引用的情况下,还对b进行赋值。这就相当于改变常量的值,所以是不对的。
第四条语句,虽然常量能给变量赋值,但是变量引用并不能绑定常量,因为我们可以通过改变变量的引用来改变变量的值。常量的特性是保持值不变,如果我们通过它的引用能改变它的值,那常量并不能算常量。
既然有常量引用,那必然也有常量指针。
const double pi = 3.14; // pi是个常量,它的值不能改变
double * ptr = π //错误:ptr是一个普通指针
const double * cptr = π //正确:cptr可以指向一个双精度常量
(* cptr) = 42;//错误:不能给*cptr赋值
第二条语句和上面的第四条语句是一个道理。变量指针无法绑定常量。
第四条语句和上面的第3条语句同理。指向常量的指针初始化后,所指向的值无法更改。
第三条语句定义了一个指向常量的指针,这里就要带出一些比较复杂的概念
指针指向加上const,单从变量常量来说,分为指向常量的变量指针,指向变量的常指针,指向常量的常指针。
也就是下面三种情况
const int * p
int * const p
const int * const p
三种情况,我自己一般是这理解的。
指向常量的变量指针
表示指针指向的对象的值是无法改变的
指向变量的常指针
表示指针所指向的地址是无法改变的,地址的值可以改变。
这里我初始化一个常指针,那么常指针指向的一个变量值,有一个地址,这个地址就定了,不会再变了。
不变的是地址,而非地址内存放的值。
指向常量的常指针
这种情况就是两个的结合体,地址定了,值也定了。
指针指向的地址是固定的,地址内的值也是定的。
指针本身是一个对象,它又可以指向另外一个对象。因此,指针本身是不是常量以及指针所指的是不是一个常量就是两个相互独立的问题。
用名词顶层const( top-level const)表示指针本身是个常量,而用名词底层const (low-level const)表示指针所指的对象是一个常量。
简单点说就是,我本身是常量,我就是顶层。我指的对象是常量,那对应的const就是底层。
这篇文章主要是梳理了一下const的一些用法,平常实际运用到,但总是分不清到底指的什么东西,只能知道是个常量。这一遍梳理下来,总归还是有些好处的。