这期博客我们来讲贯穿C++中的一个十分重要的修饰词:Const。一般我们知道:**Const修饰过的变量再也不能做为左值了,且值初始化完成后是不能被修改的。**那么这句话的真正意思你理解了吗?
首先我们来看看C语言与C++中Const最本质的区别:Const的编译方式不同。
在C语言中,Const修饰的变量是当做一个变量来编译生成指令的。怎么来理解这句话呢?就是说Const尽管修饰了一个变量,但这个变量的本质并不会变成一个 常量,无法修改,而是变成了一个叫常变量的东西。常变量可以不初始化,但赋值只有在初始化的时候才有机会赋值,除此之外再也无法赋值,即无法通过等式来修改其值。这个就是常变量中“常”的来由。
但并非这个常变量就是修改不了的,让我们看下面一段代码:
#include <stdio.h>
void main()
{
const int a = 20;
int *p = (int*)&a; //p指向a的内存
*p = 30; //通过指针解引用,把指针指向内存的值改为30
printf(“%d %d %d \n”, a ,*p, *(&a)); //结果3个都是30
}
结果显而易见,被Const修饰的整形变量a的值被修改了。这说明了什么?其实C语言中Const只是语法上保证a不能被作为左值修改,但可以通过修改内存的方式来看修改其值。这就是常变量中“变”的来由。
而在C++中,被Const修饰过的变量称为常量,所有出现Const常量名字的地方,编译时都被常量的初始化值替换了。为什么称为常量呢,因为前面提到了在C++中会将出现常量名字的地方都替换成初始化值,其本身甚至可以用作定义数组的下标个数。
但如果用的是变量来作为Const修饰的变量的初始化的右值,那么又成了常变量,因为初始值不是立即数,是一个变量。而成为常变量后,与上边C语言的Const的修饰情况一样,可以通过指针的解引用来修改其值。下面还是通过一段代码来更直观地理解C++中Const的情况:
#include <iostream>
using namespace std;
int main()
{
const int a = 20; //a的内存确实被修改为了30
int *p = (int*)&a;
*p = 30;
cout<< a <<*p <<*(&a) <<endl;
//变成了printf(“%d %d %d \n”, 20 ,*p, 20(这里两个20与变量a的内存没有关系,p的指针解引用才真正取的是a的内存里的数据));
//结果是 20 30 20
int b = 20;
const int c = b; //此时c为常变量,因为替换时替换成的是b
int *p2 = (int*)&c;
*p2 = 30;
cout<< c <<*p2 <<*(&c) <<endl;
//打印出来的结果是三个30,情况与上边C语言中的const一样
return 0;
}
看完这段代码,相信大家都对C++中Const的情况有所了解了吧,我们下期再见!