const
关键字指定变量的值是常量并通知编译器防止程序员对其进行修改。
const
修饰的变量不能够再作为左值!!!初始化完成后,值不能被修改!!!
一、C 和 C++中const的区别
1. 初始化
C语言
在C语言中,const修饰的量可以不用初始化;
被const修饰的量不叫常量,叫常变量。常变量本质上还是一个变量,除了不能作为左值,和普通的变量没有任何区别。
const int a; //合法
a = 20; // 不合法
C++
C++中const修饰的量必须进行初始化,叫做常量;
const int a = 20; // 合法
const int b; // 不合法
2. 用来初始化数组的长度
在C语言中,被const修饰的量是常变量,不能用来初始化数组的长度。
const int a = 20;
int arr[a] = {}; // 不合法
C++中,被const修饰的量是常量,可以用来初始化数组的长度。
const int a = 20;
int arr[a] = {}; // 合法
但是在下面这个代码中:
int b = 10;
const int a = b;
int arr[a] = {}; // 不合法
此时的a不是一个常量,依旧是一个常变量,此时的定义是不合法的。理由可以参考下面修改const量的值中的知识点(替换)。
3. 间接修改const量的值
const int a = 20;
int* p = (int*)&a;
*p = 30;
printf("%d %d %d \n", a, *p, *(&a));
上面这段代码在C语言程序中的运行结果是:30 30 30
,而在C++程序中运行结果为20 30 20
。
造成这种现象的原因是在C和C++中,const的编译方式不同。
在C语言中,const就是被当做一个变量来编译生成指令的,我们虽然不可以直接修改变量a的值,但是可以通过取地址的方式, 将a变量所在的内存地址内的数据进行修改。所以最后输出为30 30 30
。
但是在C++中,是将所有出现const常量名字的地方,都被常量的初始值替换了,将代码中后续所有的常量a的位置都等价替换为a的初始值。
二、const和一级指针结合
C++语言规范:const修饰的是离它最近的类型。
代码段 | 说明 | *p = 20;(修改指针指向内存地址中的值) | p = &b;(修改指针所指向的内存地址) |
---|---|---|---|
const int *p = &a | const 修饰的类型是int | 不合法 | 合法 |
int const *p = &a | const 修饰的类型是int ,同上 | 不合法 | 合法 |
int *const p = &a | const 修饰的类型是int * | 合法 | 不合法 |
const int *const p = &a | const 修饰的类型是int 和int * | 不合法 | 不合法 |
const
和指针之间的类型转换:
const int*
可以转换为int*
;int*
不能转换为const int*
。(const int*
和int const*
没有区别)
const
如果右边没有指针*的话,const
是不参与类型的。上述四种情况的具体类型如下图所示:
下面几种类型间的转换都是合法的。
int a = 10;
int* p1 = &a;
const int* p2 = &a; // const int* <== int*
int* const p3 = &a; // int* <== int*
int* p4 = p3; // int* <== int*
下面是不合法的类型转换:
int a = 10;
const int* p = &a;
int* q = p; // int* <== const int*
三、const和二级指针结合
来看const和二级指针结合的几种方式。
代码段 | 说明 |
---|---|
const int **q; | const 修饰的是int ,**q 不能被赋值 |
int *const* q | const 修饰的是int * ,*q 不能被赋值 |
int **const q; | const 修饰的是int ** ,q 不能被赋值 |
int**
和 const int **
之间的互相转换都是错误的。
int**
可以转换为int*const*
,int*const*
不能转换为int**
。
int a = 10;
int* p = &a;
// const int** q = &p; // 不合法 const int** <== int** 如果成立,会存在将常量地址赋值给普通指针的情况,不允许
int* const* q = &p; // 合法 int *const* <== int**