数据在内存中是怎样储存的

数据的存储
首先我们要明白数据在内存中是以什么形式存在的——二进制数,但是,内存中存储的真的就是数据所对应的二进制数吗?显然不是,今天我们就来说说数据在内存中是怎样储存的,存储的形式是怎样的,打印的时候又是怎样出现的?
数据在内存中是以补码的形式存在的,说到补码我们来了解一下相关知识
**原码:**数据的二进制形式
**反码:**符号位不变,其余按位取反
**补码:**在原码的基础上+1
所以我们在编写的时候输入一个数据,系统是把它先转化为二进制数也就是原码,然后再转化为反码,最后化为补码存到内存中;既然知道怎么存进去的,那又是怎么样取出来的呢?其实就是把补码返回到原码打印出来。
要注意的是:数分为有符号和无符号数,有符号数又分为正数和负数,其中正数和无符号数二者的原码、反码、补码三者是一样的,只有负数的补码需要经过计算;
到现在,我们知道了数据在内存中是以补码的形式存在的;但并非是二进制数,而是二进制数所转换的十六进制数的形式(即4bit化为一个数字)
举个例子

int a = -1;

a的原码为:
10000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
补码:11111111 11111111 11111111 11111111
然后把这32个1转化为十六进制数ff ff ff ff,这就是存储在内存中的内容;
数据在内存中是怎样储存的
文章图片
那么我们思考一个问题,当a = 1的时候,存在内存中的是什么形式呢?
1的原码为00000000 00000000 00000000 00000001,因为正数的补码和原码相同,所以存储在内存中的十六进制应该为
00 00 00 01,那让我们来看一下
数据在内存中是怎样储存的
文章图片
怎么回事?怎么会是01 00 00 00呢?
这个就又涉及到大端和小端的问题
**大端模式:**指数据的低位保存到高地址上,而数据的高位则保存到低地址上;
**小端模式:**指数据的低位保存到低地址上,而数据的高位则保存到高地址上;
数据在内存中是怎样储存的
文章图片

#include int main() { char a = -1; unsigned char b = 1; printf("a = %db = %d", a, b); return 0; }

数据在内存中是怎样储存的
文章图片
这道题中的b为什么输出的是255?明明-1的补码是
11111111 11111111 11111111 11111111,这就涉及到了类型对于数据的影响,虽然-1是32位的一个数字,但是它存储在char类型的b中,而char类型只有存储一个字节的数据,也就是11111111;
当b要打印为十进制有符号位(%d)时,要进行整型提升,整型提升为
00000000 00000000 00000000 11111111 也就是255;
那么什么是整型提升呢?
整型提升的概念为字符型变量和短整型变量转换为整型使用时需要整型提升
整型提升规则:
当数据为有符号数时,前面24位需要补当前符号位,即正数补0,负数补1;
当数据为无符号数时,前面24位需要补0;
值得注意的是,整型提升怎么提升就要看变量本身是有符号还是无符号的,和打印什么类型的数据无关;而返回的原码、反码、补码时候相同就要看需要打印什么类型的变量了;
举个例子
int main() { char a = -1; printf("%u", a); return 0; }

%u表示要打印无符号十位进制数,我们来解一下,首先是要先把-1的原码写出来
原码:10000000 00000000 00000000 00000001
反码:111111111 111111111 111111111 111111110
补码:111111111 111111111 111111111 111111111
a为char类型,存储一个字节数据——11111111
a为负数,整型提升后为11111111 11111111 11111111 11111111
因为要打印一个无符号数,所以其原码和补码一致;
【数据在内存中是怎样储存的】数据在内存中是怎样储存的
文章图片

    推荐阅读