2016-05-17 42 views
1

打印不同的试图了解工会的行为无法弄清楚为什么printf的标准输出

#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变量“temp.arr [0]”正在打印0x61,而它应该再次打印0x3?

+1

使用'“%x”'打印'unsigned long'是未定义的行为。使用匹配的说明符和参数。 – chux

回答

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

答案是

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

在我的代码片段中,printf为temp.arr [0]打印不同的值。根据我的理解,在这两种情况下,它应该打印0x3 – abhishekd

+0

http://www.tutorialspoint.com/cprogramming/c_unions.htm 给它一个阅读,它会清除你的每个关于工会的问题。此外,如果您仍然有问题发布完整的代码。 – Mazhar

+0

那是因为你试图打印struct abc而不是它的成员a。如果你会纠正它,它会显示正确的输出。此外,这不是标准做法。在你的情况下联合的答案是相同的,只是因为你使用的是几乎相同的类型,即两者都是无符号长整数。 – Mazhar

1

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

+1

我同意你的意见。即使我交换要打印的变量序列,它也会打印,因为我期待着,但问题仍然存在,为什么它会像这样发生。 – abhishekd

+0

@ user3891247 - 对我来说这看起来像一个未定义的行为 - '%x'正在等待一个无符号整数,并且当您将'temp.a'而不是'temp.a.a'传递给'struct'时, – edtheprogrammerguy

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语句相同。即 add:0x3 0x61 0x3

1

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

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

首先参数被压入堆栈。显然,第一个要推送的参数是temp.arr [0],然后temp.a被推送。所以你的堆栈将包含整个temp.a变量,即:3,'a',接着是temp.arr [0]。 printf查看格式字符串,并要求打印一个整数弹出前3个,当被要求弹出另一个int时,它弹出'a'= 0x61。

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

相关问题