2014-10-03 160 views
0
#include <stdio.h> 

    int main(void) 
    { 
     double a = 1234.5f; 
     int b = 71; 
     int c = 68; 
     int d;                                
     printf("%d %d %d %d\n", a,b,c,d); 
     return 0; 
    } 

輸出:奇怪的行爲

0 1083394560 71 68 

這裏,爲什麼b爲給垃圾值,而C是給的b和d是給的C值,甚至是未初始化值?

+3

重視您的編譯器警告。不匹配的格式說明符和輸入數據會導致*未定義的行爲*。 – DCoder 2014-10-03 06:36:17

+0

** Dcoder **,我看到了編譯器的警告,我有意編寫代碼,我只是想知道它的原因是bahaviour。 – JagsVG 2014-10-03 07:59:22

回答

6

在格式說明"%d"預計int,但a的類型爲double,所以這是不確定的行爲。

可能發生的一種可能性是,編譯器將變量逐個放入堆棧。如果在您的平臺上,double的大小是8個字節並且是int的兩倍,編譯器會錯誤地假設讀取值的位置。但是,這又是一個未定義的行爲,編譯器可以自由地爲您的代碼做任何事情。

1

打印雙值格式說明應該是%f%d

printf("%f %d %d %d\n", a,b,c,d); 
0

您正在使用int的格式說明符並傳遞類型爲double的參數。

printf("%d %d %d %d\n", a,b,c,d); 

代替

printf("%f %d %d %d\n", a,b,c,d); 

當參數printf不對應的轉換符,你遇到不確定的行爲。

http://en.cppreference.com/w/cpp/io/c/fprintf

參數指定要打印的數據。如果任何參數不是相應轉換說明符所期望的類型,或者參數的格式少於格式所需的參數,則行爲是未定義的。如果參數比格式要求多,則會評估並忽略無關參數

2

行爲在此處未定義。但是如果你使用32bt機器的解釋很簡單:

你打印每個元素爲int(%d)。 Int是4個字節。 Double是8個字節,具有不同的表示形式。所有參數都通過堆棧傳遞給printf。所以前8個字節是a,然後是4個字節b,然後是4個字節c,然後是4個字節d。
printf接受const char參數並根據它從棧中檢索參數;首先%d 4個字節應該是整數,但是它找到了一半的double並打印垃圾。然後%d下一個int,但是printf在堆棧的後半部分找到double(再次垃圾)。然後%d,再次4個字節。它找到b並打印出來。然後再%d 4個字節的整數,打印c。字符串中沒有%,所以printf停止打印。