2016-05-17 39 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作爲參數。

相關問題