我们已经介绍并且大致清楚了整形数据的存储是以二进制的补码形式存储在内存中的——正数的原反补相同,负数按照原反补规则改变后将补码存储在内存中。
可是内存在数据中既然以二进制来放置,那么一个整形的数据是怎么放置呢?
接下来我们就来详细的探讨一下该类知识:
首先我们创建两个变量
int a = 1;
int b = -10;
我们知道,会以补码的形式存储在内存中:,a则是相应的二进制序列
a的补码:00000000000000000000000000000001 | b的补码:11111111111111111111111111110110 |
让我们在vs2019的环境下来看看两者数据在内存中的存储情况:
我们可以看到a的数据存放是:01 00 00 00。b的数据存放是 f6 ff ff ff。
这是因为在内存中,我们是以十六进制来存储数据,我们可以稍加转化一下——因为四个二进制位可以转换成一个十六进制位,因此:
对比一下我们在内存中的存储,可以说是大同小异,只是数值摆放顺序不同。
而对于b变量来说就有如下解析:
(我们没有设置b为-1,因为这样的话我们会得到”ff ff ff ff“这个数据难以观察)由此我们可以确信——数据在内存中是以补码的形式存放的。
可奇怪的是,他们的存储似乎跟我们算出来的十六进制数的摆放位置有所不同,这是为什么呢?
这里我们需要介绍另一个知识点——大小端字节序存储
大端字节序存储:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址
中
小端字节序存储:是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地
址中。
为什么会有该类存储模式呢?因为在计算机系统中,我们是以字节为单位的,而每个地址单元都对应着一个字节,一个字节为8个bit,但是我们由数据的类型便可知,除了char类型是8个bit之外,int是32个bit(4字节) short是16个bit(2字节)。另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
我们来假设一段如下的内存空间:左边低地址右边高地址,我们可以得到两种存储模式的状况如下
而由上图可知,我们在vs2019编译环境下是小端字节序存储模式
我们也可以来写一个代码验证数据在vs中是如何存储的:
#include<stdio.h>
int main()
{
int a = 1;
char* p = &a;
if (*p == 1)
printf("是小端存储\n");
else
printf("是大端存储\n");
return 0;
}
如果是小端存储,在内存中便是:01 00 00 00,大端则是:00 00 00 01
我们将a的地址取出放到一个char*变量中,当我们解引用p变量时便会得到a的第一个字节的数据01(小端)或者00(大端),这时只需要判断是否等于1便可确定大小端存储模式。
运行结果如上:确实在vs中,数据是以小端字节序存储的。至此,我们便清晰的认识了整形数据的存储模式以及新的知识点——大小端字节序存储。好啦,整形数据的存储我们便暂时告一段落,不过数据的存储篇章可还没有完结,敬请期待。