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

来源:互联网 发布:amos软件怎么读 编辑:程序博客网 时间:2024/05/19 04:28

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

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