Bigendian、littleendian的结构体反序总结

Bigendian顺序和读出来相同,littleendian和读出来顺序相反。

对于一个结构体,使用bigendian和littleendian,内部元素的顺序变化,取决于具体的元素类型。

反序的原则:

  • 对于连着的几个超过一个字节(含一个字节)的元素,例如下图中的sourceport、destinationport、sequencenumber、requestnumber而言,无论大端小端,它们之间的先后顺序是不会改变的。

Bigendian、littleendian的结构体反序总结_第1张图片

  • 对于连着的几个小于一个字节的元素而言,例如下图中的res1+doff、fin到cwr这两组元素,这两组内部的顺序是前后颠倒的,即元素之间的顺序会因大端小端而不同,但两组之间的先后顺序依然是不变的。

Bigendian、littleendian的结构体反序总结_第2张图片

  • 对于一个大元素(字节倍数大小)内部的反序,实际上是按字节为单位的反序,同时也是具体bit位的全反序(即,12345678 23456789是变成98765432 87654321,而不是变成23456789 12345678,这个可以详见后文),可见下面这张图片的例子。一个十六进制数字,4个bit,两个才是1字节,所以实际上判断的是字节之间的十六进制的01和02的先后。但这里看不出是不是具体bit的先后。

Bigendian、littleendian的结构体反序总结_第3张图片

  • 下图中,8个一位元素的颠倒只证明了字节组内部元素之间的顺序会颠倒,但不能看出具体某个超过1bit的元素内部的所有bit位是否会颠倒。res1和doff同样只能证明前者,无法说明后者。

Bigendian、littleendian的结构体反序总结_第4张图片

  • 那如果是4个2bit元素的倒序,到底是只颠倒一个字节内元素间顺序不颠倒元素内顺序,还是既颠倒元素间顺序,又颠倒元素内顺序呢。其实,小元素(8bit以下)字节组内部的具体元素的倒序实际上就是按bit倒序(详见后文证明)。
  • 现在,我们来看看如何探索在同一字节内的1bit以上,8bit以下小元素内部,小端机是否让每个元素内部倒序。
  • 首先需要证明我的机器是小端机器。代码如下:
    int main(int argc, char **argv)
    {
        union {
            short s;
            char c[sizeof(short)];
        } un;//联合结构体
        un.s = 0x0102; //注意是十六进制
        if (sizeof(short) ==    2) {
            if (un.c[0] == 1 && un.c[1] == 2) {
                printf("big-endian\n");//地址从低到高读出的数字和实际数字相同
            }     else if (un.c[0] == 2 && un.c[1] == 1)
            {
                printf("little-endian\n");//地址从低到高读出的数字和实际数字相反
            } else {
                printf("unknown\n");
            }
        } else {
            printf("sizeof(short) = %d\n", sizeof(short));
        }
        exit(0);
    }
    

    结果:

Bigendian、littleendian的结构体反序总结_第5张图片

 

  • 可见的确是小端机器。
  • 然后我们通过c++的bitset来看看具体的每个bit位的情况。方法是,设置一个8位的bitset元素,用字符串“11100100”来初始化,然后按0到7依次输出,若结果为00100111,则证明小端机会按bit取反字节;如果是11100100,则证明小端机不会按bit取反。
  • 代码如下:
    #include 
    //#define _CRT_SECURE_NO_WARNINGS
    #include 
    #include 
    
    using namespace std;
    
    int main(int argc, char const *argv[])
    {
    	string s = "11100100";
    	bitset<8> bit8(s);
    
    
    	for (int i = 0; i < s.length(); i++) {
    		cout << bit8[i] << " ";
    	}
    
    	return 0;
    }

    结果:

Bigendian、littleendian的结构体反序总结_第6张图片

事实证明,小端机器在对结构体内元素取反的时候——大元素间和字节级小元素组间及相互之间顺序固定,大元素内部的字节级小元素内部的具体bit位,会随着小端的方式按bit位全部取反。只是读取的时候,两种机器的读取顺序各自按照自己的方式,所以读出来的,每一个具体小元素,和大元素的每一个字节元素,对应另外一种机器的值是相同的,但相互的顺序是反的。

你可能感兴趣的:(Bigendian、littleendian的结构体反序总结)