【问题标题】:Why garbage value in union integer?为什么联合整数中的垃圾值?
【发布时间】:2015-04-19 16:58:25
【问题描述】:

对于下面的程序 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

【问题讨论】:

  • 此时Union中只能存储一个值。
  • 你的意思是使用struct而不是union
  • @ligoore 你可以为问题中的第二个程序输入你的 cmets 吗?
  • 第二个例子是正确的。您只能访问当前设置的值。所有值都存储在同一个内存块中。

标签: c


【解决方案1】:

联合将对其所有成员使用相同的存储位置。您设置了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 个元素。

对于您的第二个示例,尝试设置三个成员,然后再输出它们的值,它们将再次成为垃圾。它之所以有效,是因为您在设置之后和覆盖之前立即输出。

【讨论】:

  • 知道了。是的,如果最后全部打印,就会发生转换。
【解决方案2】:

联合的全部意义在于设置一个值会覆盖所有其他值。

您在联合中设置的最后一件事是c=21.50。然后 a 的值将是 21.50 的位,就好像它们代表一个 int。

21.50 的值是 0x41ac0000(请参阅float to hex converter),它转换为 int 恰好是 1101791232(见hex to decimal converter)。

【讨论】:

    猜你喜欢
    • 2017-11-27
    • 2020-09-18
    • 2014-06-06
    • 2016-03-02
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多