为什么x和y的值是1

时间:2015-03-17 09:23:40

标签: c

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 

为什么这些奇怪的输出?

4 个答案:

答案 0 :(得分:4)

编译器为最大union成员分配内存。在这种情况下,将分配z的内存。由于上次分配使z具有值1,因此只有此值将在内存中覆盖先前的值。因此,存储在已分配内存中的最后3位为001。访问其他3位成员将获得结果1

对于z等于21030,最后3位为010010110分别等于226十进制。

答案 1 :(得分:1)

这是一个工会,这就是工会的工作方式。所有成员变量(x,y,z)都在内存中的相同地址,因此如果您更改了一个,则将其全部更改。从技术上讲,你应该只读你写的最后一个。写入z然后阅读xy是未指定的行为。

来自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