与C中的并集混淆

与C中的并集混淆,c,unions,C,Unions,我不明白工会是如何运作的 #include <stdio.h> #include <stdlib.h> int main() { union { int a:4; char b[4]; }abc; abc.a = 0xF; printf(" %d, %d, %d, %d, %d, %d\n", sizeof(abc), abc.a, abc.b[0], abc.b[1], abc.b[2], abc.b[3]); re

我不明白工会是如何运作的

#include <stdio.h>
#include <stdlib.h>

int main()
{
    union {
    int a:4;
    char b[4];
    }abc;
abc.a = 0xF;

    printf(" %d, %d, %d, %d, %d, %d\n", sizeof(abc), abc.a, abc.b[0], abc.b[1], abc.b[2], abc.b[3]);

    return 0;
}
#包括
#包括
int main()
{
联合{
INTA:4;
charb[4];
}abc;
abc.a=0xF;
printf(“%d、%d、%d、%d、%d、%d\n”),大小(abc)、abc.a、abc.b[0]、abc.b[1]、abc.b[2]、abc.b[3]);
返回0;
}

在上述程序中。
我做了
inta:4
因此,a应该取4位。
现在我存储,
a=0xF//i、 EA=1111(二进制形式)


因此,当我访问
b[0 0r 1或2或3]
时,为什么输出不是像
1,1,1

,因为每个
char
占用(在大多数平台上)1字节,即8位,所以
a
的所有4位都属于
b[]
的单个元素


除此之外,位字段的存储方式取决于编译器,因此它没有定义,
b[]
的哪个字节映射到…

0xF是-1,如果您将其视为4位有符号,那么输出是正常的。b甚至没有完全赋值,所以它的值没有定义。它是一个4字节的实体,但您只分配了一个4位实体。所以在我看来一切都很正常。

0xF是-1,如果您将其定义为4位有符号数字。检查以了解原因


您没有初始化
b
,因此它可能包含任何随机值。

您的工会的总大小将至少为
4*sizeof(char)

假设您正在使用的编译器将此定义为行为,请考虑以下内容:

  • abc
    从未完全初始化,因此它包含一个随机的零和一组合。大问题。所以,首先要这样做:
    memset(&abc,0,sizeof(abc))
  • union应该是其最大成员的大小,因此您现在应该有4个零字节。字节。
    00000000000000000000000000000000000000
  • 您只设置了4位高,因此您的工会将变成这样:
    00000000000000000000001111

    1111000000000000000000000000


    我不确定编译器如何处理这种类型的对齐,因此这是我能做的最好的了
  • 你也可以考虑做一个字符到二进制的转换,这样你就可以手动检查二进制格式的每一个比特的值:


    祝你好运

    实际上,据我所知,在分配给
    abc.a
    之后访问
    abc.b
    是一种未定义的行为。你不应该以任何你认为有效的方式依赖它。@NiklasB。如果C11不再可用,它就在那里定义了。@Daniel Fischer:很好,谢谢。@OP:我想你把位和字节混淆了。@Daniel:它也定义了它如何与位字段一起播放吗?