C语言测试大小端模式

大小端是什么?

这个问题在这里不做过多解释,可以参考:大小端模式详解。
但还是给出一些基本概念:
大小端问题产生的原因:由于在各种体系结构的处理器中,对多个字节数据的内存操作有着不同的定义,所以当处理器在读写一个多个字节内存时,可能涉及到大小端问题。如果处理器读写指令针的数据长度不一致的时候,就会产生大小端的问题。

在小端模式中,数据的低字节将会存放在内存的低地址处,数据的高字节会存放在内存的高地址处。

而在大端模式中,数据的高字节则会存放在内存的低地址处,数据的低字节则存放在内存的高字节出。所以可能一段涉及内存的代码,在小端模式和大端模式有着不同的输出结果。


测试代码1.

int checkCPU(void)  
{  
    union  
    {  
        int a;  
        char b;  
    }c;  
    c.a = 1;  
    return (c.b == 1);  
}  

这个代码也是上述博客中给出的,其中分析上面分析的已经很透彻了,这里在做一个自己的总结。

由于union变量的地址和它的各成员的地址都是同一地址,并且union的存放顺序是所有成员都从低地址开始存放的,所以可以利用这两个特点来检测CPU是大端模式还是小端模式。

首先,1的内存地址是:0x00 00 00 01(因为1位整型,占用四个字节,而char只会占用一个字节),其中数据源的高字节是:0x00,低地址处是:01。

如果CPU是小端模式的话,则c.a从低地址处开始存放的就是低字节数据,也就是01,所以 c.b就会被赋值为0x01;

如果是大端模式的话,则c.a从低地址处开始存放的就是高字节数据,也就是0x00,所以c.b就会被赋值为0x00。

这样的话,根据c.b的赋值情况就可以看出CPU是小端模式还是大端模式了。


测试代码2.

int main(void)  
{  
     union   
     {  
        short n;  
        char c[sizeof(short)];  
     }un;  
     un.n = 0x0102;  

     if ((un.c[0] == 1 && un.c[1] == 2))  
         //判断这种情况是大端还是小端
         printf("大端模式!\n");
     else if ((un.c[0] == 2 && un.c[1] == 1))  
         //判断这种情况是大端还是小端
         printf("小端模式!\n");
     else  
         printf("error!\n");  
     return 0;  
}

首先分析一下这个union可以看出,由于short占用了两个字节,所以char的c数组大小为2。然后我们给un.n赋值为:0x0102,从数据字节来分析,0x0102的高字节是:01,低字节是02。

同样的利用union的存放顺序是从低地址开始存放的特点,由于内存栈的特点在这里c[0]是低地址,c[1]是高地址。

所以如果是小端模式的话,低地址处就会存放数据的低字节,也就是c[0]会存放02,而c[1]就会存放01,也就是说c[0] == 2,c[1] == 1。

相反如果是大端模式,低地址处就会存放数据的高字节,也就是c[0]存放的是01,而c[1]存放02,也就是说c[0] == 1,c[1] == 2。根据以上的分析,可以知道,第一个if判断下面应该写上输出大端模式,第二个if判断下面写上输出小段模式。


代码:

C语言测试大小端模式_第1张图片

两个代码的共同测试结果:

C语言测试大小端模式_第2张图片

你可能感兴趣的:(C/C++)