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

目录

一,基本数据类型分类

1.1整型

1.1.1char型与整型的关系

1.1.2从短整形 short 到更长的整型 long long

1.2浮点型

1.2.1浮点数分类

二,整型在内存中的存储

2.1原码,反码,补码

2.1.1正数

2.1.2负数

2.2大小端(字节序)存储

 三,浮点数在内存中的存储

 3.1 IEE754的规定

3.1.1对不同大小浮点数的规定

 3.1.2对有效数字M的规定

3.1.3对指数部分(阶码)的规定

3.2取出浮点数的规定

3.2.1E不是全0,不是全1

3.2.2 E为全0

3.2.3 E为全1

3.2.4浮点数不能错过的例子

,其他数据类型


一,基本数据类型分类

我们知道的是,数据在内存中是有整型,浮点型,字符型等数据类型的,如下图所示:

但是当我们仔细分析来看,应该是只有整型以及浮点型。分析如下:

1.1整型

1.1.1char型与整型的关系

因为字符型char数据在内存中是一个字节存放的,而整型int型是四个字节存放的。而字符型数据表示的128个字符表示的ASCII码值,其内容在整型中是可以存放的。

除此之外,char在vs编译器中默认为有符号的char型,即unsigned char其大小范围为:-128~127。这个区间在整型的区间范围之内,所以可以将其称为整型的一个小部分,但是也不能完全称为整型,因为整型不能表示字符。

1.1.2从短整形 short 到更长的整型 long long

short型数据,即短整形数据,是两个字节存储的数据类型,即整型的一半。

long型数据,即长整形数据,是四个数据字节存储的数据类型,也可以称为long int型。

longlong型数据,是八个字节存储的数据类型,也可以称为两倍的整型。也即是一个64位存储单元。

以上这些数据类型,基本都是整型的衍生,与整型的使用相差不大,所以我们认为,从char到longlong型,基本都可以认为是整型。

1.2浮点型

在我们日常生活中,当然不仅仅有整数,还有小数,那么这些小数在内存中是如何处理的,浮点数为我们提供一个方便的存储小数的数据类型。

1.2.1浮点数分类

float 单精度浮点数,四个字节空间,即32位存储空间。其特点是运算快,占用空间少。

double 双进度浮点型,八字节空间,64位存储空间。其特点是运算进度高。

二,整型在内存中的存储

变量在内存中存储是需要开辟空间的,那么开辟多大的空间是高效的呢,这就需要根据不同的变量类型来决定了,下面我们来学习整型变量是如何开辟空间来供自己使用的。

首先我们的需要先学习整型的几个重要的概念。

2.1原码,反码,补码

那么首先我们需要知道一个很简单的规则,那就是二进制符号位,0 表示正数,1 表示负数。

二进制数是有三种表示形式的,分别为原码,反码,补码。计算机在内存中是以补码的形式存放数据的,所以计算机在存储时,会将十进制数据变成二进制数据的补码形式存入内存,那么为什么计算机这样做呢,这是因为整型数据有正负之分,换算成补码之后,计算机便可以统一处理。

2.1.1正数

对于正数,由于符号位为0 ,所以它的原反补码都是一样的。、

2.1.2负数

由于负数的符号位1,所以需要将其统一,然后计算机就可以统一处理了。

原码:将十进制整型数据以二进制形式表示,即为原码,但需要注意符号位的区别。

反码:将原码符号位不变,其他位按位取反得到的便是反码。

补码:反码取反加1,得到补码。

那么从计算器取出的时候,我们直接对补码取反加1 ,之后就得到了原码,将其翻译成十进制数即可。

那么我们来看一个例子:

 那么我们知道char类型在内存中是一个字节存放的,但是打印的时候我们发现,是需要按照有符号整型打印的,那这样的话,我们应该怎么求其值呢?

首先我们知道,a,b,a+b在内存中存放的形式如下图:

 那么首先,直接打印 a+b 时,由于a+b 的补码满足%d的32位整型数据打印,所以直接打印,该二进制换算成十进制之后,值为300。

好的,那么第二个打印,我们是需要将a+b的和放入字符型数据c中,但是字符型数据只有8个比特位,所以我们需要取出a+b的补码的后8位,然后将其存入c 中。

最后我们发现,以%d打印的时候,需要整型提升。所以最后结果为:

 所以最后打印的结果为:

2.2大小端(字节序)存储

大端存储:数据的低位存储在内存地址的低位,数据的高位存储在内存地址的高位。

小端存储:数据的低位存储在内存地址的高位,数据的高位存储在内存地址的低位。

 那为什么有大小端存储之分呢(已知内存地址是有高低之分的)?

因为数据在内存中是按字节存放的,那么必然有多于一个字节的数据,那么假如一个四字节整型数据在内存中如何存放的呢?

此时就有了大小端字节序存储之分了。

那么怎么区分大小端存储呢?

这个是根据编译器决定的,一般的编译器是按小端存储的,但是大端存储也没有任何的坏处,因为数据在内存中存储,它的值始终是不变的。

 三,浮点数在内存中的存储

要知道浮点数在内存中的存储规则,我们首先需要知道国际标准IEEE754协议,它规定浮点型数据有如下格式:

 任意浮点数:(-1)^S * M * 2^E

S:S为0, 该浮点数为负数,S为1,该浮点数为正数。

M:M为有效数字,其值大于1小于等于2。

E:E为指数(阶码) 

 3.1 IEE754的规定

3.1.1对不同大小浮点数的规定

首先,对于32位浮点数。

最高位1 位为S,接着的8位为阶码E,最后 23 位为有效数字E。

而对于64位浮点数。

最高位1 位为S,接着的11位为阶码E,最后 52 位为有效数字E。

 3.1.2对有效数字M的规定

因为M必然是一个1和2之间的数,所以当存储时,规定将其正数部分去掉,只保留小数部分,这样小数部分的位数便多了一位。比如1.XXXXXX存储时,只存储XXXXXX,而当从内存中取出时,再将整数部分加上,还原为1.XXXXXX。

3.1.3对指数部分(阶码)的规定

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

E有8位和11位,那么E的最大范围是0~255,0~2047,但是我们知道科学计数法E是可以为负数的,所以,规定,当E存放时,32位浮点数E+127,之后再存入,而64位浮点数E+1023,然后再换算成二进制数存入,这个中间数是必不可少的。

存入内存之后,我们需要将其从内存中取出。

3.2取出浮点数的规定

3.2.1E不是全0,不是全1

此时E为正常数,所以取出时,以32位浮点数为例,将E减去中间数127,然后,将有效数字M加上整数部分1,得到原来的1.XXXXXX。这样一个一般正常的浮点数就完成了存取操作。比如我们存放一个数0.5,将其写为二进制数为0.1,正数所以S为0,然后0.1化为 1.0*2^(-1),所以阶码E为-1+127=126,M则去掉正数部分1,留下小数部分0,所以二进制表示为:

 

 然后,当我们取出时,E-127,M加上整数部分1,再转变为十进制数,得到原来的数0.5。

3.2.2 E为全0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值。

此时,取出时M的值不再加上整数部分,而是直接变为0.XXXXXX,这样做是为了避免出现出现无穷接近于0 的数。

我们简单的分析下,为什么会出现无限小的数。如果E为全0 ,此时原先的E应该是 -127,那么2^(-127),即为1/(2^127),这个数将是一个无限小的数。

3.2.3 E为全1

此时如果有效数字为全0,则将产生一个无穷大的数。

3.2.4浮点数不能错过的例子

如图所示:

 那首先,我们分析当存储的是整型数据的时候,我们应该怎么做,如图所示:

这里我们用到的当E为全0时,E是用1-127,M为0.XXXXXXX。但是,用%f打印时,只能打印默认六位小数,所以打印结果为0.000000。

其次,当存储的是浮点型时,而用整型打印时,如图所示:

此时,当满足了整型的存放空间即32位时,会直接求出该二进制数字的值,为1091567616。 

,其他数据类型

当然,除了基本数据类型之外,还有结构体等一些数据类型,后续再介绍。

最后不得不提的是类型的意义到底是什么???

我觉得,分为两个部分,首先是存放时开辟的内存空间,其次是取出时的视角,即你打算以什么方式取出。
好了,关于数据类型的介绍后续更精彩哦,如有错误,还请指正哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值