首先:需要指出的是指针常量和常量指针都是和const有关系。都是有和const有关的属性。
1:指针常量 ,定义形式 int *const p1;
2:常量指针,定义形式 int const*p2或const int*p3;
我们先来将名称(指针常量和常量指针)和定义形式,联系起来。因为我们要将(名称和定义融合到概念的理解中去)
1:指针常量:先定义指针 (int *)(把指针定义符号理解为指针),第二,定义常量中的常(const),第三定义常量中的量,也就是信号名称 p1。
2:常量指针:先定义常量中的常 int const ,第二定义指针*p2。
把上面记下来,然后,可以自己在草稿纸上,写上几遍,于是我们便记住了指针常量和常量指针的定义形式了。
接下来,我们看名称。尝试从名称中理解;
1)指针常量:本质上还是常量,而常量最重要的性质:(一)不可被修改。(二)声明和定义时,必须被初始化。指针常量具有常量的以上两种特性。而指针常量和整形常量一样,不同的是指针常量。只能存储的是地址,整形常量中存储的是,整形数。指针常量,可以指向常量,也可以指向变量。
2)常量指针:本质上还是指针,不过前面的修饰语“常量”,需要注意的是常量指针,本身可以指向常量,可以指向变量。其常量修饰,只是限定了,其不能通过指针引用改变指向变量或常量的值
闲话少说,看代码
#include<iostream>
using namespace std;
int main()
{
int a124=124;
int a125=125;
int *const a123=&a124; /*指针常量,本质是常量,它必须指向常量,但是普通指针也能指向常量,指针常量也必须在定义时初始化*/
/*尝试一下,吧指针常量赋值其他变量,的地址*/
a123=&a125; /*这里是非法操作,因为试图修改指针常量的值*/
int *const a128; /*这也是错误情况,因为指针常量在定义时,没有初始化赋值*/
const int a126= 126;
const int a127= 127; /*定义两个常量a125,和a127来供下面定义的常量指针使用*/
int const *p2; /*这里定义了一个常量指针,常量指针不需要再声明定义时必须得初始化*/
p2 = &a126;
cout<<p2<<endl;
p2 =&a127;
*p2=129; /*这是一个非法操作,因为在尝试通过常量指针,修改a127的值
cout<<p2<<endl;
p2=a124; /*这是一个合法操作,编译时不会报错*/
*p2=130; /*这也是一个非法操作,尝试通过常量指针,修改a124的值*/
return 0;
}
输出结果如上图;我们看到指针常量,定义时,必须初始化,它可以指向基类型相同的任何变量或常量的地址。然后就此封印。不能再改变,不能再指向其他变量了。常量指针,能指向任何变量或常量,但是不能通过,(*p)= 123去改变指向数据的值。
延伸扩展1:
const int a = 25;
const int * const b = &a;
int c=26;
const int * const d=&c;//这也是一个合法的操作
这是非常特殊的,可以理解为 先定义一个指针常量(int*const b)这部分限定了,该指针指向一个地址后就不能再变化,(const int *)限定了,该指针指向某个(常量或变量后),不能再通过*p格式,来改变改变量的值,我们把这种变量叫做:常指针。
常指针定义声明时,非必须初始化。
指针常量:声明和定义时,必须初始化。
总结:那常量指针与指针指针的使用场景如何:
1:常量指针,即常指针。它指向一个(变量或常量后),不能通过指针引用,来修改这个值。
要先了解为什么c规范中,要定义常量指针或指针常量,先看一段代码
int main()
{ const int A=100;
int *p1;
p1=&A;
printf("第一次使用指针指向常量,使用*p1格式打印A的值=%d\n",*p1);
*p1=200;
printf("第一次使用指针修改了常量,使用*p1格式打印A的值=%d\n",*p1);
return 0;
}
这一点,可能是C规范中的,一个小BUG。客户定义的常量是可以通过指针修改的。
这就出现了,一个问题。如果我们频繁的使用指针来调用变量。可能就会把指针指向用户定义的常量,然后对常量作出修改,导致程序出现bug。
于是常指针就出现了。
#include <stdio.h>
#include <stdlib.h>
int main()
{ const int A=100;
int *p1;
p1=&A;
printf("第一次使用指针指向常量,使用*p1格式打印A的值=%d\n",*p1);
*p1=200;
printf("第二次使用指针修改了常量,使用*p1格式打印A的值=%d\n",*p1);
/*使用常量指针,指向常量,常量不可被修改*/
const int *p2;
const int B=300;
p2=&B;
printf("第一次使用指针指向常量,使用*p2格式打印B的值=%d\n",*p2);
//*p2=A;
// printf("第二次使用指针指向常量,使用*p2格式打印B的值=%d\n",*p2);
p2=&A;
printf("使用常指针指向其他值后,打印B的值=%d",B);
return 0;
}
可以看到,常指针,尝试修改B的值时,编译阶段就会出现错误。把错误18和20行屏蔽掉,再运行代码。
可以看到,常指针指向其他变量后,不会改变常量B的值。
第二种情况:我们只想通过指针来读取数据,而不需要通过指针来对数据进行修改(注意:有些情况下,是必须不能修改数据,只能读取),我们就可以使用常指针。
指针常量 (int*const p3),定义时必须初始化,且之后的程序中是不能被修改,即指针常量中的地址不能再被改变。
场景一:我们定义了一段重要的文本字段“xixihaha38”这是一个重要的密码或激活码!
char*const p3="xixihaha38"
如果使用普通的指针,或常指针,指向“xixihaha38”编译也不会出错,但是如果普通指针或常指针指向其他变量或常量时。我们就会丢失掉“xixihaha38”这个常量字符串。这个问题是比较严重的。
如果使用普通指针,还可能“xixihaha38”被改写。
场景2:当我们使用指针常量指向一个变量时。指针常量会一直指向这个变量,不会改变。
我们可以通过这个指针,时刻关注这个变量的变化,可以用在调试中。