测试big-little-endianness的代码如何工作?

时间:2017-01-20 14:28:32

标签: c endianness

我正在研究Endianness,当我读到一本教科书时,他们提供了这个运行时测试来检查(在运行时)代码是在一个小型还是大端系统上运行。这本书没有解释任何内容,我对此代码的工作方式感到困惑。任何人都可以帮我解释这段代码是如何工作的。提前谢谢

/* Test platform Endianness */
    int bigendian(void) {
        int i;
        union {
            char Array[4];
            long Chars;
        } TestUnion;
        char c = 'a';

    for(i=0; i<4; i++)
        TestUnion.Array[i] = c++; 
    if (TestUnion.Chars == 0x61626364)
        return 1;
    else
        return 0;
}

3 个答案:

答案 0 :(得分:3)

union提供了不同的数据视图 - 此处TestUnion可以解释为:

  • 一个char[4]数组,或
  • a long int

for循环将TestUnion填充为char[4]数组 - 请注意,字符a的ASCII代码为0x61b为{{ 1}}等等。因此,内存中填充了4个字节0x620x610x620x63,每个字节的地址位置都按升序排列。

0x64语句通过将if解释为TestUnion int来检查它是否为BigEndian。如果它是BigEndian,则从左到右读取long int数字,转换为long。否则它是LittleEndian,它从右到左阅读,意思是0x61626364

您可以使用以下代码检查系统中的功能:

0x64636261

答案 1 :(得分:2)

字节顺序表示低字节或高字节是否先存储在内存中。小端机器首先存储低字节,大端存储首先存储高字节。如果整数有两个以上的字节,那么其他订单也是可能的,但是很少见。

代码正在做的是建立一个联合,以便char数组和一个长整数共享相同的地址空间。然后通过计算期望值来检查查看长整数字节的方向。由于很多原因,写得很糟糕。从技术上讲,写入联合的一个字段然后从另一个字段读取是未定义的行为。代码假定await Task.Delay(TimeSpan.FromSeconds(30)); ,ASCII是字符集,编译器将按预期处理union。可能所有这些都将成立。他还将有符号值与十六进制值与高位设置进行比较 - 我认为这没关系,但它取决于C标准的最小值。

更好的测试就是

sizeof(long) == 4

答案 2 :(得分:1)

假设您正在使用ASCII作为其字符集的系统,则值0x610x620x630x64代表字母分别为abcd

循环:

char c = 'a';

for(i=0; i<4; i++)
    TestUnion.Array[i] = c++; 

使用char arrayTestUnionab填充联盟c的{​​{1}}部分。如果您在以32位d访问联合时使用大端机器,则它将表示为long;如果它是little-endian,则长0x61626364

这不是一个好的&#34;一般情况&#34;但是,测试字节序的算法是因为:

  1. 并非所有系统都使用ASCII来表示字符
  2. 0x64636261不一定是long字节宽