关于这段代码的简单问题:
union MyUnion
{
int a;
int b;
};
union MyUnion x, y;
x.a = 5;
y.b = 2;
y.a = 3;
x.b = 1;
int c = (x.a - y.b) + (y.a - x.b);
有人可以解释为什么c
的值为0吗?
答案 0 :(得分:6)
您只能访问联合的最后写入字段。此代码违反了此规范,因此会调用未定义的行为。
实质上,由于MyUnion.x和MyUnion.y共享相同的内存,您可以用以下代码替换代码:
int x, y;
x = 5;
y = 2;
y = 3;
x = 1;
int c = (x - y) + (y - x);
这简化为c = (1 - 3) + (3 - 1)
,-2 + 2
或0
。
请注意,这只是基于以下观察:这是编译器通常似乎实现联合的方式,并且它解释了观察到的行为。它仍然是 未定义,你应该小心这样的代码。
答案 1 :(得分:5)
因为(1 - 3)+(3 - 1)= 0
联合中只有一个'值',它们都使用相同的内存位置,因此最后一个赋值就是值。
答案 2 :(得分:5)
这是未定义的行为。如果您上次写信至x.a
,则不允许您阅读x.b
,反之亦然。
实际上,您可以像这样重新安排表达式:
int c = (x.a - x.b) + (y.a - y.b);
由于实际上x.a
和x.b
共享相同的内存位置(y.a
和y.b
也是如此),+
的两个操作数始终为零
答案 3 :(得分:3)
x和y都存储一个值,这是最后指定的值,因此x保持1,y保持3(该值保存在“a”和“b”成员中,因为它们的存储“重叠” “(这就是工会)。
所以等式为(1 - 3) + (3 - 1) = 0
是的,正如其他人评论的那样,行为是未定义的(取决于您的编译器,您可能得到不同的答案),但这是为什么您获得的值为0.
答案 4 :(得分:3)
int c =(1 - 3)+(3 - 1);
使用union时,只在内存中为一个变量创建空间,从而用最后一次使用的调用替换它的值。