C++ 这种联合和比特场交互是如何工作的?

C++ 这种联合和比特场交互是如何工作的?,c++,unions,bit-fields,C++,Unions,Bit Fields,下面是一个例子: struct field { unsigned int a : 8; unsigned int b : 8; unsigned int c : 8; unsigned int d : 8; }; union test { unsigned int raw; field bits; }; int main() { test aUnion; aUnion.raw = 0xabcdef; printf("

下面是一个例子:

struct field
{
    unsigned int a : 8;
    unsigned int b : 8;
    unsigned int c : 8;
    unsigned int d : 8;
};

union test
{
    unsigned int raw;
    field bits;
};

int main()
{

    test aUnion;
    aUnion.raw = 0xabcdef;

    printf("a: %x \n", aUnion.bits.a);
    printf("b: %x \n", aUnion.bits.b);
    printf("c: %x \n", aUnion.bits.c);
    printf("d: %x \n", aUnion.bits.d);


    return 0;
}
现在运行这个我得到:

a: ef
b: cd
c: ab
d: 0
我想我真的不明白这里发生了什么。所以我把raw设为一个值,因为这是一个并集,其他所有的东西都是从这个值中提取出来的,因为它们都被设为小于一个无符号int?那么位字段是基于原始数据的?但这是怎么形成的呢?为什么d:0在这个实例中

非常感谢您的帮助。

这是因为您的unsigned int的32位长度不够,所有32位未设置为完全填充所有位字段值。因为它只有24位长,所以位字段d显示十六进制值00。试试看

aUnion.raw = 0xffabcdef;
那会产生什么

a: ef 
b: cd 
c: ab 
d: ff
由于dd位字段占用little endian上的位24-32,除非已分配的无符号int字段已分配一个占用这些位集的值,否则该位字段位置也不会显示该值。

这是因为无符号int的32位长度不够,所有32位都未设置为完全填充所有位字段值。因为它只有24位长,所以位字段d显示十六进制值00。试试看

aUnion.raw = 0xffabcdef;
那会产生什么

a: ef 
b: cd 
c: ab 
d: ff

由于dd位字段占用little endian上的位24-32,除非分配的无符号int字段被分配了一个占用这些位集的值,否则该位字段的位置也不会显示该值。

使用整数的十六进制表示法非常有用,因为它可以明确整数的每个字节的值。那么背景呢

aUnion.raw = 0xabcdef;
表示最低有效字节的值为0xef,第二个最低有效字节的值为0xcd,依此类推。但是您正在设置union的原始字段,它是一个整数,因此长度为4字节。在前面的表示法中,缺少最高有效字节,因此可以将其写入

aUnion.raw = 0x00abcdef;
这就像明确表示一个整数x=42有0百、0千等等

union字段分别表示整数raw的a=字节[0],b=字节[1],c=字节[2]和d=字节[3],因为在union中,所有元素共享相同的内存位置。这是正确的,因为您正在一个小的endian体系结构中运行代码,最低有效字节排在第一位

因此:


使用整数的十六进制表示法非常有用,因为它可以明确整数的每个字节的值。那么背景呢

aUnion.raw = 0xabcdef;
表示最低有效字节的值为0xef,第二个最低有效字节的值为0xcd,依此类推。但是您正在设置union的原始字段,它是一个整数,因此长度为4字节。在前面的表示法中,缺少最高有效字节,因此可以将其写入

aUnion.raw = 0x00abcdef;
这就像明确表示一个整数x=42有0百、0千等等

union字段分别表示整数raw的a=字节[0],b=字节[1],c=字节[2]和d=字节[3],因为在union中,所有元素共享相同的内存位置。这是正确的,因为您正在一个小的endian体系结构中运行代码,最低有效字节排在第一位

因此:


@Inian是union上面的结构。明白了,可能你错过了typedef,但union需要定义为union test aUnion;和位作为结构字段位;-这是我的计算机上的一个快速示例,它可以编译。可能是编译器差异和C++是不同的语言。除非你在询问它们之间的区别,否则不要同时标记它们。据我所知,您的代码在C++中有未定义的行为。@ In它的结构在联盟之上。得到它,您可能错过了TyWIFF,但是联盟需要定义为联合测试AUnion;和位作为结构字段位;-这是我的计算机上的一个快速示例,它可以编译。可能是编译器差异和C++是不同的语言。除非你在询问它们之间的区别,否则不要同时标记它们。据我所知,您的代码在C++中有未定义的行为。好的,因为我已经将联盟的字段设置为十六进制值,拉位字段根据EnDad和字段的每个部分的大小从第一个到最后拉。谢谢,这很好地解释了我想知道的,好吧,因为我已经将并集的字段设置为十六进制值,拉位字段根据endian和字段每个部分的大小从头到尾拉位。谢谢这很好地解释了我想知道的