1.整数在内存中的存储:
1.1.大小端字节序:
int main()
{
int a = 0x11223344;
return 0;
}
调试代码时发现:
数据在内存中并不是按照高位在前低位在后的顺序存储,而是倒着存储
其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储,下⾯是具体的概念:
大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。
小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。
一般的x86都是小端模式
判断机器的大小端:
#include <stdio.h>
int check_sys()
{
int i = 1;//十六进制:0x00000001
return (*(char *)&i);
}
int main()
{
int ret = check_sys();
if(ret == 1)
{
printf("⼩端\n");
}
else
{
printf("⼤端\n");
}
return 0;
}
通过返回值0/1,即可判断机器的字节序
例题:
#include <stdio.h>
int main()
{
char a = -128;
//10000000000000000000000010000000(-128补码)
//10000000(int类型(-128)放到char类型变量a中发生截断后的数据)
//11111111111111111111111110000000//整形提升后的数据
printf("%u\n",a);//以无符号数形式打印
return 0;
}
涉及截断和整型提升,注意事项:
1.提升哪个变量就按照哪个变量的类型进行提升
2.提升发生在使用变量时
3.提升的类型有符号位则在前面加上符号数,无符号位则补0
运行结果如下:
计算器计算提升值:
两者相同,无误
2.浮点数在内存中的存储:
2.1.浮点数的存储:
根据国际标准IEEE(电⽓和电子工程协会) 754,任意⼀个二进制浮点数V可以表示成下面的形式:
*V = (−1) ^S M ∗ 2^E
• (−1)^S 表示符号位,当S=0,V为正数;当S=1,V为负数
• M 表示有效数字,M是大于等于1,小于2的
• 2^E 表示指数位
对于32位的浮点数,最高的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
对于64位的浮点数,最高的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M
2.1.1.浮点数存的过程:
a.M的存储:1≤M<2,故每个小数都只存小数点后面的数据,位数不够就在后面补0至23位,取出时加上一即可,这样就相当于用23位(bit)存放24位有效数字了
b.E的存储:存储E时要加上中间数(因为科学计数法中指数可能为负,但E应该为一个无符号整数),8位E的中间数位27,11位E的中间数为1023
2.1.2.浮点数取的过程:
有以下三种情况:
con1:E不全为0或不全为1:
指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第⼀位的1。
con2:E全为0:
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第⼀位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
con3:E全为1:
如果有效数字M全为0,表示±无穷大(正负取决于符号位s)
注意:
1.一定不要忘记加减中间数!!!
2.2代码解析:
请看下面一段代码:
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);//9
printf("*pFloat的值为:%f\n", *pFloat);
*pFloat = 9.0;
printf("num的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);
return 0;
}
9以补码(000000000000000000000000000000001001)的形式存到n中,从上到下第二个printf打印时,将9的补码按照浮点数进行打印,会被解读为:
0(符号位) 00000000(E-指数位) 000000000000000000000001001(M-有效数值位)
取出打印的时候符合E全为0的情况,所以得到的结果是一个非常接近0的小数
9.0(1001)作为浮点数存储到内存中,符号位为0, 指数位E为3+127=130(10000010),有效数值位M为1.001(001000000000000000000000)
即为:0 10000010 001 0000 0000 0000 0000 0000(1,091,567,616)
运行结果如下: