深度剖析数据在内存中的存储

2023-05-16

小编认为要想成为一个好的程序员,不能仅仅只做到会使用,而要做到理解其本质 。做到可持续发展。接下来小编会向大家介绍数据在内存中究竟是如何存储与运算的,也算是修炼内功了吧。

目录

一、数据类型介绍

1.整型家族

2.浮点数家族

3.构造类型

4.指针类型

5.空类型

二、整型家族

1.原、反、补码

2.大小端字节序

2.1方法一(指针访问)

2.2方法二(联合体)

3.整型提升

整型提升的意义:

整型提升的规则:

4.有无符号的数据区分

三、浮点型在内存中的存储

IEEE 754规定

M

E


一、数据类型介绍

1.整型家族

char:unsigned char、signed char

short:unsigned short、signed short

int:unsigned int、signed int

long:unsigned long、signed long

值得注意的是,char类型也属于整型家族原因是:字符本质为ASCII值,是整型,所以划分到整型家族。另外char究竟是singed char还是unsigned char取决于编译器的底层实现。

2.浮点数家族

float、double、long double

3.构造类型

数组类型

结构体类型 struct

枚举类型 enum

联合类型 union

4.指针类型

int * 、char *、float*、void* ……

5.空类型

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

二、整型家族

1.原、反、补码

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

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

而数值位正数的原、反、补码都相同。负整数的三种表示方法各不相同。

原码:直接将整型数字按照正负数形式翻译成二进制,即可得到原码

反码:将原码的符号位不变,其他位依次按位取反即可得到反码

补码:将反码加一即可得到补码

在计算机系统中,整型数值一律使用补码来表示与存储,但是为什么呢?

1.使用补码可以将符号位和数字域统一处理。

2.加法和减法可以统一处理(CPU只有加法器)。

   例:CPU计算1 - 1时,会计算1 + (-1)

3.补码与原码相互转换,其运算过程相同,不需额外的硬件电路。

2.大小端字节序

接下来,看看下面这张图:

变量a的补码用十六进制表示不是0x00000001吗,在内存中看怎么会是这个样子呢?这就不得不提到大、小端字节序存储模式了。

大端(存储)模式:

是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;

小端(存储)模式:

是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。

:一个 16bit的short型变量x ,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节, 0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即 0x0011中。小端模式,刚好相反。

从上图可以看出小编所用的环境是小端字节序存储模式,那么为什么会有大小端之分呢?

这是因为在计算机系统中是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8 bit。但是在C语言中除了 8bit 的char之外,还有 16bit 的short型,32bit 的long型(要看具体的编译器)。另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。

我们常用的X86(32位)结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。


 

 百度就曾有一年的笔试题,考过这个知识点。这道题,我将讲述两种解法:

2.1方法一(指针访问)

#include <stdio.h>
int check_sys_1()
{
	int i = 1;
	char* p = (char*)&i;
	return *p;
}
//简化后:
int check_sys()
{
	int i = 1;
	return (*(char*)&i);
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

2.2方法二(联合体)

#include <stdio.h>
int check_sys()
{
	union
	{
		int i;
		char c;
	}un;
	un.i = 1;
	return un.c;
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

联合体的所有成员在内存中具有相同的首地址,共占同一段内存空间,这些成员可以相互覆盖。

利用该条特性实现大端与小端的判断,该方法实在"秀"。

3.整型提升

C的整型算术运算总是至少以缺省整型(即默认整型)类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升

整型提升的意义:

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度
一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长
度。
通用CPU (general-purpose CPU) 是难以直接实现两个字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
 

整型提升的规则:

整型提升是按照变量的数据类型的符号位来提升的,若无符号直接补0。

4.有无符号的数据区分

以char类型为例:

字符型数据char可分为unsigned char(无符号)和signed char(有符号)

具体char代表的是有符号字符型还是不符号字符型,取决于你编译器的具体实现。以VS2019为例,char所代表的便是signed char。

 

 由此可见,signed char的取值范围是-128到127,unsigned char的范围是255.

三、浮点型在内存中的存储

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

(-1)^S * M * 2^E(即用科学计数法表示)

IEEE 754规定

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

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

M

计算机内部保存M时,默认这个数的第一位总是1。因此,可以被舍去,只保存后面的小数部分,读取时再将第一位的1加上。节省一位有效数字,可提高小数部分的精确度。

E

(1)放入

E为一个无符号整数。若E为8位,它的取值范围位0-255。若E为11位,它的取值范围为0-2047。

但科学计数法中的E是可以出现负数的。所以IEEE 754规定,存入内存时E的真实值必须加上一个中间值。对于8位的E,中间值位127。对于11位的E,中间值为1023。

(2)取出

1.E不全为0或不全为1

        E减127(1023)得E的真实值——即正常反向计算

2.E全为0

        浮点数的指数E等于1-127(或者1-1023)即为真实值。有效数字M不再加上第一位的1,而是还原为0.xxx的小数。这样是为了表示+/-0,以及接近于0的很小的数字。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度剖析数据在内存中的存储 的相关文章

  • winsock connect socket连接,报10061错误

    问题现象 xff1a 上位机去创建socket连接 xff0c 报10061错误 问题分析 xff1a 10061是server 拒绝了client的request xff0c 主要原因是a misconfigured server xff
  • 【踩坑专栏】lombok报错程序包org.slf4j不存在

    问题描述 xff1a 在Pom中引入了依赖 xff0c idea中也有lombok的插件 xff0c 之前使用lombok的 64 Slf4j注解没有问题 xff0c 最近在某一个项目中 xff0c 在编译时突然报错程序包org slf4j
  • Ubuntu1804_server 离线安装GCC_7.5

    本文利用一个比较简单方便的方法为Ubuntu1804 server的服务器离线安装GCC 7 5 之前写过一篇关于离线安装软件的文章 xff0c 有兴趣的同学请移步Ubuntu18 04 离线安装nginx 可是如果生产服务器有大量需要离线
  • 关于Java之IO流音乐拼接小项目

    需求 xff1a 做一个音乐串烧 分析 xff1a 1 有n个音乐 xff0c 找到高潮部分 xff0c 2 获取高潮部分的流对象 3 把这部分对象保存成一个mp3 4 把它们拼接起来 以下为源码供大家分享 xff1a 方法一 xff1a
  • 192.168.和10.0.开头的IP、内网IP段、IP简介、分类

    IP地址分为五大类 xff1a A类 B类 C类 D类和E类 xff0c 如下图所示 xff1a 在这五类IP地址中 xff0c 我们最常使用的是A类 B类和C类地址 在这三类地址中 xff0c 绝大多数的IP地址都是公有地址 xff0c
  • 牛客网. 跳跃游戏-II

    题目概述 解题思路 我开始想到的做法是贪心 首先维护两个指针i和cur xff0c i用于顺序遍历 xff0c cur用来指向上一次可以跳到的最远的位置 维护一个一维数组 xff0c 用来记录跳到每个位置需要的最短步数 然后考虑当前能跳到的
  • OpenEuler 20.03 LTS yum 安装redis后systemctl启动异常

    前言 通过命令yum install redis xff0c 安装redis后 xff0c 通过systemctl启动报如下错误 xff1a span class token punctuation span root 64 ecs e50
  • python ahttp:简单、高效、异步requests请求模块

    ahttp xff1a 简单 高效 异步requests请求模块 ahttp 是一个所有的http连接请求均使用协程的方式 使请求过程中 IO 操作交给其他硬件 xff0c 而CPU专注于处理计算型任务 xff0c 可以大量的节约等待的时间
  • uniapp 页面跳转出现闪屏、短暂白屏的解决办法

    在项目pages json里设置页面的背景色和页面中page或container的背景色一致即可解决这个问题 34 path 34 34 pages ecosystem index 34 34 style 34 34 navigationB
  • softmock-基于mitmproxy实现系统性管理maplocal

    softmock 介绍 softmock 是一个拦截 http https 到本地的工具 请求拦截到本地之后 xff0c 可以进行修改 新增等操作 xff0c 使下次请求直接返回到本地的数据 而不依赖远程服务器 softmock 是从 抓包
  • django设置samesite

    较新版本的chrome会因samesite策略而禁止跨域的cookie 解决方法在项目中的setting py设置 xff1a SESSION COOKIE SAMESITE span class token operator 61 spa
  • 使用python构造一个微信聊天机器人

    申请一个图灵的APIKEY http www tuling123 com python3环境下安装wxpy pip install wxpy linux下还需安装pillow pip install pillow 然后执行以下代码 xff1
  • aiohttp 简易使用教程

    0 前言 本文翻译自aiohttp的官方文档 xff0c 如有纰漏 xff0c 欢迎指出 aiohttp分为服务器端和客户端 xff0c 本文只介绍客户端 由于上下文的缘故 xff0c 请求代码必须在一个异步的函数中进行 xff1a asy
  • Zabbix 5.4 Server安装

    系统 xff1a ubuntu 1804 xff08 1804 server zabbix 5 4 mysql 5 7 x1f4d3 UTF 8是Zabbix支持的唯一编码 它可以正常工作而没有任何安全漏洞 用户应注意 xff0c 如果使用
  • vue基本格式

    MVVM模式 vue的基本步骤 数据绑定 v model name 数据渲染 xff0c 双向绑定
  • Activity中使用onNewIntent方法避免多次实例化同一个Activity

    最近写的项目中有一个搜索 搜索结果 搜索这样一个循环的过程 xff0c 发现了几个问题 xff1a 1 循环导致多次实例化这两个类 xff1b 解决方案 xff1a 在Manifest里面对应activity下面设置启动模式为singleT
  • Linux 无密码自动登录

    GNOME环境 etc gdm3 custom conf文件 xff0c 修改其中的AutomaticLoginEnable xff0c AutomaticLogin项 xff0c 具体如下所示 xff1a Configure Automa
  • FileItem类

    文件上传时需要用到FileItem类 xff0c FileItem是一个接口 xff0c 它的实现类是DiskFileItem 如图为FileItem 接口中定义的方法 xff1a 1 getInputStream xff1a 以流的形式返
  • mysql数据表中文乱码解决办法

    在往 mysql 数据库中插入数据的时候出现数据 汉字 乱码情况 xff1a 在把数据库 xff0c 数据表的编码改为UTF 8后 xff0c 还是乱码 Mysql 的默认编码方式是 Latin1 xff0c 不支持中文 xff0c 因此

随机推荐

  • Spring xml配置文件头解析

    Spring文档中默认的XML文件格式 xff1a lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 gt lt beans xmlns 61 34 http www springfra
  • SpringMVC请求静态资源异常

    问题描述 xff1a 使用 REST 风格的资源URL时 xff0c SpringMVC请求静态资源 图片 js等 发生异常 优雅的 REST 风格的资源URL 不希望带 html 或 do 等后缀 若将 DispatcherServlet
  • web项目异常A web application registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister

    异常 xff1a A web application registered the JBDC driver com mysql jdbc Driver but failed to unregister it when the web app
  • @Controller和@RestController的区别?

    64 Controller和 64 RestController的区别 xff1f 官方文档 xff1a 64 RestController is a stereotype annotation that combines 64 Respo
  • get方式传值中文乱码

    如下情况 xff1a lt a id 61 span class hljs string 34 bookname 34 span title 61 span class hljs string 34 span class hljs vari
  • Zabbix 5.4 server安装后的相关操作

    通过前面的安装 xff0c 相信大家已经能够正常登录zabbix server的管理页面了 在进行正式的使用之前 xff0c 建议大家最好把下面这个管理页面中左侧的操作树中的每一项功能都打开看看 xff0c 这样心中对zabbix serv
  • Maven搭建的SSM项目中遇到的问题

    Maven搭建的SSM项目中遇到的问题 1 EL表达式失效 2 装配异常Unable to configure ssm 解决办法 其实这两个问题的出现都是因为servlet版本和java版本不合适造成的 xff0c EL表达式在servle
  • Java小工具Lombok的安装与使用

    1 Lombok简介 Lombok是一个代码生成器 xff0c 可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具 xff0c 通过使用对应的注解 xff0c 可以在编译源码的时候生成对应的方法 使用 lom
  • 日常记录(1)

    数据库连接池Druid Alibaba github地址 xff1a https github com alibaba druidBlog xff1a http blog csdn net pk490525 article details
  • vnc 设置自定义分辨率

    1 vnc设置分辨率 vncserver geometry 1600x900即可 xff0c 之后通过window下vnc连接后的ubuntu分辨率即为1600x900了 注意这里的X是小写的x而不是 2 但是 xff0c 登录后 xff0
  • 解决Vcenter Client启动Fault Tolerance辅助虚拟机被禁用保护的问题

    解决FT辅助虚拟机被禁用的问题 项目场景 xff1a 学习虚拟机中问题描述 xff1a 辅助虚拟机被禁用原因分析 xff1a 解决方案与结论 项目场景 xff1a 学习虚拟机中 最近这个学期在学习虚拟化技术 xff0c 由于课程是新开的 x
  • kali的重复登录与vnc灰屏

    云安全 xff08 二 xff09 VNC连接的一些小问题 文章目录 云安全 xff08 二 xff09 VNC连接的一些小问题 前言 xff1a 问题重现一 解决灰屏问题二 普通用户循环登录1 原因2 解决方法 三 原因分析四 总结五 项
  • sql注入闯关笔记【Less-1】基于错误的GET单引号字符型注入

    云安全之sql注入 xff08 sqli labs Less 1 文章目录 云安全之sql注入 xff08 sqli labs Less 1 前言一 闯关一 测试注入点二 手工注入三 sqlmap注入 二 总结三 思路与解惑 前言 这学期学
  • 写一个简单的爬虫,可直接复制学习!!

    简单爬虫直面代码 xff0c 可直接复制学习 这个代码的作用主要是用来获取到百度首页的数据 xff0c 只用来供理解学习 真 小白 福利 todo 首先导包requests 用于爬取数据 import requests todo 定义你要爬
  • 教你如何开发VR游戏系列教程五:UI 交互

    原文链接 xff1a 欢迎关注AR学院 上一篇介绍了ugui NGUI 以及普通3D模型的UI设计 这一讲主要介绍怎么样利用这些UI做交互 大家在VR游戏看到的UI以及UI交互 xff0c 主要有哪几种 xff1f 1 头控悬停 xff08
  • C/C++斐波那契数全解(哪种方法更好?)

    目录 一 递归思想 二 空间换时间 三 动态规划 四 通项公式 五 矩阵快速幂 六 总结 本文章参考leetcode斐波那契数官方题解 斐波那契的边界条件是 F 0 61 0 和 F 1 61 1 当 n gt 1 时 xff0c 每一项的
  • Zabbix 5.4客户端安装

    通过前面的操作 xff0c 相信大家的zabbix server已经能够正常的运行起来了 xff0c 但是仅有zabbix server是不完整的 xff0c server的目标是监控其他的主机 xff0c 而并非只监控自身 xff0c 所
  • Linux中kill -2、kill -9等区别 && kill signal汇总

    xfeff xfeff kill号令用于终止指定的过程 xff08 terminate a process xff09 xff0c 是Unix Linux下过程经管的常用号令 凡是 xff0c 我们在须要终止某个或某些过程时 xff0c 先
  • Linux下查找文件(find、grep命令)

    目录 一 find命令 1 按文件名 2 按文件类型查询 3 按照文件大小查找 4 按照文件日期查找 4 1按照创建日期查找 4 2按照修改日期查找 4 3按照访问日期查找 5 按深度查找 5 1查找起始点以下n层的目录 xff0c 不超过
  • 深度剖析数据在内存中的存储

    小编认为要想成为一个好的程序员 xff0c 不能仅仅只做到会使用 xff0c 而要做到理解其本质 做到可持续发展 接下来小编会向大家介绍数据在内存中究竟是如何存储与运算的 xff0c 也算是修炼内功了吧 目录 一 数据类型介绍 1 整型家族