判断系统大小端字节序的方法

1、字节序
1.1、大端字节序(big-endian)
数据低位存储在高地址位,数据高位存储在低地址位。
假设定义一个变量并赋予初值:
int a = 0x12345678;
对于这个整型数据,一共有四个字节,假设为其分配的地址空间为0x1001~0x1004,则从低位到高位,每个字节依次是:12、34、56、78。数据将会以下面的形式储存在内存中:

1.2、小端字节序(little-endian)
数据低位存储在低地址位,数据高位存储在高地址位。
假设定义一个变量并赋予初值:
int a = 0x12345678;
对于这个整型数据,一共有四个字节,假设为其分配的地址空间为0x1001~0x1004,则从低位到高位,每个字节依次是:78、56、34、12。数据将会以下面的形式储存在内存中:

2、验证大端字节序还是小端字节序
2.1、通过联合体union判断
联合体是一个能在同一存储空间存储不同类型的数据类型。简单来讲,这段地址空间是联合体中各成员变量共用的,具体用到多少空间取决于各成员变量自身的大小。但是,一个联合体的大小取决于联合体成员中最大的变量的大小。
定义一个联合体:

union u_data  
{  
    unsigned char a;  
    unsigned int b;  
} data;

在这个联合体中,共用的是低地址位的一个字节,如果需要获取b的值,那么就需要根据系统其对应的大小端字节序来取4个字节的值,而获取a的值,系统只会从该段地址中的低地址取1个字节的值。
所以,通过给b赋值,然后再获取a的值,即可根据结果判断系统是大端字节序还是小端字节序。
根据上面的图示,如果构建联合体u_data,并将b赋初值0x12345678,如果读取a的值为0x78,则代表系统是小端字节序,如果读取a的值为0x12,则代表系统是大端字节序。
代码验证:

#include <stdio.h>    
    
int main()    
{    
    union u_data    
    {    
        unsigned char a;    
        unsigned int b;    
    } data;    
    
    data.b = 0x12345678;    
    
    if (data.a = 0x78)    
    {    
        printf("小端字节序\n");    
    }    
    else if (data.a == 0x12)    
    {    
        printf("大端字节序\n");    
    }    
    
    return 0;    
}

2.2、通过指针判断
先用代码实现,然后再分析实现原理:

#include <stdio.h>    
    
int main()    
{    
    int a = 0x12345678;  
    char *p = NULL;  
  
    p = (char *)&a;  
  
    if (*p == 0x78)  
    {  
        printf("小端字节序\n");  
    }  
    else if (*p == 0x12)  
    {  
        printf("大端字节序\n");  
    }    
    
    return 0;    
}

代码中定义了一个整型变量a,char型指针变量*p。指针会指向整型数的首地址,当调用*p往地址里取值时,系统会根据指针的类型大小取对应大小的值。
例如,程序中char型的指针就会从它指向的地址往后取char类型(1个字节)的值,故首先会取其低地址位的1个字节的内容。如果*p==0x78,可以判断系统是小端字节序;如果*p==0x12,可以判断系统是大端字节序。

posted @ 2024-09-24 21:24  白鹤淮  阅读(26)  评论(0编辑  收藏  举报