2010-04-25 95 views
1
#include<stdio.h> 

#define a(x) (x * x) 

int main() 
{ 
    int i = 3, j; 

    j = a(i + 1); 
    printf("%d", j); 

    return 0; 
} 

我想知道爲什麼程序沒有給出輸出16。 (我得到的輸出7。)C程序輸出


我明白了點非常多,但如果程序是這樣的:

#include<stdio.h> 

#define a(x) (x * x) 

int main() 
{ 
    int i = 3, j, k; 

    j = a(i++); 
    k = a(++i); 
    printf("%d\n%d", j, k); 

    return 0; 
} 

那麼爲什麼上面的程序給出以下的輸出:

9 
49 
+1

@Paul在這種特殊情況下,如果它是作業的上下文,有什麼關係?也許是這樣,也許OP已經很好地將問題簡化成了一個最小化的程序,它展示了令他們困惑的行爲。我不是說這是一個好問題,我只是說(這一次),這不是一個壞問題,因爲它可能是也可能不是家庭作業。除非作業是「爲什麼這個程序打印7?」,在這種情況下,作業是一個不好的問題。 – 2010-04-25 08:21:06

+1

@帕斯卡爾:主要原因在於它是作業,所以最好提供有用的提示或一般指導而不是完整的解決方案,以便幫助學生學習一些東西。如果它不是家庭作業,那麼顯然一個完整的解決方案是適當的。 – 2010-04-25 09:02:39

+0

@保羅好點。 – 2010-04-25 09:04:40

回答

7

因爲你犯了一個糟糕的宏:

a(i + 1) 

擴展到

i + 1 * i + 1 

這相當於

i + i + 1 

2 * i + 1 

使用括號:

#define a(x) ((x) * (x)) 

然後你會得到它擴大到

(i + 1) * (i + 1) 

這你想要做什麼。

+0

感謝好友.... – sandy101 2010-04-25 08:19:09

+0

你能告訴我什麼是新的宏的問題.... – sandy101 2010-04-25 08:32:55

+2

@ sandy101:編輯代碼的問題是,它改變'我'兩次,沒有介入序列點。這是調用未定義的行爲。 (或者在這種情況下是_unnspecified_無論如何,結果可能會因不同編譯器,月相和不同而有所不同) – sbi 2010-04-25 08:36:29

2

閱讀C運算符的優先順序,並考慮在這種情況下宏a擴展到的內容。

2

預處理線後

j=a(i+1); 

將是:

j=(i+1*i+1); 

其中當評價i=3會給j=7

j=(3+1*3+1); 

爲了讓你需要定義宏作爲期望的結果:

#define a(x) ((x)*(x)) 

導致:

j=((i+1)*(i+1)); 

,並給出結果16i=3

+0

你能告訴我新的宏的問題 – sandy101 2010-04-25 08:33:53

1

因爲a(i+1)被預處理成(i+1*i+1)

和3 + 3 + 1 = 7

您可能需要使用括號周圍x

編輯:哇,這是多餘的還是什麼。 :/

0

因爲你的宏是錯的。顯然它可以工作,但錯誤更微妙(不完全,但仍然),因爲擴展的代碼有一些問題,因爲不遵循預期的操作順序。

j = a(i+1)將展開爲j = i + 1 * i + 17

如果你想解決您的問題重新定義宏爲:

#define a(x) ((x)*(x)) 

這是很好的,你現在已經遇到了這個問題,而不是以後。這些類型的錯誤,有時很難調試,但現在你會知道如何編寫「專業」宏:)。

0

因爲(i + 1)被預處理成(i + 1 * i + 1)。

和3 + 3 + 1 = 7

您可能需要使用括號x周圍。

編輯:哇,這是多餘的還是什麼。 :/

鏈接|標記