const 指针出现的值不一致

kindsky 2006-02-10 11:16:19
const int x = 2;
int *y = (int *)&x;
*y = 3;
cout << y << ":" << *y << " " << &x << ":" << *(&x) << endl;

程序运行后的结构是
y和x的地址一样,然而他们值确实不一样的啊
...全文
228 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
windforce05 2006-02-13
  • 打赏
  • 举报
回复
我试过不同的C编译器会产生不同的结果。

而我上次讲的是针对一个很旧的编译器的。查了资料,目前的C编译器主要都是eric8231(1328cire)所讲的这种处理模式。

不过在实际编程中,除非是一个逻辑错误的程序,否则一般不会像lz那样去使用它。

这个就是我的看法。
losedxyz 2006-02-12
  • 打赏
  • 举报
回复
现在有三版本.哪个是正确的?
cenlmmx 2006-02-11
  • 打赏
  • 举报
回复
对于现在主流的编译器,代码const int x = 2;当后面用到变量x的时候,编译器会优化掉对x的存取,而直接使用立即数2.所以出现y和x的地址一样,然而他们值确实不一样.
chengzanmiao 2006-02-11
  • 打赏
  • 举报
回复
mark
ericqxg007 2006-02-11
  • 打赏
  • 举报
回复
应该是把x的地址赋给y的时候使用了强制类型转换
把const int* 转换成了 int *
如果去掉int * 强制类型转换的话 就会看到编译器报错
shenjonken 2006-02-11
  • 打赏
  • 举报
回复

int *y = (int *)&x;//这一句其实真的是没用的话
首先因为(int *)&x一句的意思是把X的CONST INT*的地址转为INT*的地址,也就是把常量区的地址转为一般的栈地址,产生一个INT*的临时对象,然后把这个地址给这个临时对象,然后把他的地址再传给INT* Y,所以出现了一样的地址,不一样的结果.因为这里面的结果都是内存的偏移量,一样没什么稀奇的,一个是常量区,一个是栈区,不信你们可以去试着修改x的值,一定失败,y的值,一定没没问题
xyjchinese 2006-02-11
  • 打赏
  • 举报
回复
没看明白.......-_-
Jiana 2006-02-11
  • 打赏
  • 举报
回复
scott的书说过,为了防止const常量被修改,const常量在内存有两个副本,一个在一般的地址(const int x;&x得到这个地址值),你这种情况就把这个地址所指的int值改了。另一个地址在某个我们不知道的地方,我们无法修改,所以用x取的值就保证不变为2。所以就有两个值。cout<<*&x编译器会优化成cout<<x,如果用的是cout<<*(int*)(&x)值为一般地址的3,
sankt 2006-02-11
  • 打赏
  • 举报
回复
编译器做了优化
const int x = 2;
int *y = (int *)&x;
*y = 3;
cout << y << ":" << *y << " " << &x << ":" << *(&x) << endl;

//==========
遇到x时,直接用2代替了


windforce05 2006-02-11
  • 打赏
  • 举报
回复
编程测试如下:
int a = 1;
const int x = 2;
int *y = &a;
printf("%x%x", &x, &a);
看看,a与x的地址差距就知道了。
windforce05 2006-02-11
  • 打赏
  • 举报
回复
我不同意eric8231的看法,你们认为呢?

并且通过编程验证了eric8231的看法是错误的。
windforce05 2006-02-11
  • 打赏
  • 举报
回复
其实这个答案很简单:

在有些偷懒的编译器中,const所分配的常量也是在内存中的,所以对y所指向的内存进行赋值的时候能够成功。对x赋值不功能是由编译器在编译的时候判断的。

你可以尝试着把指针y的地址和x的地址都显示出来,如果地址连续,表明x是分配在内存中,而不是分配在const区域。反之,有一些编译器很好的,它是分配在不同的区间段的。
kinglytt 2006-02-11
  • 打赏
  • 举报
回复
eric8231老兄说的很清楚了。
编译器由于这一句,int *y = (int *)&x,确实给x分配了内存。
楼主写*(&x)的本意是想取内存中的x的值,但是现在的编译器看到这句,会毫不犹豫的把它直接优化成2。

若想躲过编译器的优化,只能分两步写。
const int *z = &x;
cout << (*z);
但这时的z和y其实时一样的了。
CSDNWW 2006-02-11
  • 打赏
  • 举报
回复
顶eric8231
eric8231 2006-02-11
  • 打赏
  • 举报
回复
老问题了。
1. 编译器通常会把常量以“<名字,值>”的形式存放在符号表中,此后若用到这个常量,就直接从符号表中查。

2. 通常情况下编译器可能不会为常量分配内存,但当你取一个常量地址时,仍会为常量分配内存,以便让你可以得到这个地址。此时,这个地址对应的内存中存放的值,只是符号表中相应的常量值的一个副本。 所以,你可以通过指针修改这个值,但无论如何,你不能修改符号表中的那个值
problemMan 2006-02-11
  • 打赏
  • 举报
回复
我觉得是不是存储常量的地址和存储临时变量的地址段不同,所以在把常量地址付给栈中地址时,需要一个副本!副本地址就是Y,
fayzhou 2006-02-10
  • 打赏
  • 举报
回复
这题挺有意思,如果把const去掉,x,y值就都变成3了
难道针对const修饰的数据存储在别的特定的内存位置?
xyjchinese 2006-02-10
  • 打赏
  • 举报
回复
怪啊,真的哦,我太菜了,不清楚为啥.估计基地址不一样吧

64,691

社区成员

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

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