前面基本上系统的过了一遍C的所有基础知识。感觉好像重新认识了C一样,学到了很多不一样的东西。不过,在真正的编程工作中,有那些知识是远远不够的,所以,从这一篇文章开始,就要深挖一些更加深层次的知识。记得第一节C语言课上就是学了二进制还有数制转换啥的。所以,这个探索的开始也就以数据开始喽,小伙伴们和我一起呀!
内存中数据的存储
一、数据归类
首先,当然要提一下为什么会有数据的类型,还记得《C专项——数组和指针》这一篇博客里介绍的指针吗,指针的类型存在的意义跟数据类型的意义还是有相似之处的。在这里,就把数据类型的意义说一下:
- 决定了开辟的内存空间的大小(可以使用的内存空间的大小)
- 决定了我们要站在怎样的角度去看待这片内存空间
比如:int 型和 float 型都占4 byte ,同样的数字0,int 存储的是0,float 存储的就是0.0。
好了,讲完意义,下面把我做好的类型分类的图放到这里,就不再一一列举了。
- 空类型(void) , 通常应用于函数的参数、返回值、指针等等。
二、大小端字节序
1、定义
先说明,数据从左到右是由高位到低位
- 大端存储:数据的低位保存在内存高地址;高位保存在低地址
- 小端存储:数据的低位保存在内存的低地址;高位保存在高地址
2、意义
在内存的存储中,是以1个字节为1个存储单元,但是C语言中的数据大小1个内存单元是满足不了的,所以就出现了如何去安排多字节的问题,也就因此有了这两种常见的存储模式。
3、设计一个小程序来判断当前机器的字节序
#include <stdio.h>
int main()
{
int a = 1;
char b = (char)a;
if (b)
{
printf("该机器是小端字节序存储!\n");
}
else
{
printf("该机器是大端字节序存储!\n");
}
return 0;
}
三、整型数据在内存中的存储
1、有符号整数的表示方式
表示方式有三种:原码、反码、补码
对于正数,三种表示方式一样;对于负数,如下:
- 原码:最高位表示符号位(0正1负),其余位直接按二进制翻译过来就是
- 反码:符号位不变,其余位在原码的基础上取反(即0换成1,1换成0)
- 补码:补码加1
2、整型的存储方式
对于整型来说,数据存放到内存中的其实是补码。原因主要有以下三个:
- 可以将符号位、数值位统一处理
- 可以把所有运算统一到加法运算
- 原码补码的转换过程一致(对正数不变,负数取反加一),不需要额外的硬件电路
对于1个有符号的8个比特位,即1字节。内存是如下处理的:
其他字节数不同的数据类型同理,相信聪明的你一定能举一反三,这里就不做赘述啦~
四、浮点型数据在内存中的存储
根据国际标准IEEE(电气和电子工程协会)规定,任何一个二进制浮点数V可以表示成下面的形式:
- (-1) ^ s * M * 2 ^ E
- (-1) ^ s表示符号位,当s为0时,v为正数;当S为1时,v为负数
- M表示有效数字,1<= M <2
- 2^E表示指数位
举个例子:十进制的5.5,写成二进制是101.1,化成上面表示的形式就是(-1) ^ 0 * 1.011 * 2 ^ 2,可以得出s = 0,M = 1.011,E = 2。
单精度float有32位,双进度double有64位,具体的分布见下图:
IEEE 754对有效数字M和指数E,还有一些特别规定。
对于M,默认这个数的第一位总是1(即数字是1.xxxxxx),因此可以被舍去,只保存后面的xxxxxx部分。这样做的目的,是节省1位有效数字。
对于E,它是为一个无符号整数(unsigned int), 这意味着,如果E为8位,它的取值范围为0–255;如果 E 为11位,它的取值范围为0–2047。但是实际的 E 是可以出现负数的,所以 IEEE 754规定,存入内存时 E 的真实值必须再加上一个中间数,对于8位的 E ,这个中间数是127;对于11位的 E ,这个中间数是1023。比如,2^10的E 是10,所以保存成32位浮点数时,它的 E 必须保存成10+127=137,即10001001。
由于加了中间值,E 从内存中取出分成三种情况:
-
E不全为0或不全为1
E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
比如: 0.5的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),
E为-1+127=126,表示为01111110
M为1.0去掉整数部分为0,补齐0到23位00000000000000000000000
最终其二进制表示形式为:0 01111110 00000000000000000000000 -
E全为0
还原为0.xxxxxx的小数,表示±0,以及接近于0的很小的数字。 -
E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)
好了,今天分享到此结束!是不是满满干货!!自己又回忆了一遍!我真棒!!看了文章的小伙伴你也很棒,欢迎评论区指正喔!拜拜~下次见