int const *p和int *const的区别

flymiaomiao 2009-07-03 08:22:29
首先,我是来虚心学习的,希望大家指出我的错误!我用的是Visual C++。
一直都不太清楚int const *p和int *const的区别,在网上找大部分人都解释为:
int const *p中 *p指望的内容不可变,int *const p中p指向的地址不可变。
实例分析下:
#include<iostream.h>
void main()
{
int n=0;
int m=1;
const int *p1 = &n;
int * const p2 = &n;
cout<<*p1<<endl;
cout<<p2<<endl;
p1 = &m; //不能用(*P1=m),可以用(p1=&m)。否则出错。
cout<<(*p1)<<endl;
cout<<p1<<endl;
(*p2) = m; //不能用(p2=&m),可以用(*p2=m)。否则出错。
cout<<p2<<endl;
cout<<*p2<<endl;
}
从2行注释看的确如此。
可是,程序运行的结果为:
0
0x0012FF7C
1
0x0012FF78
0x0012FF7C
1
结果发现*p1的内容变了,由0变成了1。
*p2指向的地址没变 1代替了0原来在内存中的地址。
那么是不是用(p1=&m)能改变*p1的值,用(*p2=m)也不能改变p2的值(地址)呢?再看以下程序:
#include<iostream.h>
void main()
{
int a[]={1,2,3};
int b[]={5,6,7};
int const *p1=a;
int *const p2=b;
cout<<*p1<<endl;
cout<<p1<<endl;
cout<<p2<<endl;
p1++;
cout<<*p1<<endl;
cout<<p1<<endl;
*p2=b[1];
cout<<*p2<<endl;
cout<<p2<<endl;
}
运行发现*p1的值和p1的值都变了;
*p2的值变了,可p2的值不变。
那么是不是可以说:
int const *p只能阻止*p=m,这种语句的赋值,而不能保护*p的值不变。
int *condt p能阻止p=&m,这种语句的赋值,也能保护p的值不变。
求大家指点。

...全文
10041 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
devilFredo 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 baihacker 的回复:]
int const *p和int *const的区别 

前者指向的内容不可改变.
后者指针不能再指向其它的东西了.
[/Quote]

mark
ptshan 2009-12-28
  • 打赏
  • 举报
回复
学习了,楼上讲得很清楚。
lihan6415151528 2009-07-04
  • 打赏
  • 举报
回复
const 是左结合的
ayayazf 2009-07-04
  • 打赏
  • 举报
回复
学习啦!
zhangzhongke007 2009-07-04
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090701/19/541c38b9-a7bb-4a56-98ac-d1457f0c0a86.html?seed=141810448
Fleeboy 2009-07-04
  • 打赏
  • 举报
回复
好像坛子里有个前辈发明了“左内右本”的秘诀,不妨去查查,大概意思是:
const 如果在*的左边,如const int* p = ...; 那么p所指向的内容是常量,指针本身是可以改变的;
const 如果在*的右边,如int* const p = ...; 那么p这个指针本身是常量,但内容是可以改变的;
如果写成这样:
const int* const p = ...;
那么p这个指针本身,以及它所指向的内容都是不能改变的。

Effective C++有一个条款对此有详尽的讲述,可以看看。
飞天御剑流 2009-07-04
  • 打赏
  • 举报
回复
int const *p中 *p指望的内容不可变,int *const p中p指向的地址不可变。
---------------------------------------------------------------
说*p指向的内容不可变的说法都是错误的,基础不过关。第二句话也有问题,虽然我理解作者想说什么,但此说法不准确,准确地说,是p的值不能

被直接赋值,但可以初始化,还可以通过不违反标准的方法去改变它,只是不能进行直接的赋值。之所以说是不违反标准的方法,是因为c/c++标准都规定

尝试对const对象进行修改的行为是未定义的,不同的编译器可能会有不同的处理方法,有的允许,有的可能采取一种叫常量折叠的方法。



对于int const *p,int const并非表示它指向的内容不可变, 而是表示不能通过p改变它指向的对象,p指向的对象不一定是不可改变的对象,例如:

int n = 10;
int const * p = &n;
*p = 20; //非法,不能通过p修改n
n = 20; //合法,n的值依然可改变



现在来看看int * const p中的值是如何用不违反标准的方法去改变的,首先找一个允许这种修改的编译器,例如gcc:

int n = 10;
int j = 20;
int * const p = &n;
int ** k = &p; //不允许
int ** k = (int ** )&p; //允许

为什么int ** k = &p非法?当然是类型不兼容,&p的类型是什么?大概你会糊涂了,&p的类型是int * const *,&p是个二级指针,第一级指向的对象是

const的,而k的第一级指针指向的对象是非const的,把一个指向const对象的指针赋予非const指针违反了兼容性规则。把&p强制转换为int**后就能赋值了。

接着看:

printf("%d\n", *p);
*k = &j; //改变p的值
printf("%d", *p);

第一个*p的值是10,第二个是20,可见p这个const对象的值已经被改变了,从n的地址变成了j的地址。

上面是允许修改的情况,有些编译器可能会直接用p初始化的值在所有用p的地方代替p,这样无论你*k改成什么,在使用p的时候总是那个初始化的值,这叫常

量折叠。
gdtwgz 2009-07-04
  • 打赏
  • 举报
回复
建议楼主看看<C专家编程>,里边对这个问题讲的很好,还有扩展
billow_zhang 2009-07-03
  • 打赏
  • 举报
回复

const int *p1 = &n;
int * const p2 = &n;

1. const int *p1;
这是表示p1是一个指向int数据类型的指针.并且它所指的这个值是不能改变的;也就是说,你不能写: *p1 = 2;这样的语句,否则,在编译的时候就会出错.
但 p 本身的值可以改变, 例如:
const int n;
int vn;

你可以写:
p1 = &n;
p1= &vn;

但最后结果,就是不能写:
*p1 = x;

2. int * const p2;
表示p2指针的值不能改变.它的初始值必须被定义.如果你仅仅向上面那样声明是通过不了编译的.可以声明和定义如下:

int n;
int * const p2 = &n;

在整个程序运行中,p2只能等于n的地址了,不能再改变了,但是它所指向的内容是可以改变的.例如:

*p2 = 3;
但不能再写成:
p2 = &n2了.

如果,你声明:
int n;
const int * const p3 = &n;

则p3本身的值和所指向的值都不能改变了.也就是说,你既不能写 p3 = &n1,也不能写 *p3 = 100了.

实际编程的情况: int * const p的定义很少去用,用的比较多的是 const char * const msg = "Hello";这样的定义, 用于在C++中,代替C中使用宏来定义常量字串的作用.



melucia 2009-07-03
  • 打赏
  • 举报
回复
运行发现*p1的值和p1的值都变了; ???p1的指向是可变的,p1指向其他地方,当然*p也变了。
*p2的值变了,可p2的值不变???这是当然的。
p2是常指针呀,p2所指的方向是不变得,所指空间中的内容可变,p2的值是p2所指的空间地址
mstlq 2009-07-03
  • 打赏
  • 举报
回复
ps:请勿发蛋帖,这样会影响积极性的……
mstlq 2009-07-03
  • 打赏
  • 举报
回复
[Quote=引用楼主 flymiaomiao 的帖子:]
那么是不是可以说:
int const *p只能阻止*p=m,这种语句的赋值,而不能保护*p的值不变。
int *const p能阻止p=&m,这种语句的赋值,也能保护p的值不变。
[/Quote]

是的,楼主确实领会到了真理^_^。
可能有人会不同意你的说法,楼主的表述可能令很多人认为不恰当,不过我确认楼主明白了问题的实质,剩下的只是语文的问题^_^。
baihacker 2009-07-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 blh 的回复:]
蛋贴
[/Quote]
照样回.
blh 2009-07-03
  • 打赏
  • 举报
回复
蛋贴
ljt3969636 2009-07-03
  • 打赏
  • 举报
回复
const修饰指针一共只有三种写法
1类型:const char* p;
表示p指向const类型的对象(其实也可以指向非const对象,但是反过来非const指针不能指向const对象,原因很简单我定义一个类型就是不想他的值,倘若让一个非const指针可以指向他那么岂不是可以通过这个指针修改它的值了?),根本目的在于为了不可以通过p改变p所指对象的值例如:
int i=0,j=0;
const int *pi=&i;//这里就是const指针指向非const对象
i=2;//ok i是非const 值可以改变
*pi=3;//错误pi是指向const对象的指针不可通过它改变指向对象的值
pi=&j;//ok,p是指向const类型的指针,而本身不是const指针,可以改变指向
2类型:char* const p;
这是p常被叫做const指针这个const可以理解为修饰指针p,就是说p一旦指向某对象就不可以再改变指向了,因此要就定义这个const指针时必须初始化
例如 int i=0,j=0;
int * const p=&i;//ok定义时初始化
*p=1;//ok,p不是指向const对象的指针
p=&j;//错误,因为p已经指向i了不能更改指向了
3类型 const char* const p;
就是像两个的综合:既不能通过p改变指向对象值也不可在p初始化后改变指向

另外还有一种写法是 int const *pi=&i和第一种类型写法是一个意思,但是忘记它只记得1类型就OK了.
龙之白云 2009-07-03
  • 打赏
  • 举报
回复
const有就近原则
flymiaomiao 2009-07-03
  • 打赏
  • 举报
回复
LS的看下程序 运行后p1指向的int值被改变了的啊 。
sm_dlkey001 2009-07-03
  • 打赏
  • 举报
回复
int const * | p
p就是一个普通的指针变量,可以指向任意一个int值,但是指向的int值是一个不变常量
int * | const p
p是const常量,p是const所以不能变,也就是p指向的地址不可变,但是指向的地址中对应
的内存是可改变的
风老二 2009-07-03
  • 打赏
  • 举报
回复
int const *p =const int *p呗?
flymiaomiao 2009-07-03
  • 打赏
  • 举报
回复
可是程序运行不是这样的啊?求解
加载更多回复(1)

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧