在计算机科学领域中,字节序是指存放多字节数据的字节顺序。
典型的情况是整数在内存中的存放方式和网络传输的传输顺序。
大端序:网络字节序;小端序:主机字节序。
字节序、端序、尾序 英文:EndIanness(有时也可指位序)
大小端序跟硬件的体系结构有关,所有 X86 和 X64 系列的CPU都是小端序。
大小端序跟操作系统是无关的:
- 在 X86 系列的 PC 上,Solaris系统是小端序。
- 在 sun sparc 平台上的 Solaris系统是大端序。
大端字节序:高字节存于内存低地址位,低字节存于内存高地址位。
小端字节序:高字节存于内存高地址位,低字节存于内存低地址位。
例如:一个long型的数据 Ox12345678 :
大端字节序:
内存低地址–> | 0x 12 |
0x 34 | |
0x 56 | |
内存高地址–> | 0x 78 |
小端字节序:
内存低地址–> | 0x 78 |
0x 56 | |
0x 34 | |
内存高地址–> | 0x 12 |
大端序:(big-endian)
地址增长方向 → |
|||||
... |
0x0A |
0x0B |
0x0C |
0x0D |
... |
数据以16bit为单位:
地址增长方向 → |
|||||
… |
0x0A0B |
0x0C0D |
… |
最高的16bit单元0x0A0B存储在低位。
小端序:(big-endian)
地址增长方向 → |
|||||
... |
0x0D |
0x0C |
0x0B |
0x0A |
... |
数据以16bit为单位:
地址增长方向 → |
|||||
... |
0x0C0D |
0x0A0B |
... |
采用大端序的CPU和采用小端序的CPU不仅在字节上是相反的,在比特位上也是相反的。
比如0x01在内存中的存储
大端序:内存低比特位 00000001 内存高比特位
小端序:内存低比特位 10000000 内存高比特位
比如0x00000001
大端序:内存低比特位 00000000 00000000 00000000 00000001 内存高比特位
小端序:内存低比特位 10000000 00000000 00000000 00000000 内存高比特位
编程判定 大端序 和 小端序 的方法
1. int 型占4字节的方法——建议用 long…
1 2 3 4 5 6 7 8 |
bool IsBigEndian() { int a =1 ; if(((char*)&a)[3] ==1) return true ; else return false ; } |
2. union共用体方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
bool IsBigEndian() { union { unsigned short a ; char b ; } c; c.a =0x0102 ; if(c.b ==1) return true ; else return false ; } |
这里有一道面试题:
问,以下代码输出什么:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
union u { int i ; char x[2] ; } a ; int main(void) { a.x[0] ='1' ; a.x[1] ='2' ; cout << a.i << endl ; return 0 ; } |
这个题,要看你使用的是什么系列的CPU,姑且假设是Intel系列的。
Union是一个特殊的结构,其中所有成员共享结一个内存地址,任意时间只能存储一个成员,上面的Union大小为4个字节,所以上面的代码存储完字符1和2之后,Union的存储貌似应该是0x31320000,31和32分别是字符’1’和’2’的十六进制ASCII码(注意是字符1和2,而不是整数),但是Intel系列的CPU都是按照小端序存储的,所以,正确的顺序是0x00003231,对应的十进制数是12849。