谁能横刀立马,唯我飞牛大将军!
———————————————————————————————————————————————————————
本节主题:#数据在内存中如何存储?
———————————————————————————————————————————————————————
数据到底有哪些类型?
.
.
first:基本的内置类型
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数
那么,C语言有没有字符串类型呢?
答案显示是no!
但是我们可以
const char *str = "Hello world";
char str[] = "Hello world";
这样来表示字符串
那么,类型的意义在哪里? 意义有二:
其一:它决定了我们定义变量时开辟内存空间的大小
其二:决定了我们如何看待内存空间的视角
.
.
second:构造类型
> 数组类型
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union
.
.
third:指针类型
int * p;
char *q;
float * s;
void *f;
double *k;
.
.
forth:空类型
>void表示空类型
>通常应用于函数的返回类型,函数的参数,指针类型等
———————————————————————————————————————————————————————
整型在内存中的存储
.
.
原码,反码,补码
1.符号位表示方法一样
a. 三种表示方法均有符号位与数值位
b. 符号位表示一样,0表示正,1表示负
2.数值位表示方法不一样
原码
直接将二进制按照正负数的形式翻译成二进制就OK啦
反码
原码符号位不变,其他位按位取反就OK啦
补码
反码加1就得到补码啦
整数的原码,反码,补码都相同
对于整型数据来说,数据在内存中是以补码的形式存放的
我们来看看整型数据在内存中存储的情况
由此可见,整型数据在内存是以补码的形式存放的,但是这里似乎出现了一点问题,为什么顺序有点不对劲呢?
OK,我摊牌了,这里涉及大小端问题
.
.
大小端问题
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。
> 写一个简单的程序验证大小端
int a = 20;
printf("%d\n", *((char*)&a));
———————————————————————————————————————————————————————
浮点型在内存中的存储
任意一个二进制数都可以表示为浮点数,为下列形式:(-1)^S * M *2^E
a.(-1)^S为符号位 —> S为0时,表示正数,S为1,表示负数
b. M表示有效数字 —>大于等于1,小于2
c. 2^E表示指数位
单精度浮点数存储模型
对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M
双精度浮点数存储模型
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
对有效数字M和指数E,还有一些特别规定
M部分
由1≤M<2,M可以写成1.xxxxxx,这里的xxxxxx表示小数部分,在计算机内部保存M时,默认第一位是1,所以可以省略,原来可以保存23位的M,现在可以保存24位了
E部分(E是无符号整数)
存入情况
我们知道,科学计数法中E是可以出现负数的,所以存入时候,要加上一个中间数,对于8位的E是127,对于11位的E是1023,比如,2^5的E是5,所以保存成32位浮点数时,必须保存5+127 = 132,而这里的132要写成8位E的二进制形式
取出情况(三种情况)
1.E不全为0或不全为1
E的值减去127,得到真实值,再将M前面加上第一位的1
比如0.5的二进制为0.1,由于规定正数部分必须为1,则将小数点右移一位,得1.0*2^(-1),阶码为 -1+127 = 126,二进制为01111110,在计算机内部保存M时,默认第一位是1,所以可以省略,得解:
0 01111110 00000000000000000000000
E全为0
这时,真实值为1-127(或者1-1023),M前面也不再加上第一位的1,整个数被还原为0.xxxxxx的小数,代表接近正负0,以及接近0的很小的数字
E全为1
这时候,如果有效数字全为0,代表正负无穷大
.
.
美好的时光总是短暂的,我们下期再会!
PS:如果我的博文有幸被哪位小伙伴看到,并且觉得我写的还行的话,可以点点订阅支持一下,手动关注不迷路,和飞牛一起上高速,哈哈!