深度理解数据在内存中的存储

简介: 深度理解数据在内存中的存储

       今天我主要给大家带来的是整形数据在内存中的存储和浮点数据在内存中的存储。在我们常用的数据类型包括int型,char型,double型,short型,float型。在这些数据类型中我们可以分为整形家族浮点家族

1.整形家族

整形家族主要包括

2.大小端

大端存储是指数据的低位放在高地址存储,数据的高位放在低地址存储。

小端存储是指数据的低位放在低地址存储,数据的高位放在高地址存储。

       例如在我的电脑中打开vs,写一个变量a=0x11223344,在这里低位是44,高位是11,我们进入调试

它在内存中为44 33 22 11,故我们可以画图为

        因此我们可以看到我的电脑为小端存储。对于如何判断电脑的存储方式我们可以写一个判断的小程序,代码如下:

#include <stdio.h>
int main()
{
  int a = 1;
  char* p = (char*)&a;
  if (*p == 1)
    printf("小端存储");
  else
    printf("大端存储");
  return 0;
}
       在电脑中,数据是以 二进制的方式进行存储, int类型占4个字节在64位机器中占32个bite位它的二进制位00000000000000000000000000000001。 char类型占1个字节,8个bite位。我们利用指针再将其 强制转化为char*类型,由于我们指向离低地址近的位置,如果是大端存储则为00000000,小端存储则指向00000001.故我们运行程序可以得到是哪一种存储方式。

3.%d和%u

%d打印的是10进制,有符号的类型;

%u打印的是10进制,无符号的类型;

4.练习

4.1练习一

代码如下

#include <stdio.h>
int main()
{
  char a = -1;
  signed char b = -1;
  unsigned char c = -1;
  printf("a = %d b = %d c = %d", a, b, c);
  return 0;
}

       我们知道整形的数据在内存中以二进制的形式存在,也就是数据的补码,要想知道数据补码,需要得到它的源码和反码。对于-1,它的原码是10000000000000000000000000000001,反码为11111111111111111111111111111110,

补码为11111111111111111111111111111111。由于char占1个字节也就是8个bite位故a,b,c在内存中都是11111111的形式存储。由于需要以%d的形式输出所以需要进行整型提升a的类型为char,符号位为1所以补1,补码为11111111111111111111111111111111,反码为10000000000000000000000000000000;原码为10000000000000000000000000000001故为-1。b的类型为signed char属于有符号的char需要以%d的形式输出所以需要进行整型提升符号位为1所以补1,补码为11111111111111111111111111111111,反码为10000000000000000000000000000000;原码为10000000000000000000000000000001故为-1。c的类型为unsigned char 类型属于无符号类型补码原码反码相同在进行整型提升时补0,补码原码反码为00000000000000000000000011111111.输出255.

4.2 练习二

代码如下

#include <stdio.h>
int main()
{
  char a = -128;
  printf("%u", a);
  return 0;
}

        -128的补码为11111111111111111111111110000000由于时char类型所以10000000在内存中存储,由于需要以%u输出,所以需要进行整型提升符号位为1所以补1.,得到补码为11111111111111111111111110000000,由于需要以%u输出,所以它是无符号类型,所以原码反码补码相同都是11111111111111111111111110000000,故答案为4294967168。

5.大轮盘理解

对于char由于它是只有8个bite位所有最大为11111111.它的具体数值我们可以画图来了解

我们可以进一步得到:

在signed char类型中

进一步得到

在int short long 类型和这相似,想要研究的小伙伴可以自行计算。

6.浮点家族

7.IEEE标准

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S * M * 2^E

(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。

M表示有效数字,大于等于1,小于2。

2^E表示指数位。

IEEE 754规定:

对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。

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

例如10进制的5.5转化为二进制为101.1=(-1)^0*1.011*2^2;

S=0 M=1.011 E=2;

E为一个无符号整数(unsigned int)

这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们

知道,科学计数法中的E是可以出

现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127.

所以存储时S=0  E=10000001 M =01100000000000000000000

故在内存中以0 10000001 01100000000000000000000

8.练习

学到这里我们看一下代码

#include <stdio.h>
int main()
{
  int a = 9;
  float* p = (float*)&a;
  printf("%d\n",a);
  printf("%f\n", *p);
  *p = 9.0;
  printf("%d\n", a);
  printf("%f\n", *p);
  return  0;
}

       在printf("%d\n",a);中毫无疑问是9,对于*p由于在存储时是二进制为00000000000000000000000000001001,由于是浮点型 S=0 E=00000000 M=00000000000000000001001 E=0-127=-127,故(-1)^S * M * 2^E为0;

10进制为9.0二进制为1001.0=(-1)^0*1.001*2^3;

S=0 M=1.001 E=3+127=130;故为0 1000 0010 00100000000000000000000;

   printf("%f\n", *p);为9.000000;

到这里我们今天的内容就结束了,内容制作不易,希望大家可以一键三连。

目录
相关文章
|
4天前
|
消息中间件 存储 缓存
kafka 的数据是放在磁盘上还是内存上,为什么速度会快?
Kafka的数据存储机制通过将数据同时写入磁盘和内存,确保高吞吐量与持久性。其日志文件按主题和分区组织,使用预写日志(WAL)保证数据持久性,并借助操作系统的页缓存加速读取。Kafka采用顺序I/O、零拷贝技术和批量处理优化性能,支持分区分段以实现并行处理。示例代码展示了如何使用KafkaProducer发送消息。
|
3月前
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
96 11
|
4月前
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
109 14
|
4月前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
197 1
|
4月前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
4月前
|
监控 Java easyexcel
面试官:POI大量数据读取内存溢出?如何解决?
【10月更文挑战第14天】 在处理大量数据时,使用Apache POI库读取Excel文件可能会导致内存溢出的问题。这是因为POI在读取Excel文件时,会将整个文档加载到内存中,如果文件过大,就会消耗大量内存。以下是一些解决这一问题的策略:
540 1
|
3月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
544 1
|
2月前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
3月前
|
Java
JVM内存参数
-Xmx[]:堆空间最大内存 -Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的 -Xmn[]:新生代的最大内存 -xx[use 垃圾回收器名称]:指定垃圾回收器 -xss:设置单个线程栈大小 一般设堆空间为最大可用物理地址的百分之80
|
3月前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
34 3