C语言-数据在内存中的存储

欢迎大家继续来和我一起学习,今天我们要学习的是数据在内存中的存储。

目录

1.整型在内存中的存储

2.⼤⼩端字节序和字节序判断

2.1 大端与小端的判断

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

3.1 浮点数在内存中的取出


1.整型在内存中的存储

我们知道,整型的二进制表示方法一共有三种,分别是:原码,反码和补码。

整数分为有符号整数和无符号整数,对于有符号的整数来说,它的二进制表示由符号位和数值位组成,正数的符号位为0,负数的符号位为1。而对于无符号的整数,所有的二进制位都是数值位。

而在内存中,整型其实是以补码的形式进行存储的,之所以这样也是有原因的:

在计算机系统中,数值⼀律⽤补码来表⽰和存储。原因在于,使⽤补码,可以将符号位和数值域统⼀处理;同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
2.⼤⼩端字节序和字节序判断

我们知道,内存中的每个地址指向一块空间,这些空间由比特位组成,对于整型数据,他们在内存中的存储方式又是怎样的呢?

对于超过⼀个字节的数据在内存中存储来说,有存储顺序的问题,按照不同的存储顺序,我们分为⼤端字节序存储和⼩端字节序存储,下⾯是具体的概念:
⼤端(存储)模式:
        是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存在内存的低地址处。
⼩端(存储)模式:
        是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存在内存的⾼地址处。

 对于在内存中一个字节大小的空间,它的每个比特位的位置是不同的,对于整数20,它的二进制表示在一个字节内为00010100,而在内存中就有大端和小端两种储存方式。下面是两种储存方式下的图解:

大端存储:

小端存储:

 

 

为什么会有⼤⼩端模式之分呢?
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着⼀个字节,⼀个字节为8bit 位,但是在C语⾔中除了8 bit 的 char 之外,还有16 bit 的 short 型,32 bit 的 long 型(要看
具体的编译器),另外,对于位数⼤于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度⼤于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。因此就导致了⼤端存储模式和⼩端存储模式。
2.1 大端与小端的判断
那么该怎样判断一个整型数据在内存中到底是哪一种存储方式呢?
我们知道 1 的二进制序列是00000000 00000000 00000000 00000001 若 1 在内存中是大端排序,那我们打印第一个字节的结果应该是 0 ,而小端排序时打印结果应该为 1 。

可以看到在作者的电脑上打印结果为1,说明作者的电脑是小端排序的, 

我们来看一道关于小端排序的题:

#include <stdio.h>
//X86环境 ⼩端字节序
int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;
}

对于数组a来说,数组中每个元素用十六进制可以写成下图形式,由于是小端排序,所以写成10 00 00 00,但要注意的是10才是1的十六进制在小端排序的正确形式。
 

我们接下来看这道题,首先来看ptr1,数组的地址+1跳过一个数组的长度,再强制转化为jin* 类型

而ptr1[ -1 ]表示的是ptr1-1,由于ptr1被强制转换为了int*类型,所以-1时跳过4个字节,此时ptr1就指向4。

再来看ptr2 ,先将ptr2强制转换为int类后+1,我们知道ptr2 代表首元素地址,而整型+1就跳过1,所以ptr2指向的位置应跳过一个字节。再转换为int*类型,对其解引用,应该访问四个字节,且最后打印结果以十六进制输出,所以结果应该为2000000 。

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

讲完了整数在内存中的存储,接下来我们来学习一下浮点数在内存中的存储。

对于一个浮点数,它有两种写法:小数型和指数型(3.14159、1E10等)而对于每一个以小数形式写出的浮点数,也可以改写为指数型写法。

而在内存中,浮点数的储存是以指数形式进行储存的。

要把一个小数写成指数形式,我们还要知道是怎样变换来的,对于一个十进制数123,我们可以写成1.23*10^2,这一方法对二进制数同样适用。

根据国际标准IEEE(电⽓和电⼦⼯程协会) 754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:
  • V   =  (−1) ^ S * M * 2^E
  • (−1)^S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
  • M 表⽰有效数字,M是⼤于等于1,⼩于2的
  • 2 ^ E 表⽰指数位

比如说十进制的5.0,写成⼆进制是 101.0 ,相当于 1.01×2^2 ,根据上⾯V的格式,可以得出S=0,M=1.01,E=2。

所以⼗进制的-5.0,写成⼆进制是 -101.0 ,相当于 -1.01×2^2 。那么,S=1,M=1.01,E=2。

对于浮点数的内存空间分配,同样有规定:

IEEE 754规定:
对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

 32位浮点数,也就是float类型的数,一个float类型的数据分配四个字节的空间,在这四个字节当中,有1位用来储存S,8位用来存储E,剩下23位全用来储存有效数字M,同理可得64位浮点数,也就是double类型的数据的空间分配。这也就是为什么double类型的数据精度要比float类型数据高的原因。

                                         两图分别是float和double类型的空间分配

因为二进制数写成指数部分M的整数部分必为1,所以在储存数据的时候在M的空间中只存储小数部分,这样也能有效提高精度。

而对于指数E,有更复杂的情况,在内存中储存的E必须是无符号整数,但事实上指数部分可能会存在负数,所以IEEE 754规定,存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。⽐如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

这样就能保证存储的E全为正数。

3.1 浮点数在内存中的取出

对于指数E从内存中取出还可以再分成三种情况:

1.E不全为0或不全为1

这时,浮点数就采⽤下⾯的规则表⽰,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第⼀位的1。

2.E全为0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第⼀位的1,⽽是还原为0.xxxxxx的⼩数。这样做是为了表⽰±0,以及接近于0的很⼩的数字。

3.E全为1
这时,如果有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s);
 
因为E只在存储的时候是无符号数,当E为全0时,减去中间值,则指数部分为2的-(1-127)或-(1-1027)次方,就趋向于0,所以M的整数部分忽略不写。
当E为全1时,指数部分为2的(1-127)或(1-1027)次方,趋向于无穷大。
我们今天的数据在内存中的存储就像学习这么多,让我们下次再见
  • 31
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言-学生信息管理系统是一个基于链表数据结构的学生信息管理系统。链表是一种数据结构,可以存储和管理一系列具有相同类型的数据。在学生信息管理系统,链表被用来存储和操作学生的基本信息。 该系统主要有以下功能: 1. 添加学生信息:可以添加学生的姓名、学号、性别、年龄等信息,并将该学生的信息节点插入到链表。 2. 删除学生信息:根据学号或其他关键词查找到对应的学生信息节点,并从链表删除该节点。 3. 修改学生信息:根据学号或其他关键词查找到对应的学生信息节点,并根据需求修改学生的信息。 4. 查询学生信息:可以根据学号或其他关键词查找到对应的学生信息节点,并显示该学生的详细信息。 5. 遍历学生信息:可以遍历整个链表,显示所有学生的基本信息。 链表的优势在于插入和删除节点的操作比较高效,因为只需要改变节点的指针指向即可,不需要移动其他节点。而数组在插入和删除操作时需要移动其他元素,效率较低。 在实现学生信息管理系统时,可以使用指针来操作链表,通过指针的指向找到链表的某个节点,并进行相应的操作。同时,需要注意对内存的管理,确保动态分配和释放内存的正确性,避免内存泄漏和访问错误。 总之,C语言-学生信息管理系统是一个基于链表数据结构的系统,可以实现学生信息的增删改查等功能。通过灵活运用链表的特点,可以高效地管理学生的基本信息。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值