嘿,我在此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。
为您的帮助加油。
答案 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]。但是,至少float
和int
可能具有相同的大小,因此包含它们的union
更有意义。
我知道这可能是教育性的练习或初学者的练习,但是该练习未能强调union
的目的和正确的用法。
使用union
的方式是用不同的方式解释相同的数据。
一个常见的例子是有多少个网络API将为IPv4地址定义一个联合体
union ipv4addr {
unsigned address;
char octets[4];
};
当将此信息传递给函数时,这提供了灵活性。也许一个特定的函数只关心32位值,而另一个函数只关心该32位值中的特定字节。
我建议您read this answer和this one too来详细了解union
为何有用以及如何正确使用它们的更多信息。