union test{
unsigned int x: 3;
unsigned int y: 3;
int z;};
int main(){
union test t;
t.x = 5;
t.y = 4;
t.z = 1;
printf("t.x = %d, t.y = %d, t.z = %d", t.x, t.y, t.z);
return 0;
}
我无法理解为什么x和y的值是1, 感谢任何帮助。
编辑: 感谢所有人的输入,你已经要求输出我目前没有编译器,无论如何我在线编译代码,这些是输出
for z= 1 : t.x = 1, t.y = 1, t.z = 1
for z= 2 : t.x = 2, t.y = 2, t.z = 2
for z= 10 : t.x = 2, t.y = 2, t.z = 10
for z= 30 : t.x = 6, t.y = 6, t.z = 30
为什么这些奇怪的输出?
答案 0 :(得分:4)
编译器为最大union
成员分配内存。在这种情况下,将分配z
的内存。由于上次分配使z
具有值1
,因此只有此值将在内存中覆盖先前的值。因此,存储在已分配内存中的最后3位为001
。访问其他3
位成员将获得结果1
。
对于z
等于2
,10
和30
,最后3
位为010
,010
和110
分别等于2
,2
和6
十进制。
答案 1 :(得分:1)
这是一个工会,这就是工会的工作方式。所有成员变量(x,y,z)都在内存中的相同地址,因此如果您更改了一个,则将其全部更改。从技术上讲,你应该只读你写的最后一个。写入z
然后阅读x
或y
是未指定的行为。
来自C-11草案规范§6.2.6.1
当一个值存储在union类型的对象的成员中时, 对象表示的字节与该对应的字节不对应 成员,但确实对应其他成员采取未指定的值。
回应编辑:
10位十进制的低三位是010
二进制,即2位小数
30位小数的低三位是110
二进制,即小数点后6位。
答案 2 :(得分:1)
在Union,我们一次可以使用一名成员。最后,您将值指定为1.Refer here.
Union将获取该成员中具有最大大小的内存。因此,从那个记忆中,所有成员都必须参与其中。最后z
将访问内存,然后将值作为一个。
所有成员都将使用相同的内存,因此前两个成员将值作为一个。
你可以这样验证。分配每个值后设为printf
。
t.x=5;
printf("t.x = %d, t.y = %d, t.z = %d", t.x, t.y, t.z);
t.y=4
printf("t.x = %d, t.y = %d, t.z = %d", t.x, t.y, t.z);
t.z=1;
printf("t.x = %d, t.y = %d, t.z = %d", t.x, t.y, t.z);
答案 3 :(得分:0)
没有错。
z的最后3位与x和y共享。
表示z = 30 t.x = 6,t.y = 6,t.z = 30
z = 0x1E = 00011110。
t.x = 110 = 6
t.y = 110 = 6