关闭

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

标签: C-C++指针常量指向常量的指针
196人阅读 评论(0) 收藏 举报
分类:

首先,我们从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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6179次
    • 积分:193
    • 等级:
    • 排名:千里之外
    • 原创:11篇
    • 转载:11篇
    • 译文:0篇
    • 评论:0条