您的位置:首页 > 其它

一个地址两个值?怎么可能!!!

2011-12-30 21:50 169 查看
缘由是这样的:

有个学生写了一个程序,代码如下:

#include <stdio.h>

int main(void)

{

const int a = 10;

*(int *)&a = 20;

if ( a == 20)

printf("a = 20\n");

printf("%d, %X\n", a, &a);;

printf("%d, %X\n",*(int *)&a,(int *)&a);

return 1;

}

程序的输出结果相信大家都知道,我也贴出来吧

10, 31F73C
20, 31F73C

看到这个结果,这个学生就有点懵了,他问:

“同一个地址,怎么会有两个值呢?”

当时,我看的时候,初以为他是用C语言编译器编译的,我就问他这怎么会通过编译阶段呢?(注:学院教的是MTK开发,开发语言用的是C语言,所以先入为主了。)

后来一看文件类型,哦,原来是.cpp文件。Visual C++ 6.0默认新建源文件的格式是cpp文件,编译用的当然是C++的编译器;如果文件名写明了.c(比如test.c),那么编译的时候就会使用C语言的编译器进行编译。
这个小程序里面的关键之处就是const,如果把它去掉,则每个会C的都能懂。关于const的用法,网上有很多很深入的探索 ,我这里就不再详细谈了,请参考:
1. http://www.vckbase.com/document/viewdoc/?id=412 ————————const使用详解
2. http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html ——————C/C++中const关键字详解
只说一点:在C语言中const修饰成“只读变量” ;在C++中修饰成“常量”。

常量一般来说是不可以改变的,也就是不可以给它赋值。但程序里没有这么做,而是直接把a的地址取出来,然后根据地址在内存里直接放入20,这是没有问题的。当我说到这里的时候,这个同学发问了:“你说a的值改变了?那为什么 if 判断为假呢?”。我接着跟他说,a不是一个值,它只是内存里某个地址的代号。至于

if ( a == 20)确实不会为真,因为10不可能等于20。在VC编译器编译代码的时候,它会有一个“源代码优化”的阶段,当它检测到常量a的时候,会把后面的a都替换成10,所以if语句判断为假,从第二条打印语句也可以看出来。最后一条打印语句的意思是,取a所代表的内存地址中的值,所以肯定是20,而不是10了。
这个小程序的调试结果看不出来问题所在,和打印的结果是一样的,但反汇编能瞄出端倪,有兴趣的可以自己看看汇编代码。
总结一下,同一个地址当然不能存放两个不同的值!千万不要被编译器骗了!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐