联合数据类型字段的行为

时间:2019-06-10 23:37:07

标签: c

我很难弄清楚这段代码是如何工作的。 主要是,我对如何在x.str.a和x.str.b分别获得值4和2之后x.br如何获得516的值感到困惑。 我是工会的新手,所以也许我缺少一些东西,但是在任何给定时间,工会中不应该只有1个活动字段吗?

#include <stdio.h>
void f(short num, short* res) {
    if (num) {
        *res = *res * 10 + num % 10;
        f(num / 10, res);
    }
}
typedef union {
    short br;
    struct {
        char a, b;
    } str;
} un;
void main() {
    short res = 0; un x;
    x.str.a = 4;
    x.str.b = 2;
    f(x.br, &res);
    x.br = res;
    printf("%d %d %d\n", x.br, x.str.a, x.str.b);
}

如果有人为我解决了这个问题,我将非常感谢,谢谢!

3 个答案:

答案 0 :(得分:3)

要添加到@Deepstop答案,并更正关于您的理解的重点-

  

在任何给定时间,一个联合中不应该只有1个活动字段吗?

工会中没有活动字段之类的东西。所有不同的字段都引用相同的内存(未对齐的数据除外。

您可以将不同字段视为解释相同数据的不同方式,即可以将并集读为两个字段或8位或一个16位字段。但是两者总是会同时“起作用”。

答案 1 :(得分:1)

OK short可能是16位整数。字符a,b均为8位字符。

因此,您为两者使用了相同的16位内存位置。

0000 0010 0000 0100 is the 16 bit representation of 516
0000 0010           is the 8 bit representation of 2
          0000 0100 is the 8 bit representation of 4

您要在其上运行的CPU是'little-endian',因此16位整数的低位字节排在第一位,即2,而高位字节4在第二位。

因此,通过将2然后4写入连续的字节,然后将它们读回为16位整数,您将得到516,即2 * 256 +4。如果您写入3然后5,则将得到3 * 256 + 5,即783。

重点是并集将两个数据结构放置在完全相同的内存位置。

答案 2 :(得分:1)

  

在x.str.a和x.str.b获得它们之后,x.br如何获得516的值   值4和2

您的联合定义

typedef union {
    short br;
    struct {
        char a, b;
    } str;
} un;

指定un.brun.str共享相同的内存地址。这是工会的重点。这意味着,当您修改un.br的值时,您同时也在修改un.str.aun.str.b的值。

  

我是工会的新手,所以也许我缺少一些东西,但是   给定时间在一个联合中不应该只有1个活动字段吗?

不确定“仅是1个活动字段”是什么意思,但是联合的成员都被映射到相同的内存地址,因此,每当您向联合成员写入值时,它都会将该值写入相同的地址内存地址为其他成员。如果希望将成员映射到不同的内存地址,以便在写入成员的值时仅修改该特定成员的值,则应使用struct而不是union