无法弄清楚为什么printf打印在标准输出上有所不同

时间:2016-05-17 12:41:53

标签: c

试图理解联盟的行为

#include <stdio.h>
struct abc{
        unsigned long a;
        unsigned long b;
//      unsigned long c;
};

union temp
{
        struct abc a;
        unsigned long arr[2048];
};

int main()
{
        union temp temp;
        temp.a.a = 3;
        temp.a.b = 'a';
//      temp.a.c = 2;
        printf("add : 0x%x 0x%x 0x%x \n", temp.a.a, temp.a.b, temp.arr[0]);
        printf("add : 0x%x 0x%x \n",temp.a,temp.arr[0]);
        return 0;
}

Output:
add : 0x3 0x61 0x3 
add : 0x3 0x61 

问题:为什么在第二个printf变量&#34; temp.arr [0]&#34;正在打印0x61,而它应该再次打印0x3?

4 个答案:

答案 0 :(得分:1)

在你的第二个printf temp.a这不是你想要的。 如果您将其更改为temp.a.a,它将按预期工作。

答案 1 :(得分:1)

程序在第二个printf上做了什么?

    printf("add : 0x%x 0x%x \n",temp.a,temp.arr[0]);

首先将参数推送到堆栈上。显然,要推送的第一个参数是temp.arr [0],然后推送temp.a。所以你的堆栈将包含整个temp.a变量,即:3,&#39; a&#39;然后是temp.arr [0]。 Printf查看格式字符串,并且当要求打印一个整数时弹出前3个,当被要求弹出另一个int时,弹出&#39; a&#39; = 0x61。

要获得正确的输出,只需将temp.a.a作为参数。

答案 2 :(得分:0)

您可以定义具有许多成员的联合,但在任何给定时间只能有一个成员包含值。

在联合中,您必须存储在任何数据成员中,然后使用相同的数据成员访问它。如果要从不同的数据成员访问,则在使用该成员访问之前存储它。请参阅下面的示例。

#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;
}

Ans将是

data.i : 10
data.f : 220.500000
data.str : C Programming

答案 3 :(得分:0)

在下面的行中,temp.a.a和temp.a.b使用了前两个格式说明符,因为您传递的是整个结构变量而不是单个成员。

 printf("add : 0x%x 0x%x \n",temp.a,temp.arr[0]);

因此没有为temp.arr [0]留下格式说明符来将其值打印到控制台。您应该提供第三个格式说明符或将temp.a更改为temp.a.a

 printf("add : 0x%x 0x%x 0x%x \n",temp.a,temp.arr[0]);

这将打印与第一个print语句相同的输出。即 添加:0x3 0x61 0x3

相关问题