指针常量
指针常量:顾名思义它就是一个常量,但是是指针修饰的。
格式为:
int * const p //指针常量
在这个例子下定义以下代码:
int a,b;
int * const p=&a //指针常量
//那么分为一下两种操作
*p=9;//操作成功
p=&b;//操作错误
因为声明了指针常量,说明指针变量不允许修改。如同次指针指向一个地址该地址不能被修改,但是该地址里的内容可以被修改
常量指针
常量指针:如果在定义指针变量的时候,数据类型前用const修饰,被定义的指针变量就是指向常量的指针变量,指向常量的指针变量称为常量指针,格式如下
const int *p = &a; //常量指针
在这个例子下定义以下代码:
int a,b;
const int *p=&a //常量指针
//那么分为一下两种操作
*p=9;//操作错误
p=&b;//操作成功
因为常量指针本质是指针,并且这个指针是一个指向常量的指针,指针指向的变量的值不可通过该指针修改,但是指针指向的值可以改变。
思考一下
指向常量的指针常量该怎么写?
答案:
const int * const b = &a;//指向常量的指针常量
说到这里,我们顺带提一下在C++中,我们有顶层const和底层const两个概念
顶层const: 表示指针本身是一个常量;
底层const: 表示指针所指的对象是一个常量
更一般的,顶层const可以表示任意的对象是常量,这一点对任意的数据类型都适用;
底层const则与指针和引用等复合类型的基本类型部分有关;
例如:
int i=0;
int *const p1=&i; //这是一个顶层const,不能改变p1的值
const int ci=42; //这是一个顶层const,不能改ci的值
const int *p2=&ci; //这是一个底层const,允许改变p2的值
const int *const p3=p2;//靠右的const是顶层const,靠左的const是底层const
const int &r=ci //用于声明引用的const都是底层const
当执行对象的拷贝操作时,常量是顶层const还是底层const的区别明显。其中,顶层const不受什么影响:
i=ci; //正确,ci是一个顶层const,对此操作无影响
p2=p3; //p2,p3指向的对象类型相同,p3顶层const的部分不影响
另一方面,底层const的限制却不能忽视。当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。一般来说,非常量可以转换为常量,反之则不行:
int *p=p3; //错误,p3包含底层const的定义,而p却没有
p2=p3; //正确,p2,p3都是底层const
p2=&i; //正确,int*能转成const int*
int &r=ci; //错误,普通的引用不能绑定到int常量上
const int &r2=i; //正确,const int&可以绑定到一个普通int上