const用法
- 在C代码中const修饰的量,可以不用初始化,C中不叫常量,而叫常变量,不能作为左值被改变,可以通过指针找到常变量的内存地址改变其值,常变量不可做为数组的下标。
- 在C++中,必须初始化,叫常量。与C不同,C中const被当作一个变量来编译生成指令,而C++,所有出现const常量名字的地方都被常量的初始化替换了。
- 在C++中,当const被一个变量初始化(int a = 10; const int b = a;)时,而不是被立即数初始化,则他退化成常变量,与C语言一样,是一个变量。(注意 变量不可作为数组下标,常量可以)
const和一级指针的结合
在C++中,const修饰的是离他最近的类型。
已知int a = 10; int b = 20;
举例如下:
- const int
*p
= &a;
cosnt修饰的类型是int,因为他离const最近,除去类型剩下的就是const修饰的表达式*p
,被const修饰的表达式不能被修改。
所以*p
不能再赋值,即不能通过指针来修改指向的内存的值,但可指向不同的int类型的内存。
表达式 | 是否能修改 |
---|---|
p = &b | ✔ |
*p = 20 | × |
- int const
*p
;
const修饰的类型不能是*
,因为*
不是类型,而最近的应该是int六日行,所以cosnt修饰的类型是int,const修饰的表达式*p
。
*p
不能再赋值,即不能通过指针来修改指向的内存的值,但可指向不同的int类型的内存,与例1一致。
表达式 | 是否能修改 |
---|---|
p = &b | ✔ |
*p = 20 | × |
- int
*
const p = &a;
const修饰的类型的int*,const修饰的表达式为p,则指针p为常量,不能再指向其他内存,但是可以通过指针解引用修改指向内存的值。
表达式 | 是否能修改 |
---|---|
p = &b | × |
*p = 20 | ✔ |
- const int * const p;
第一个const修饰的类型是int,修饰的表达式是*p;
第二个const修饰的类型是int*
,修饰的表达式是p。
则不能指向其他内存以及不能通过解引用修改内存的值。
表达式 | 是否能修改 |
---|---|
p = &b | × |
*p = 20 | × |
const类型转换(一级)
const类型转换只需记住如下三点公式:
- int* <= const int * (不可转换)
- const int * <=
int*
(可转换)
//例:
int a = 10;
const int *p = &a;//const int* <= int* 可行
int *q = p; //int * <= const int* 不可转换
- const如果右边没有指针*的话,const是不参与类型的
int a = 10;
int *const p1 = &a; //const右边没指针 所以类型转换是int* <= int* 同类型可互相转换
const和二级指针的结合
int a = 10;
int *p = &a;
int **q = p;//q指向p,再指向a
代码解析图如下:
q中存放p的地址,p中存放a的地址,*q存放p的值(0x100),*p存放a的值(10)。
q有三种表达式:
q => 0x200;用于存放p的地址
*q => p的值;
**q => a的值;
const修饰的类型 | const修饰的表达式(不可变) | 可变 | |
---|---|---|---|
const int **q | int | **q | q、*q |
int * const* q | int* | *q | **q、q |
int** const q | int** | q | *q、**q |
const类型转换(二级)
公式:
- int** <= const int **
- const int** <= int **
以上两个公式都相互转换,多级指针很两边要么两边都有const或都没有才可以相互转换。
例子:
- int** <= const int **
两边同时删去int*,* <= const *,变成一级指针的const转换,看一级指针的const转换公式,显然不能转化。 - const int** <= int **
两边删去int*, const* <= *,变成了一级指针的const转换,可以转换。