联合中这种行为背后的逻辑是什么?

时间:2016-09-06 14:51:09

标签: c structure unions

我已经声明了一个带有2个结构的联合,并为每个元素赋值,然后将它们打印出来。

union data {
    struct s1 {
        int a;
        int b;
    }c;
    struct s2 {
        int d;
        int e;
    }f;
} x;

/* Assignment */
x.c.a=1;
x.f.e=2;
x.c.b=3;
x.f.d=4;

printf("%d %d %d %d\n", x.c.a, x.f.e, x.c.b, x.f.d);

它输出像这样 - > 4 3 3 4

但是,当我按照以下顺序分配值时 - >

x.c.b=3;
x.f.d=4;
x.c.a=1;
x.f.e=2;

它输出像这样 - > 1 2 2 1

这种变化背后的逻辑是什么?

3 个答案:

答案 0 :(得分:4)

为了了解发生了什么,您需要回忆一下union成员共享相同的内存。在您的情况下,union有两个成员:一个称为c,另一个称为f

c成员的任何分配都将更改f成员的内容,反之亦然。在您的情况下,两个成员的结构是相同的,以下对共享相同的空间:

x.c.a / x.f.d
x.c.b / x.f.e

该对中的一个成员的任何分配也导致该对中的另一个成员也改变其值。这正是您看到的行为:每对成员的值都等于上次赋值的值。

答案 1 :(得分:4)

union有足够的空间来存储其最大的成员。在您的情况下,两个成员的大小相同。 x的内存布局可以容纳两个int

x.c.a=1;    // Sets the value of the first int to 1
x.f.e=2;    // Sets the value of the second int to 2
x.c.b=3;    // Sets the value of the second int to 3
x.f.d=4;    // Sets the value of the first int to 4

在这些陈述的最后,您在第一个3中有int,在第二个4中有int

printf("%d %d %d %d\n", x.c.a, x.f.e, x.c.b, x.f.d);

相当于:

int i1 = x.c.a;  // i1 is 4
int i2 = x.c.b;  // i2 is 2

printf("%d %d %d %d\n", i1, i2, i2, i1);

产生输出4 3 3 4

使用时:

x.c.b=3;    // Sets the value of the second int to 3 
x.f.d=4;    // Sets the value of the first int to 4
x.c.a=1;    // Sets the value of the first int to 1
x.f.e=2;    // Sets the value of the second int to 2

在这些陈述的最后,您在第一个1中有int,在第二个2中有int

这解释了第二个输出。

答案 2 :(得分:1)

您可能已经知道这一点,但union在同一数据块上指定了多个视图。您恰好指定了两个相同的视图(两个int s的结构)。

因此,您的两个赋值序列可以分别重写为:

x.c.a=1;
x.c.b=2;
x.c.b=3;
x.c.a=4;

x.c.b=3;
x.c.a=4;
x.c.a=1;
x.c.b=2;

在第一种情况下,对x.c.ax.c.b的最后一次分配分别为43,因此它们仍然存在。在第二种情况下,这些是12,因此它们反映在输出中。