深度剖析数据在内存中的存储

目录

前言

一、数据类型详细介绍

二、整形在内存中的存储(原码,反码,补码)

( 原码,反码,补码)

三、大小端字节序介绍及判断

1.什么是大小端?

2. 为什么要存在大小端而不统一标准?

3.如何知道编译器是大端还是小端?

四、浮点型在内存中的存储解析

1.常见浮点数:

2.浮点数储存规则

 3.对于有效数字M和指数E还有一些特别的规定

而指数E情况较为复杂:

1)指数E的储存

2)指数E的取出

总结



前言

        随着编程语言学习的不断深入,越发觉得有必要深度探讨一下数据在内存中的储存原理,正所谓知其然更要知其所以然.可能大部分同学对数据的理解程度仅仅停留在不同的数据类型对应的字节大小,当然这对于应付考试和日常编程以绰绰有余.如果想要加深对底层的理解认知希望我的总结能对你产生一定启发.


一、数据类型详细介绍

        早先我们已经学习了各种数据类型及其对应大小.学习这些类型可以帮助我们初步以内存的视角来看待问题.

char
short
int
long
long long
float
double
//字符数据类型
//短整型
//整形
//长整型
//更长的整形
//单精度浮点数
//双精度浮点数

二、整形在内存中的存储(原码,反码,补码)

        我们都知道变量的创建要在内存中开辟空间,而空间的大小是根据不同的类型而决定的.

例如:  int a = 20;我们都知道为a分配了四个字节的空间,那么a在内存中又是如何储存的呢?

( 原码,反码,补码)

        计算机中整数有三种表示方法即原码,反码,补码.每种表示方法都有符号位和数字位.符号位用"0"表示正,"1"表示负.正数的原码,反码,补码都相同,而负数的数值位三种表示方法各不相同.

原码:直接将二进制按照正负数的形式翻译成二进制就可以。
反码:将原码的符号位不变,其他位依次按位取反就可以得到了。
补码:反码+1即可

        因此对于整数来说数据存放在内存中其实就是存放其补码.因为CPU只有加法器,使用补码可以将符号位和数值位统一处理,并且原码与反码的相互转换不需要额外的硬件电路.

 20转换为二进制为 0000 0000 0000 0000 0000 0000 0001 0100(原码),为了方便内存中由16进制表示为00 00 00 14.

-20转换为二进制为1000 0000 0000 0000 0000 0000 00001 0100(原码),符号位不变其余位按位取反,反码为 1111 1111 1111 1111 1111 1111 1110 1011 ,补码为反码加一:

1111 1111 1111 1111 1111 1111 1110 1011转换为16进制就是 ff ff ff ec.

这时大家就会发现分析出的内存与实际储存方式居然是相反的,这时为什么呢?这就牵扯到了大小端存储的问题.

三、大小端字节序介绍及判断

1.什么是大小端?

大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址
中;
小端(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地
址中。
        简而言之就是:大端符合正常人的相反,小段反着来.接下来用一张图表明

注意!!大小端指的是字节序而不是二进制序,若只有一个字节无法谈大小端.

2. 为什么要存在大小端而不统一标准?

        因为大小端各有其优势,我们都知道计算机正常的内存增长方式是由低到高(除栈以外),取数据

的方式是从基址根据偏移找到它们的位置.从储存方式可以看出,大端存储因为第一个字节就是高位,

从而很容易看出它是正数还是负数,对一些数据判断会非常迅速.而小端存储第一个字节是它的低位,

符号位在最后一个字节,这样在做数值四则运算时从低位每次取出相应字节运算,最后直到高位,并且

最终把符号位刷新,这样的运算方式会更高效.

3.如何知道编译器是大端还是小端?

        我们可以假设一个变量为int i = 1;如图我们只需判断低地址是 0还是1即可.

        取出i的地址,强转为char*,此时解引用只能访问一个字节刚好是最低位的数据.        

四、浮点型在内存中的存储解析

1.常见浮点数:

        3.14159 1E10 浮点家族包含 float double long double.

为了区分浮点数与整形在内存中的存储差异我们先以整形的视角来看一组代码.

 可以发现结果与我们预计千差万别,那么造成这种差异的原因就是浮点型与整形在内存中的存储差异.

2.浮点数储存规则

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式
(-1)^S * M * 2^E
(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位
        例如:十进制的5,写成二进制就是0........0101.相当于1.01*2^2.按照上面V的格式可以写成S=0,M = 1.01,E=2. 对于32位浮点数,最高位的一位是符号位,接着8位是指数E,剩余23位是数值位M.

 双精度数则略有不同.

 3.对于有效数字M和指数E还有一些特别的规定

        通常M写成1.xxxxxx的形式,xxxxxx表示小数位.我们发现无论如何M的整数位都是1,所以在计算机内部保存时可以省略只保留小数部分,等到取出时再加上1.这样有效数字就会变成24位(以32位而言).

而指数E情况较为复杂:

1)指数E的储存

         我们都知道E为unsigned int 即无否号整数,但现实生活中的科学计数法E却可以为负.这意味着如果E为8位取值范围是0-255,E为11位取值为0-2047,存入内存时的数值加上一个中间数就可以有效的解决这个问题.0-255的中间数为127,0-2047的中间数为1023.例如,2^10 E为10,保存为32位浮点数时必须保存为127+10=137.即1000 1001.如果是2^-10 E为- 10,保存为32位浮点数时必须保存为127+(-10)=117.即0111 0101.

2)指数E的取出

   (1)当指数E不全为0或一时:

        E值减去127或1023,得到真实值,再在有效数字M前加上原本的1.例如:0.5的二进制形式为0.1,转换为标准形式就是 1*2^(-1).那么此时E为(-1)+127=126.表示为01111110,1.0再去其整数部分剩余0补齐至23位得到 0 01111110 00000000000000000000000

   (2)E全为0:

        此时指数E为1-127或1-1023,由数学知识可以2^-126或2^-1022乘以一个数无限趋近于0;正负取决于符号位.

   (3)E全为1:

        此时指数E为255-127或2034-1023,由数学知识可以2^126或2^1022乘以一个数趋近于正无穷;正负取决于符号位.

      


总结

以上就是我要分享的全部内容,如有不足之处还请各位批评指正.

  • 3
    点赞
  • 3
    收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页
评论 6

打赏作者

Node_Hao

您的支持是我创作的不懈动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值