最初认识const当然是在C语言中,做为C语言的一个关键字,它在我们编程中经常用到,比如字符串相关的库函数的实现等。在C语言中,对于const的理解就是const修饰谁,谁就不能被改变。基于对句话的理解,使我在C++const和指针的结合中对const越来越迷。毕竟C和C++中的const还是有巨大差别的。言归正传,先来说一下C中的const。
**
C语言中的const
**
- const修饰的量,可以初始化,也可以不用初始化。但其实这个如果你一开始不初始化,那后面也不能再给它赋值了。
- const所修饰的量叫做常变量,所以不能用它来定义数组的大小。数组的大小在编译时期就需要确定,但是它的值在运行时期才能确定。
它之所以称之为常变量,是因为const只是在语法上保证它所修饰的变量不能作为左值被修改,但是可以通过访问其内存来修改值。 - const与变量的唯一区别就是无法作为左值。
- 常变量的编译方式,和普通变量一模一样,在运行时才确定值。
在.c文件中,虽然a被初始化为const,但是仍可以利用访问内存来修改它的值。所以相应的可以理解为const修饰的是a,所以a不能直接被修改,但是却可以通过访问内存来修改。
**
C++中的const
**
- C++中用const修饰的量,必须初始化。
- const定义的量叫做常量,可以用来定义数组长度。
- C/C++中编译器对const的编译方式不同。C中,const被当做一个变量来生成指令。而在C++中,所有出现该常量名字的地方都被它的初
值所替换。这一点和宏类似,所以这也是为什么在C++中的常量可以用来确定数组大小了。
根据打印结果可以看出来,出现常量名字的地方a,*(&a)都被替换成了初值。 - 如果用变量来初始化const所修饰的量,那么它会退化成常变量。
int a = 10;
const int b = a;//用变量来初始化b,b退化为常变量。
- const常量和普通变量的区别:①编译方式不同②不能作为左值
**
const和一级指针的结合
**
const与指针结合时修饰的是离它最近的类型。它与一级指针结合有以下几种情况:
1、const int *p; //修饰int,*p不能被修改 *p = 20; err p能被修改 p = &b; ok。即*p可以任意指向不同的int类型的内存,但是不能通过指针间接修改指向的内存的值
2、int const *p; //修饰int,*p不能被修改 *p = 20; err p能被修改 p = &b; ok
3、int *const p; //修饰int*,const表示p是个常量,所以p不能被修改;但是*p可以被修改。这个指针p现在是常量,不能再指向其它内存,但是可以通过指针解引用来修改指向的内存的值
4、const int *const p; //这种情况是以上两种的结合,p既不能被修改,*p也不能被修改。第一个const修饰int,第二个const修饰int*。
const修饰的量常出现的错误是:
1、不能再作为左值 <=> 直接修改常量的值
2、不能把常量的地址泄漏给一个普通的指针或者普通的引用变量 <=> 间接修改常量的值
总结const和一级指针的类型转换公式:
1、int* = const int*; // err 把一个常量的地址泄漏给了一个普通的指针
2、const int* = int*; // ok
const什么时候参与类型:
const的右边如果没有指针的话,const是不参与类型的。即只有const右边有有指针的话,它的类型中就含有const了。
**
const和二级指针的结合
**
const与二级指针结合的几种情况:
1、const int **q; //const修饰int,所以**q不能被修改,*q和q都可以被修改。
2、int *const *q; //const修饰int*,所以*q不能被修改,**q和q可以被修改。
3、int **const q; //const修饰int**,所以q不能被修改,**q和*q可以被修改。
总结const和二级指针的类型转换公式:
int** = const int**; //err
const int** = int **; //err
//const和二级指针结合,必须两边都有const
如何将const看起来的二级指针划分为一级指针:
int ** = int *const* ===> * = const* err(和一级指针结合)
int *const* = int** ===> const* = * ok (和一级指针结合)
const的应用:
1、
int a = 10;
const int *p = &a;
int *q = p; // int * = const int * err
//可以改为:const int *q = p; 或 int const *q = p;
2、
int a = 10;
int *const p = &a;
int *q = p; // int * = int * ok
3、
int a = 10;
int *const p = &a;
int *const q = p; // int * = int * ok
4、
int a = 10;
int *const p = &a;
const int *q = p; // const int * = int * ok
5、
int a = 10;
int *p = &a;
const int **q = &p; //const int ** = int ** err
//可以改为:const int *p = &a; 或者 const int *const*q = &p;
6、
int a = 10;
int *const p = &a;
int **q = &p; // int** = int *const * err
//可以改为:int * const *q = &p;
7、
int a = 10;
const int *p = &a;
int *const *q = &p; //int *const * = const int ** err
//可以改为:const int *const *q = &p; 或者 const int **q = &p;