const
关键字与指针有多种不同的组合,不同的组合对于不同的问题,提供了对应的需求。我们学习中可以看到如下四种
const
指针.
指向常量的指针
将指针定义为指向常量。即不能通过指针去修改指针所引用的值。如下,声明了一个整数指针和指向整数常数的指针:
int tmp=10;
const int li=100;
int *pi=&tmp;
const int *pl=&li;
我们 可以通过引用指向常量的指针读取对应值,这在编译上没有任何问题:
cout << *pl << endl; //输出 100
但是因为其是指向常量的指针,所以我们不能解引指向常量的指针并改变指针所引用的值,但是可以改变指针值(指针的值并非常量)。即指针可以改为引用另一个整数常量,或者整数。即做如下的操作是合法的:
pl = &tmp; //输出10
同样可以解引读取值,但不能解引修改值。
即如下的通过指针赋值是错误的:
*pl = 1999;
上述赋值会出现如下报错:
在这里,指针指向的是一个常量,也就无法通过指针来修改此整数,但是可以通过变量名来修改tmp
变量。
所以我们可以对**指向常量的指针(pl)**做如下归纳:
pl
可以被修改为指向其他的整数常量或非整数常量- 可以解引
pl
读取数据 - 不能解引
pl
而修改指向的数据
指向非常量的常量指针
声明一个指向非常量的指针,即指针的指向不可改变,但是指向的值可以改变.
int tmp = 100;
int *const pl = &tmp;
声明为**指向非常量的常量指针(pl)**时:
pl
必须被初始化为指向非常量变量- 指针值(
pl
)不可被修改 - 指针指向的值(
*pl
)可以被修改
对指针指向的值进行修改,可以解引pl
并重新赋值。即如下是合法的:
*pl = 1999;
*pl = 715;
但如果试图把pl
指向为其他常量,则是不合法的:
const int pi = 17;
int num= 13;
pl = π //错误,无法从“const int *”转换为“int *const
pl = # //错误,不能给常量赋值
指向常量的常量指针
指向常量的常量指针,即指针本身不可修改,指针指向的值不可修改。
const int tmp = 1214;
const int* const pcl = &tmp;
int tr = 1706;
const int* const pcl2 = &tr; //也可将可变值的变量地址赋给pcl2
声明指向常量的常量指针时必须进行初始化。
指向 指向常量的常量指针 的指针
指向常量的指针也可以有多层间接引用。
const int tmp = 36;
const int* const pcl = &tmp; //从右往左读:指向常量的指针常量
//声明一个指向 指向常量的指针的指针 的指针
const int* const* p = &pcl;
cout << **p << endl; //输出36
对上述四种指针做如下总结:
指针类型 | 指针是否可修改 | 指针指向值是否可修改 |
---|---|---|
指向常量的指针 | 是 | 否 |
指向非常量的指针 | 是 | 是 |
指向常量的常量指针 | 否 | 否 |
指向非常量的常量指针 | 否 | 是 |