如果每道题都这么有趣,那天天看知道也不会无聊了。
这个题相当有趣。而且,几乎没有资料仔细的解释过这个问题。
正确的符合标准C++的输出结果确实应该是4 。
分析一下你的操作:
你取他的地址,你确实取到了,这是真的。
你利用这个地址修改其中的值,你也确实修改了那个地址的值,那个地址位置的内存中所保存的确实是你修改后的值8,这也是真的:原来恒量p所在的地址中的值现在是8。
为什么输出是4的原因,其实打印语句根本没有跑去内存里面读那个地址的值,而是直接把一个常量‘4’扔给cout了。这是编译器做的手脚。目的是为了符合C++标准:恒量不许被修改,即便是利用一个可以进行修改的指针指向这个恒量(标准规定这个指针可以被当作指向了这个恒量,但不必真的指向他,而且不可以通过这个指针修改恒量内容)。
举个例子说明一下编译器的行为方式:
const int i=10;
b(i);
会被编译器当成
const int i=10;
b(10);
来处理。
所以你无论把i所在的内存改成什么都无所谓,反正b收到的参数都是10.
实际上这个语法在C++里面可以当做替代预处理器的#define语句,而编译器处理他们的方式也基本是这个样子,就是扔个常量给他,不去读他们所在的内存。不变是const存在的意义,正因为有这个保证才能执行这样的操作:
const int a=10;
int b[a];
0013FF7C int *h=(int *)&p; //取p的地址转化成整形指针类型 cout<<*h<
0013FF7C
这两个输出是指针 表示你的变量存的地址
由于你打印的时候写的是指针
所以人家以指针形式给你打引出来了
你画下指针的图就清楚的狠了
下面给你加了注释
#include
using namespace std;
void main()
{
const int p=4;
cout<
*h=8; //把这个指针执行的变量赋值为8
cout<
运行结果:
4 //打印普通整型
4
8
0013FF7C
0013FF7C
#include int *h=(int *)&p; //取p的地址转化成整形指针类型 cout<<*h< 这个的注释错了,正确输出怎么会是8嘛,p仍然是整型4.
using namespace std;
void main()
{
const int p=4;
cout<
*h=8; //把这个指针执行的变量赋值为8
cout<
楼上的其他的都对,但是
cout<
越分析发现这个代码越不简单...请允许我多修改几次.
最后的输出,p的地址,与h所在的地址是同一个地址,但是h指向的值是整型8...
p是const int,所以下面的代码不可能修改它的值与类型。所以p永远是int,等于4.
关键是int *h = (int *)&p;这一句。这一句其实是将p的地址作为h指向的地址。*h=8,只改变它的值,而没有改变h指向的地址。注意,是h所指向的内存地址,h本身的地址&h,是不一样的。
如果把const int p = 4;去掉,p的值就会被改变.所以肯定是编译器的保护机制起的作用.其实主要还是强制转换的副作用!
知道你问的不是那么简单的问题。我分析来看,就是编译器对const型的处理机制问题,强制转换的副作用也是一个原因。
#include int *h=(int *)&p; //取p的地址转化成整形指针类型 cout<<*h<
using namespace std;
void main()
{
const int p=4;
cout<
*h=8; //把这个指针执行的变量赋值为8
cout<
}
内存模型就是
h里面存放p的强制类型转换后的地址