字节序(Endianness)指的是多字节数据的内存排列顺序。
字节的排列方式有两个:
大端序(Big-Endian)将数据的低位字节存放在内存的高位地址,高位字节存放在低位地址。
小端序(Little-Endian)将数据的的低位字节放在较小的地址处,高位字节放在较大的地址处。
比如数字 0x1A 34 5C 78在内存中的表示形式为:
1)大端模式:
低地址 -----------------> 高地址
0x1A | 0x34 | 0x5C | 0x78
2)小端模式:
低地址 ------------------> 高地址
0x78 | 0x5C | 0x34 | 0x1A
为什么会有大小端模式之分呢?
这是因为在计算机中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8 bit,对于多字节的数据,如C语言的int(32位机中一般占4字节),那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
字节顺序使用情况:
以1字节为基本单位的文件格式独立于字节顺序,例如ASCII文件。
其他文件格式使用一些固定的端顺序格式,例如JPEG文件以大端顺序格式存储。
java 全部为大端(与平台无关): Java二进制文件中的所有内容都以大端顺序存储。这意味着如果您只使用Java,那么所有文件在所有平台(Mac、PC、UNIX等)上的处理方式都是相同的。
C语言默认是小端模式:用C语言编写的程序通常使用 小端顺序。
测试C语言的字节序的代码
代码一:
- #include
-
- int main (void)
- {
- union
- {
- short i;
- char a[2];
- }u;
-
- u.a[0] = 0x11;
- u.a[1] = 0x22;
-
- printf ("0x%x\n", u.i); //0x2211 为小端;0x1122 为大端
-
- return 0;
-
- }
输出:
0x2211
或者,用代码二:
- #include
-
- int main (void)
- {
- short i = 0x1122;
- char *a = (char*)(&i);
-
- printf ("0x%x\n", *(a + 0)); //大端为 0x11;小端为 0x22
- printf ("0x%x\n", *(a + 1));
-
- return 0;
-
- }
输出:
0x22
0x11
字节序是由什么决定的?
字节序就是数据存储的格式。对于操作系统之上的应用程序来说,字节序实际上是由操作系统和编译器决定的。只要操作系统和编译器支持,你就可以使用这种字节序。但是,如果使用了CPU不支持的字节序,数据访问时就必须先转换为CPU支持的字节序,将会加大的降低程序效率。因此操作系统和编译器所提供给应用程序的运行环境的默认字节序一定是CPU支持的字节序。但是,由于以太网协议等很多通信协议、硬件接口的数据格式都是大字节序,因此需要使用这些协议或硬件的程序在数据访问时必须使用大字节序,当然程序本身仍然必须使用操作系统默认的字节序。不过,应用程序也无需过于担忧,只需要在必须使用指定字节序的时候使用操作系统提供的字节序转化函数将默认字节序转换成需要的字节序即可,其他的自然有操作系统和编译器帮你搞定。此段摘自:https://www.zhihu.com/question/65234861/answer/229751964