在C中与联盟感到困惑

时间:2012-05-30 13:25:33

标签: 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]);

    return 0;
}

enter image description here
     在上面的程序中。
我做了int a : 4;
所以,应该采取4位 现在我正在存储,a = 0xF; //i.e a= 1111(Binary form)
因此,当我访问b[0 0r 1 or 2 or 3]时,为什么输出不会像1, 1, 1, 1

那样

4 个答案:

答案 0 :(得分:3)

您的工会总规模至少为4 * sizeof(char)

假设您使用的编译器将此处理为已定义的行为,请考虑以下事项:

  1. abc永远不会完全初始化,因此它包含随机分类的零和1。大问题。因此,请先执行此操作:
    memset(&abc, 0, sizeof(abc));
  2. 联合应该是其最大成员的大小,因此您现在应该有4个清零字节00000000 00000000 00000000 00000000
  3. 你只设置4 ,所以你的联盟会变成这样的:
    00000000 00000000 00000000 00001111
    11110000 00000000 00000000 00000000

    我不确定你的编译器如何处理这种类型的对齐,所以这是我能做的最好的。
  4. 您可能还考虑进行char-to-bits转换,以便您可以手动检查二进制格式的每个位的值:
    Access individual bits in a char c++

    祝你好运!

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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

除此之外,它依赖于编译器如何存储位字段,因此未定义,映射到b[]的哪个字节...

答案 3 :(得分:0)

如果您将其定义为4位有符号数,则0xF为-1。检查two-complement binary representation以了解原因。

你没有初始化b,所以它可以保留任何随机值。