使用if语句输出并集

时间:2019-06-13 02:27:44

标签: c if-statement union

嘿,我在此C代码上有一个作业问题:

#include<stdio.h>

typedef union{
    char var1;
    int var2;
    float var3;
}data;

int main()
{
    data mydata;

    mydata.var1 = 'B';
    mydata.var2 = 12;

    if(mydata.var1 == 'B')
        mydata.var3 = 3.5;
    else
        mydata.var3 = 7.1;

    printf("%.1f", mydata.var3);
    return 0;
}

输出是7.1,我想知道是否有人可以解释为什么输出是7.1而不是3.5。

为您的帮助加油。

2 个答案:

答案 0 :(得分:5)

您应该知道的第一件事是,union为其所有成员分配一个公共存储空间。 我们一次只能访问一个工会成员。

在您的示例中,“ B”分配给联合成员“ mydata.var1”。内存位置名称为mydata.var1,此位置存储的值为“ B”。 然后将12分配给联合成员“ mydata.var2”。现在,内存位置名称为“ mydata.var2”,其值为12。 (联盟一次只能容纳一个成员)。 这就是在程序中调用else部分的原因。如果要打印3.5而不是7.1,则应使用struct而不是并集,因为该结构会为所有成员分别分配空间。

typedef struct{
    char var1;
    int var2;
    float var3;
}data;

int main()
{
    data mydata;

    mydata.var1 = 'B';
    mydata.var2 = 12;

    if(mydata.var1 == 'B')
        mydata.var3 = 3.5;
    else
        mydata.var3 = 7.1;

    printf("%.1f", mydata.var3);
    return 0;
}

希望这会对您有所帮助。

答案 1 :(得分:0)

  

输出为7.1,我想知道是否有人可以解释为什么   输出是7.1,而不是3.5。

联合的成员都共享相同的内存地址。设置并集的任何成员的值时,它将修改该内存地址处的值,并且由于所有成员都映射到该地址,因此当您读取该值时,它将反映最后写入的值该地址。

此行:

mydata.var1 = 'B'; 

将该内存的值设置为0x42,然后下一行:

mydata.var2 = 12;

您将该内存的值设置为12,以便在到达此处时:

if(mydata.var1 == 'B')
    mydata.var3 = 3.5;
else
    mydata.var3 = 7.1;

执行else子句,现在该内存的值设置为7.1。

这是您代码的更大问题:在char,int和float之间使用并集确实没有意义

原因相对简单:成员所需的内存大小不同。

char所需的内存为1字节,因为它是运行代码的计算机的最小可寻址单元。 int(又名带符号的int)所需的内存至少为2字节或16位,但是如今在大多数计算机上,内存为4字节或32位。由于IEEE 754单精度二进制浮点格式,大多数机器上float所需的内存为4字节或32位。成员本身可以表示的值也完全不同。签名的char通常是[-128,127]。假定为32位的有符号int为[−2,147,483,647,+2,147,483,647],而float为[1.2 * 10 ^ -38,3.4 * 10 ^ 38]。但是,至少floatint可能具有相同的大小,因此包含它们的union更有意义。

我知道这可能是教育性的练习或初学者的练习,但是该练习未能强调union的目的和正确的用法。

使用union的方式是用不同的方式解释相同的数据。

一个常见的例子是有多少个网络API将为IPv4地址定义一个联合体

union ipv4addr {
  unsigned  address;
  char      octets[4];
};

当将此信息传递给函数时,这提供了灵活性。也许一个特定的函数只关心32位值,而另一个函数只关心该32位值中的特定字节。

我建议您read this answerthis one too来详细了解union为何有用以及如何正确使用它们的更多信息。