请问:一个内存地址,居然可以存在两个不同的值,为什么可以?

Jackson1997__ 2017-10-02 05:29:51
如题,现在一脸懵中

#include<iostream>
using namespace std;
int main()
{
const int a = 10;
const int * p = &a;
int *q;
q = const_cast<int *>(p);
*q = 20; //fine
cout <<a<<" "<<*p<<" "<<*q<<endl;
cout <<&a<<" "<<p<<" "<<q<<endl;
return 0;
}

运行结果:
10 20 20
002CFAF4 002CFAF4 002CFAF4
...全文
759 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
自信男孩 2017-11-07
  • 打赏
  • 举报
回复
引用 18 楼 zhu339111520 的回复:
就一句话: 指针是一种特殊类型的变量, 遵循变量的特性,可以拷贝和复制
对野指针进行拷贝数据是不行的。所以这句话不够严谨。
自信男孩 2017-11-07
  • 打赏
  • 举报
回复
https://www.zhihu.com/question/19772701/answer/20426924 const_cast的用法不是将一个const变量变成非const变量的.看一下标准就可以知道,使用const_cast把一个原本是const的变量转换为非const,这是一个未定义行为.所以楼主所说const_castthis->.....是非常非常危险的举动.const_cast的目的,在于某些变量原本不是const的,但由于某种特殊原因,无意间被变成了const的,例如使用了一个const引用指向了一个本来不是const的对象.结果写了一些代码之后发现它实际上需要被修改. 这在平时的工作中不会遇到因为你可以直接把const引用修改成非const的,但C++中可能的情况太多,尤其考虑到很多复用的时候,有时还是会出现本不该是const的对象被const引用了这种情况.尤其是使用模板,比较复杂的情况.这才是const_cast的意义所在.想了解const_cast使用中可能出现的未定义行为,可参考如下代码:int main(){const int k=10;int& x=const_cast<int>(k);x=11;return k;}这段代码中出现的就是典型的const_cast的未定义行为,return的值是完全不确定的,全看编译器心情.而以下代码是正确的:int main(){int k=10;const int& ref=k;int& x=const_cast<int>(ref);x=11;return k;}
自信男孩 2017-11-07
  • 打赏
  • 举报
回复
引用 4 楼 hdt 的回复:
const 类型的变量,也叫做常量。就是永远也不变的量。 既然是常量,编译器就可以直接用字面值代替变量。 比如你的代码 cout<<a<<.... 编译器可以直接编译为 cout<<10<<...
这个“永远也不变的量”,这句话需要加个引号哦;他不能变只是说明不能通过a去改变这个值,但是不等于不能通过其他路径来修改这个值。
FD_2013 2017-11-07
  • 打赏
  • 举报
回复
就一句话: 指针是一种特殊类型的变量, 遵循变量的特性,可以拷贝和复制
enaxM 2017-11-06
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
理解讨论之前请先学会如何观察! 电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息…… http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素
hello, android
悟了个空 2017-10-10
  • 打赏
  • 举报
回复
const不是不能再改变, 只是告诉我们不要去修改
bravery36 2017-10-10
  • 打赏
  • 举报
回复
编译器认为常量不会被修改,直接在用到a的地方用10替换了,还有就是这种代码很傻。
赵4老师 2017-10-10
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他!) VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素
赵4老师 2017-10-10
  • 打赏
  • 举报
回复
不要纠结各种常量了,这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢!
zilaishuichina 2017-10-10
  • 打赏
  • 举报
回复 1
你的代码, 编译器优化成了如下代码:

#include<iostream>
using namespace std;
int main()
{
    const int a = 10;
    const int * p = &a;
    int *q;
    q = const_cast<int *>(p);
    *q = 20;    //fine
    cout << 10 <<" "<<*p<<" "<<*q<<endl;  // ps:此处的常量a会被优化成10
    cout << &a <<" "<<p<<" "<<q<<endl;
    return 0;
}
tnt阿信 2017-10-03
  • 打赏
  • 举报
回复
引用 楼主 qq448545478 的回复:
如题,现在一脸懵中

#include<iostream>
using namespace std;
int main()
{
    const int a = 10;
    const int * p = &a;
    int *q;
    q = const_cast<int *>(p);
    *q = 20;    //fine
    cout <<a<<" "<<*p<<" "<<*q<<endl;
    cout <<&a<<" "<<p<<" "<<q<<endl;
    return 0;
}
运行结果: 10 20 20 002CFAF4 002CFAF4 002CFAF4
此处一个存储地址并没有存储两个值,a的确存储了10,p存储着a的地址,q被赋值为p所以他也是存储的a的地址,至于输出结果,就是一些指针的基本取值操作而已,请题主自行百度指针
xskxzr 2017-10-03
  • 打赏
  • 举报
回复
并不fine,修改常量是未定义行为,也就是说编译器会假设常量不会被修改来翻译/优化程序,在你这个例子里,编译器就直接把常量用字面值替代了。
真相重于对错 2017-10-02
  • 打赏
  • 举报
回复
既然是常量,没有必要像普通变量一样在运行时求它的值 编译器是在编译时直接把他的值写入,需要他的语句里
真相重于对错 2017-10-02
  • 打赏
  • 举报
回复
引用 7 楼 qq448545478 的回复:
在知乎搜到这样的回答。不知道这样理解可不可以。 const的常量是存在一个常量表里的,可能是寄存器里吧? 编译后,a的值从寄存器里直接取,所以a就是10了,
知乎在瞎说,寄存器本来就是经常变化的。 反编译一下,就知道了 cout<<a<< endl;这是源码 0136165A mov esi,esp 0136165C mov eax,dword ptr [__imp_std::endl (136A2F0h)] 01361661 push eax 01361662 mov edi,esp 01361664 push 0Ah 注意这里 01361666 mov ecx,dword ptr [__imp_std::cout (136A2ECh)] 0136166C call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (136A2E8h)]
Jackson1997__ 2017-10-02
  • 打赏
  • 举报
回复
在知乎搜到这样的回答。不知道这样理解可不可以。 const的常量是存在一个常量表里的,可能是寄存器里吧? 编译后,a的值从寄存器里直接取,所以a就是10了,
Jackson1997__ 2017-10-02
  • 打赏
  • 举报
回复
引用 5 楼 s709323361 的回复:
只有a是一个实际存储数据的变量,p和q都只是指向a所在的地址
q修改了p的值,那么a也应当改变的
JamesShao-23 2017-10-02
  • 打赏
  • 举报
回复
只有a是一个实际存储数据的变量,p和q都只是指向a所在的地址
热血打工人 2017-10-02
  • 打赏
  • 举报
回复
a是整数,&a是指针的地址。 同理,p,q是指针,指向了地址。 *p,*q是指针所指向的数据。
真相重于对错 2017-10-02
  • 打赏
  • 举报
回复
const 类型的变量,也叫做常量。就是永远也不变的量。 既然是常量,编译器就可以直接用字面值代替变量。 比如你的代码 cout<<a<<.... 编译器可以直接编译为 cout<<10<<...
真相重于对错 2017-10-02
  • 打赏
  • 举报
回复
const int 是不能改变的。 那段地址的数据确实已经变成的20,但是如果你看反汇编的话,你会发现。所有涉及到a的语句都是直接用0Ah代替a,所以那段地址的内容无论如何变,你对a的访问只能得到10
加载更多回复(1)

64,659

社区成员

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

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