【数据在内存中的存储】

目录

  1. 整数在内存中的存储
  2. 大小端字节序和字节序判断
  3. 浮点数在内存中的存储

1. 整数在内存中的存储

整数的二进制表示方法有三种: 原码、反码和补码
三种表示方法均有符号位和数值位两部分,符号位0表示“正”,1表示"负",而数值位最高的一位被当做符号位,剩余的都是数值位

正数的原、反、补码都相同
负数的三种都不同:
原码: 直接将数值按照正负数的形式翻译成二进制就是原码
反码:原码的符号位不变,其他位依次按位取反就可以得到反码
补码: 反码+1得到补码

对于整形来说,数据在内存中存放的是补码,原因在于补码可以吧符号位和数值域统一处理,加法和减法也可以作为加法统一处理。补码与原码互换,运算过程相同,不需要额外的硬件电路

1.1 取值范围

signed char 和 unigned char

以下列出char类型二进制所有的取值,探讨它的范围

在这里插入图片描述
对于有符号的char,最大值就是0111 1111,再加1就是1000 0000,如下图

在这里插入图片描述
从0到127,再加1就成为最小值-128,全为1时是负数最大值-1,每次递增1的情况是这样

在这里插入图片描述

对于无符号的char,127再加1是128,如下图

在这里插入图片描述

它的递增图形如下图

在这里插入图片描述

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

了解了整数存储后,看一个细节

int a = 0x11223344 ;

调试看到该数是倒着存储的

在这里插入图片描述

2.1 什么是大小端

超过一个字节的数据在内存中存储的时候,就有存储顺序的问题了,按不同的顺序,分为大小端存储

大端存储模式: 数据的低位字节存在高地址处,高位字节存在低地址处
小端存储模式: 数据的低位字节存在低地址处,高位字节存在高地址处

2.2 为什么有大小端之分

计算机以字节为单位,每个地址单元对应一个字节,一个字节8bit位,c语言除了8bit的char外,还有16bit的short,32位的long,另外,对于位数大于8位的处理器,如16位处理器和32位处理器,由于寄存器宽度大于一个字节,必然存在着一个如何将多个字节安排的问题,因此导致了两种存储模式

例如: 一个16bit的short型变量x,在内存中地址为0x0010,值为0x1122,那么0x11就是高字节,0x22就是低字节,大端将0x11放在低地址,0x22放在高地址,小端相反,常用的x86结构是小端模式,KEIL C51则为大端模式。很多的ARM,DSP都为小端模式,有些ARM处理器可以由硬件选择是大端还是小端

2.3 练习

2.3.1 练习1

简述大端字节序和小端字节序的概念,设计一个小程序判断当前机器的字节序 (10分)-百度笔试题

思路: 大端小端在于变量值的存储顺序不同,可以以1值举例,大端会将1存在高地址处,所以可以取出变量一个字节判断,变量地址是低地址处,为0就是大端

也可以利用联合体,给int类型赋值,联合体加一个char类型,取出char的值判断

代码:

//1
int a = 1;
if (*(char*)&a = 0) {printf("大端");
}
else {printf("小端");
}//2
union {int i;char c;
}un;un.i = 1;
printf("%d",un.c);

2.3.2 练习2

char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a=%d,b=%d,c=%d", a, b, c);

输出:

在这里插入图片描述

a和b都是有符号,存-1打印出的就是-1,c是无符号的,存到char里8个1都是数值,原码值就是最大值255

2.3.3 练习3

char a = -128 ;
printf ( “%u\n”, a) ;
char a = 128 ;
printf ( “%u\n”, a) ;

输出:

在这里插入图片描述

第一个char a存的是1000 0000,将它当做无符号打印,整形提升补符号位,补24个1,当做无符号整型打印,所以这个值就是很大的数

在这里插入图片描述
第二个,128的二进制是1000 0000,a存的是这个,因为a是有符号的,即使以无符号打印,整形提升依然补充符号位,所以和上面的结果一样

2.3.4 练习4

char a[1000] ;
int i ;
for ( i = 0; i < 1000; i++ )
{
a[i] = -1 -i ;
}
printf (“%d”, strlen (a) ) ;
}

第一次,i=0时,保存-1.i=1时,保存-2。因为数组是char类型,最多到负数最小值-128,根据有符号char的递增图,-128再减1得到127,当减到0时,strlen结束,所以长度就是128 + 127 = 255

2.3.5 练习5

unsigned char i = 0 ;
unsigned int i1;
for ( i = 0; i <= 255; i++ ) 
{printf ( "hello world\n" ) ;
}for ( i1 = 9; i1 >= 0; i-- ) 
{printf ( "%u\n", i ) ;
}

上述两个都是死循环,第一个无符号char的取值范围是0-255,所以<=255恒成立,第二个无符号数不可能小于0,所以>=0恒成立

2.3.6 练习6

int a[4] = { 1, 2, 3, 4 } ;
int* ptr1 = (int *)(&a + 1) ;
int* ptr2 = (int *)((int)a + 1) ;
printf("%x,%x", ptr1[-1], *ptr2) ;

在这里插入图片描述

假设a的地址是19ff20
ptr1取的是整个数组的地址,+1是跳过整个数组.是图中所示19ff30,,转化为int指针,访问-1就是往后减一个4字节,19ff2c,取整形内容,就是4
将a转换为整形,+1就是原地址加一个字节,图中所示19ff21,转换为int指针,访问值取四个字节,就是,19ff21-19ff25,小端存储由高到低排列十六进制就是00020000,

输出:

在这里插入图片描述

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

先思考一下下面代码的输出结果:

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);

输出:

在这里插入图片描述

3.2 浮点数的存储

上面的num和*pFloat存的都是一个数,为什么读取的结果差距这么大,这说明整形和浮点数的存储和读取方式是不一样的

3.2.1 浮点数存的过程

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

V = (-1)S * M * 2E
(-1)S表示符号位,当S=0时,V为正数,S=1,V为负数
M表示有效数字,M是大于等于1,小于2的
2E表示指数位

举例5.5,用二进制表示为101.1

在这里插入图片描述
相当于1.011 × 22
按照上面的V格式,S=0,M=1.11,E=2

IEEE 754规定:
对于32位浮点数,最高的1位存储符号位S,接着的8为存储指数位E,剩下的23位存储有效数字M
对于64位浮点数,最高的1位存储符号位S,接着的11为存储指数位E,剩下的52位存储有效数字M

在这里插入图片描述
因为,1<M<2,所以M的5.5的二进制101.1写成1.xxxx的形式
计算机存储浮点数时,默认M第一位总是1,因此1可以舍去,只存1小数点后面的数字,读取的时候再补上1和小数点,就可以多存一位数字

至于指数E,比较复杂
规定E为一个无符号整数 (unsigned int)
这意味着,如果E为8位,取值为0-255,E为11位,取值为0-2047。但是,科学计数法中的E可能是负数,所以E必须加一个中间值,8位中间数就是127,11位就是1023,比如E为10,保存时加上127,就是137

所以,存的二进制就是,符号位S:0,E指数位127+2=129,M寸011,后面补0

在这里插入图片描述
小尾排列就是00 00 B0 40

3.2.2 浮点数取的过程

分为三种情况:

E不全为0或不全为1

这时,浮点数用下面的规则表示,指数E减去127(或1023),得到真实值,再将有效位M前加上第一位的1

比如上面的5.5,指数位E转换为十进制是129,减去127就是2,M补上1.,就是1.011,乘2的2次方,就是101.1,转换为十进制就是5.5

E全为0

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

E全为1

这时,如果有效数字M全为0,表示±无穷大,(正负取决于符号位s)

3.3 题目解析

现在来看上面的题目

在这里插入图片描述
首先第一个,整数n存为9,打印的仍是9,将存的9以浮点数取出,就是

00000000 00000000 00000000 0000009,指数位全为0,就是一个接近于0的很小的数字,就是,所以值为0

将浮点数9.0按浮点数的方式存下来

0 1000 0010 00100000 00000000 0000000
0100 0001 0001 0000 0000 0000 0000 0000 //四位一排

按整数取出来,数据位就是0后面的部分,浮点数的形式取出依旧是浮点数的9.0

后面的整数值如下:

在这里插入图片描述
输出:

在这里插入图片描述

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

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

相关文章

Java中的链式编程风格与应用案例

引言 链式编程是一种在编程中经常使用的风格&#xff0c;它可以使代码更加简洁、易读和易于维护。在Java中&#xff0c;链式编程可以通过方法链的方式来实现。本文将介绍Java中的链式编程风格&#xff0c;并通过几个应用案例来说明其实际应用。 一、链式编程的概念与特点 链式…

如何理解Rust语言中的“impl”关键字

在Rust编程语言中&#xff0c;impl是一个关键字&#xff0c;用于为类型实现方法和特性&#xff08;traits&#xff09;。impl关键字后面可以跟一个类型或者特性名称&#xff0c;然后在大括号中定义该类型或特性的具体实现。 当我们使用impl关键字为一个类型实现方法时&#xf…

Go实现MapReduce

背景 当谈到处理大规模数据集时&#xff0c;MapReduce是一种备受欢迎的编程模型。它最初由Google开发&#xff0c;用于并行处理大规模数据以提取有价值的信息。MapReduce模型将大规模数据集分解成小块&#xff0c;然后对这些小块进行映射和归约操作&#xff0c;最终产生有用的…

《工程数值计算Python教程》笔记

文章目录 [toc]第一章&#xff1a;绪论 1.1 1.1 1.1|数值计算在工程科学中的重要性 1.2 1.2 1.2|数值计算方法 1.3 1.3 1.3|程序设计盒图计算方法的选取减少运算次数避免相近的数相减 1.4 1.4 1.4|误差的来源、表示及传递误差的来源和分类模型误差观测误差截断误差舍入误差 误差…

RabbitMQ消息顺序性保障

RabbitMQ 没有属性设置消息的顺序性&#xff0c;只能设置消息的优先级&#xff0c;因此消息顺序性保障只能在 consumer 上实现 场景分析&#xff1a; 生产者向 RabbitMQ 里发送了三条数据&#xff0c; 顺序依次是 data1-> data2 -> data3&#xff0c;压入的是一个内存…

基于vue+element-plus+echarts制作动态绘图页面(柱状图,饼图和折线图)

前言 我们知道echarts是一个非常强大的绘图库&#xff0c;基于这个库&#xff0c;我们可以绘制出精美的图表。对于一张图来说&#xff0c;其实比较重要的就是配置项&#xff0c;填入不同的配置内容就可以呈现出不同的效果。 当然配置项中除了样式之外&#xff0c;最重要的就是…

1、什么是 Python?

Python是一门高级编程语言&#xff0c;它是一种通用、解释型、面向对象的语言&#xff0c;以其简洁、清晰的语法和强大的功能而备受程序员欢迎。在学习Python之前&#xff0c;让我们一起来了解一下这门语言的基本特性和应用领域。 Python的起源和命名 Python的故事始于上个世…

Stable Diffusion 微调及推理优化实践指南

随着 Stable Diffsuion 的迅速走红&#xff0c;引发了 AI 绘图的时代变革。然而对于大部分人来说&#xff0c;训练扩散模型的门槛太高&#xff0c;对 Stable Diffusion 进行全量微调也很难入手。由此&#xff0c;社区催生了一系列针对 Stable Diffusion 的高效微调方案&#xf…

python 安装

要在Linux上安装Python&#xff0c;您可以按照以下步骤进行操作&#xff1a; 打开终端。 使用以下命令检查系统是否已经安装了Python&#xff1a; bash python --version 如果已经安装了Python&#xff0c;将显示已安的Python版本。如果未安装Python或者版本较低&#xff0c;继…

CentOS新系统工具安装

时区设置 ## 查看当前时区 timedatectl | grep "Time zone" ## 查看时区列表 thiimedatectl list-timezones ## 设置时区 sudo timedatectl set-timezone Asia/ShanghaiCentOS7桌面怎么校准时间&#xff1f;&#xff08;设置时区&#xff09; 安装Docker 环境 # …

如何在PHP中进行性能分析?

在PHP中进行性能分析是为了识别和解决代码中的性能瓶颈&#xff0c;以提高应用程序的执行速度和效率。以下是一些用于在PHP中进行性能分析的常见工具和技术&#xff1a; 使用内置函数&#xff1a; PHP提供了一些内置的函数&#xff0c;用于测量脚本的执行时间&#xff0c;例如m…

Qt之QNetworkAccessManager 从本地和内存中上传数据到Http服务器

简述 接连做了好几个服务器的项目&#xff0c;例如文件传输用的Ftp和对象存储服务器(Object Storage Service)&#xff0c;简单的信息传输用的WebServer&#xff0c;之前也有用过HttpServer不过都和WebServer一样简单的调用接口提交数据并没有上传过文件&#xff0c;正好趁这次…

spring 笔记十 Spring事务管理

文章目录 编程式事务控制相关对象PlatformTransactionManager TransactionDefinition事务隔离级别事务传播行为 TransactionStatus基于XML 的声明式事务控制什么是声明式事务控制 声明式事务控制的实现切点方法的事务参数的配置 基于注解的声明式事务控制使用注解配置声明式事务…

力扣LCR 130. 衣橱整理(DFS 解法)

Problem: LCR 130. 衣橱整理 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 首先该问题可以归纳为一类遍历二维矩阵的题目&#xff0c;此类中的一部分题目可以利用DFS来解决&#xff0c;具体到本题目&#xff1a; 我们可以利用一个布尔类型的二维数组记录我们已经访…

no module named ‘xxx‘

目录结构如下 我想在GCNmodel的model里引入layers的GraphConvolution&#xff1a;from GCNmodel.layers import GraphConvolution&#xff0c;但这样却报错no module named GCNmodel&#xff0c;而且用from layers import GraphConvolution也不行。然后用sys.path.appen(xxx)…

selenium-grid4.3.0两种模式记录

selenium-grid4.3.0两种模式记录 本文运行&#xff0c;需要提前配置好Java11以及安装好Chrom、Firefox、Safari其中一个浏览器&#xff0c;如果是Chrom、Firefox需要下载对应版本的驱动&#xff0c;并给 webdriver 配置环境变量&#xff0c;Safari浏览器Mac系统会自带&#xf…

使用下载代替物理串口输出-STM32 Debug (printf) Viewer

使用下载代替物理串口输出-STM32 Debug 硬件要求配置方法代码要求打印输出结果 硬件要求 STM32的PB9、PB10引脚的串口1通常用作其他功能使用后&#xff0c;无法通过printf()函数打印输出想要调试输出查看变量或调试信息。现已使用另外一种方法实现printf()函数打印输出。 ST…

百度搜索品牌形象优化怎么做?

搜索口碑现代网络营销不可或缺的一部分&#xff0c;特别是品牌搜索形象的优化是品牌方最为关注的重点之一。随着竞争的加剧&#xff0c;企业必须确保他们的产品或服务在搜索引擎结果中的排名尽可能地靠前&#xff0c;同时也必须保持自身品牌形象的丰满和调性。 企业如何做好品牌…

Mr. Cappuccino的第67杯咖啡——MacOS通过PD安装Win11

MacOS通过PD安装Win11 下载ParallelsDesktop安装ParallelsDesktop激活ParallelsDesktop下载Windows11安装Windows11激活Windows11 下载ParallelsDesktop ParallelsDesktop下载地址 安装ParallelsDesktop 关闭上面的窗口&#xff0c;继续操作 激活ParallelsDesktop 关闭上面的…

【LeetCode刷题】-- 161.相隔为1的编辑距离

161.相隔为1的编辑距离 方法&#xff1a;一次遍历 首先&#xff0c;我们要确认字符串的长度不会相差太远。如果长度差了2个或更多字符&#xff0c;那么 s 和 t 就不可能是一次编辑之差的字符串。 接下来&#xff0c;我们假设 s 的长度总是短于或等于 t 的长度。如果不是这样&…