1. 大端法和小端法
int32_t num = 0x01020304;
一个int32_t
是4个字节,在内存中的存储是高位字节在低地址,低位字节在高地址。
(数字)前者的高低是数字位数的高低,左边是高位数,右边是低位数;
(地址)后者的高低是内存中的地址的大小,大的值就是高地址。
-
大端法:
-
小端法:
网络程序要考虑字节序的问题。
由于PC机较多,所以将小端字节序作为主机字节序。而大端字节序用作网络字节序。
发送端发送数据时,都将字节序转为大端序,也就是网络字节序。
接受端接收到网络字节序的数据,根据需求决定是否进行转。
代码判断字节序
-
利用联合体各成员共用内存空间的特点:
void check_byte_order() {union value {int16_t value;int8_t union_bytes[sizeof (value)];} test;test.value = 0x0102;if (test.union_bytes[0] == 1 && test.union_bytes[1] == 2) {printf ("big endian\\n");} else if (test.union_bytes[0] == 2 && test.union_bytes[1] == 1) {printf ("little endian\\n");} else {printf ("unknown\\n");} }
存进去的数字是
0x0102
,但是不知道在内存中是0x0102
还是0x0201
这样的顺序存放。
union_bytes[0]
是低地址处的数据,union_bytes[1]
是高地址处的数据。
根据大端小端的定义,进行比较即可。 -
直接用指针,道理都一样的:
void check_byte_order_2() {int16_t num = 0x0102;int8_t *addr = (int8_t *) #if (addr[0] == 1 && addr[1] == 2) {printf ("big endian\\n");} else if (addr[0] == 2 && addr[1] == 1) {printf ("little endian\\n");} else {printf ("unknown\\n");} }
-
使用编译器预定义宏,宏的名称并没有标准化,这里使用gcc12:
void check_byte_order_3() {if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)printf ("little endian\\n");else if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)printf ("big endian\\n");elseprintf ("unknown\\n"); }