数据在内存中的储存

简介: 数据在内存中的储存

c语言中数据在内存中都是以二进制储存的,但是不同的数据类型储存的方式也不一样,我们先简单了解一下整数和浮点数在内存中储存的方式。


1.整数在内存中的存储


整数的二进制有三种表示方法:原码反码补码。一般在内存中存的是补码

正数的原码,反码,补码都相同,

而负数的原码最高位是符号位,0表示正,1表示负,其他位用二进制来表示,

反码原码的符号位不变,其他位取反+1,得到反码

补码就是反码+1,


例如:-12

原码:10000000  00000000  00000000   00001100

反码:11111111    11111111     11111111     11110011

补码:11111111    11111111     11111111     11110100


2. 大小端字节序和字节序判断


了解了整数在内存中存储的方式,我们来看一道题,

# include <stdio.h>
int main ()
{
int a = 0x11223344 ;
char* p=&a;
*p = 0;
printf("%x ", a);
return 0 ;
}


a会变成什么呢?


       


为什么改变的时44呢?这就涉及到大小端字节序的储存方式了,

⼤端(存储)模式:是指数据的 低位字节 内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存 在内存的低地址处。

⼩端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存 在内存的⾼地址处。

低位字节和高位字节指的是权重,例如:



权重低的成称为低位字节,权重高的称为高位字节,

如何判断该字节序是大端储存还是小端储存呢?


int main()
{
    int a = 0x11223344;
    char* p = &a;
    *p = 0;
    if (*((char*)&a) == 0)
        printf("小端\n");
    else
        printf("大端\n");
    return 0;
}



 


3.浮点数在内存中的储存


浮点存的过程


知道整数的储存方式后,那么浮点数是怎么储存的呢?



例如:

十进制的 5.0 写成二进制是  101.0 ,也就是 1.01*2^2    (1<=M<2)

按上面的格式写就是:S=0,M=1.10,E=2  V=(-1)^0  *  1.01  *  2^2

内存中只储存S,M的小数部分,E

因为我们默认为M的整数部分为1,所以不去储存它,节省一位用来储存小数部分,使浮点数储存更精确。


IEEE 754规定:

对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M

对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M


画图示例:



对于指数 E来说,是一个无符号整数(unsigned int),如果E是八位,范围是0~255,如果E是11位,范围是0~2047,但是在科学计数法中E是可以为负数的,所以我们(IEEE什么协会)规定,存储E的值要加上127(如果是11位要加上1023),


比如E是10,必须保存为 10+127,那么储存在内存中的是10001001


窃窃私语:也不知道为啥这么麻烦


浮点取的过程


M取出来时,要记得加上整数部分的1,

指数E取出来有三种情况:E不全为0也不全为1 , E全为0,  E全为1,

E不全为0也不全为1:

这种情况比较简单,把E取出来减127(或者1023),

E全为0:这时E的真实值就是1-127(或者1-1023)表示无限接近0的值

E全为1:这时E的真实值就是E的值就非常大了,表示无穷大的值,正负取决于符号位S


学到这里,我们已经了解了浮点数的储存,浮点数有可能不是完全精确的储存在内存中,就是会有误差,因为把小数部分转化成二进制没办法完全精确。


4.结语


讲解的不是很详尽,有不对的地方或者哪里需要补充,请在评论区留言哦!

相关文章
|
4天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
11 2
|
8天前
|
存储
数据在内存中的存储(2)
数据在内存中的存储(2)
21 5
|
7天前
|
存储 编译器 C语言
数据在内存中的存储
数据在内存中的存储
14 2
|
7天前
|
存储
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)
|
7天前
|
存储 C语言
C语言----数据在内存中的存储(2)
C语言----数据在内存中的存储
13 0
|
7天前
|
存储 C语言
C语言----数据在内存中的存储(1)
C语言----数据在内存中的存储
|
12天前
|
消息中间件 存储 Kafka
实时计算 Flink版产品使用问题之 从Kafka读取数据,并与两个仅在任务启动时读取一次的维度表进行内连接(inner join)时,如果没有匹配到的数据会被直接丢弃还是会被存储在内存中
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
8天前
|
存储 小程序 编译器
数据在内存中的存储(1)
数据在内存中的存储(1)
25 5
|
8天前
|
存储 安全 Java
SpringSecurity6从入门到实战之初始用户如何存储到内存
Spring Security 在 SpringBoot 应用中默认使用 `UserDetailsServiceAutoConfiguration` 类将用户信息存储到内存中。当classpath有`AuthenticationManager`、存在`ObjectPostProcessor`实例且无特定安全bean时,此配置生效。`inMemoryUserDetailsManager()`方法创建内存用户,通过`UserDetails`对象填充`InMemoryUserDetailsManager`的内部map。若要持久化到数据库,需自定义`UserDetailsService`接口实
|
15天前
|
存储 C++
C primer plus 学习笔记 第12章 存储类别、链接和内存管理
C primer plus 学习笔记 第12章 存储类别、链接和内存管理