引言:
#include <stdio.h>
int main()
{
int n = 5;
float* pfloat = (float*)&n;
printf("n=%d\n", n);
printf("n=%f\n", *pfloat);
*pfloat = 5.0;
printf("n=%d\n", n);
printf("n=%f\n", *pfloat);
return 0;
}
为何会出现这种结果呢?下面请先容我讲述一下整形和浮点型在内存中的存储差异再做解释
一.整形
1.分类:int,short,long,.....
2.整数的取值范围在 #include <limits.h>中定义
3.整形在内存中存储方式:
将十进制的整数转化为二进制得到它的原码,若为正数,前面补0直至32位(32位平台下)/64位平台下补0直至64位,再按一定的转化规律(原码符号位不变,其余位按位取反得到反码,反码+1得到补码)得到他的补码,将其补码存在内存中。
二.浮点型
1.分类:float,double,.....
2.浮点数取值范围在 #include <float.h>中定义
3.浮点型在内存中存储方式:
1>官方定义:任意一个二进制浮点数V可以表示成V=(-1)^S*M*2^E
(-1)^S表示符号位,S=0,V为正数;S=1,V为负数;
M表示有效数字,1<=M<2;
2^E表示指数
2>对浮点数的二进制表示:
3>浮点数的存储:
最高位:S
指数位:8位(32平台)/11位(64平台)
注:由于在存储中E为无符号整形,但实际E可能取负值,所以规定在32位平台下,E+127后在 进行二进制转换并存储/在64位平台下,E+1023后在进行二进制转化并存储
有效数字位:23位(32平台)/52位(64平台)
注:对于1.xxxxx的数字,在进行存储时可以省略1,直接存储小数点后的二进制转化,并补0直 至相应的位数
4>当指数位全为0时,E=1-127/1-1023,此时该二进制表示+/-0,及趋于0的数字
当指数位全为1时,此时该二进制表示+-无穷大
那么我们现在来解释引言中的情况:
1.n=9时,站在int的角度上看,他的二进制表示为00000000 00000000 00000000 00000101
将他的地址强转为float*,站在float的角度上来看,他的二进制表示为
0 00000000 00000000000000000000101,此时E全为0,表示0
2.*pfloat=5.0时,站在float的角度来看,他的二进制表示为
0 10000001 01000000000000000000000
当以%d的形式打印时,是站在int的角度来看这个二进制:
01000000 10100000 00000000 00000000,此时他表示一个很大的正数