> 文章列表 > 1. 大端法和小端法

1. 大端法和小端法

1. 大端法和小端法

int32_t num = 0x01020304;

一个int32_t是4个字节,在内存中的存储是高位字节在低地址,低位字节在高地址。

(数字)前者的高低是数字位数的高低,左边是高位数,右边是低位数;
(地址)后者的高低是内存中的地址的大小,大的值就是高地址。

  1. 大端法:
    1. 大端法和小端法

  2. 小端法:
    1. 大端法和小端法

网络程序要考虑字节序的问题。

由于PC机较多,所以将小端字节序作为主机字节序。而大端字节序用作网络字节序

发送端发送数据时,都将字节序转为大端序,也就是网络字节序。

接受端接收到网络字节序的数据,根据需求决定是否进行转。

代码判断字节序

  1. 利用联合体各成员共用内存空间的特点:

    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]是高地址处的数据。
    根据大端小端的定义,进行比较即可。

  2. 直接用指针,道理都一样的:

    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");}
    }
    
  3. 使用编译器预定义宏,宏的名称并没有标准化,这里使用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");
    }