const int *p *p不可改 p可改
int* const p *p可改 p不可改
int const * p 等同于const int*p
这里,我再补充以下三种情况。其实只要上面的语义搞清楚了,这三种情况也就已经被包含了。不过作为三种具体的形式,我还是简单提一下吧!
情况一:int * pi指针指向const int i常量的情况
const int i1=40;
int *pi;
pi=&i1;//这样可以吗?不行,VC下是编译错。
//const int 类型的i1的地址是不能赋值给指向int 类型地址的指针pi的。否则pi岂不是能修改i1的值了吗!
pi=(int* ) &i1; // 这样可以吗?强制类型转换可是C所支持的。
//VC下编译通过,但是仍不能通过*pi=80来修改i1的值。去试试吧!看看具体的怎样。
C++中常量一般是不分配存储空间的。严格的来说,是否对常量分配存储空间,依赖于对它如何使用。如当对常量取地址或者是将常量声明为extern类型的,编译器便会为其分配存储空间,否则,常量只是保存在符号表里。当读取常量的值时,是去符号表里取其相应的值,如果读取地址,则是为常量分配一个与其值相等的常量(具有存储空间),可以通过对地址作强制类型转换,对这个分配存储空间的常量作修改。
也就是说,在编译阶段所有涉及到i1的地方都会用40代替,而p1=(int *)&i1是强制转换i1在内存中复制的常量,强制转换后其值可以被修改,但修改的只是*p1,i1还是40
*p1 = 80;
printf("%d\n",*p1);// 80
printf("%d\n",i1); //40
情况二:const int * pi指针指向const int i1的情况
const int i1=40;
const int * pi;
pi=&i1;//两个类型相同,可以这样赋值。很显然,i1的值无论是通过pi还是i1都不能修改的。
情况三:用const int * const pi申明的指针
int i
const int * const pi=&i;//你能想象pi能够作什么操作吗?pi值不能改,也不能通过pi修改i的值。因为不管是*pi还是pi都是const的。