计算机的大小端
计算机的大小端指的是不同的字节顺序储存方式。
如0x1A2B3C4D,总共四个字节,两个十六进制数表示一个字节,高位字节为0x1A,低位字节为0x4D;中间两个字节分别为0x2B和0x3C;数值0x1A2B3C4D想要在计算机中正确使用,就必须要考虑在内存中将其对应的四个字节合理存储。
对于一个数值多个字节顺序存储就有两种存储方式:
- 大端:(Big-Endian):就是把数值的高位字节放在内存的低位地址上,把数值的低位字节放在内存的高位地址上(低字节在后,高字节在前)
- 人类习惯读写大端字节序,比如1234 -> 一千两百三十四。
- 除了计算机的内部处理,其他的场合几乎都是大端字节序,比如网络传输和文件储存
- 优点:符号位的判定固定为第一个字节,容易判断正负。高位字节也容易进行大小对比
1 2 3 4 | 举例: 内存低地址 --------------------> 内存高地址 0x1A | 0x2B | 0x3C | 0x4D 高位字节 <-------------------- 低位字节 |
- 小端:(Little-Endian):就是把数值的高位字节放在高位的地址上,低位字节放在低位地址上(低字节在前,高字节在后)
- 为什么会有小端字节序?计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。
- 123 + 342 -> 先从个位开始算,再十位,百位
- 优点:强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
1 2 3 4 | 举例: 内存低地址 --------------------> 内存高地址 0x4D | 0x3C | 0x2B | 0x1A 低位字节 --------------------> 高位字节 |
注意:
- 不管是大端法还是小端法存储,计算机在内存中存放数据的顺序都是从低地址到高地址,所不同的是首先取低字节的数据存放在低地址还是取高字节数据存放在低地址。
- 大小端是数据在存储时的表现,而不是在寄存器中参与运算时的表现
- 计算机处理字节序的时候,不知道什么是高位字节,什么是低位字节,也并不存在所谓的数据类型,比如char,int等。它只知道按顺序读取字节,先读第一个字节,再读第二个字节,如果是大端字节序,先读到的就是高位字节,后读到的就是低位字节。小端字节序正好相反
- 所谓的数据类型,比如char,int等,在代码中的作用就是让编译器知道每次应该从那个地址起始读取多少位的数据,赋值给相应的变量
举例,16位整数:
buf是整个数据块在内存中的起始地址,offset是当前正在读取的位置
大端:第一个字节((高位字节)左移8位(即后面添8个0),然后再与第二个字节进行或运算。
1 | x = buf[offset] << 8 | buf[offset+1]; |
小端:第二个字节左移8位,然后再与第一个字节(低位字节)进行或运算。
1 | x = buf[offset+1] << 8 | buf[offset]; |
如何用代码检测用的是大端还是小端
- 借助联合体union的特性实现(union类型数据所占的内存空间等于其最大的成员所占的空间,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | int main(){ union { int a; //4 bytes char b; //1 byte } data; data.a = 1; //占4 bytes,十六进制可表示为 0x 00 00 00 01高字节->低字节 //b因为是char型只占1Byte,a因为是int型占4Byte //所以,在联合体data所占内存中,b所占内存等于a所占内存的低地址部分 if (1 == data.b){ //走该case说明a的低字节,被取给到了b,即a的低字节存在了联合体所占内存的(起始)低地址,符合小端模式特征 printf ( "Little_Endian\n" ); } else { 0 == data.b printf ( "Big_Endian\n" ); } return 0; } |
- 通过将int强制类型转换成char单字节,判断起始存储位置内容实现
1 2 3 4 5 6 7 8 9 10 11 | int main(){ int a = 1; //占4 bytes,十六进制可表示为 0x 00 00 00 01 //b相当于取了a的低地址部分 char *b =( char *)&a; //占1 byte if (1 == *b) { //走该case说明a的低字节,被取给到了b,即a的低字节对应a所占内存的低地址,符合小端模式特征 printf ( "Little_Endian!\n" ); } else { printf ( "Big_Endian!\n" ); } return 0; } |
Reference:
- https://www.jianshu.com/p/633b52b7baec
- https://www.ruanyifeng.com/blog/2016/11/byte-order.html
__EOF__

本文作者:cancantrbl
本文链接:https://www.cnblogs.com/cancantrbl/p/16031052.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/cancantrbl/p/16031052.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战