• 【C语言笔记】【小技巧系列】 判断字节序


    【C语言笔记】【小技巧系列】 判断字节序

    整理一些用于判断机器字节序(Byte Order)的程序,通过预定义宏或者数据在内存中的布局进行判断。

    1.通过预定义宏判断

    1.宏定义BYTE_ORDER

    宏定义BYTE_ORDER表示当前机器的字节序,BYTE_ORDER的值被定义为LITTLE_ENDIANBIG_ENDIAN或者PDP_ENDIAN的其中之一。

    其中宏定义LITTLE_ENDIAN表示Little-Endian小端,宏定义BIG_ENDIAN表示Big-Endian大端,宏定义PDP_ENDIAN表示PDP-Endian。

    使用BYTE_ORDER需要包含头文件#include

    使用BYTE_ORDER判断机器字节序的测试程序:

    void check(void)  
    {
        if(BYTE_ORDER == LITTLE_ENDIAN)
            printf("Little-Endian\n"); 
        else if(BYTE_ORDER == BIG_ENDIAN)
            printf("Big-Endian\n");
        else
            printf("PDP-Endian\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    或者

    void check(void)  
    {
    #if BYTE_ORDER == LITTLE_ENDIAN
        printf("Little-Endian\n"); 
    #elif BYTE_ORDER == BIG_ENDIAN
        printf("Big-Endian\n");
    #else
        printf("PDP-Endian\n");
    #endif
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.宏定义__BYTE_ORDER

    宏定义__BYTE_ORDERBYTE_ORDER含义相同,表示当前机器的字节序,__BYTE_ORDER的值被定义为__LITTLE_ENDIAN__BIG_ENDIAN或者__PDP_ENDIAN的其中之一。

    其中宏定义__LITTLE_ENDIAN表示Little-Endian小端,宏定义__BIG_ENDIAN表示Big-Endian大端,宏定义__PDP_ENDIAN表示PDP-Endian。

    使用__BYTE_ORDER需要包含头文件#include

    使用__BYTE_ORDER判断机器字节序的测试程序:

    void check(void)  
    {
        if(__BYTE_ORDER == __LITTLE_ENDIAN)
            printf("Little-Endian\n"); 
        else if(__BYTE_ORDER == __BIG_ENDIAN)
            printf("Big-Endian\n");
        else
            printf("PDP-Endian\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    或者

    void check(void)  
    {
    #if __BYTE_ORDER == __LITTLE_ENDIAN
        printf("Little-Endian\n"); 
    #elif __BYTE_ORDER == __BIG_ENDIAN
        printf("Big-Endian\n");
    #else
        printf("PDP-Endian\n");
    #endif
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.宏定义__BYTE_ORDER__

    __BYTE_ORDER__是GNU C 扩展的预定义宏。

    __BYTE_ORDER__ 被定义为 __ORDER_LITTLE_ENDIAN____ORDER_BIG_ENDIAN____ORDER_PDP_ENDIAN__ 值之一。

    使用__BYTE_ORDER__来判断字节序的测试程序:

    void check(void)  
    {
        if(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
            printf("Little-Endian\n"); 
        else if(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
            printf("Big-Endian\n");
        else
            printf("PDP-Endian\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.通过数据在内存中的布局判断

    可以根据数据在内存中的布局来判断。

    1.方式一

    定义一个32位整形数,进行赋值,然后根据每个字节的位置来判断当前机器的字节序。

    可以通过判断低地址的值。

    void check(void)  
    {
        int32_t val = 0x44332211;
        int8_t *ptr = (int8_t *)&val;
    
        if(ptr[0] == 0x11)
            printf("Little-Endian\n"); 
        else if(ptr[0] == 0x44)
            printf("Big-Endian\n");
        else
            printf("PDP-Endian\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    也可以改成判断高地址的值。

    void check(void)  
    {
        int32_t val = 0x44332211;
        int8_t *ptr = (int8_t *)&val;
    
        if(ptr[3] == 0x44)
            printf("Little-Endian\n"); 
        else if(ptr[3] == 0x11)
            printf("Big-Endian\n");
        else
            printf("PDP-Endian\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.方式二

    改成用union类型来判断。

    通过判断低地址的值,测试程序如下:

    void check(void)  
    {
        union
        {  
            int32_t num;
            int8_t buf[4];
        } val;
        
        val.num = 0x44332211;
        
        if(val.buf[0] == 0x11)
            printf("Little-Endian\n"); 
        else if(val.buf[0] == 0x44)
            printf("Big-Endian\n");
        else
            printf("PDP-Endian\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    也可以改成判断高地址的值。

    void check(void)  
    {
        union
        {  
            int32_t num;
            int8_t buf[4];
        } val;
        
        val.num = 0x44332211;
        
        if(val.buf[3] == 0x44)
            printf("Little-Endian\n"); 
        else if(val.buf[3] == 0x11)
            printf("Big-Endian\n");
        else
            printf("PDP-Endian\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    通过判断低地址的值来判断字节序,也可以修改union的成员,将程序修改为:

    void check(void)  
    {
        union
        {  
            int32_t num;
            int8_t x;
        } val;
        
        val.num = 0x44332211;
        
        if(val.x == 0x11)
            printf("Little-Endian\n"); 
        else if(val.x == 0x44)
            printf("Big-Endian\n");
        else
            printf("PDP-Endian\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    【参考资料】

    3.7.2 Common Predefined Macros


    本文链接:https://blog.csdn.net/u012028275/article/details/126112405

  • 相关阅读:
    【体验有奖】用 AI 画春天,函数计算搭建 Stable Diffusion WebUI
    微服务项目:尚融宝(31)(前端搭建:会员列表搭建(2))
    论文导读 | 支持事务与图分析的图存储系统
    共享茶室小程序开发解决方案
    Cesium从零开始开发
    Apache paimon表管理
    【JavaWeb】Day47.Mybatis基础操作——删除
    学长告诉我,大厂MySQL都是通过SSH连接的
    docker 配置 Mysql主从集群
    三、T100应收管理之出货立账
  • 原文地址:https://blog.csdn.net/u012028275/article/details/126112405