指向常量的指针,指针常量,指向常量的指针常量

  指向常量的指针,指针常量,指向常量的指针常量

呵呵,光是看见这些字就让人糊涂了,其中第一个还经常被称为为常量指针,它们分别对应如下情况:
const int* pi; int const *pi;
int* const pi;
const int* const pi;
除了字母 pi 肯定排在最右边以外,要正确的把左边“ const ”、“ * ”、“ int ”和“空格”这几个写出来都不容易啊。
 
其实,要记住也不难。
首先要明确, pi 是一个变量,是指针类型的变量, *pi pi 指向的内容,是 int 。对于上面举的例子来说, int 可以当它是透明的,关键看 const 是修饰什么的。
先看第一个: const int* pi int const *pi ,把 int 去掉,那么变成 const * pc const *pc ,呵呵现在变得明朗了, const 就是修饰 *pi 的(至于中间有个空格,确实费劲, int* p int *p int * p 等价,再晕),因此 *pi 是常量,就是说, pi 指向的内容(是 *pi )不可变,但 pi (本身的值,即 pi 指向的地址)可变。
例如:
int a=1;
const int* pi=&a;//ok,pi 本身可变
*pi=a;//error,pi 指向的内容不可变
pi=&a;//ok,pi 本身可变
再看:
int a=1;
const int* pi=&a;//ok,pi 本身可变
pi=&a;//ok,pi 本身可变
a=9;
cout<<*pi<<endl;
int b=8;
pi=&b;
cout<<*pi<<endl;
结果输出 9 8 ,诡异吧, *pi 是常量,不可直接赋值,但在这里却可以通过修改它指向的地址的内容来进行修改。这就是指向的内容不可变,利用指向的地址可变来修改指向的内容,拗口!
 
再看第二个: int* const pi; int 去掉,那么变成 * const pi ,显然 const 修饰的是 pi ,即 pi 的值不可变,也就是说 pi 指向的地址不可变,但该地址的内容(即 *pi )可变。
例如:
int a=1;
int* const pi=&a;//ok pi 本身不可变,但 const 有一次初始化的机会
*pi=a;//ok pi 指向的内容可变
pi=&a;//error pi 本身是 const ,不可变
 
最后看第三个: const int* const pi; 有了前面两个的基础,其实这个问题已经解决了。
例如:
int a=1;
const int * const pi=&a;//ok pi 本身不可变,但 const 有一次初始化的机会
*pi=a;//error pi 指向的内容不可变
pi=&a;//error pi 本身是 const ,不可变
 
最后,来看一个常见的现象:
char * pc = "Hello";
    *pc = 'W';
上述代码在 vc debug 模式编译没有问题,但运行出错。原因在于“ Hello ”是一个常量,上述代码相当于:
const char * pc = "Hello";
    *pc = 'W';
此时第二行不能通过编译,从上面的分析我们知道原因是什么。
但在 release 模式下呢?如下代码:
char * pc = "Hello";
    *pc = 'W';
cout<<*pc<<endl;
输出结果是“ W ”,这不过是一种极度危险的运行成功而已,因为编译器总是假定 release 模式已经经过了 debug 模式的检查,为了效率的优化,它去掉了这种检查,放弃了对常量的保护。
 
题外话:有两个东西已经困扰了我好几年了,就是斜杠和反斜杠怎么区分??我一直没有找到好的方法,到现在还是分不清“ / ”和“ / ”!救命!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值