news 2026/7/1 6:50:58

从零开始玩转C语言(五):整数和浮点数在内存中的存储

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零开始玩转C语言(五):整数和浮点数在内存中的存储

一、整数在内存中的存储

1.计算机中有符号整数的三种二进制编码方式:

原码:最高位为符号位(0正1负),其余位为数值的绝对值二进制
反码:符号位不变,其余位按位取反(仅用于负数)
补码:反码 + 1(仅用于负数)


正数的原码 = 反码 = 补码。


2.为何内存中存的是补码?

- 符号位和数值位统一处理,无需区分
- 加法器即可做减法(x - y = x + (-y 的补码)),CPU 无需额外减法器
- 补码和原码互转的运算过程相同(取反 + 1),硬件复用

二、大小端字节序和字节序判断

其中内存当中a的地址是倒着存的,这是因为当前系统是小端。

2.1.什么是大小端?

多字节数据在内存中的存储顺序分两种:

- 低位字节存高地址("高位在前",类似写数字从左到右)
- 小端:低位字节存低地址,高位字节存高地址("低位在前",x86 架构)

例:数字 0x12345678,从低地址到高地址:
| 大端 | 12 | 34 | 56 | 78 |
| 小端 | 78 | 56 | 34 | 12 |

2.2.为什么有大小端?

根本原因:寄存器宽度 > 字节宽度,多字节数据就要排顺序。

- CPU 一次能处理 16/32/64 位(多字节),但内存按字节编址,每个地址存 1 个字节
- 所以一个 short(2 字节)或 int(4 字节)必须拆成多个字节,分几个地址存放,这就产生了顺序问题

典型:
- x86 → 小端
- ARM/DSP → 多小端(可配置)
- KEIL C51 → 大端


一句话:因为一个数字占多个地址单元,先存高位还是先存低位,各家 CPU 设计选择了不同方案。

2.3.练习

2.3.1 练习1

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

#include<stdoi.h> int check_sys() { int a=1; return *(char*)&a; } int main() { if(check_sys()==1) { printf("小端"); } else { printf("大端"); } return 0; }

当前平台为x64,然后输出小端。

2.3.2 练习2

#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; }

答案如下:

https://i-blog.csdnimg.cn/direct/b83c2e48e5144c47a0bab6615eacd26b.png

2.3.3 练习3

这是左边题目的解题过程,补码为1111 1111 1111 1111 1111 1111 1000 0000

最后按照%u来打印,是按照无符号整数来打印,结果为4294967168

右边题目因为char 默认是signed char,为有符号类型,它只能输出-128-127之间的数

所以128存进内存时为1000 0000,此时已经溢出了,因为最高位被当做符号位了,

1000 0000被认为是-128的补码,不是128

所以最后扩展为int时候补充的是1,结果还是为4294967168

2.3.4 练习4

答案:

https://i-blog.csdnimg.cn/direct/97dab134fbcc4411be54769baba1b4d3.png

2.3.5 练习5

左边代码超出了char类型255的界限,右边代码也超出了int类型的0,变成了负数,不在范围内。

所以两个代码都会死循环。

2.3.6 练习6

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

3.1浮点数的存储规则

3.2 练习

题目解析:

*pFloat在n=9时,二进制为0 00000000 00000000000000000001001

第一个0为S,代表正负数,后面8个0代表E,再后面的23位代表M

即值应该为(-1)的0次方*0.00000000000000000001001*2的(-126)次方

结果值为0.000000,%f最多显示小数点后六位。

*pFloat=9.0后

它的二进制为1001.0

用IEEE标准公式直接计算就行

(-1)的0次方*1.001*2的3次方

S=0

E=3(指数) + 127=130 (当E等于1-254时才+127),等于255时为无穷大或者NaN

M=1.001(前导1隐含,只存后面的001)

按照32位二进制可以写成

0 10000010 00100000000000000000000

转换成10进制结果就为1091567616

*pFloat=9.0时会自动进行IEEE的编码

3.2 浮点数的存储回顾

3.2.1 浮点数存的过程

IEEE 754 对有效数字M和指数E,还有⼀些特别规定。

前面说过, 1≤M2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中 xxxxxx 表示小数部分。 IEEE 754 规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后面的 xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第⼀位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第⼀位的1舍去以后,等于可以保存24位有效数字。

至于指数E,情况就比较复杂

首先,E为一个无符号整数(unsigned int)

这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是 10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

3.2.2 浮点数取的过程

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 6:50:31

vivo 微服务架构实践之 Dubbo 性能优化

在Java技术栈场景&#xff0c;vivo主要基于 Apache Dubbo 框架来作为微服务之间的通信桥梁&#xff0c;在内部业务的大规模实践过程中&#xff0c;我们碰到了质量、性能和容量等方面的挑战&#xff0c;通过一系列的扩展与优化&#xff0c;较好的解决了相关问题&#xff0c;助力…

作者头像 李华
网站建设 2026/7/1 6:47:23

3分钟搞定Windows PDF打印难题:PDFtoPrinter终极解决方案深度解析

3分钟搞定Windows PDF打印难题&#xff1a;PDFtoPrinter终极解决方案深度解析 【免费下载链接】PDFtoPrinter .Net Wrapper over PDFtoPrinter util allows to print PDF files. 项目地址: https://gitcode.com/gh_mirrors/pd/PDFtoPrinter 还在为Windows系统上的PDF打…

作者头像 李华
网站建设 2026/7/1 6:43:37

Unicode转汉字用Python,一键解码,别再手动翻车了

此工具给出了在线编码转换, 能够达成中文转, 转中, ASCII转, 转ASCII, 于文本框内键入要转换的内容, 接着点击要转换的类型按钮, 转换完毕后便可瞧见对应的内容。它属于一种字符编码标准, 其目的在于将全球各式各样的文字、符号的呈现方式予以统一, 该标准是由联盟所制定的, 它…

作者头像 李华
网站建设 2026/7/1 6:40:39

如何用AutoTask解放双手:Android自动化助手终极指南

如何用AutoTask解放双手&#xff1a;Android自动化助手终极指南 【免费下载链接】AutoTask An automation assistant app supporting both Shizuku and AccessibilityService. 项目地址: https://gitcode.com/gh_mirrors/au/AutoTask 想要告别重复的手机操作&#xff0c…

作者头像 李华