C++ 常量指针与指向常量的指针详解

常量指针与指向常量的指针不同,常量指针指的是指针自身是个常量,指向常量的指针表示该指针指向的对象是个常量。表示方法如下:

常量指针:int *const p
指向常量的指针:const int *p
指向常量的常量指针:const int *const p

指向常量的指针

类似于“常量引用”(即指向 const 变量的引用,或指向常量的引用),指向常量的指针不能用于改变其所指对象的值。

(1)要想存放常量对象的地址,只能使用指向常量的指针。

const double dval = 3.14;       // dval 是个常量,它的值不能改变
double *ptr = &dval;            // 错误:ptr 是一个普通指针
const double *cptr = &dval;     // 正确:定义指向常量的指针
*cptr = 42;                     // 错误:不能通过指向常量的指针来修改其所指对象的值

(2)允许令一个指向常量的指针指向一个非常量对象,但不允许通过该指针修改其所指对象的值。

“常量引用”一样,指向常量的指针也没有规定其所指的对象必须是一个常量。所谓指向常量的指针仅仅要求不能通过该指针改变对象的值,而没有规定那个对象的值不能通过其他途径改变。

double dval = 3.14;             // dval 是个双精度浮点数,其值可以改变
const double *cptr = dval;      // 正确:但是不可以通过 cptr 改变 dval 的值

试试这样想吧:所谓指向常量的指针或者引用,不过是指针或引用“自以为是”罢了,它们觉得自己指向了常量,所以自觉地不去改变所指对象的值。

(3)与“常量引用”不同的是,指向常量的指针不能指向字面值或者一个一般表达式,因为它们不是一个对象。

要时刻记住,指针是用来存放其他对象的地址的。
在为指针赋值时,可以使用 & 运算符来获取对象的地址,将其赋值给指针;如果要使用一个字面值常量来为指针赋值,只能使用 0 来为指针赋值,因为 0 等价于 NULL(此时的 0 必须是字面值常量,不可以是整型类型的对象,因为类型不匹配,除非进行强制类型转换),而不可以使用其他整型数值(无论是字面值常量,或者是整型类型的对象)来为指针赋值。

int i = 0;  

int *p1 = 0;            		// 正确:可以使用 0 来为指针初始化,相当于 NULL
int *p2 = i;            		// 错误:类型不匹配,需要进行强制类型转换。
int *p3 = (int *)i;     		// 正确:强制类型转换后可以使用整型对象为指针赋值
int *p4 = 3;            		// 错误:不可以直接用 0 之外的整型字面值为指针赋值或初始化
int *p5 = (int *)3;     		// 正确:p5 的值为 0x3

在下面例子中,自然也就不能使用一个字面值常量来为 cptr1 赋值,更不能使用 & 获取字面值常量的地址;表达式的计算结果是一个临时对象,不可以使用 & 获取临时对象的地址。

double dval = 42;
const double *cptr1 = 42;           // 错误:不能使用一个非 0(NULL) 的值来初始化指针
const double *cptr2 = &(dval * 2);  // 错误:取临时对象的地址会出错

常量指针

指针是对象而引用不是,因此就像其他对象类型一样,允许把指针本身定义为常量。

(1)常量指针必须初始化。

因为 const 对象必须初始化,而常量指针也作为常量对象,所以也必须初始化。
而且一旦初始化完成,则它的值(也就是存放在指针中的那个地址)就不能再改变了。

int errNumb = 0;
int *const curErr = &errNumb;       // curErr 将一直指向 errNumb
const double pi = 2.14;
const double *const pip = π      // pip 是一个指向常量对象的常量指针

curErr 是一个常量指针,其指向了一个普通的整型对象;pip 也是一个常量指针,它指向的对象是一个双精度浮点型常量。

(2)指针本身是一个常量并不意味着不能通过指针修改其所指对象的值,能否这样做完全依赖于所指对象的类型。

例如 pip 还是一个指向常量的常量指针,则不论是 pip 所指的对象值还是 pip 自己存储的那个地址都不能改变。相反的,curErr 指向的是一个一般的非常量整数,那么完全可以用 curErr 去修改 errNumb 的值:

*pip = 2.72;                // 错误:pip是一个指向常量的指针
if(*curErr) {
    errorHandler();
    *curErr = 0;            // 正确:把 curErr 所指的对象的值重置
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值