const 指针的关系主要存存在三种:
1、常指针(const pointer)
int* const p;
2、指针类型的常量(const to pointer)
const int *p; int const *p;
3、指向常量的常指针
const int * const p;
那么这三种不同的类型是如何使用的呢?首先我们来看下面的代码:
#include<iostream> using namespace std; //1、const 和 指针 的关系 int main() { int a = 10; int b = 20; int *p1 = &a; //1、const pointer int * const p2 = &a; //2、const to pointer //这两种方式等价 const int * p3 = &a; //int const * p3 = &a; //3、 const int * const p4 = &a; return 0; }
1、常指针的修改
int main() { cout << *p2 << endl; //10; *p2 = b; //rigth cout << *p2 << endl; //20 p2 = &b; //error }
我们可以发现,在const 修饰指针本身的时候(int *const p2)。我们可以修改指针解引用后的值,但是不能修改指针本身所指向的地址。
2、指针类型的常量的修改
int main() { cout << *p3 << endl; //*p3 = b; //error cout << *p3 << endl; p3 = &b; //right cout << *p3 << endl; }
当指针是一个指向常量的指针时(const int *p3)。我们可以改变指针所指向的对象,但是不能修改指针解引用后的值。
3、指向常量的常指针修改
*p4 = b; //error p4 = &b; //error
当指针是指向常量的常指针的时候,我们既不能修改指针本身,又不能修改指针解引用后的值。
int main() { int a = 10; int b = 20; const int *p = &a; //int *s0 = p; //error,可以通过s0修改p指向的内容的值。 const int *s1 = p; //right,类型匹配 //int * const s2 = p; //error,s2的指向的地址不能改变,但是可以解引用来改变p的值,错误。 const int *const s3 = p; //right return 0; }
int main() { int a = 10; int b = 20; int * const p = &a; int *s0 = p; //right const int *s1 = p; //right int * const s2 = p; //right const int *const s3 = p; //right system("Pause"); return 0; }
int *const p = &a; 这条代码表示p是一个常指针,这个指针所指向的是地址不可改变的。这个常指针存放的是a的地址。其他的指针指向的也是a的地址,这些指针的赋值是正确的。因为常指针仅仅只是规定指针p不可以指向其他的地址,并没有规定其他指针不能改变这个指针解引用的值。况且其他指针的修改也仅仅只是修改这些指针本身(s0、s1、s2、s3)解引用的值(p的值)或者指向的地址,编译可以正常通过。
首先来看一个概念:只读变量(常变量)。
const int n = 5; int a[n]; //C99:error //C++:right //ANSI C规定数组的大小必须是一个常量,常量不等于“不可变的变量”, //但是C++中没有规定。 //常量的定义:enum枚举类型和#define宏定义定义的。 //只读变量:const 来定义。 //原因:常量被编译器存放在内存中的只读区域,不可修改。 // 只读变量会在内存中申请一块空间来存放它的值,只不过是编译器限定的不可修改。
所以说,在C++中我们会将常变量看作为常量。
int main() { const int a = 10; int b = 20; int *p = &a; //error:这样改变解引用的值会修改原先a的值,但是a是 //const类型不可修改,报错。 *p = b; //int *p = const_cast<int *>(&a); }
这段代码编译器会报错,原因如下:
要解决可以使用 C++的标准转换运算符const_cast。
C++提供了四个转换运算符来移除变量的const限定符:
只需将代码改为 int *p = const_cast<int *>(&a); 即可移除变量a的const 限定符,实现初始化。
未完… …