对于下面的程序,int打印有垃圾值但预期是初始化值50,输出中该值是否有任何特定原因?
#include <stdio.h>
#include <string.h>
union data
{
int a;
float c;
char b[10];
};
int main()
{
union data x;
x.a = 50;
strcpy(x.b,"hello");
x.c = 21.50;
printf ("x.a:= %d\n",x.a );
printf ("x.b:= %s\n",x.b );
printf ("x.c:= %f\n",x.c );
return 0;
}
输出:
x.a:= 1101791232
x.b:=
x.c:= 21.500000
更新:对于下面提到的类似程序,一切正常,我没有线索如何产生预期的结果
#include <stdio.h>
#include <string.h>
union Data
{
int i;
float f;
char str[20];
};
int main( )
{
union Data data;
data.i = 10;
printf( "data.i : %d\n", data.i);
data.f = 220.5;
printf( "data.f : %f\n", data.f);
strcpy( data.str, "C Programming");
printf( "data.str : %s\n", data.str);
return 0;
}
输出:
data.i : 10
data.f : 220.500000
data.str : C Programming
答案 0 :(得分:4)
工会的重点是设置一个值会覆盖所有其他值。
你在联盟中设置的最后一件事是c=21.50
。然后,a的值将是21.50
的位,就好像它们代表一个int。
21.50
的值为0x41ac0000
(请参阅float to hex converter),其转换为int恰好是
1101791232
(见hex to decimal converter)。
答案 1 :(得分:4)
联盟将为其所有成员使用相同的存储位置。您设置了x.a
,但是当您设置x.c
时,它也会覆盖x.a
的内存位置。
在二进制中,整数值1101791232
与浮点值22.50
相同,您可以轻松验证:
float f = 21.50;
int * iP = (int*)&f;
cout << *iP;
联合数据在内存中看起来像这样(每个X都是一个字节):
XXXXXXXXXX <- union data
XXXX <- int a
XXXX <- float c
XXXXXXXXXX <- char b[10]
因此写入a或c将覆盖另一个,加上char数组的前4个元素。
至于你的第二个例子,尝试设置三个成员,然后才输出它们的值,它们将再次变为垃圾。它只能起作用,因为你在设置之后和覆盖之前立即输出。