关于系统字节序

    技术2025-05-26  15

    记录一下从网上搜索的关于系统字节序的相关帖子内容

     

        因为现行的计算机都是以八位一个字节为存储单位,那么一个16位的整数,也就是C语言中的short,在内存中可能有两种存储顺序big-endian和litte-endian.    考虑一个short整数0x3132(0x32是低位,0x31是高位),把它赋值给一个short变量,那么它在内存中的存储可能有如下两种情况:大端字节(Big-endian):----------------->>>>>>>>内存地址增大方向short变量地址       0x1000                  0x1001_____________________________|                           ||         0x31             |       0x32|________________ | ________________高位字节在低位字节的前面,也就是高位在内存地址低的一端.可以这样记住(大端->高位->在前->正常的逻辑顺序)小端字节(little-endian):----------------->>>>>>>>内存地址增大方向short变量地址       0x1000                  0x1001_____________________________|                           ||         0x32             |       0x31|________________ | ________________低位字节在高位字节的前面,也就是低位在内存地址低的一端.可以这样记住(小端->低位->在前->与正常逻辑顺序相反)可以做个实验在windows上下如下程序#include #include void main( void ){        short test;        FILE* fp;                 test = 0x3132; //(31ASIIC码的’1’,32ASIIC码的’2’)        if ((fp = fopen ("c://test.txt", "wb")) == NULL)              assert(0);        fwrite(&test, sizeof(short), 1, fp);        fclose(fp);}    然后在C盘下打开test.txt文件,可以看见内容是21,而test等于0x3132,可以明显的看出来x86的字节顺序是低位在前.如果我们把这段同样的代码放到(big-endian)的机器上执行,那么打出来的文件就是12.这在本机中使用是没有问题的.但当你把这个文件从一个big- endian机器复制到一个little-endian机器上时就出现问题了.

    下面代码示范了两种检测系统字节序的方法。第一种方法,使用强制类型转换的方式。C 语言在把占用2个字节的 short 变量强制转换为 char 之后,会把 short 变量的首地址赋给 char 变量,可以根据 char 变量的值判断系统字节序是 大端 还是 小端。第二种方法,利用 联合类型 的特性。联合类型 共享同一段内存,首地址是相同的。/******************* * 文件名:endian.c ******************/#include <stdio.h>

    /********************************************************* * 使用类型的强制转换实现little-endian与big-endian的判断  ********************************************************* * 返回值:                                               *          1 表示是小端字节序。                          *          0 表示不是小端字节序。                        *********************************************************/int is_little_endian_a(void){     unsigned short flag = 0x4321;    if(*(unsigned char*)&flag == 0x21)        return 1;    else        return 0;}

    /********************************************************************************* * 利用联合的特点来判断little-endian与big-endian ********************************************************************************* * 返回值:  *          1   表示是小端字节序。 *          0   表示是大端字节序。 *          -1  表示不能使用这种方法确定字节序。比如有的机器的 short 长度不是 2 。 ********************************************************************************/int is_little_endian_b(void){    union endian_un{        short var;        char bits[sizeof(short)];    };

        union endian_un flag;    flag.var=0x0102;

        //判断低位和高位的存储内容,确定是何种方式    if(sizeof(short) == 2){        if(flag.bits[0] == 1 && flag.bits[1] == 2)            return 0;        else if(flag.bits[0] == 2 && flag.bits[1] == 1)            return 1;        else            return -1;    }         return -1;}

    int main(void){    int type = 0;

        type = is_little_endian_a();    if (1 == type)        printf("judged by first method, little-endian/n");    else if (0 == type)        printf("judged by first method, big-endian/n");

        type = is_little_endian_b();    if (1 == type)        printf("judged by second method, little-endian/n");    else if (0 == type)        printf("judged by second method, big-endian/n");    else        printf("can't judge it/n");

        return 0;}

     

    最新回复(0)