指针常量和指向常量的指针

首先,我们从const 说起。

const 有两种写法格式:const int n=20 和 int const n=20,它们相同吗?毫无疑问它们是相同的,这点务必记住。总之记住const 和 int 哪个放前面哪个放后面没关系,都是一样的。有了这个概念后,我们再来看const int *p 和int const *p,按照你的理解它们相同吗?其实它们也是相同的,还是那句话int 和const的前后位置不影响语义。好了,到现在我们明白了这一对的关系,那么int * const p 和它们相同吗?下面我们具体分析它们的语义。

一、const int *p的语义(当然int const *p也是一样的)

下面先看一个例子:

//********代码开始*******
int a=30;
int b=40;
const int *p=&a;
p=&b;			//1、注意,p可以重新赋值一个新内存地址
b=80;			//2、想想看,这里能用*p=80;来代替吗?当然不能
printf("%d",*pi);//3、输出是80
//********代码结束*******

语义分析:从这个例子中不难看出,p的值可以被修改,即它可以重新指向另一内存地址。但是不能通过*p来修改b的值。为什么呢?

先,const修饰的是整个*p(注意我写的是*p不是p),所以*p是常量,是不能被赋值的(尽管p所指的b是变量,不是常量)。

其次,pi前没有被const修饰,所以p是指针变量,即能被赋值重新指向另一内存地址。

二、int *const p

下面还是先看一个例子:

//********代码开始*******
int a=30;
int b=40;
int *const p=&a;
//p=&b;				4、注意,p不能再这样重新赋值了,即不能再指向另一个新地址。
a=80;				//5、想想看,这里能用*p=80;来代替吗?可以,这里可以通过*p修改a的值
printf("%d",*pi);	//6、输出是80
//********代码结束*******
语义分析:从这段代码有没有发现,pi的值不能重新赋值修改了。它只能永远指向初始化时的内存地址。相反,这次你可以通过*p来修改a的值了。看下面的分析:

首先,p因为有了const的修饰,所以只是一个指针常量。也就是p不能修改了,即p不能重新赋值指向b了(如第4行)

其次,整个*p的前面没有const的修饰,也就是说*p是变量而非常量。所以我们可以通过*p来修改它指向内存a的值(如第5行的注释)

所以我们可以发现,p是指向int变量类型数据的指针常量。

最后总结两句:

1)如果const放在*p前,则不能修改的是*p(即不能这样 *p=80)而不是指p;

2)如果const放在p前,则p不能修改(即不能p=&b)

三、补充三种情况

情况一:int *p指向const int i常量的情况

//********代码开始*******
const int i=30;
int *p;
p=&i;	//可行吗?不行,const int类型的i的地址是不能赋值给
		//指向int类型地址的指针的,否则p岂不是可以修改i的值了吗
//********代码结束*******

我自己试了,虽然有警告,但是可行,而且可以利用p来修改i的值。如*p=100。(当然直接修改i的值肯定不行)所以为了避免我们可以把指针定义为const int *p

情况二:const int *p指向const int i常量的情况

//********代码开始*******
const int i=30;
const int *p;
p=&i;	//两个类型相同,可以这样赋值。
		//很显然,i的值无论是通过p还是i都是不能修改的
//********代码结束*******
情况三:用const int *const p申明的指针

//********代码开始*******
int i=30;
const int *const p;
p=&i;	//你能想象p能够做什么操作吗?p值不能改,
		//也不能通过p的值修改i的值。因为不管是*p还是p都是const的
//********代码结束*******





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值