指针和const
- 可以用两种不同的方式将const关键字用于指针。第一种方法是让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值;第二种方法是将指针本身声明为常量,这样可以防止改变指针指向的位置。
int age=39; const int* pt=&age;//将**常规变量**的地址赋给了**指向const的指针**
该声明指出,pt指向一个const int,因此不能用pt来修改这个int值。即*pt的值为const,不能被修改:
*pt+=1;//invalid
cin>>*pt;//invalid
- 注意,pt的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对pt而言,这个值是常量。上述例子中,pt指向age,而age不是const。可以直接通过改变age变量来修改age的值,只是不能用pt指针来修改它。
- 还有两种可能:将const变量的地址赋给指向const的指针、将const的地址赋给常规指针。
变量和指针 | 是否可行 |
---|---|
将常规变量的地址赋给常规指针 | 可行 |
将常规变量的地址赋给指向const的指针 | 可行 |
将const变量的地址赋给指向const的指针 | 可行 |
将const的地址赋给常规指针 | 不可行 |
const float g_earth=9.80;//const变量
const float*pe=&g_earth;//valid,const变量的地址赋给指向const的指针
//不能用g_earth来修改值9.80,也不能使用pe来修改
const float g_moon=1.63;//const变量
float * pm=&g_moon;//invalid,将const的地址赋给常规指针
//禁止的原因:如果将g_moon的地址赋给pm,则可以使用pm来修改g_moon的值,这是荒谬的
- 如果将指针指向指针,情况更复杂。
假如涉及的是一级间接关系,则将非const指针赋给const指针是可以的:
int age=39;
int* pd=&age;
const int*pt=pd;//常规变量(pd)的地址赋给指向const的指针(pt)
不过,进入两级间接关系时,将const和非const混合的指针赋值方式将不再安全。
const int **pp2;
int *p1;
const int n=13;
pp2=&p1;//常规变量(p1)的地址赋给指向const的指针
//因此可以使用p1来修改const数据(p1指向const值),not allowed
*pp2=&n;//const变量的地址赋给指向const的指针
*p1=10;
如果数据类型本身并不是指针,则可以将const数据或非const数据的地址赋给指向const的指针,但只能将非const数据的地址赋给非const指针
- 如果有一个由const数据组成的数组,因为禁止将常量数据的地址非常量指针,所以不能将数组名作为参数传递给使用非常量形参的函数。
- const的第二个用法:
int age=39;
const int*pt=&age;//只能防止修改pt指向的值,而不能防止修改pt的值,也就是说可以将一个新地址赋给pt
int sage =80;
pt=&sage;
第二种使用const的方式使得无法修改指针的值:
int sloth=3;
const int * ps=&sloth;
int*const finger =&sloth;//const关键字的位置与原来不同,这种格式使得finger只能指向sloth,但允许使用finger来修改sloth的值。
- 还可以声明指向const对象的const指针:
double trouble=2.0E30;
const double * const stick=&trouble;//stick只能指向trouble,stick不能修改trouble的值。
- 通常将指针作为函数参数来传递时,可以使用指向const的指针来保护数据。只要有一层间接关系就可以这样做。但如果它们是指针或指向指针的指针,则不能使用const。