C++:指针常量和常量指针

常量指针与指针常量的区分

常量指针(const int* p)

常量指针本质上是一个指针,是一个指向“常量”的指针,即不能通过指针改变指向对象的值(不能解除引用),但可以更改指向。用法如下

1
2
3
4
int a=3,b=4;
const int *p=&a; /初始化指向a
p=&b; /可以更改指向,现在指向b
*p=5; /不可以通过指针改变对象的值

指针常量(int* const p)

指针常量本质上是一个常量,const是修饰p的,即指针的值自身是一个常量,不可改变,始终指向一个地址,在创建的同时必须进行初始化,用法如下

1
2
3
4
int a=3,b=4;
int* const p=&a; /初始化指向a
*p=5; /可以进行解引用,更改指向对象的值
p=&b; /不可以更改指向

区分:

a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const int c=5; /常量,创建时就需要初始化
const int* p1; /常量指针
int* const p2=&a; /指针常量,创建时就需要初始化,指向a
-----------------------------------------------------------
int *wrong=&c; /错误,常量地址不能初始化普通指针,只能赋值给常量指针
int* const p=&c; /错误,报错:无法从“const int *”转换为“int *”,即必须拥有相同的底层const资格
p1=&c; /正确,只能赋值给常量指针
-----------------------------------------------------------
const int* const p3=&a; /指向“常量”的指针常量,具有常量指针和指针常量的特点,指针内容不能改变,也不能指向其他地方,定义同时要进行初始化
*p3=5; /错误
p3=&b; /错误
--------------------------------------------------------------------
char* p4="abc"; /"abc"是字符常量放在常量区,p4指向的是"abc"的首地址,即'a'的地址
*p4='b'; /错误,*p4相当于对字符'a'修改,但"abc"是一个字符串常量,不可修改

常量引用与引用常量区分

常量引用(const int& a)

本质上是一个引用,对常量的引用,不能通过引用改变绑定对象的值
注:当初始化值是一个字面值时,则只能对一个const T&(常量引用)赋值。而且这个赋值是有一个过程的:首先将值隐式转换到类型T,然后将这个转换结果存放在一个临时对象里,最后用这个临时对象来初始化这个引用变量。

1
2
3
4
int a=3;
const int& reference1=a;
const int& reference2=5;/ 对常量、字面值的引用只能通过常量引用,会创建一个临时对象,用这个对象进行初始化
reference1=5; /错误,常量引用不能改变对象的值

引用常量(int& const t???)

注意:原则上不存在引用常量(所以我使用了???),会报warning C4227: 使用了记时错误: 忽略引用上的限定符。