c++ union位域

来源:互联网 发布:淘宝网店注册 编辑:程序博客网 时间:2024/06/17 18:59
原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和本声明。否则将追究法律责任。http://zhouxiaodan.blog.51cto.com/1177793/1202163

最近碰到一道题,顺带复习一下union的数据分布,题目如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
unionpacket
{
structpacket_bit
{
unsignedchar a:2;
unsignedchar b:3;
unsignedchar c:4;
} bit;
inti;
} data;
intmain()
{
data.i = 0;
data.bit.a = 1;
data.bit.b = 2;
data.bit.c = 15;
printf("0x%04x\n",data.i);
return0;
}

先来看一下struct packet_bit是如何分布的

成员a、b、c都是char型,所占的位数为2,3,4。由于union类型不能跨字节(本题为unsigned char,为单字节),所以a、b在同一个字节内,后面补3个位,c在第二个字节内。而struct packet的size为4个字节,所以其分布图如下:


(第一字节)                    (第二字节)

—— —— —— —— —— —— —— ——|—— —— —— —— —— —— —— ——|后16位为0(两个字节)

          (     b    )(  a   )            (     c       )

因为字节填充是从低位填起,所以a、b、c的分布情况如上图,由不同的颜色标出。


所以,当执行赋值语句后,a=1,b=2,c=15,对应上图的情况是:


(第一字节)                    (第二字节)

—— —— —— 0 1 0 0 1|—— —— —— —— 1 1 1 1|后16位为0(两个字节)

           (  b  ) ( a )             (    c    )


所以data.i在大端的情况下的值为:0x090f0000

小端的情况下,值为:0x00000f09。

所以上面的答案为 0x0f09。(intel cpu)


关于union不能跨类型字节的理解,可以看下面这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
typedefstruct _strBitData_
{
unsignedint  ulData1:2;
unsignedint  ulData2:12;
unsignedint  :2;
}strBitData;
typedefstruct _chBitData_
{
unsignedchar  ulData1:2;
unsignedchar  ulData2:7;
unsignedchar  :2;
}chBitData;
intmain()
{
strBitData stData;
chBitData chData;
unsignedint *pOuputData;
unsignedchar *pchOuputData;
memset((void*)&stData, 0,sizeof(strBitData));
memset((void*)&chData, 0,sizeof(chBitData));
stData.ulData1 = 0x7;
stData.ulData2 = 0x010;
chData.ulData1 = 0x7;
chData.ulData2 = 0x010;
pOuputData = (unsignedint *)&stData;
pchOuputData = (unsignedchar *)&chData;
printf("0x%x\n", *pOuputData);
printf("0x%x\n", *pchOuputData);
return0;
}
结果为:0x43

       0x3

如果位域在类型的范围内,则拼接,否则,不可以跨类型拼接。

还需要注意的是,0x7被截断成为两个位,故为0x3
原创粉丝点击