const到底是什么 二. 基本用法


const最基本的用法就是对一个变量的声明限制, 是和普通的变量声明放在一起的. 比如

const int myInteger = 5;

不过这种声明是在编译阶段就要有的一种约束, 这个关键字是为编译器所使用的. 注意这句话, const是应用于编译器检查的, 不是一个运行时的属性.
那么就可以回答前文的一个问题, 在内存中int和const int有什么区别呢? 可以说, 完全没有区别, 他们是一回事.

比如我写个例子.

const int myConst = 10;
int* pConst = const_cast<int*>(&myConst);
*pConst = 100;
printf("address(myConst) = %d, pConst = %d/n", &myConst, pConst);
printf("value(myConst) = %d, *pConst = %d/n", myConst, *pConst);

大家先不忙往下看, 在这段代码执行之前, 先预测一下执行的结果会是什么样呢?

首先, 两个地址是同一个内存. 其次, 输出的数据一个是10, 一个是100. 这下估计很多朋友要大吃一惊了, 为什么同样的一个内存里居然会保存两个数据... 呵呵, 这就是const所谓的编译规则, 而不是运行时规则. 大家理解一下哦.


在编译的时候, 编译器已经对被声明为const的变量在引用处已经进行了优化. 因为这对编译器来说很合理啊, 反正你的这个变量是不可修改的, 那么为了提高效率, 我在运行时就把它的值用起来, 何必要等到运行时再取呢? 于是第二个printf语句被编译器作了个优化, 实际上是形如如下的伪码了.
printf("value(myConst)=%d, *pConst=%d/n"), 10, *pConst);

这是一个比较隐晦的问题, 但是我很乐意把它拿到开始来与大家分享, 因为这是const用法的指导原责.

 

好, 现在我们回到
const int myInteger = 5;
接着往下推理一下规则吧. 既然是一个常量是不可以修改的, 那么其他的赋值语句, 就是不可接受的. 这时再来一个myInteger = 10;就会被编译器视为一个错误. 好了, 这样一个声明的格式被接受, 一个赋值的语句被报错, 我们又可以生成一个新的规则, 即const所声明的东西, 必须是在初始化之前时有值.

那么, 请大家再看下面的句子.
int a = 10;
int b = 5;
const int* pInt = &a;
pInt = &b;
这段代码却是没有问题的, 会不会有人又很奇怪呢? 这不是和刚才说的"const声明的东西必须是在初始化之前时有值". 矛盾吗? 不矛盾, 请注意看清楚前面是写作const int myInteger = 5; const修饰的目标是int, 表示说这是一个int型的常量. 而后边的写法很容易让人混淆, const int* pInt; 那个*号是服务于pInt, 而不是服务于int的. 这个声明的意思是, 声明了一个指向常量的指针. 再换句话说, 不允许用户通过这个指针改变任何一个变量的值... 对于这个指针指向哪里可没有任何约束的... 哈哈哈. 于是我们反推出一个结论,
int* p, q; 是什么意思? 它声明了一个int变量q, 一个int型指针p. 那个*号是和int无关的. 那么大家在声明的时候, 为了规范和减少别人误解的可能(后期维护人员的水平可不一定比你高), 还是请写成这个样子: int *p, q; 这个*号修饰谁, 我们就把它放在什么地方...

如果你想用const约束一个指针, 那么请写作如下
const int a = 10;
const int b = 5;
int* const pInt = &a;     //通过
pInt = &b;         //失败
这就看出, const直接修饰的目标是不可改的. 现在const已经在修饰一个指针类型了, 所以给它重新赋一个地址, 就是不可接受的. 同时, 也看出C++的一个词法上的不足之处. 它在声明指针类型时, 推荐*与变量名为一个整体, 以区分另一个指针变量. 但是在声明const时, 却又使用类型*的格式实现. 这是一个容易混淆的地方. 须注意.


那么我再极端一点作下面的操作,
int a = 10;
int* const pA = &a; 会发生什么呢?
希望您不要被刚才的一大端const给弄糊涂. 这段代码是错的. 因为赋值号两端的数据类型完全不匹配. 左边的类型是int* const, 右边的类型是int*

好了, 说到底, 我们现在可以得出下面的几个结论了:
1. const是编译时的声明
2. const只修饰它直接服务的目标, 并对针对它的操作进行限制
3. const也是类型声明的一部分.
4. const对声明的风格也会有适当的要求.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值