news 2026/10/18 1:43:52

大小端字节序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大小端字节序

目录

摘要:

一:现象及例题

1:现象

2:例题

二:大小端概念

1:概念

2:读取大小端

3:大小端对数组存储的影响

三:验证大小端的两种方式

1:验证的思路

2:整形验证

3:联合体验证


摘要:

本文旨在彻底理解大小端模式的含义,并且讲解两种验证大小端模式的方法~


一:现象及例题

1:现象

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

调试以一行四列和一行一列查看&a:

解释:

①:int a = 0x11223344 的32位二进制是:00010001 00100010 00110011 01000100;其中的44(01000100)叫做32位中的低位字节,11(00010001)叫做32位中的高位字节

很好理解:比如十进制的123,其中1是百位所以是高位,3是个位所以是低位

③:而此时在内存中存储的现象是:在7C,7D,7E,7F这样地址呈递增的内存空间中,分别存储的44,33,22,11!也就是低位字节44存储在低地址处7C,高位字节11存储在高地址处7F

低位字节存储在低地址处,高位字节存储在高地址处

2:例题

#include <stdio.h> // x86 int main() { int a[4] = { 1, 2, 3, 4 }; int* ptr = (int*)((int)a + 1); printf("%x", *ptr); return 0; }

解释:

①:a为数组名,其代表数组首元素的地址,也就是整形1的地址,此时被强转为int整形,也就是指针变量被强转为了整形int值,然后进行+1,代表进行的就是整形值+1(如果100就变成101),随后再被强转为int*整形指针类型,此时解引用求*ptr;

②:经过这一系列操作,其实就是把指针指向的位置往后移动了一个字节,然后int*指针进行解引用,代表求往后的4个字节的值,等同于求元素1的第2个字节开始往后的4个字节

如图:

②:因为环境未变,所以此时在内存中的存储特点仍然是:低位字节存储在低地址处,高位字节存储在高地址处!所以此时的00000002,若按照高位到低位的表达方式,应该为20000000,注意,02整体是1个字节,所以内部没有高位低位之分~

③:所以%x打印*ptr的值, 就是16进制打印0x02000000,所以值就为2000000(7位)

④:当然4个字节应该对应8个16进制位,这里的2000000只有7个16进制位,是因为%x会把最前面的0省略了,如果以%p形式打印,则不会省略:


二:大小端概念

1:概念

其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储,下⾯是具体的概念:

大端(存储)模式:
是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。

小端(存储)模式:
是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。

注:不管大端小端,内存是按字节编址的,一个字节内部不再高位低位!

所以在上述的调试现象和例题中,都是低位字节存储在低地址处,高位字节存储在高地址处,故博主的环境就是小端模式!反之就是大端存储!


2:读取大小端

❓️:在初次学习大小端的时候,会有一个常见的误区,那就是一个整形分别在大端和小端的模式下存储的顺序不同,此时进行读取,会不会值不同呢?

💡:不管大端小端,读取的值都是一样的!这就是为什么我们不管环境是大端小端,创建的变量值是多少,读取打印的值就是多少~

整形1在大端和小端下的存储:

❓️:会不会大端下读取到的1的补码为:00000000 00000000 00000000 00000001;而小端下读取到的补码为:00000001 00000000 00000000 00000000;这样打印结果前者为1,后者为16777216?

💡:当然不会!

CPU会抹去大小端下存储机制的差异化,让我们读取到的值都一样!CPU会把内存中的字节重新组合成正确的数值,所以无论大端还是小端,读取到的补码都是:00000001 00000000 00000000 00000000。大端和小端的差异只存在于内存存储层面,CPU 读取后都会转换成统一的二进制格式(高位在左),所以数值永远一样。

而上文中的例题中的图为:

❓️:此时可能会不理解为什么读取到的不是0x00000002?

💡:此时按地址从低到高排列:00 00 00 02,CPU会将其恢复为高位在左,低位在右,也就是02000000,这才是这四个字节所存储的值,所以%x打印为2000000~

3:大小端对数组存储的影响

需要注意的一点是,在一个数组内,大小端只会让单个元素内部字节存储顺序不同!而数组整体的线性地址递增顺序,完全不受大小端影响。下标越大,地址一定越高。并且不会出现一个整形数组{1,2,3,4}在不同端下会存储为{4,3,2,1}的情况,这是极大的误解!


三:验证大小端的两种方式

1:验证的思路

面试中,验证大小端是一个常见的问题,我将介绍两种方式验证大小端~

首先,需要知道一个char*指针去取地址的时候,在大小端取到的地址虽然相同,但是该字节的内容不相同!

比如:

❓️:CPU不是会抹去大小端下存储机制的差异化,让我们读取到的值都一样吗?所以这里两个char*对应的空间存储的值为什么不同?

💡:在大端和小端中,一个字节的内容存储在一个地址处,这是恒定的!所谓的组合顺序,也不会改变每个地址中的存储的内容!此外,须知CPU 只在读取才做组合成正确数值这一操作,而且CPU做这件事,也不会影响到大端小端的存储特点!

所以,验证大小端的思路就是我们利用整形1,整形1只有低位的那一个字节为1,其余3字节都是0,所以如果我们单独利用char*取出整形存储在低地址处的那一个字节,如果*解引用验证为1,代表为小端,反之为0则大端!!

2:整形验证

#include <stdio.h> 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; }

解释:对整形i进行取地址,此时取到的就是整形i的起始地址,也就是存储在低地址处的那个字节的地址,然后进行强转char*,在*解引用,得到了该字节的值,为1则小端,反之大端

3:联合体验证

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

解释:

①:联合体的成员变量占据同一块内存,所以读取char就是读取int的第一个字节。小端下整形该字节是1,大端下整形该字节是0,由此判断字节序。

②:所以需要把成员变量i置为1,再用c的值去判断

📌 [ 作者 ] shylyly
📃 [ 首次发布 ] 2026.5.16
❌ [ 最新修改 ] 2026.10.17
📜 [ 声明 ] 由于笔者水平有限,文中难免有疏漏或不妥之处,还望读者不吝赐教。

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

推荐关于钱币书

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/18 1:38:49

关于学习钱币最容易懂的书

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/18 1:38:27

毫米波雷达微多普勒特征提取与物理可解释识别

简介&#xff1a;本资源是一套面向雷达信号处理与智能感知方向的Matlab/Python混合实现项目&#xff0c;适用于高校研究生、雷达算法工程师及自动驾驶感知开发者&#xff0c;聚焦毫米波雷达微多普勒特征建模、目标识别与实时跟踪三大核心问题。压缩包共54个文件&#xff08;50.…

作者头像 李华
网站建设 2026/10/18 1:38:24

MCLDNN实战:多通道轻量级网络实现自动调制识别与二次开发

简介&#xff1a;MCLDNN 是发表于自动调制识别领域的时空多通道学习框架官方实现&#xff0c;面向从事无线通信信号处理、深度学习研究的高校师生与算法工程师。该框架创新性地融合一维卷积、二维卷积与 LSTM 三层结构&#xff0c;从单个及组合同相/正交符号中提取时空特征&…

作者头像 李华
网站建设 2026/10/18 1:36:17

CAN总线布线规范全解析:从终端电阻到屏蔽层接地的实战避坑指南

简介&#xff1a;CAN总线是工业控制、汽车电子和储能系统中应用最广泛的现场总线之一&#xff0c;其物理层设计的质量直接决定通信的可靠性。很多人以为只要软件配置正确就能保证通信稳定&#xff0c;却忽略了布线规范对信号完整性的根本影响。终端电阻的阻值与位置、双绞线绞距…

作者头像 李华