数据在内存中的存储

目录

1. 数据类型介绍

1.类型的基本归类

2. 整形在内存中的存储

1.原码、反码、补码

2.大小端介绍

大端字节序(存储)模式,

小端字节序(存储)模式,

3. 浮点型在内存中的存储 

浮点数存储规则


1. 数据类型介绍

1 2 4 4 8 4 8

类型的意义:

1. 使用这个类型开辟内存空间的大小(大小决定了使用范围)。

2. 如何看待内存空间的视角。

1.类型的基本归类

int == signed [int],long,short同理。

char 是否等于 signed char取决于编译器。

unsigned就是正数,signed是有符号数(有正有负)

浮点数家族

 构造类型也被叫做自定义类型

 数组类型:如 int arr[10] 的类型是int [10](去掉数组名就是类型)

2. 整形在内存中的存储

1.原码、反码、补码

计算机中的整数有三种2进制表示方法,即原码、反码和补码。

三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,

而数值位正数的原、反、补码都相同。负整数的三种表示方法各不相同。

负数原码符号位不变,取反得到反码,而反码+1得到补码。

对于整形来说:数据存放内存中其实存放的是补码。

2.大小端介绍

大端字节序(存储)模式,

把一个低位的数据,存放在高地址处

把一个高位的数据,存放在低地址处。顺着存

小端字节序(存储)模式,

把一个低位的数据,存放在低地址处,

把一个高位的数据,存放在高地址处。逆着存

3. 浮点型在内存中的存储 

浮点数家族包括: float、double、long double 类型

1E10 表示1.0*10^10。

浮点数存储规则

  • (-1)^S * M * 2^E
  • (-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
  • M表示有效数字,大于等于1,小于2。
  • 2^E表示指数位。

如5.5,用二进制表示为101.1,写成科学计数法为

1.011 * 2^2,后面再乘个(-1)^0

就是(-1)^S * M * 2^E

则 S=0,M=1.011,E=2+127(float)或者2+1023(double)

IEEE 754对有效数字M和指数E,还有一些特别规定。

前面说过, 1≤M

IEEE 754规定,

在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。

保存E,首先,E为一个无符号整数

总结:

存放S,0为正数,1为负数

存放M,只存小数部分

存放E(要加中间数,float+127,double+1023):

1.E全为0 说明E实际上为-127或者-1023,数很小,

则不再计算,E直接就是1-127或者1-1023,

M也不再加上1,直接用小数表示。

2.E为全1,说明E是个非常大的数字,这个时候M如果为0,表示正负无穷大

3.E有1有0,正常表示 (-1)^s *(M+1) *2^(E-127) float,double同理

例子:

#include<stdio.h>
int main()
{
    //程序运行结果是什么?
    int n = 9;
    float* pFloat = (float*)&n;
    printf("n的值为:%d\n", n);
    printf("*pFloat的值为:%f\n", *pFloat);
    *pFloat = 9.0;
    printf("num的值为:%d\n", n);
    printf("*pFloat的值为:%f\n", *pFloat);
    return 0;
}
#include<stdio.h>
int main()
{
    int n = 9;
    //00000000000000000000000000001001 补码
    //0  00000000  00000000000000000001001
    //S    E         M
    //E全为0,则E=1-127=-126,S=0,M=00000000000000000001001
 
    float* pFloat = (float*)&n;
    printf("n的值为:%d\n", n);//9
    printf("*pFloat的值为:%f\n", *pFloat);//0.000000
    *pFloat = 9.0;
    //1001.0   ->   1.001*2^3*(-1)^0
    //s=0,M=001,E=3+127=130
    //0 10000010  00100000000000000000000   -补码,正数原反补相同
    printf("num的值为:%d\n", n);//1091567616
    printf("*pFloat的值为:%f\n", *pFloat);//9.0
    return 0;
}


版权声明:本文为weixin_74085729原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。