谁能解释下这个问题!巨诡异!!!!!!!!!!!!!!!!!!!! #include "stdio.h"void main(){ const int n = 0; int *p=(int*)(&n); *p = 255; printf("%d %d %d %d\n", n, *p, *&n, *(int*)&n);}输出:0 255 0 255何解? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 引用,解引用是不是疑惑在const上? int *p=(int*)(&n); 这就是一个错误。要真想知道为啥,你搜索一下 常量折叠。 这里出现的const采用了类似宏替换方式。http://c.chinaitlab.com/ccjq/795439.html 没什么好诡异的,这个问题我以前研究过的.因为这个变量是const的,虽然你用指针指向了这块指向n的内存区域,并改变了它.但是VC编译器将const变量直接放进了一个const调用区中,当程序中调用n的时候,并不是通过内存地址去访问它,其他的变量都是push [xxxxx]这样进行访问的,而const变量直接调用push 0xA这样的语句,你反汇编看下就知道了n对应的这块内存地址确实被你改变了不错,但是没用,当调用N的时候,并不是到这块内寸中去取它的值,而是从一开始加入const调用区的对应关系中去找它的 int *p=(int*)(&n); const 属性被强行去除(暂时的),因此 *p 可以另行赋值。当你输出的时候 n 的值依然是 0,不变,但是 *p 的值已被更改。 编译器对编译的时候可以确定值得地方作了优化由于n是const int所以在出现n的地方都是一个确定值。所以直接将数值优化到代码中了这是编译器输出的代码,注意看call _printf之前push的参数; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08 TITLE C:\Documents and Settings\xp\桌面\test.cpp .686P .XMM include listing.inc .model flatINCLUDELIB LIBCMTINCLUDELIB OLDNAMESCONST SEGMENT$SG3834 DB '%d %d %d %d', 0aH, 00HCONST ENDSPUBLIC _mainEXTRN _printf:PROC; Function compile flags: /Odtp; File c:\documents and settings\xp\桌面\test.cpp_TEXT SEGMENT_n$ = -8 ; size = 4_p$ = -4 ; size = 4_main PROC; 4 : { push ebp mov ebp, esp sub esp, 8; 5 : const int n = 0; mov DWORD PTR _n$[ebp], 0; 6 : int *p=(int*)(&n); lea eax, DWORD PTR _n$[ebp] mov DWORD PTR _p$[ebp], eax; 7 : *p = 255; mov ecx, DWORD PTR _p$[ebp] mov DWORD PTR [ecx], 255 ; 000000ffH; 8 : printf("%d %d %d %d\n", n, *p, *&n, *(int*)&n); mov edx, DWORD PTR _n$[ebp] push edx push 0 mov eax, DWORD PTR _p$[ebp] mov ecx, DWORD PTR [eax] push ecx push 0 push OFFSET $SG3834 call _printf add esp, 20 ; 00000014H; 9 : } xor eax, eax mov esp, ebp pop ebp ret 0_main ENDP_TEXT ENDSEND 大概在4/5个月前,CSDN首页上就有一篇加红的文章讲 const的,我对它其中讲的关于更改const变量觉得很有兴趣,然后进行了探索,反汇编立刻就能看出端倪,恰好你今天问了这个问题 如果是C的代码就是 lz所期望的 255 255 255 255 请教有关GDI+ Bitmap的问题 关于多线程的问题 法师进来 要在vc/mfc里怎样创建一个任务(CreatTask) CSocket的Create问题 csdn 被盗链 "微软招聘出奇招",求解 在类中自定义的函数不能调用,不知道是为什么----网上众高手帮忙 今天用了mfc dll的向导,但是生成的程序,不知道如何下手,请大家帮忙? 出错,为什么?VERIFY(m_Button.SubclassDlgItem(IDC_BUTTON1,this)); 请问怎么样在强行覆盖一个已经打开的程序 List Control的最尾的空白,如何去除?
是不是疑惑在const上?
http://c.chinaitlab.com/ccjq/795439.html
由于n是const int所以在出现n的地方都是一个确定值。所以直接将数值优化到代码中了这是编译器输出的代码,注意看call _printf之前push的参数; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08 TITLE C:\Documents and Settings\xp\桌面\test.cpp
.686P
.XMM
include listing.inc
.model flatINCLUDELIB LIBCMT
INCLUDELIB OLDNAMESCONST SEGMENT
$SG3834 DB '%d %d %d %d', 0aH, 00H
CONST ENDS
PUBLIC _main
EXTRN _printf:PROC
; Function compile flags: /Odtp
; File c:\documents and settings\xp\桌面\test.cpp
_TEXT SEGMENT
_n$ = -8 ; size = 4
_p$ = -4 ; size = 4
_main PROC; 4 : { push ebp
mov ebp, esp
sub esp, 8; 5 : const int n = 0; mov DWORD PTR _n$[ebp], 0; 6 : int *p=(int*)(&n); lea eax, DWORD PTR _n$[ebp]
mov DWORD PTR _p$[ebp], eax; 7 : *p = 255; mov ecx, DWORD PTR _p$[ebp]
mov DWORD PTR [ecx], 255 ; 000000ffH; 8 : printf("%d %d %d %d\n", n, *p, *&n, *(int*)&n); mov edx, DWORD PTR _n$[ebp]
push edx
push 0
mov eax, DWORD PTR _p$[ebp]
mov ecx, DWORD PTR [eax]
push ecx
push 0
push OFFSET $SG3834
call _printf
add esp, 20 ; 00000014H; 9 : } xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END