我们都知道在c语言中有多种数据类型,其中有自带的int、folat、char、指针变量等等,还有还有自定义类型结构体、联合体、枚举等等,那这些数据在创建之后是怎样存储的呢?在学习之后我相信可以对这些数据的使用和理解代码会更深。
一、整形在内存中的存储
int a=-10;
我们知道创建int类型变量a时,编译器会为a分配4个字节的空间来存储,那怎么把10放入这4个字节中呢?
首先我们要知道一个概念,原码、反码、补码,这三种表示形式均有符号位和数值位两部分,其中第一位为符号位0代表正,1代表负,其余位为数值位,其中正数的原反补码相同。
原码
即将数值10转为二进制
10000000 00000000 00000000 00001010
反码
将原码符号位不变,其他位置取反
11111111 11111111 11111111 11110101
补码
反码+1为补码
11111111 11111111 11111111 11110110
对于整形来说:数据存储在内存中的是补码。
![](https://i-blog.csdnimg.cn/blog_migrate/fbd6b0ba66fbfd623d53cdd78669043d.png)
我们打开编译器看一下发现内存里确实存的是补码,好但是像有点不太对劲,好像这4个字节是不是放反了?
这就涉及到大小端字节序问题?
什么是大小端嘞
![](https://i-blog.csdnimg.cn/blog_migrate/ab9b9bdcc740a285d6ebaa14a0ba6628.png)
那为什么会有大小端之分呢?我们在计算机系统中,我们是使用字节为单位的,一个字节为8个比特。对于我们大于为8位的处理器,例如16位32位和64位的处理器,寄存器宽度大于8,就面临多个字节如何安排的问题,就这样产生了大小端字节序的问题。
二、浮点数在内存中的存储
也不扯多的了,根据国际标准IEEE(电气电子工程师学会)754,任意一个二进制浮点数V可以表示成以下的形式
(-1)^S*M*2^E
(-1)^S表示符号位,当s=0时,V为正数,当s=1时,V为负数
M表示有效数位,大于等于1,小于2
2^E表示指数位
是不是感觉一长串的好复杂,其实就看成M*2^E,再区分用s区分一下正负就ok了。
而有效数位M又是怎么来的呢,比如5.0,转换成二进制就是101.0,再把小数点左移2位得到有效数位1.01,而这个时候指数位E就是2,上面的公式就是1.01*2^2。
这是32位浮点数在内存中的存储
![](https://i-blog.csdnimg.cn/blog_migrate/28244c507a089dd013b18e1c241eebb1.png)
然后754规定中对有效数位M和指数E还有一些规定
有效数位M总是大于等于1小于2,所以在存储的时候,就不存1了,直接存小数点后面的数,比如保存1.01的时候,只保存01,取出来算的的时候再把1加上,这样就能多保存一位了。
指数E为一个无符号整数,在把真实的E存进去的时候要加上一个中间数,对于8位的E这个数是127。对于64位浮点数11位的E,这个数为1023。
比如指数是10,那存入内存的值为10+127=137,取出的时候再减去127就得到真实的E了。
当E为全0时
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,
有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字
E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);
数据在内存中的存储就先到这了,希望可以帮助到大家一点点