《C++覆辙录》——1.6:对常量(性)的认识误区

本节书摘来自异步社区出版社《C++覆辙录》一书中的第1章,第1.6节,作者: 【美】Stephen C. Dewhurst(史蒂芬 C. 杜赫斯特),更多章节内容可以访问云栖社区“异步社区”公众号查看。

.6:对常量(性)的认识误区

在C++中的常量性概念是平凡的,但是这和我们对const先入为主的理解不太符合。首先我们要特别注意以const饰词修饰的变量声明和字面常量的区别:

int i = 12;
const int ci = 12;```
字面常量12不是C++概念中的常量。它是个字面常量。字面常量没有地址,永远不可能改变其值。i是个对象,有自己的地址,其值可变。用const关键字修饰声明的ci也是个对象,有自己的地址,尽管在本例中其值不可变。

我们说i和`ci`可以作为左值使用,而字面常量12却只能作为右值。这两个术语来源于伪表达式`L=R`,说明只有左值能出现在赋值表达式左侧,右值则只能出现在赋值表达式右侧。但这种定义对C++和标准C来说并不成立,因为在本例中`ci`是左值,但不能被赋值,因为它是个不可修改的左值。

如果把左值理解为“能放置值的地方”,那么右值就是没有与之相关的地址的值。

int *ip1 = &12; // 错误!
12 = 13; // 错误!
const int *ip2 = &ci; // 没问题
ci = 13; // 错误! `
最好仔细考虑一下上面ip2的声明中出现的const,这个饰词描述了对我们通过ip2ci的操作的约束,而不是对于ci的一般操作的约束21。如果我们想声明指涉到常量的指针,我们应该这么办:

const int *ip3 = &i;
i = 10; // 没问题,约束的不是i的一般操作而是通过ip3对i的操作
*ip3 = 10; // 错误!  ```
这里我们就有了一个指涉到`const int`型别的指针,而这个`const int`型别对象又是一个普通int型别对象的引用。这里的常量性仅仅限制了我们能通过ip3做什么事。这不表明i不会变,只是对它的修改不能通过ip3进行。如果我们再把问题说细一点,请看下面这个把`const`和`volatile`结合使用的例子:

extern const volatile time_t clock;`
这个const饰词的存在表明我们未被允许(在代码中显式地直接)修改变量clock的值,但是同时存在volatile饰词说明clock的值肯定还是会通过其他途径发生变更22。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值