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"); else printf ("unknown\n"); }