返回信息流如下:const int a=2
int *p
p=const_cast<int*>(&a);
cout<<*p<<endl<<a<<endl;
*p=10;
cout<<*p<<endl<<a<<endl
我想问下,这里p指针变量的值明明跟a的地址是一样的,a也声明为常量不可变了,但是对*p改变这算怎么回事,这里p跟&a值始终是一样的,相同的地址下可能有不同的值吗?
谢谢啦
这是一条镜像帖。来源:北邮人论坛 / cpp / #82996同步于 2014/10/2
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
关于地址对应的数值
casemonkey
2014/10/2镜像同步9 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
先说第二个问题,没有编译运行过,但猜想最后一句的输出应该是10和2,碰到这种奇怪问题,不应该是得出“相同的地址下可能有不同的值”这种毁三观的结论,而应该是首先怀疑编译器是不是做了什么手脚,一般而言,编译器看到a,并且a是个常量整数,就直接把a替换成2了,因为编译器觉得a的值不会变化。cout<<*p<<endl<<2<<endl
如果没有&a这个取地址,编译器会直接把所有的a替换成2,跟预处理的宏差不多,a根本不占内存。但因为有&a这个语句,编译器就会在内存里开辟出一个空间来存放a,以保证编译不会出错,这时可以用另一个非常量的指针来改变内存的值,但这不意味着以后访问a的时候编译器会从这块内存里重新读取值。
如果想看到10和10 的情况,可以强迫编译器每次访问a的时候都从内存里重新读取值,第一句换成这样volatile const int a=2
【 在 casemonkey 的大作中提到: 】
: 如下:const int a=2
: int *p
: p=const_cast<int*>(&a);
: ...................
这个问题以前有人问过。const是对变量做的一个约束,目前的编译器实现是从逻辑上对const变量不可变,在编译期间从语法上确定的不可改变。const修饰的变量一般来说处于的内存区域是可读写的,所以可以通过指针改变那块内存的值。至于“相同的地址下可能有不同的值吗? ”这个问题,第二个输出语句输出的是10和2,你查看对应的汇编码就会发现,那是因为在编译时发现a不可改变,编译器优化了,直接使用2替换了a变量,减少了内存的读取。所以输出10,2。
又学了个新东西
【 在 gaoweiwei 的大作中提到: 】
: 先说第二个问题,没有编译运行过,但猜想最后一句的输出应该是10和2,碰到这种奇怪问题,不应该是得出“相同的地址下可能有不同的值”这种毁三观的结论,而应该是首先怀疑编译器是不是做了什么手脚,一般而言,编译器看到a,并且a是个常量整数,就直接把a替换成2了,因为编译器觉得a的值不会变化。cout<<*p<<endl<<2<<endl
: 如果没有&a这个取地址,编译器会直接把所有的a替换成2,跟预处理的宏差不多,a根本不占内存。但因为有&a这个语句,编译器就会在内存里开辟出一个空间来存放a,以保证编译不会出错,这时可以用另一个非常量的指针来改变内存的值,但这不意味着以后访问a的时候编译器会从这块内存里重新读取值。
: 如果想看到10和10 的情况,可以强迫编译器每次访问a的时候都从内存里重新读取值,第一句换成这样volatile const int a=2
这种东西一般交由编译器自己弄,标准不管,不推荐这样写,所以跟编译器实现有关
【 在 casemonkey (小白||坚持己心||戒躁||offer会有的) 的大作中提到: 】
: 如下:const int a=2
: int *p
: p=const_cast<int*>(&a);
: ...................
通过『我邮2.0』发布