我正在学习考试,我正在尝试解决一些练习问题。我一直在努力这一段时间......但是无法理解。请看一下代码片段:
union {
int i;
short x;
unsigned short u;
float f;
} testout;
testout.i=0xC0208000;
在我提出问题之前,有人可以向我解释上述代码的工作原理吗?我的猜测是testout.i=0xC0208000
放入int,short,unsigned short或float,并将结果放入该地址。 (?)
问题是如果我们写printf("%d", testout.x)
会打印出什么?我知道我们应该期待数字....但我不知道他们从哪里得到数字....没有输出。
任何解释都将不胜感激。谢谢!
答案 0 :(得分:3)
定义联合时,将为联合中的最大类型分配内存。在您的情况下,它是float
。当你说testout.i=0xC0208000;
0xC0208000存储在分配的内存中时。当你尝试打印testout.x
时,printf将在union内存中检索4个字节(假设4字节int)并将其打印为整数。您可以阅读工会here
答案 1 :(得分:0)
在联合中,所有成员都在相同的内存地址中。在内存中它只是bit'n'bytes。每种类型都以不同的方式解释这些位,这也取决于CPU。
通常使用联合,你在联合之外有额外的变量,它被设置为告诉分配给联盟成员的类型,因此代码知道回来采用相同的类型(注意:你必须使用ifs或switch显式编码) )。这通常包含在
之类的内容中struct Variant {
int type;
union { int number; const char *text; };
}
Union也是一种干净的方法,例如通过存储浮点数并使无符号脱离联合来检查浮点数的原始位。
您的printf实际上与
相同printf("%d\n", (short)((int)0xC0208000));
注意:上面“有效相同”仅适用于整数字段,对于浮点数进行实际值转换,使用union字段仍然只取位。
答案 2 :(得分:0)
在Little Endian机器(x86,x64等)上,答案是-32768
。
以下是Little Endian答案的原因,您应该从中找出Big Endian的原因。
union
将其所有成员存储在同一内存位置,其大小由其最大大小的成员确定。假设sizeof(int)
为4个字节且sizeof(float)
为4个字节,这意味着testout
成员存储在4个字节的位置。既然我们有Little Endian架构,那么testout.i = 0xC0208000
语句在内存中存储i
如下:
0x00
存储在最低字节地址,假设此地址为0x123456
。0x80
存储在下一个较高的地址,即0x123457
,0x20
存储在地址0x123458
。0xC0
存储在0x123459
。看起来像这样
Addresses -> 0x123459 0x123458 0x123457 0x123456
Binary Values -> 11000000 00100000 10000000 00000000
Hex Values -> 0xC0 0x20 0x80 0x00
这里的关键点是 union
的所有成员都从相同的字节地址开始存储。因此当您访问testout.x
时,x
的LSB为0x00
,0x123456
的值为0x80
,MSB为0x123457
,即下一个更高地址0x8000
的值,我们将2字节表示为-32768
,等于十进制{{1}}。