• 【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

  • 相关阅读:
    Golang 协程池 Ants 实现原理,附详细的图文说明和代码
    建议收藏【整合】基于经典全连接神经网络的(cat、dog、panda分类)【步骤完备、图形完整】
    nginx实时流量拷贝ngx_http_mirror_module
    plink遗传数据质控--每个个体QC、每个marker(变异)质控、全基因组关联meta分析QC
    【闲聊杂谈】源码追踪Spring的Bean创建流程
    矩阵的基础知识
    Graph RAG: 知识图谱结合 LLM 的检索增强
    Windows 事件日志监控
    如何恢复被盗的加密货币?
    【无人机】基于PID控制器和A星算法实现无人机路径规划附matlab代码
  • 原文地址:https://blog.csdn.net/u012028275/article/details/126112405