指针常量、常量指针、指向常量的指针常量,这三个概念让很多人感到拗口,不好记住。但是只要你仔细研究,其实也就这么回事。
一. 指针常量
1. 所谓的指针常量指的是指针是一个常量,也就是常指针,和我们平时说的常量一样,指针指向的内存空间的地址是无法改变的
2. 声明一个指针常量 int* const p = &a,定义一个指针p并且该指针是常量只能指向变量a。记住指针常量只能在定义的时候初始化一次,其它地方不能再对它赋值,例如 p = &b就是错误的写法
3. 看下面的例子
int main(){ char str1[] = "hello"; char str2[] = "world"; char* const p1 = str1; char* const p2 = str2; //test cout<<p1<<endl; //输出"hello" cout<<p2<<endl; //输出"world" *p1 = 'H'; *p2 = 'W'; cout<<p1<<endl; //输出"Hello",说明指针指向的内存空间可修改 cout<<p2<<endl; //输出"World",说明指针指向的内存空间可修改 //会报错 //p1 = p2; //报错,不允许把p1指向其它地址空间 //p2 = p1; //报错,不允许把p2指向其它地址空间 return 0; }
二. 常量指针
1. 常量指针指的是指向常量的指针,指针指向的内存空间可以改变,但是指针指向的内存空间的值不允许改变(也就是不允许通过指针来修改内存空间的内容)
2. 声明一个常量指针 const char *p;p = &str;定义了一个指针变量p,p指向的str的内存空间并且不允许通过p去修改str的内容
3. 指针可以指向不同的地址空间
4. 看下面的例子
int main(){ char str1[] = "hello"; char str2[] = "world"; const char *p1 = str1; const char *p2 = str2; //test cout<<p1<<endl; //输出"hello" cout<<p2<<endl; //输出"world" //报错语句 //*p1 = 'H'; //报错,说明不允许通过指针p1修改str1的内容 //*p2 = 'W'; //报错,说明不允许通过指针p2修改str2的内容 p1 = p2; cout<<p1<<endl; //输出"world",说明指针p1可以指向其它地址空间 return 0; }
三. 指向常量的指针常量
1. 指向常量的指针常量,表示指针是一个常指针,并且指针指向的内容不允许修改。说明指针指向的内存地址不能改变,并且也不能通过指针修改变量的值
2. 声明一个指向常量的指针变量 const char* const p = &str; 定义指针p是常指针,并且变量str的内容不能通过指针p修改
3. 看下面例子
int main(){ char str1[] = "hello"; char str2[] = "world"; const char* const p1 = str1; const char* const p2 = str2; //test cout<<p1<<endl; //输出"hello" cout<<p2<<endl; //输出"world" //报错 //*p1 = 'H'; //说明不允许通过指针p1修改str1的内容 //*p2 = 'W'; //说明不允许通过指针p2修改str2的内容 //报错 //p1 = p2; //说明指针p1不允许指向别的地址空间 //p2 = p1; //说明指针p2不允许指向别的地址空间 return 0; }
记忆法:const在谁前面谁就是常量。
char* const p = &str; const在p前面说明指针p是常量,即指针常量
const char *p = &str; const在char前面说明变量是常量,即常量指针
const char* const p = &str;const既在char前面又在p前面说明是指向常量的指针常量