椋鸟C语言笔记#26:数据在内存中的存储(大小端字节序)、浮点数的存储(IEEE754)

萌新的学习笔记,写错了恳请斧正。


目录

大小端字节序

什么是大小端

写一个判断大小端的程序

浮点数在内存中的存储(IEEE 754规则)

引入

存储规则解释

读取规则解释

1.阶码不全为0或全为1(规格化数)

2.阶码全为0(非规格化数)

3.阶码全为1,尾数全为0(inf)

4.阶码全为1,尾数不全为0(非数,NaN,Not a Number)

练习

1.浮点数

2.整型存储

a.下面程序的输出为

b.下面两个程序的输出为

c.下面程序的输出为

d.下面两个程序的输出为

e.下面程序的输出为(假设小端环境)


大小端字节序

什么是大小端

首先,我们要知道,整数(short、int、long、long long)在内存中以补码的形式存储,无符号整数(unsigned)在内存中以原始二进制序列存储。

当数据长度小于等于一个字节时 ,很显然计算机就直接存储在一个字节内(内存存储的基本单元是字节)。而大小端字节序,则是超过一个字节的数据在内存中存储的两种方式。

为了更清楚的理解大小端字节序,下面我们创建一个变量a:

#include <stdio.h>int main()
{int a = 0x12345678;return 0;
}

我们知道int整型占4个字节,也就是说12、34、56、78会分别存储在4个字节单元中。那么,这4个字节单元在内存中是从高地址向低地址排列还是由低向高就成了一个问题。

我们把78这一头叫做数据的低位字节,12那一头叫做高位字节。那么:

  • 将数据的低位字节存储在内存的高位,就叫大端存储,对应大端机器
  • 将数据的低位字节存储在内存的低位,就叫小端存储,对应小端机器

下面我们在Visual Stodio(x86 Debug)环境下调试上方代码, 并打开内存窗口,观察变量a的内存空间:

这就是将数据的低位字节(78)储存在了内存的低位,是小端存储模式。

我们常用的大多数环境(x86、x64…)都是小端结构( 有计算优势),但是仍然存在大端模式的机器(如KEIL C51)。甚至有些ARM处理器可以让硬件选择采用大端还是小端。
写一个判断大小端的程序

其实很简单,我们截取数字1在内存中的第一个字节即可。

如果输出是1就是小端机器,如果是0就是大端机器。

#include <stdio.h>int check_sys()
{int i = 1;return *(char*)&i;
}int main()
{if (check_sys())printf("该机器为小端字节序机器\n");elseprintf("该机器为大端字节序机器\n");return 0;
}

这里先取a的地址、强制类型转换为char*再解引用来取出a在内存中的第一个字节。

注意:这里不能直接将a强制类型转换为char类型来读取第一个字节,因为这样永远只会截取数据最低位的字节,和大小端机器无关。

或者我们也可以用联合体的方式取第一个字节(联合体相关内容在之后的笔记):

int check_sys()
{union{int i;char c;} u;u.i = 1;return u.c;
}

浮点数在内存中的存储(IEEE 754规则)

引入

浮点数包括float、double、long double等类型,可写成小数形式(3.14)或科学计数法(1.1E2)

不同浮点数的数据范围在float.h头文件中被规定

下面我们看一段代码:

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

这段代码的输出结果为:

n的值为:9
*p的值为:0.000000
n的值为:1091567616
*p的值为:9.000000

明明n与*p在内存中是同一个数,为什么会出现上方的情况呢?

这与浮点数在内存中的存储有关

存储规则解释

浮点数在内存中的存储遵循IEEE 754规则,由电气与电子工程师协会(IEEE)规定

单精度浮点数为例,我们将其分为3个部分存储在内存中(都是01组成的二进制):

  • 符号位S:1位,0代表正数,1代表负数
  • 阶码E:8位,就是科学计数法的指数部分加127(因为其表示精度的是-126次方到127次方,要加上127让阶码从数字1到254便于存储,因此单精度浮点数也叫余127码)(阶码0与255有特殊含义,见下方读取相关内容
  • 尾数M:23位,就是科学计数法中数字小数点后的部分

以数字5.0为例:

  1. 其为正数,则S=0
  2. 其可以表示成二进制科学计数法1.01*2^2,则尾数M为01000000000000000000000
  3. 其科学计数法指数为2加上127得到阶码E=129=10000001(二进制)
  4. 合起来就能得到数字5.0在内存中的存储:0100 0000 1010 0000 0000 0000 0000 0000

对于双精度浮点数,其规则与单精度浮点数类似,但是阶码变为11位(余1023码),尾数变为52位。总字节数由4字节变为8字节。

读取规则解释

读取时有3种情况:

1.阶码不全为0或全为1(规格化数)

读取时阶码减去127(或1023)得到指数部分,尾数加1得到数字部分

所以说单精度浮点数规格化数的指数范围是-126到127

2.阶码全为0(非规格化数)

读取时阶码加一再减去127(或1023)得到指数部分(加一使浮点数取值连续),尾数不加1,用于表示极其接近0的数字

如果尾数也全为0,则代表浮点数的±0

3.阶码全为1,尾数全为0(inf)

被判定为浮点数的无穷,正负由符号位决定,用代码inf表示

4.阶码全为1,尾数不全为0(非数,NaN,Not a Number)

代码NaN表示,用于表示异常数据(比如某个数除以0就会返回NaN,也有可能输出IND-indeterminate不确定的)

练习

1.浮点数

这时上面浮点数存储开头的那一段代码就好理解了

首先第一部分将整型9当做浮点数输出,整型9在内存中存储为:

0000 0000 0000 0000 0000 0000 0000 1001

将其当做浮点数,则S=0,阶码E=00000000,由上面非规格化数内容我们知道这是一个趋近于0的数,所以输出了0.000000

第二部分将浮点数9.0当做整数输出,浮点数9在内存中存储为:

0100 0001 0001 0000 0000 0000 0000 0000

将其当做整型输出即补码转换为原码为:1091567616

2.整型存储
a.下面程序的输出为
#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;
}

就是很简单的截取,输出a=-1,b=-1,c=255

b.下面两个程序的输出为
#include <stdio.h>int main()
{char a = -128;printf("%u\n", a);return 0;
}
#include <stdio.h>int main()
{char a = 128;printf("%u\n", a);return 0;
}

两个程序的输出结果均为4294967168

也是简单的整型提升的问题

比如第一段程序-128的补码为1111 1111 1111 1111 1111 1111 1000 0000

截取到a为1000 0000,整型提升回1111 1111 1111 1111 1111 1111 1000 0000

其直接二进制转换十进制为4294967168

第二段等价,对于char来说127之上就循环回到-128,所以128与-128在这里没有区别

c.下面程序的输出为
#include <stdio.h>int main()
{char a[1000];int i;for (i = 0; i < 1000; i++){a[i] = -1 - i;}printf("%d", strlen(a));return 0;
}

此代码输出为255

同样的,对于char类型,-128在减一就循环回到了127。所以这里就是从-1一直降到-128,在从127降到1(strlen遇到“\0”结束,其ASCII码为0,所以之后的没意义)

d.下面两个程序的输出为
#include <stdio.h>unsigned char i = 0;
int main()
{for (i = 0; i <= 255; i++){printf("hello world\n");}return 0;
}
#include <stdio.h>int main()
{unsigned int i;for (i = 9; i >= 0; i--){printf("%u\n", i);}return 0;
}

这两段代码都是死循环,很简单

e.下面程序的输出为(假设小端环境)
#include <stdio.h>int main()
{int a[4] = { 1, 2, 3, 4 };int* ptr1 = (int*)(&a + 1);int* ptr2 = (int*)((int)a + 1);printf("%x,%x", ptr1[-1], *ptr2);return 0;
}

其输出结果为4,2000000(有可能引发读取访问权限冲突)

很好理解,指针1减一指向数组第4个元素,指针2指向第一个元素向后偏移一位字节,也就是略过了数字1内存第一个字节又加上了数字2内存第一个字节。在小端环境下即为0x02000000


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

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

相关文章

IDEA Maven项目如何引用本地jar包,并打包发布

jar包位于当前路径下的lib目录中 引入所需要的配置 查看当前jar包的相关信息 包的引入,需要使用到当前包的artifactId, groupId, version 需要到包的/META-INF/maven/ 下面的 pom.xml 文件里面找 在Maven构建项目时&#xff0c;生成的依赖包中的/META-INF/maven目录存放了一些…

【JUC】二十八、synchronized锁升级之偏向锁

文章目录 1、偏向锁出现的背景2、从共享对象的内存结构看偏向锁3、偏向锁的持有4、启动偏向锁5、sleep暂停来启动偏向锁6、偏向锁的撤销7、总体流程8、SinceJava15 偏向锁的废除 1、偏向锁出现的背景 如果一个线程连续几次抢到锁&#xff0c;仍然重复加锁解锁&#xff0c;就会…

【深度学习】注意力机制(六)

本文介绍一些注意力机制的实现&#xff0c;包括MobileVITv1/MobileVITv2/DAT/CrossFormer/MOA。 【深度学习】注意力机制&#xff08;一&#xff09; 【深度学习】注意力机制&#xff08;二&#xff09; 【深度学习】注意力机制&#xff08;三&#xff09; 【深度学习】注意…

产品入门第三讲:Axure产品流程图绘制

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​​​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Axure》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还…

机器人行业数据闭环实践:从对象存储到 JuiceFS

JuiceFS 社区聚集了来自各行各业的前沿科技用户。本次分享的案例来源于刻行&#xff0c;一家商用服务机器人领域科技企业。 商用服务机器人指的是我们日常生活中常见的清洁机器人、送餐机器人、仓库机器人等。刻行采用 JuiceFS 来弥补对象存储性能不足等问题。 值得一提的是&am…

Docker容器如何优雅地访问宿主机网络

# 前言 某些时候&#xff0c;我们会有在容器内容访问宿主机某个服务的需求&#xff0c;比如现在 openai 无法直接访问&#xff0c;需要给项目添加代理&#xff0c;我的 chatgpt-dingtalk (opens new window) 项目支持了通过环境变量指定代理地址。 添加方式如下&#xff1a; …

嵌入式奇妙之旅:Python与树莓派编程深度探索

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在这个数字化的时代&#xff0c;嵌入式系统的应…

主动学习与弱监督学习

人工智能数据的获取没有想象中的那么简单&#xff0c;虽然我们早已身处大数据的浪潮下&#xff0c;很多公司在获取数据的大浪中翻滚却始终没有找到一个合适的获取数据的渠道。很多情况下&#xff0c;获取高质量的人工智能数据需要消耗大量的人力、时间、金钱&#xff0c;但是对…

Vue3-08-条件渲染-v-if 的基本使用

v-if 是什么 v-if 一个指令&#xff0c; 它是用来根据条件表达式&#xff0c;进行选择性地【展示】/【不展示】html元素的。比如 &#xff1a; 有一个按钮A&#xff0c;当条件为真时&#xff0c;展示该按钮&#xff1b;条件为假时&#xff0c;不展示该按钮。与 js 中的 条件判…

绝地求生:PGC2023胜者组D2下半场:17天霸成功晋级,TL、NH跌入最后机会组

第四场 第一名&#xff1a;LGC 第二名&#xff1a;T5 第三名&#xff1a;FaZe 17仅剩两人&#xff0c;T5踩住高点&#xff0c;sujiu前顶时被T5架枪位击倒&#xff0c;小鬼的盾牌没能挡住对方的雷遗憾第五出局。然而T5自己也进圈不易&#xff0c;仅剩两人。 LG独狼卡住T5却忽…

Leetcode 2132. 用邮票贴满网格图(Java + 两次一维前缀和 + 二维差分)

Leetcode 2132. 用邮票贴满网格图&#xff08;Java 两次一维前缀和 二维差分&#xff09; 题目 给你一个 m x n 的二进制矩阵 grid &#xff0c;每个格子要么为 0 &#xff08;空&#xff09;要么为 1 &#xff08;被占据&#xff09;。给你邮票的尺寸为 stampHeight x sta…

Linux_Ubuntu 系统入门

Ubuntu 系统是和 Windows 系统一样的大型桌面操作系统&#xff0c;因此功能非常强大。 本节的目的是掌握后续嵌入式开发所需的 Ubuntu 基本技能&#xff0c;比如系统的基本设置、常用的 shell 命令、vim 编译器的基本操作等等…… Ubuntu 的图形化界面操作和 Windows 下基本一致…

数据分析基础之《matplotlib(3)—散点图》

一、常见图形种类及意义 1、matplotlib能够绘制折线图、散点图、柱状图、直方图、饼图。我们需要知道不同的统计图的意义&#xff0c;以此来决定选择哪种统计图来呈现我们的数据 2、折线图plot 说明&#xff1a;以折线的上升或下降来表示统计数量的增减变化的统计图 特点&…

智能优化算法应用:基于白鲸算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于白鲸算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于白鲸算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.白鲸算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

实践干货 | CodeWave如何支持多人协作开发应用

在传统软件开发领域里&#xff0c;要完成具备一定复杂程度的软件&#xff0c;通常都会由一个研发团队协作开发。软件复杂度越大&#xff0c;研发团队的规模也就越大。 为了让研发团队能够高效的进行协同开发&#xff0c;业务引入了优秀的代码版本管理工具&#xff0c;比如传统软…

C语言union联合体(共用体)

一、定义 联合体&#xff08;共用体&#xff09;是一种特殊的自定义的数据类型&#xff0c;它包含一系列的成员变量&#xff0c;这些成员变量共用一块内存空间。 语法&#xff1a; union 标识符 { data_type 标识符1; data_type 标识符2; . . . dat…

【数组Array】力扣-5 最长回文子串

目录 题目描述 题解labuladong 题目描述 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#xff1a;"bab"…

在javaweb项目中resource目录和webapp目录的区别

resource存放的是一些配置文件&#xff0c;这些文件一般都是与java代码相关的配置文件&#xff0c;比如这里的jdbc配置文件,在java中可以使用这个目录下的文件&#xff0c;不用写全路径 webapp存放的是web的资源文件&#xff0c;如jsp,html,css&#xff0c;js文件,在网页请求会…

【NSX-T】5. 搭建NSX-T环境 —— NSX架构基础配置

目录 5. 准备 NSX 基础架构5.1 准备工作5.2 创建传输域&#xff08;1&#xff09;创建 Overlay 传输域&#xff08;2&#xff09;创建 VLAN 传输域 5.3 创建 IP 池5.4 准备 ESXi 主机 参考资料 5. 准备 NSX 基础架构 5.1 准备工作 vCenter 中已存在 DVS。 为 NSX-T 创建两个 …

计算机毕业设计 基于Web的城市旅游网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…