在C++中,我们经常有取变量地址的操作,实际上是取变量在内存中的开始处的地址,例如:
- #include<iostream>
- using namespace std;
- struct T
- {
- int i;
- int j;
- }
- int main(void)
- {
- T t;
- cout << &t << endl; //取变量t的地址
- cout << &t.i << endl; //取变量t中i处的地址
- }
#include<iostream>using namespace std;struct T{ int i; int j;}int main(void){ T t; cout << &t << endl; //取变量t的地址 cout << &t.i << endl; //取变量t中i处的地址}
打印出的结果是相同的。
在C++中reinterpret_cast可以把内存中的字节以另一种方式来解释,相当于同一件事情(等价于内存中的某一区域)不同的人来看待有不同的结果。以下是一段使用reinterpret_cast的代码:
- #include <iostream>
- #include <cstring>
- using namespace std;
- struct T
- {
- long i;
- int j;
- };
- int main(void)
- {
- T t;
- memset(&t, 0, sizeof(t));
- t.i = 65;
- unsigned char *p = reinterpret_cast<unsigned char *>(&t);
- cout << *p << endl;
- p++;
- *p = 1;
- p++;
- *p = 1;
- p++;
- *p = 1;
- cout << t.i << endl;
- }
在我的VS2008下编译通过,打印出A和16843073
这是怎么得到的呢?
我们把内存想象成一格一格的,在t.i处的地址在我电脑上打印出来是地址0012FF54于是有:
在0012FF54中存放着65,即01000001,
而在0012FF55一直到0012FF57中全部存放的是0(因为之前我用memset将他们都设为0了),
而当我使用reinterpret_cast<unsigner char*>时,相当于说将0012FF54内存中的内容作为一个unsigned char来看待,于是得到了65所对应的ASII值,打印出来为字符A。
之后我使p每次递增一(因为unsigned char 只占一个字节),所以之后将0012FF55到0012FF57的内容都设置为了1,
即在0012FF55中为0000001, 0012FF56中也为00000001,0012FF57中也是00000001,最后我要打印
i的值,现在i是作为long形式来打印的,它占4个字节,所以i的值应该是将0012FF54到0012FF57所有的内容联合起来解译,即为
00000001000000010000000101000001(B)[二进制形式],转换成十进制正好是16843073.