数据的存储--深度解剖数据在内存中的存储(上)

简介: 数据的存储--深度解剖数据在内存中的存储(上)

本章重点

1.数据类型详细介绍

2.整形在内存中的存储:原码、反码、补码

3.大小端字节序介绍及判断

4.浮点型在数据中的存储解析

一 数据类型介绍

前面我们已经学习了一些基本的数据类型。

long long这种类型在C99中才有,所以在新的编译器中才有这种类型。VC6.0中就不支持这种类型

int 在早期16位平台上是2个字节,现在的32位平台和64位平台都是4个字节

C语言规定sizeof(long)>=sizeof(int)                       long long 8个

在新的编译器里面还有long double     在vs2019 也是8个字节

1.1 类型的基本分类

整形家族

方括号[] 说明可以省略,也可以不省略

char

     unsigned char

     signed char

short

     unsigned short [int]

     signed short [int]

int

     unsigned int (无符号整型)      

     signed int (有符号整形)

long

     unsigned long [int]

     signed long [int]

字符(char)的ASCII码值是整形,所以char也归到整形家族

long long也属于整形家族

无符号整型用%u打印

平常中的int(可以放正数,也可以放负数) 就是signed int(signed int 等价于 int),unsigned int 无论里面放的是正数还是负数,都会转化为相应的正整数来计算。

signed short 等价于 short

signed long等价于 long

char 等价于signed char 还是 unsigned char 是取决于编译器实现的,常见的编译器是等价于signed char ,VS2019 char 等价于signed char 。

浮点数家族

float

double

float 单精度 double 双精度,它的精度更加高

构造类型

数组类型

结构体类型 struct

枚举类型 enum

联合类型 union

构造类型,又叫自定义类型,例如 int arr[5] 和 int arr[7] 他们两个的类型分别是 int [5] int [7], 通过自己的定义而发生改变。

指针类型

int *pi;

char *pc;

float* pf;

void* pv;

空类型

void 表示空类型(无类型)

通常应用于函数的返回类型、函数的参数、指针类型

函数参数void说明不需要传入参数,void*p,说明p可以是任何类型的指针类型

二 整形在内存中的存储

变量的创建是要在内存中开辟空间的。空间的大小是根据不同的类型决定的。

注意:在调试器的内存窗口中,展示的是16进制,但是内存中储存的是二进制(为了方便展示)

2.1 原码、反码、补码

计算机的整数有三种表示方法,即原码、反码、补码。

三种表示方法,均有符号位和数值位两部分。符号位都是用0表示“正”,用1表示“负”

负整数的三种表示方法各不相同

原码

直接将二进制按照正负数的形式翻译成二进制就可以。

反码

将原码的符号位不变,其他位依次按位取反就可以得到了。

补码                                                                                                                                                    反码+1

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

0的原码、反码、补码都是000000000 00000000 00000000 00000000

对于整形来说:数据存放内存中其实存放的是补码:原因是:在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;原码相加会出现错误,补码就不会。同时,加法和减法也可以统一处理(CPU只有加法器)(计算机中只有加法器,减法是模拟出来的)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路

四位二进制表示的最大数字是16,所以两位16进制表示一个字节,一个字节=8位在编译器内存显示器中10,0a 00 00 00,数据的低位放在低地址中,这就是下面要讲述的大小端。

2.2 大小端介绍

什么大端小端:

大端(存储)模式(大端字节序存储),是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;

小端(存储)模式(小端字节序存储),是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

char 类型是没有大小端的,因为char就一个字节,大小端是以字节为单位的。

在这里就可以非常明显的看见数据的低位放在内存的低地址中。

为什么有大端和小端:

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元

都对应着一个字节,一个字节为8bit。但是在C语言中除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就

导致了大端存储模式和小端存储模式。

例如:一个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为

高字节, 0x22 为低字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。                                                                                                                     小端模式,刚好相反。我们常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

设计一个程序,判断当前机器的字节位。

a = 1; 0x 00 00 00 01 (大端);0x 01 00 00 00 (小端),比较第一个地址的是否等于1,即可,仅仅想拿第一个字节的地址,那么解引用的时候用char即可。

代码1展示:

1. #include <stdio.h>
2. int main()
3. {
4.  int a = 1;
5.  char* pa = (char*)&a;//强制类型转换
6.  if (*pa == 1)
7.  {
8.    printf("小端\n");
9.  }
10.   else
11.   {
12.     printf("大端\n");
13.   }
14.   return 0;
15. }

代码2展示:(函数以及简化)

1. #include <stdio.h>
2. int check_sys()
3. {
4.  int a = 1;
5.  return *(char*)&a;
6. }
7. int main()
8. {
9.  int a = check_sys();
10.   if (a == 1)
11.   {
12.     printf("小端\n");
13.   }
14.   else
15.   {
16.     printf("大端");
17.   }
18.   return 0;
19. }


相关文章
|
1天前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
3天前
|
监控 Java easyexcel
面试官:POI大量数据读取内存溢出?如何解决?
【10月更文挑战第14天】 在处理大量数据时,使用Apache POI库读取Excel文件可能会导致内存溢出的问题。这是因为POI在读取Excel文件时,会将整个文档加载到内存中,如果文件过大,就会消耗大量内存。以下是一些解决这一问题的策略:
12 1
|
5天前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
6天前
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
13 2
|
10天前
|
存储 编译器
数据在内存中的存储
数据在内存中的存储
29 4
|
8天前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
24 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
3月前
|
存储 分布式计算 Hadoop
HadoopCPU、内存、存储限制
【7月更文挑战第13天】
249 14
|
2月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
260 0
|
16天前
|
存储 机器学习/深度学习 人工智能
数据在内存中的存储
数据在内存中的存储
|
11天前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储