首先上几行代码说明下const:
int a = 100, b = 200;
int const *p1 = &a;//注意const的位置
int * const p2 = &a;
//*p1 = 200; 有'//'的都是编译报错的,下面就不说明了
p1 = &b;
//p2 = &b;
*p2 = 100;
在指针里,const修饰的是紧跟的内容,比如这边的p1那一行,修饰的就是*p1,所以*p1是一个常量,无法修改,而p1不是常量,是可以被修改的。再看p2,这次我让const修饰的是p2,这样p2自然无法被修改,而*p2是可以被修改的。
有一点先说一下,int const* p1 和 const int * p1是一样的,都是在修饰*p1,这里和int位置无关。
再解释一下上面的内容,const修饰*p1时,常量是指针p1指向地址内的值,也就是p1指向的a是一个常量,无法修改。const修饰p2时,常量是p2,也就是说这个指针是个常量,它不能指向别的地方。
再看代码:
int a = 100, b = 200, c = 300;
int const* p1 = &a;
int * p2 = &b;
int *const p3 = &c;
p1 = p2;
p1 = p3;
//p2 = p1;
p2 = p3;
//p3 = p1;
//p3 = p2;
先说报错的那几个,直接看p3,const直接修饰p3,所以这个指针不能修改,也就是说p3不能作为左值,所以最后两个都不行。
然后看p2 = p1这个,因为const修饰了*p1,所以*p1是无法修改的,而p2是int*类型,它是可以修改放在里面的内容的(就是可以修改*p2),那么我们把p1分配给p2后,是不是就可以用*p2来代替*p1来修改*p1里内容的值了?,但定义p1时,我们加const不希望*p1被修改,所以这个转换是不行的。
还是看p2的(p2 = p3这个),这个为什么可以呢?我们看p3,const修饰的是p3,就是说p3为常量指针,而*p3可以修改。这时我们把p3分配给p2,p2通过*p2修改的是c的值,可以修改,如果把p2再指向别的地址(比如p2 = p4,没定义p4,自己想象),p3指向的地址是不变的,所以这个式子是没有问题的。从这里可以看出,p3作为右值是完全没问题的,所以p1 = p3也是对的。
还剩下p1 = p2,p2是没什么限制的一个指针,分配给p1自然是没问题的,而且p1无法修改其中的内容,相当于只可读,而p2访问的是b,显然是可读的。