2016-02-21 161 views
2
#include <stdio.h> 

int main(void) 
{   
    double aRate[10] = { 0.0, 0.1, 0.25, 0.5, 0.5, 0.6, 0.65, 0.8, 0.82, 0.97}; 
    int nAge = 0, i = 0, nFee = 1000; 
    int a = 0; 

    printf("%d : \t%d \n", i, (int)(nFee*aRate[2])); 
    return 0; 
} 

此代碼的結果是0:250,如所預期的,但如果我省略這樣的括號,這段代碼有什麼區別?

printf("%d : \t%d \n", i, (int)nFee*aRate[2]); 

那麼結果是0:0

爲什麼

printf("%d : \t%d \n", i, (int)(nFee*aRate[2])); 

printf("%d : \t%d \n", i, (int)nFee*aRate[2]); 

不同?

是否與優先順序有關?

+2

它與UB有關,在第二種情況下,您正在讀取雙精度型的低32位。 250.000是* IEEE754 *中的* 406f400000000000 *。 –

+0

這是括號的差異。在第一次嘗試中,您將'nFree * aRate [2]'的值轉換爲int,然後將其打印出來。你的第二次嘗試是'double',那麼你不能使用'%d'來打印值 –

+1

你的編譯器不會對第二種情況發出警告嗎? – alk

回答

8

類型的(int)nFee*aRate[2]double,因爲它是一樣((int)nFee)*aRate[2]因爲operator precedencedouble的乘法結果和int晉升爲double。因此,您使用%d作爲double的格式說明符,其產生未定義的行爲。

(int)(nFee*aRate[2])的類型是int因此%d作爲格式說明符是正確的,您會得到250(0.25 * 1000)的執行結果。

1

是的,它與括號有關。 (int)綁定非常緊密,所以在第二個示例中,它將nFee轉換爲整數,這有點無意義,因爲它已經是一個整數。 *然後乘以int和double,產生double。 在第一個示例中,類型爲double的括號表達式(nFee*aRate[2])(int)轉換爲整數。

這是table of the operator precedences