源自《代码大全》第二版,13.1节。(P324)
又加入了一些自己原创的东西。
如何解释内存中某个位置的内容,是由指针的基类型决定的。如果某个指针指向整数,这就意味着编译器会把该指针所指向内存位置的数据解释为一个整数。当然,你可以让一个整数指针,一个字符串指针和一个浮点数指针都指向同一个内存位置。但是其中(至多)只有一个指针能正确的解释该位置的内容。
内存并不包含任何与之相关联的内置解释。只有通过使用一个特定类型的指针,一个特殊位置的比特才能解释为有意义的数据。
例如对于内存地址:
0A | 61 | 62 | 63 |
以如下的观点分别可以解释为:
四字节的整数: 1667391754
双字节的整数: 24842
四字节的浮点数: 4.17595656202980E+0021
字符(串): (换行符) abc
下面的程序演示了各种解释:
#include <iostream> using namespace std;
int main() { int a = 1667391754; int *p_int = &a; cout << "四字节整数:\t" << *p_int << endl;
short *p_short = (short*)p_int; cout << "双字节整数:\t" << *p_short << endl;
float *p_float = (float*)p_int; cout << "双字节浮点数:\t" << *p_float << endl;
char *p_char = (char*)p_int; cout << "字符串:\t" << p_char << endl;
return 0; } |
运行结果:(VC++6.0)
四字节整数: 1667391754 双字节整数: 24842 四字节浮点数: 4.17596e+021 字符串: abc? Press any key to continue |
下面分别说说计算机是怎样用不同的观点解释数据的。
0A | 61 | 62 | 63 |
预备知识:
数制。内存中是以二进制的方式存储数据的,每个二进制数字占一个位(bit)。上面的表格中每个格子代表一个字节,也就是8个位,而其中的数字(如0A)则是十六进制的表示。2位的十六进制数字可以转化为8位的二进制数字。
字节排序:要明确的是这里的字节排序方式是"大数在先"的。也就是说将最高有效字节存于最低数值的字节地址中。
四字节整数:
这里的最高有效字节存于最低数值的字节地址中,所以内存应解释为: 63 62 61 0A。把它们连起来看成一个十六进制的数字,再转化为十进制,就可以得到1667391754。
二字节整数:
计算机先找到所需要的内存总量(两字节),之后按照大数在先的方式解释,得到 61 0A。同样的,把十六进制转化为十进制,得24842。
四字节浮点数:
浮点数的解释比较复杂。现在计算机所用的浮点表示法为IEEE标准。对于单精度的浮点数(即四字节浮点数,共32位),第一个位表示符号,后面8个位表示阶码,最后23位表示尾数。在这个例子中,内存中数据为:(即0A 61 62 63的二进制)
01100011 01100010 01100001 00001010
符号位 0 ,表示这是一个正数。
8位阶码,11000110,变为十进制是198,减去指数偏移量127得到实际的指数 71。
后面的23位尾数则是实际的数字内容。按照IEEE标准,它应该被解释为二进制的 1. 1100010 01100001 00001010。
把上面的合起来,得到 + 1. 1100010 01100001 00001010 * 2^71.即十进制的 4.17596e+021
字符串:
按照ASCII码来解释。0A,换行符,61 62 63分别是字母a,b和c。