你能解释吗?该如何解决

你能解释吗?
C/C++ code
#include <stdio.h>
int main(void)
{
    union A
    {
        char a;
        char y:3;
        char z:3;
        char x:2;
    }a;
    a.a=0x67;
    printf("%0x\n%0x\n%0x\n%0x\n",a.a,a.y,a.z,a.x);
    return 0;
}

输出结果为:
67
ffffffff
ffffffff
ffffffff
在一个论坛上看到的提问 乍看有点蒙 实际比较简单

有兴趣的朋友看看 


------解决方案--------------------
union A
{
char a;
char y:3;
char z:3;
char x:2;
}a;
联合体A 所占内存为1个字节,且A中的a,y,z,x它们共用同一个字节,当 a=0x67;赋值后,这个a所占内存的值就是:0x67,用二进制表示为:0110 0111,其二进制的从低位到高位表示,即从第0个二进制位到第7个二进制(0-7)位分别为:1 1 1 0 0 1 1 0,

而a.x占2个二进制位,即第0个和第1个二进制,也就是说a.x的二进制位表示为a.x=11B,(B)表示二进制位,

a.z占3个二进制位,它的二进制位表示为:a.z = 111B,

a.y也是占3个二进制位,它的二进制位表示为:a.y = 111B 

当进行打印的时候,由于打印的输出格式是十六进制,则会将a.a,a.y,a.z,a.x提升为整数进行打印,

把a.a进行提升整数时,会把a.a的最高位当成符号位,a.a的二进制表示为:a.a=0110 0111B,由于a.a的最高位是0,则把a.a提升整数时,其高位字节要用它的符号位0进行补充,那么a.a提升整数后,它的十六进制表示为:a.a=0x0000 0067,也就是打印出它的十六进制结果为:67

再说a.x,把a.x提升整数时,由于a.x的二进制表示为:a.x=11B,会把a.x的最高位1当成符号位,然后用其符号位进行高字节的补充,那么a.x提升整数后,它的十六进制表示为:a.x=0x1111 1111

同理,把a.z提升整数时,会把a.z的最高位1当成符号位,然后用其符号位进行高字节的补充,那么a.z提升整数后,它的十六进制表示为:a.z=0x1111 1111

同理,把a.y提升整数时,会把a.y的最高位1当成符号位,然后用其符号位进行高字节的补充,那么a.y提升整数后,它的十六进制表示为:a.y=0x1111 1111




------解决方案--------------------
C/C++ code
[16:56:48] tty:[2] jobs:[0] cwd:[/home/liangdong]
[root@jx-csblog01.jx.baidu.com liangdong]# cat main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[]) {
        typedef unsigned char uchar;

        union {
                char base;
                uchar b3:3; // 0x07
                uchar b2:2; // 0x03
                uchar b1:1; // 0x01
        }tmp_un;

        tmp_un.base = 0x67;
        printf("%x,%x,%x\n", tmp_un.b3, tmp_un.b2, tmp_un.b1);

        return 0;
}