这个是昨天写的,但是今天才整理并贴出来~
是这样的,C中的常识之一就是,const类型的值是不可修改的。
但是我昨天在看书的时候想到所有位于内存中的数据其实都是可以修改的,就用代码尝试了一下,代码如下:
#include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; const int a = 10, b = 20; int c; int * np = (int *)&a; *np = 9; *(np + 1) = 19; c = a; cout << a << ends << b << ends << c << endl; return 0; }
代码非常简单,就是成名两个const int变量,然后呢,我通过创建一个指针,通过显式类型转换,获取a变量的地址。
然后呢,我通过这个指针,修改a的值。
调试结果是这样的:
在这里可以看到,watch窗口中已经很清楚的显示了,a和b的值已经被修改了!
但是输出的结果却还是a和b的原值。
这是为什么?
为此我查看了这段程序的汇编码:
1 00401379 movl $0xa,0x18(%esp) 2 00401381 movl $0xa,0x4(%esp) 3 00401389 movl $0x4740c0,(%esp) 4 00401390 call 0x448630 <std::ostream::operator<<(int)> 5 00401395 movl $0x467640,0x4(%esp) 6 0040139D mov %eax,(%esp) 7 004013A0 call 0x44837c <std::ostream::operator<<(std::ostream& (*)(std::ostream&))> 8 004013A5 movl $0x14,0x4(%esp) 9 004013AD mov %eax,(%esp)
这里只截取了一部分,可以看到第一行的前两个数字十进制都是10,第八行的那个数字是十进制中的20.
由此我推断,在编译阶段,编译器对于所有使用了const变量值的地方统统将其用其值来替换,而非去内存中寻址取值。
所以才会导致原变量的值已经被修改的情况下,还是输出了原来的值。