大小端模式 字节序
大、小端模式的说法,来自乔纳森·斯威夫特的小说《格列夫游记》,在小人国内部分裂成 Big-endian 和 Little-endian 两派,他们的争论在于一派要求从鸡蛋的大头把鸡蛋打破,另一派要求从鸡蛋的小头把鸡蛋打破。斯威夫特借以讽刺英国的政党之争,而计算机工业则借此表示数据储存顺序的分歧。
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
记忆方法: 地址的增长顺序与值的增长顺序相反。
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
记忆方法: 地址的增长顺序与值的增长顺序相同。
那么,为什么会有大小端模式之分呢?
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址(即0x0010)中,0x22放在高地址中(即0x0011)中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以随时在程序中(在ARM Cortex 系列使用REV、REV16、REVSH指令)进行大小端的切换。
如此说来,大小端模式就是处理器在内存中对多字节数据进行存取的不同方式。注意两点:一是处理器,大小端模式是处理器的差异造成的;二是多字节数据,也就是说只有处理器操作的数据类型超过一个字节时才会存在大小端模式的问题,而操作char类型数据是不存在该问题的。
字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。字节序与大小端模式的概念相似,我们上面所说的就是在计算机内存中存储的字节顺序问题(即主机字节序),此外还存在网络传输中的字节顺序问题(即网络字节序)。
那么,为什么会存在网络字节序呢?
我们知道,网络传输上的数据流是字节流,对于一个多字节数值,在进行网络传输的时候,就需要考虑先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它是将这个字节作为高位还是低位来处理呢?实际上,接收端收到的第一个字节会被当作高位看待,这就要求发送端发送的第一个字节应当是高位。而在发送端发送数据时,发送的第一个字节是该数字在内存中起始地址对应的字节。可见多字节数值在发送前,在内存中数值应该以大端模式存放。
网络字节序是 TCP/IP 中规定好的一种数据表示格式,它与具体的 CPU 类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。好了,我们需要记住,网络字节序是一种规定,它采用的是大端模式(Big-endian)。
在网络程序开发或是跨平台开发时,就需要注意字节序的问题了。应该保证只用一种字节序,否则两方的解释不一样就会产生错误。为了方便开发,BSD socket 提供了以下四个转换函数:
htons
把 unsigned short
类型从主机序转换到网络序
htonl
把 unsigned long
类型从主机序转换到网络序
ntohs
把 unsigned short
类型从网络序转换到主机序
ntohl
把 unsigned long
类型从网络序转换到主机序
在使用 Little-endian 的系统中,这些函数会把字节序进行转换;而在使用 Big-endian 的系统中,这些函数会定义成空宏。
看到这里,就会想:为什么只有 short 和 long 类型?对于 float 和 double类型怎么处理?要是遇到64位系统怎么办?
有网友说:htons 和 htonl 是因为 TCP/IP 的一些参数用到 int 和 long,但没有 float 和 double 的参数。另外,float 和 double,与 CPU 无关。一般编译器是按照 IEEE 标准解释的,即把 float/double 看作4/8个字符的数组进行解释。因此,只要编译器是支持IEEE浮点标准的,就不需要考虑字节顺序。
大家注意到,这里说不需要转换,也是有条件的。我没有考证过例外情况的存在比例,但是我相信在绝大部分情况下,编译器都是符合IEEE标准的。如果你实在不放心,可以采取下面两种办法:
(1) 在保证不超过int范围的情况下,将浮点数乘以100(或1000,10000,视所需精度随你定)转换为整数传输,在接收端再除以100,得到浮点数。
此外,我们还会听到 Java字节序,Java字节序与网络字节序一样,采用大端模式。不是说大小端模式只跟 CPU 有关吗?也就是说不同的计算机系统采用不同的字节序存储数据,一种 CPU 不是 Big-endian 就是Little-endian。那这个 Java字节序到底是什么鬼?
Java 程序员是幸福,因为相对于 C/C++ 的不跨平台,JVM 为开发人员屏蔽了大量的底层细节和复杂性,从而能够将精力放在实现特定的业务逻辑上,因此 JVM 规定了数据的存储顺序(即大端模式)。所以做 Java 程序开发完全可以忽略字节序的存在,甚至有些 Java 程序员根本没听过字节序的概念。
大小端模式 字节序相关推荐
- 大小端以及字节序的问题
网络字节顺序NBO(Network Byte Order):按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题. The order in which the bytes of ...
- 通俗易懂说字节序,大小端,网络序和主机序
通俗易懂说字节序,大小端,网络序和主机序 1. 什么是字节序 1.1 为什么字符串不用转序 2. 什么是网络字节序 3. 什么是主机字节序 3.1 主机字节序 3.2 大小端字节序 4. 举例 4.1 ...
- 高地址和低地址、高字节低字节、大小端模式的转换,存储顺序
参考博客 https://blog.csdn.net/ce123_zhouwei/article/details/6971544 https://my.oschina.net/alphajay/blo ...
- 高地址和低地址、高字节低字节、大小端模式(及如何互换),存储顺序(!!)
参考博客 https://blog.csdn.net/ce123_zhouwei/article/details/6971544 https://my.oschina.net/alphajay/blo ...
- 通俗易懂说字节序,大小端,网络序和主机序(2)htonl和ntohl 源码实现
通俗易懂说字节序,大小端,网络序和主机序(2)htonl和ntohl 源码实现 1. htonl 内核源码实现 1.1 注意:这里有判断,如果本身内存中存储的就是网络序,那就不转 1.1 __bswa ...
- .pgr照片文件解析,C++与Java存储数据差别大小端模式
一..pgr是什么? .pgr文件是二进制的图像文件,可以用普通的文本文件打开,或者查看十六进制的文本信息: 读取需要了解~~~非常重要 !!! 基本数据类型的大小端存储模式 表头Header 详细信 ...
- 大小端、字节顺序转换函数和IP地址格式转换函数
大小端.字节顺序转换函数和IP地址格式转换函数 大小端 CPU大小端之分 常见字节序 字节顺序转换函数 Linux系统下定义 Windows系统下 ntohs() htons() htonl()和nt ...
- 大小端模式的判断方法
1. 大小端模式 大端模式:数据的高字节存储在内存的低地址中. 小端模式:数据的低字节存储在内存的低地址中. 两种模式的区别就是数据在内存中是先存储高字节还是低字节,先存高字节就是大端模式,先存低字节 ...
- STM32的大小端模式——什么是大小端模式?
目录 1. 什么是大小端模式 2. 为什么会有大小端模式之分 3. 什么情况需要考虑大小端模式 4. 常见的设备的大小端模式 5. 测试大小端模式例程 6. 大小端转化例程 1. 什么是大小端模式 大 ...
最新文章
- mysql 多库多表_shell脚本建多库、多表、多实例(mysql)
- NVL 和NVL2函数
- 皮一皮:究竟经历了什么才让他用上如此设备...
- node执行cmd命令方法
- C - 数据结构实验之排序三:bucket sort(水题)
- java枚举类是什么_Java学习--常用类(2)、Math类、枚举类
- mysql 数据传输 定时,MySQL数据库定时备份的实现方法
- LeetCode 1471. 数组中的 k 个最强值(排序)
- linux grub 串口,grub重定向到串口 - Emmoblin Blog
- free git online
- 检查用户是否有访问权限
- Firebug 入门指南
- 如何在电脑上录制qq语音
- 优知学院创始人陈睿:怎样做好一个创业公司CTO?
- 2022年京东春节,如何批量设置延迟发货?
- POI 导出Excel
- php代码审计靶场,RIPS --代码审计靶场(第一关)-华盟网
- Linux下qt/C++全局键盘监控,处理键盘事件,输出按键码
- 兼容性运行程序永远_永远不会有太多的应用程序
- P2P通信中的NAT/FW穿越