位域的应用(花费时间过长,暂时放弃了,大小端的同步一半也不需要个人去考虑,但是可以作为debug的可能方向)

C/C++的结构体有一个规定,无论大端还是小端,先定义的成员一定是低字节和低位。

在大端系统中,结构体变量及其成员的存储情况如下:

         .a1          .a2            .b1          .b2          .b3          .b4
bit      [00:01]     [02:07]         [08:10]      [11:14]      [15:19]      [20:23]
data     01          000011          100          1000         01011        0011
 
.a1[0:1] = 0b01(0x1);
.a2[0:5] = 0b000011(0x3);
.b1[0:2] = 0b100(0x4);
.b2[0:3] = 0b1000(0x8);
.b3[0:4] = 0b01011(0xb);
.b4[0:3] = 0b0011(0x3);

 在小端系统中,各个结构体成员的存储情况如下:


         .a1         .a2             .b1          .b2          .b3           .b4
bit      [01:00]     [07:02]         [10:08]      [14:11]      [19:15]      [23:20]
data     01          000011          100          1000         01011        0011
 
.a1[1:0] = 0b01(0x1);
.a2[5:0] = 0b000011(0x3);
.b1[2:0] = 0b100(0x4);
.b2[3:0] = 0b1000(0x8);
.b3[4:0] = 0b01011(0xb);
.b4[3:0] = 0b0011(0x3)

位域&大小端&以太网通信

位域可以2bit、5bit等不规则的多个bit来描述一个成员,但单通道串行通信接口只能以8bit为单位进行逐位发送,且从高bit发送还是低bit发送取决于CPU的大小端模式,大端CPU先发送bit0,小端CPU先发送bit7.

使用上文提到的结构体struct st1 data进行网络发送时会出现如下有趣现象:


大端CPU发送

发送上述数据,网络端口发送的顺序将会是(从左到右的发):01  000011  100  1000  01011  0011(为方便区分字节,同一个byte的位背景颜色相同;为方便区分结构体成员,成员间用空格隔开)。

如果接收端为大端CPU,针对每个字节的接收,收到的第一个bit放到bit0,最后一个bit放到bit7,最终收到的数据将是:bit[0:23]  01  000011  100  1000  01011  0011。如果接收端程序定义的结构体与发送端完全相同,则每个成员刚好对应上,数据解析正确。

如果接收端为小端CPU,针对每个字节的接收,收到的第一个bit放到bit7,最后一个bit放到bit0,最终收到的数据将是:bit[23:0]  1011  00111  0010  000  010000  11。如果接收端程序定义的结构体与发送端完全相同,则由于发送位序颠倒,数据已经完全紊乱。根据C/C++的规定:无论大端还是小端CPU,先定义的结构体成员一定位于低位或低字节,解析出来的数据如下:

.a1[1:0] = 0b11(0x3);

.a2[5:0] = 0b010000(0x10);

.b1[2:0] = 0b000(0x0);

.b2[3:0] = 0b0010(0x2);

.b3[4:0] = 0b00111(0x7);

.b4[3:0] = 0b1011(0xb);

和源数据相比,已经面目全非了。

你可能感兴趣的:(面试题目,c++)