📝前言:
在前面的三篇文章中我们已经完成了对字符函数和字符串函数的学习,现在就让我们探索新领域,更加深入的理解**数据在内存中的存储方式**:
1,整数在内存中的存储
2,⼤⼩端字节序存储
3,浮点数在内存中的存储
🎬个人简介:努力学习ing
📋个人专栏:C语言入门基础
🎀CSDN主页 愚润求学
🌄每日鸡汤:请记住,人生唯一确定的,就是不确定的人生
文章目录
- 一,整数在内存中的存储
- 1,为什么要以补码的形式储存呢?
- 2,原码,反码,补码的区别
- ①正数:
- ②负数:
- 二,大小端字节序存储
- 1,⼤⼩端存储的区别
- 2,为什么要有大小端存储之分?
- 三,浮点型数据在内存中的储存
- 1,二进制浮点数的另一种表示形式
- 2,浮点数储存过程
- 1)符号位S的储存
- 2)有效数M的储存
- 3)指数E的储存
- 2,浮点数取的过程
- 1)E不全为0或不全为1
- 2)E全为0
- 3)E全为1
一,整数在内存中的存储
⭐对于整型数据来说:数据是以补码的形式存放在内存中
1,为什么要以补码的形式储存呢?
(简单来说)因为:
计算机的CPU只有加法器,但是在**二进制中,正数和负数的表示方法不同。如果我们想统一加法和减法的操作,就需要将所有的数(无论正负)都转换为一种表示方式**,【补码就是其中的一种表示方式。】
当都转化为补码这一种形式的时候,我们就可以统一加法和减法操作,从而简化了计算机的运算过程。
2,原码,反码,补码的区别
原码,反码,补码到底是什么?
其实原码,反码,补码只是数据的几种不同的表示方式
📑对于所有数据来说:数据二进制的表示方式就是它的原码
那不同数据的反码和补码呢?
我们把整型分成两大类:正数和负数
①正数:
●正数的原码,反码,补码是相同的
例如(对于int 类型的数据5
)
原码:
00000000000000000000000000000101
反码:00000000000000000000000000000101
补码:00000000000000000000000000000101
●无符号整型的反码补码原码也都是相同的(因为也都是正数)
②负数:
●原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
●反码:将原码的**符号位不变,其他位按位取反**就可以得到反码。
●补码:反码+1就得到补码。
例如(对于整型数据-5
)
原码:
10000000000000000000000000000101
反码:11111111111111111111111111111010
补码:11111111111111111111111111111011
(如果要通过补码得到原码:也可以通过【将补码符号位不变,其他位按位取反;再+1的方式】)
所以对5
和-5
而言:
5
在内存中, 就是以5
的补码 : 00000000000000000000000000000101
存放的
-5
在内存中,就是以-5
的补码:11111111111111111111111111111011
存放的
二,大小端字节序存储
1,⼤⼩端存储的区别
●⼤端(存储)模式:将数据低位字节的内容保存在内存的⾼地址处,⽽数据⾼位字节的内容,保存
在内存的低地址处。
●⼩端(存储)模式:将数据低位字节的内容保存在内存的低地址处,⽽数据⾼位字节的内容,保存
在内存的⾼地址处。
其实就是看数据**低位字节的内容保存在哪里**
●保存在内存的高地址处,就是大端存储
●保存在内存的低地址处,就是小端存储
例如,对于0x11223344
这个数据:
那么,我们来看看VS:
我们可以看到:
a
的内容11223344
被储存为了44332211
这就是因为博主的计算机中的VS是用小端模式来储存数据的
2,为什么要有大小端存储之分?
C语言中的大小端存储之分主要是为了解决不同计算机系统之间的通信和数据交换问题。由于不同的计算机系统可能有不同的字节序,因此需要一种统一的方式来表示和传输数据。C语言提供了大小端存储之分,使得在不同的计算机系统之间可以正确地解析和传输数据。
总的来说,大小端存储之分是为了解决不同计算机系统之间的字节序问题,以保证数据的正确解析和传输。
三,浮点型数据在内存中的储存
开门见山:浮点数在内存中的储存与整数是不一样的!
整数是以补码的方式储存,那浮点数呢?
1,二进制浮点数的另一种表示形式
我们先来了解二进制浮点数的另一种表示形式👇🏻
根据国际标准IEEE🔍, 任意⼀个⼆进制浮点数
V
可以表⽰成下⾯的形式:
(-1)^S * M * 2^E
• (−1)^S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
• M 表示有效数字,(1<=M<2)
• 2^E表示指数位。
比如👇🏻:
•⼗进制的5.0,写成⼆进制是 101.0 ,相当于1.01
×2^2
【 S=0,M=1.01,E=2 】
•⼗进制的-5.0,写成⼆进制是 -101.0 ,相当于-
1.01
×2^2
【 S=1,M=1.01,E=2 】
•十进制的5.5,写成二进制是 101.1 ,相当于1.011
×2^2
【S=0,M=1.011,E=2】
(注意这里都是二进制,所以每一位上对应的权重的底数应该是2)
比如101.1
:从左到右每位数依次对应的权重是:2^2
,2^1
,2^0
,2^(-1)
2,浮点数储存过程
我们可以发现,每个浮点数,都可以用S
M
E
三个数据来表示出来,因此我们在储存时,也只需储存好这三个数据就可以了
IEEE 754规定:
•对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
•对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M
👇🏻
1)符号位S的储存
•正数储存0
•负数储存1
2)有效数M的储存
浮点数中的有效数一般写成 1.xxxxxx
的形式,其中 xxxxxx
表⽰⼩数部分。
如:浮点数5.5
:1.011
×2^2
, 011
是小数部分
🔍IEEE 754 规定,在计算机内部保存M时,默认这个数的第⼀位总是1
,因此会被舍去,只保存后⾯的xxxxxx
部分。(因为1<=M<2
,M总是1.xxxxxx
的形式)
如:浮点数5.5
,只保留011
这个小数部分
3)指数E的储存
E为⼀个⽆符号整数(unsigned int),意味着,如果E为8位,它的取值范围为0到255;如果E为11位,它的取值范围为0到2047。但是,科学计数法中,指数E可能是负数!!!
所以👇🏻
IEEE 754规定,E存⼊内存时,E的真实值必须再加上⼀个中间数:
•对于8位的E,这个中间数是127;
•对于11位的E,这个中间数是1023。
⽐如,5.5
:2^2
的E是2
,所以保存成32位浮点数时,必须保存成2+127=129,即10000001
。
所以浮点数5.5
在内存中的储存应该是:
2,浮点数取的过程
1)E不全为0或不全为1
•指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第⼀位的1
。
如取5.5
:
•S = 0
•E:10000001
(十进制的129),129-127 = 2
,得到真实值E = 2
•再将有效数字M(011
)前加上第⼀位的1
,得1.011
所以,5.5
= (-1)^0 × 1.011 × 2^2
2)E全为0
表示趋近于0
的很小的数字
这时,浮点数的指数E等于1-127
(或者1-1023
)即为真实值,有效数字M不再加上第⼀位的1,⽽是还
原为0.xxxxxx
的⼩数。这样做是为了表⽰±0
,以及接近于0的很⼩的数字。
0 00000000 00100000000000000000000
3)E全为1
表⽰±⽆穷⼤
(正负取决于符号位S)
0 11111111 00010000000000000000000
🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!