2015-11-17 91 views
0

在一些地方,命令printf("%f\n", 5/2);是不同的。 爲什麼,以及如何解決這個問題?爲什麼使用printf的輸出不同?

int main() 
{ 
    int a = 65; 
    char c = (char)a; 
    int m = 3.0/2; 
    printf("%c\n", c);    // output: A 
    printf("%f\n", (float)a);  // output: 65.000 
    printf("%f\n", 5/2);   // output: 65.000 
    system("PAUSE"); 
    printf("%f\n", 5.0/2);  // output: 2.5000 
    printf("%f\n", 5/2.0);  // output: 2.5000 
    printf("%f\n", (float)5/2); // output: 2.5000 
    printf("%f\n", 5/2);   // output: 2.5000 
    system("PAUSE"); 
    printf("%f\n", 5/(float)2); // output: 2.5000 
    printf("%f\n", (float)(5/2)); // output: 2.0000 
    printf("%f\n", 5/2);   // output: 2.0000 
    system("PAUSE"); 
    printf("%f\n", 5.0/2);  // output: 2.5000 
    printf("%d\n", m);    // output: 1 
    printf("%f\n", 5/2);   // output: 2.5000 


    system("PAUSE"); 
    return(0); 
} 
+2

你到底想要「修復」什麼? – 101010

+0

我想「固定」到它的實際輸出,而不是任何其他輸出...... –

+2

'5/2' - >'2'。它是整數數學。這就是C的整數工作方式。 – chux

回答

3

5/2給出一個整數作爲結果,而不是一個浮點數,和printf不能自動轉換爲另一種類型,作爲分配可以。如果使用GCC進行編譯,會得到警告「format'%f'需要類型'double'的參數,但參數2的類型爲'int'」。 (是的,double。在發送到像printf這樣的可變參數函數之前,所有的浮點數都會轉換爲雙精度值。)

您發送的參數(整數)與格式字符串%f不匹配。根據C標準,這將導致它所謂的「未定義的行爲」,這意味着任何事情都可能發生。但是,通常會發生,這是因爲printf會查看浮點數所在的內存位置,如果您已經發送了一個作爲參數,並將其中找到的任何內容解釋爲浮點數,點數。由於典型的int是32位,並且典型的double是64位,所以printf將採取一些其他數據,可能是先前調用的數字65!

要解決該問題,發送一個浮點數對printf,例如使用5.0/2,或(double)5/2代替2.55/2

+0

確定,但看起來它輸出的是與 之前相同的輸出,我想了解原因。 –

+1

@RuslanVer可能是一個浮點型參數(它首先被提升爲一個double)被傳入一個浮點寄存器,或者在堆棧中的不同位置,這就是printf希望找到你傳遞給它的參數的地方,而不是無論int參數傳遞給printf。因此,當你對它撒謊時,printf會提取一個剩餘的浮點值,並告訴它當你實際傳入一個int時,你正在傳入一個浮點數。由於代碼產生未定義的行爲,因此它可能不是確定性的或可再生的。如果你傳遞5/2(一個int),你必須使用「%d」。不是「%f」 – nos

相關問題