数据的存储【详解】【强烈推荐!!!】

news2024/11/23 21:01:24

数据的存储

  • 1. 数据类型介绍
    • 1.1 类型的基本归类
  • 2. 整型在内存中的存储
    • 2.1 原码、反码、补码
    • 2.2 大小端介绍
    • 2.3 练习
  • 3. 浮点型在内存中的存储
    • 3.1 一个例子
    • 3.2 浮点数存储规则

1. 数据类型介绍

基本的内置类型、大小(字节)(VS编译器)
在这里插入图片描述

意义:
1. 大小决定了适用范围
2. 提供了看待内存空间的视角。例如:在VS编译器中创建一个整型变量,我们向内存申请了4个字节的空间。

1.1 类型的基本归类

整型家族:

在这里插入图片描述

浮点型家族:

在这里插入图片描述

构造类型:(自定义类型)

在这里插入图片描述
指针类型:
在这里插入图片描述
空类型:

void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型。

2. 整型在内存中的存储

我们之前讲过一个变量的创建是要在内存中开辟空间的。空间的大小是根据不同的类型而决定的。

那接下来我们谈谈数据在开辟内存中到底是如何存储的?

比如:

int a = 20;
int b = -10;

我们知道为a 分配四个字节的空间。
那如何存储?

下来了解下面的概念:

2.1 原码、反码、补码

在这里插入图片描述
在这里插入图片描述
对于整型来说:数据存放内存中其实存放的是补码。
为什么呢?

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

//举个例子:
int a = 1;
int b = 1;
int c = a - b;
//1-1
//因为CPU只有加法器,所以可以这样转换。
//1+(-1)
//如果用原码计算的话,
//00000000000000000000000000000001-1
//10000000000000000000000000000001-(-1)
//10000000000000000000000000000010-(-2)
//得到了-2,这样是错误的,用反码的话实在麻烦,所以用补码很方便。

补码转成原码有两种方式:

  1. 先进行按位取反,再+1便可得到原码
  2. 先进行-1,再按位取反便可得到原码

我们看看在内存中的存储:
在这里插入图片描述
我们可以看到对于a和b分别存储的是补码。但是我们发现顺序有点不对劲
这又是为什么呢?
往下看!!!

2.2 大小端介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
例如:

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

请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。

思路:以1为例,在大端模式下,01在高地址处,在小端模式下,01在低地址处。所以我们判断低地址处的数是否为01,则可以判断大端字节序和小端字节序。

#include<stdio.h>
int check_sys()
{
	int i = 1;
	return (*(char*)&i);
	//将i的地址强制类型转为char*,再进行解引用得到1个字节内容
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

2.3 练习

进行一些练习来巩固知识。

//输出什么?
#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;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以上最后的二进制序列是补码,需要转换成原码即是答案!

#include<stdio.h>
{
	char a = -128;
	printf("%u\n", a);
	return 0;
}
//10000000 00000000 00000000 10000000-原码
//11111111 11111111 11111111 01111111-反码
//11111111 11111111 11111111 10000000-补码
//10000000-char a
//00000000 00000000 00000000 10000000-整型提升(%u是十进制的无符号数)。
//11111111 11111111 11111111 10000000-原码

在这里插入图片描述

#include<stdio.h>
int main()
{
	char a = 128;
	printf("%u\n", a);
	return 0;
}
//00000000 00000000 00000000 10000000-原码
//01111111 11111111 11111111 01111111-反码
//01111111 11111111 11111111 10000000-补码
//10000000-char a
//和上一道题目一样。

这个图就是解释上面两个题的规律,无符号的char取值范围是0-255
在这里插入图片描述

int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
//i:
//10000000 00000000 00000000 00010100-原码
//11111111 11111111 11111111 11101011-反码
//11111111 11111111 11111111 11101100-补码
//j
//00000000 00000000 00000000 00001010-原码(反码、补码)
//相加后,在进行格式化为有符号的整数
//11111111 11111111 11111111 11110110
//10000000 00000000 00000000 00001010-原码
//答案是-10

unsigned int i;
for (i = 9; i >= 0; i--)
{
	printf("%u\n", i);
}
//首先i是无符号的整数;
//然后进行一个循环,打印无符号的数
//既然i是无符号的数,那么i会一直大于等于0,结果就是死循环。
int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1-i;
	}
	printf("%d",strlen(a));
	return 0;
}
//这个程序存放从-1开始递减的数
//char是有符号的,那么取值范围是-128-127。strlen是遇到\0就停止,0就代表了\0,循环的时候,-1,-2,……,-128,127,……,1,0,此时strlen遇到\0就停止了,所以长度为255。
#include<stdio.h>
unsigned char i = 0;
int main()
{
	for (i = 0; i <= 255; i++)
	{
		printf("hello world\n");
	}
	return 0;
}
//首先无符号的char类型取值范围是0-255,所以当再一次+1时,就会从头开始
//11111111-255
//100000000-加一后,舍去前面的数
//00000000-0
//结果就是死循环

练习做完了之后,相信对整型在内存中的存储有了很深刻的印象,那么接下来讲浮点型在内存中的存储!

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

常见的浮点数:

3.14159
1E10,代表1*10^10
浮点数家族包括:float、double、long double类型。
浮点数表示的范围:float.h中定义。(查看整型的范围的话,寻找limits.h文件)

我们打开everything软件,搜索float.h,找到一个float.h文件并且打开。

3.1 一个例子

浮点数存储的例子:

int main()
{
	int n = 9;
	float* pfloat = (float*)&n;
	printf("n的值为:%d\n", n);
	printf("*pfloat的值为:%f\n", *pfloat);

	*pfloat = 9.0;
	printf("num的值为:%d\n", n);
	printf("*pfloat的值为:%f\n", *pfloat);
	return 0;
}

结果如下:
在这里插入图片描述
往下看,了解浮点数存储规则!

3.2 浮点数存储规则

num 和 *pfloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?
一定要搞懂浮点数再计算机内部的表示方法。

根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:
在这里插入图片描述
举个例子:
在这里插入图片描述

IEE 754规定:

对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。
在这里插入图片描述

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
在这里插入图片描述

IEEE 754对有效数字M集合指数E,还有一些特别规定。
在这里插入图片描述

简洁的说:保存M的时候,只保存小数,给M的空间空出1位,可以多存储。读取的时候自动加上1。

至于指数E,情况就比较复杂。
在这里插入图片描述
然后,指数E从内存中取出还可以再分成3种情况:
在这里插入图片描述
在这里插入图片描述
好了,关于浮点数的规则就讲到这里。

解释前面的题目:
在这里插入图片描述
在这里插入图片描述
注意:

有一些浮点数是不能计算它的存储方式的。
例如:3.14,换成二进制,11.xxxx,小数部分是难以算出来的,所以在一些程序中会有精度丢失的情况出现!!!

数据存储的知识就到这里了,如果对你有所帮助就点个赞吧!!! ^ __ ^

尚想旧情怜奴仆,也曾因梦送钱财------元稹《遣悲怀三首·其二》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/142174.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bootstrap校验laydate起止日期联动失效

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 项目中用到bootstrapValidator&#xff0c;以及laydate&#xff08;by:贤心&#xff0c;插件效果美观&#xff09;。 项目表单中&#xff0c;有两处需要联动校验&#xff1a;开始日期&#xff0c;结束…

第04讲:HTTP操作之ElasticSearch高级查询

3.1.4、高级查询 Elasticsearch 提供了基于 JSON 提供完整的查询 DSL 来定义查询 定义数据 : # POST /student/_doc/1001 {"name":"zhangsan", "nickname":"zhangsan", "sex":"男","age":30 } # POST…

MySQL innodb引擎架构分析-Change Buffer

系列文章目录 1. MySQL innodb引擎架构分析-Buffer Pool 2. MySQL innodb引擎架构分析-Redo log 3. MySQL innodb引擎架构分析- Double Write Buffer 4.MySQL innodb引擎架构分析-Change Buffer 文章目录系列文章目录前言一、Change Buffer是什么&#xff1f;二、Change Buffe…

日本市场的Starday开始对智能家居下重手

自从21世纪以来&#xff0c;物联网就开始进入大众视野&#xff0c;因此作为物联网基础应用的智能家居已经成为人们对生活场景的一种涉嫌。因此在国外市场当中&#xff0c;跨境电商卖家们通过物联网的智慧家居的售卖&#xff0c;获得了大量的资金&#xff0c;可知“跨境沃土”大…

LeetCode54.螺旋矩阵 LeetCode59.螺旋矩阵Ⅱ | 螺旋矩阵问题

LeetCode刷题记录 文章目录LeetCode54.螺旋矩阵思路代码LeetCode59 螺旋矩阵Ⅱ思路代码LeetCode54.螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例一 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9…

Ubuntu-22 live-server版本安装完成后的配置

软件包管理工具 aptapt 用于取代 apt-get 、apt-cache &#xff0c;apt 将分散在 apt-get 、 apt-cache 的基础操作统一包含在一起apt 与 apt-get 、apt-cache 的对应关系操作aptapt-安装软件包sudo apt install <package>sudo apt-get install <package>卸载软件包…

AcWing 1015. 摘花生(DP)

一、问题描述 二、思路分析 这道题非常类似我们数字三角形那道题&#xff0c;大家如果这道题不会的话&#xff0c;可以先去看作者之前写的数字三角形问题的解法&#xff0c;然后再回来看这道题&#xff0c;或许就能有思路了。 传送门&#xff1a; DP母题——数字三角形 1、状…

Jetpack Compose中的列表

Cloumn 和 Row 如果是普通的不是特别长的列表&#xff0c;可以直接使用 Column 和 Row 组件&#xff0c;默认 Column 和 Row 组件是不支持滚动的&#xff0c;如果需要支持滚动可以在 Column 和 Row 组件上使用 Modifier.verticalScroll() 和Modifier.horizontalScroll() 修饰符…

就在今晚!如何在公益向善的路上坚持前行

&#xff08;本文阅读时间&#xff1a;3分钟&#xff09;如何从支教助学到慈善组织到社会创业&#xff1f;如何从内心深处找回向善的力量&#xff1f;如何在挣扎中坚定前行的方向&#xff1f;本期微软ATP Public 100 公益演讲特邀嘉宾还将为小伙伴们提供干货建议&#xff01;微…

JavaScript刷LeetCode拿offer-树的遍历

什么是树 一种分层数据的抽象模型。前端工作中常见的树包括&#xff1a;DOM树&#xff0c;级联选择&#xff0c;树形控件JS中没有树&#xff0c;可以用Object和Array构建树树的常用操作&#xff1a;深度/广度优先遍历&#xff0c;先中后序遍历 深度优先遍历 访问根节点对根节…

Windows Server【开机启动和任务计划程序】实现服务器重启后项目自启动(Windows Server 任务计划程序无法执行问题处理)

1.问题说明 有些时候我们希望计算机开机后就启动一些服务或应用程序&#xff0c;比如远程工具。这里介绍两种方式。 2.开机启动 使用WinR调出运行&#xff0c;输入&#xff1a; 1️⃣ shell:startup 用户开机自启动&#xff08;程序开机自启动只针对当前登录的用户&#xf…

2分布式微服务技术栈-SpringCloud<Feign>

分布式微服务技术栈Feign HTTP 客户端Feign-基于Feign远程调用Feign-自定义配置Feign HTTP 客户端 Feign-基于Feign远程调用 声明式 事务 spring 声明一个 远程调用 封装 所有 对 userservice 的 远程调用 类似于 controller 的 注解 把接口 注入进来 不仅是 http 客户端 …

Node.js 中的模块化

1、模块化的基本概念 1.1、什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说&#xff0c;模块是可组合、分解和更换的单元。 1.2、编程领域中的模块化 编程领域中的模块化&#xff0c;就是遵守固定的规则&a…

探索性数据分析(Exploratory Data Analysis,EDA)

目录参考资料PART 02 探索性数据分析 探索性数据分析(Exploratory Data Analysis&#xff0c;简称EDA)&#xff0c;指对数据分析的过程中尽量不加入先验假设&#xff0c;而是通过作图表和统计等方式来探索数据结构和规律。 EDA最早由John W. Tukey在上世纪70年代被提出&#…

批量下载线上数据文件--业务诉求

诉求接到现场运维诉求&#xff0c;需要获取到指定业务节点的所有附件文件分析某个节点的业务信息&#xff0c;可以通过sql来筛选出全部需要的关联字段信息以及文件磁盘路径和上传路径通过脚本或命令&#xff0c;将sql筛选到的路径文件统一复制到指定目录将复制到的文件下载&…

再学C语言25:分支和跳转——continue、break和switch

一般地&#xff0c;进入循环体后&#xff0c;在下次循环判断之前程序执行循环体中所有语句 一、continue语句 continue&#xff1a;循环中&#xff0c;当运行到该语句时&#xff0c;其将导致剩余的迭代部分被忽略&#xff0c;开始下一次迭代 如果continue处于嵌套结构中&…

【深度学习】李宏毅2021/2022春深度学习课程笔记 - 各式各样神奇的自注意力机制(Self-Attention)变型

文章目录一、Self-Attention 各式各样的变型二、How to make self-attention efficient&#xff1f;三、Notice四、Local Attention / Truncated Attention五、Stride Attention六、Global Attention七、Many Different Choices八、Can we only focus on Critical Parts?8.1 C…

车牌识别应用搭建(含模型和源码)

车牌识别应用搭建 内容说明 本示例旨在展示如何在 DeepStream SDK 版本不低于 5.0.1 的情况下使用分级模型进行检测和分类。 本例中的模型均为TAO3.0模型。 PGIE(car detection) -> SGIE(car license plate detection) -> SGIE(car license plate recognization) 该流…

Linux系统下的rpm/yum管理

文章目录Linux系统下的rpm管理1.介绍2.rpm包的简单查询指令3.rpm包的其它查询指今4.卸载rpm包5.rpm6.yumLinux系统下的rpm管理 1.介绍 rpm用于互联网下载包的打包及安装工具&#xff0c;它包含在某些Linux分发版中。它生成具有.RPM扩展名的文件。RPM是RedHat Package Manager…

Java 集合的介绍和使用

1.什么是集合&#xff1f; 对一些数据的存储就叫做集合&#xff0c;相比于数组&#xff0c;这是一种动态的集合。 1.可以动态的保存任意多个对象 2.提供一些动态操作集合的方法比如&#xff1a;add ,remove ,set ,get 等。 3.使用集合更加方便&#xff0c;提高代码编写效率。…