C struct打印,解码这段代码?

时间:2012-10-31 06:24:50

标签: c memory-address

我正在学习考试,我正在尝试解决一些练习问题。我一直在努力这一段时间......但是无法理解。请看一下代码片段:

 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)会打印出什么?我知道我们应该期待数字....但我不知道他们从哪里得到数字....没有输出。

任何解释都将不胜感激。谢谢!

3 个答案:

答案 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如下:

  • 最低有效字节(LSB)0x00存储在最低字节地址,假设此地址为0x123456
  • 0x80存储在下一个较高的地址,即0x1234570x20存储在地址0x123458
  • 最重要的字节(MSB)0xC0存储在0x123459

看起来像这样

Addresses       ->  0x123459    0x123458    0x123457    0x123456
Binary Values   ->  11000000    00100000    10000000    00000000
Hex Values      ->  0xC0        0x20        0x80        0x00

这里的关键点 union的所有成员都从相同的字节地址开始存储。因此当您访问testout.x时,x的LSB为0x000x123456的值为0x80,MSB为0x123457,即下一个更高地址0x8000的值,我们将2字节表示为-32768,等于十进制{{1}}。