C/C++中的const
·
const最初的理解
const修饰的量不能再作为左值,初始化完成后值不能被修改!!
C中的const修饰的叫常变量
const int a = 10;
// int b[a];
// 首先这就不行,因为这在C语言中是常变量,本质上a还是个变量只是
// 不能被赋值改变值了
// const只是在语法上保证a不能左值被修改但是底层还是可以通过指针修改,比如
// 下边这段代码输出结果全部都是30
int* p = (int*)&a;
*p = 30;
printf("a = %d *p = %d *(&a) = %d\n", a, *p, *(&a));
C++中叫如果初始化给一个数字就叫常量,还可以拿来定义数组呢,但是如果不是一个立即数的话也会退化成一个常变量,类似C中的那种
const int a = 10;
int arr[a] = { 0 };//定义数组没问题,因为C++中这个叫常量
int* p = (int*)&a;
*p = 30;
printf("a = %d *p = %d *(&a) = %d\n", a, *p, *(&a));
cout << "a = " << a << " *p = " << *p << " *(&a) = " << *(&a) << endl;
运行结果是a = 10 *p = 30 *(&a) = 10
为什么是在这样的呢?因为C++中,所有出现const常量名字的地方,都被常量的初始化值给替换了
但是这段代码确实是已经把a内存中的值给改了
下边这段代码就是const修饰的是常变量了
int b = 20;
const int a = b;
//int arr[a] = { 0 };//定义数组会报错,因为初始值已经不是一个立即数了,退化成常变量了
int* p = (int*)&a;
*p = 30;
printf("a = %d *p = %d *(&a) = %d\n", a, *p, *(&a));
cout << "a = " << a << " *p = " << *p << " *(&a) = " << *(&a) << endl;
const与指针的结合
C++中不允许把一个常量的值泄露给一个普通的指针或者引用(会被间接给修改了)
下面这种写法就是不允许的
const int a = 10;
int* p = &a;
const与一级指针的结合
C++中const修饰的是离它最近的类型(看这种东西就把int去掉就好看了)
const int* p; *p不可以变,p可以变
int const* p; 这种和上边其实是一样的
int * const p; p是常量不可以改,但是*p可以改,p不可以指向别人
const int * const p; p和*p都不可以改了
常量的地址给一个这样的指针是可以的
const int a = 10;
const int* p = &a;
把一个普通变量的地址给一个const指针是可以的,可以理解为向更安全的级别转换是可以的
int a = 10;
int const* p = &a;
下边这行代码也没问题,详情看注释
//下边表示p2是一个常量,p2不能泄露给一个二级指针,
//const后边没有*的话,不参与类型的,所以下边这行代码的左右两边都是int*类型
//所以可以赋值成功
int* const p2 = &a;
const与二级指针的结合
第三个还必须初始化,因为这东西如果允许不初始化,那么后边在想使用赋值的时候也使用不了,因为const修饰的是p3本身,所以必须初始化,不初始化就会报错。
//const和二级指针结合有三种
const int** p;//**p不可以改,*p和p都是可以改的
int* const* p2;//*p2不可以改,**p2和p都可以改
int** const p3 ;//p3可以改,但是**和*可以改,这条代码必须初始化
如果试图将const int**转换成int**是错误的
如果试图将int** 转换成const int**也是错误的
更多推荐


所有评论(0)