const 修饰符结合指针声明变量的总结
const 关键字用来保护数据不被修改,简而言之就像常量一样
const 类似于宏定义#define PI 3.14159 但宏定义本质是替换,很容易出问题注意加圆括弧
const 这样声明const double PI = 3.14159;
const 的用法比#define 更灵活,可以创建const 数组、const 指针、指向const 的指针...
const 的基本修饰形式
展示几个const 的用法:
int const a = b; //const 修饰变量,使得变量的值不可修改
int const * a = b; //const 修饰指针时,指针指向的内存的值不可修改
int * const a = b; //const 修饰指针写在指针类型与变量名之间时,指针的指向不可修改
int const * const a = b; //const 修饰指针并且指针类型和变量名之前都修饰时,指针的指向不可修改,只针指向的内存的值不可修改
看到这里可能有点懵逼,怎么const 可以放在各种位置,甚至可以加多个const ,const 位置不同和数量不同,修饰的意义就不同了!!!不用担心,下面继续分析const 是怎么玩的
一级指针的const 应用
int * a = b; //无const 修饰 |
int * const a = b; //指针的指向不可修改 |
int const * a = b; // | 指针指向的内存的值不可修改
int const * const a = b; //指针的指向不可修改 | 指针指向的内存的值不可修改
二级指针的const 应用
int * * a = b //无cosnt 修饰 | |
int * * const a = b; //二级指针的指向不可修改| |
int * const * a = b; // | 二级指针指向的一级指针的指向不可修改|
int * const * const a = b; //二级指针的指向不可修改| 二级指针指向的一级指针的指向不可修改|
int const * * a = b; // | | 二级指针指向的一级指针指向的内存的值不可修改
int const * * const a = b; //二级指针的指向不可修改| | 二级指针指向的一级指针指向的内存的值不可修改
int const * const * a = b; // | 二级指针指向的一级指针的指向不可修改| 二级指针指向的一级指针指向的内存的值不可修改
int const * const * const a = b; //二级指针的指向不可修改| 二级指针指向的一级指针的指向不可修改| 二级指针指向的一级指针指向的内存的值不可修改
聪明的小伙伴已经发现了const作用就是用来限制值能否修改的,cosnt 可以理解成一道锁,这里可以理解成const 的数量代表锁的数量,const 的位置代表这个锁是用来锁什么(不同位置代表锁的不同类型,后文会分析)的,而int const * const * cosnt a = b; 就相当于给二级指针上了三道锁,一级指针和二级指针的指向不能修改,而且指向的内存的值也不能修改,使该变量完全无法修改了
以下四组const 声明是等价的(有一些“奇怪”的const 的情况)
int const a = b;
const int a = b;
const int const a = b;
//---
int const * a = b;
const int * a = b;
const int const * a = b;
//---
int * const a = b;
//---
int const * const a = b;
const int * const a = b;
const int const * const a = b;
可以观察得知出现等价情况的都是指针最后指向的内存加了“锁”的情况,而且都是类似的三种等价情况。假设T为数据类型,那么T const 等价于const T 等价于const T const 。这个等价的情况了解就好,写代码时建议使用基本形式,防止弄混。基本形式简单来说就是const 写在类型的后面,这样一来const 锁住的类型就是const 之前的数据类型。
如:int const * const * const a = b; 理解:
第一个const:(int) const * * a = b;
第一个const:(int *) const * a = b;
第一个const:(int * *) const a = b;
cosnt 修饰的变量在值的初始化上的不同
int a = b; //b 可以为int 和const int 类型
int const a = b; //b 可以为int 和const int 类型
int * a = b; //b 可以为int * 类型,不能为const int * 类型
int const * a = b; //b 可以为int * 和const int * 类型
int * const a = b; //b 可以为int * 类型,不能为const int * 类型
int const * const a = b; //b 可以为int * 和const int * 类型
经常看到这样的代码 int func(const double * arr, int b); 用const修饰函数的参数,这样做的意义在于,这样既可以传入普通变量,也可以传入const 修饰的变量,而函数参数无const 修饰的话,传参就只能传入普通变量,而不能传入const 修饰的变量。