2012-07-02 50 views
4

我用下面的C代碼,它給了輸出作爲通常爲:爲什麼兩個輸出都不一樣?

9,25

#include<stdio.h> 
int PRODUCT(int x) 
{ 
    return (x*x); 
} 

void main() 
{ 
    int i = 3, j, k; 
    j = PRODUCT(i++); 
    k = PRODUCT(++i); 
    printf("%d, %d\n", j,k); 
} 

然而,當我用來代替功能宏定義如下:

#include<stdio.h> 
#define PRODUCT(x) (x*x) 

void main() 
{ 
    int i = 3, j, k; 
    j = PRODUCT(i++); 
    k = PRODUCT(++i); 
    printf("%d, %d\n", j,k); 
} 

輸出是

9,49

我試着查看使用cpp filename.c編譯代碼和主要的擴張是這樣的:

void main() 
{ 
    int i = 3, j, k; 
    j = (i++*i++); 
    k = (++i*++i); 
    printf("%d, %d\n", j,k); 
} 

我不unserstand爲什麼增值業務正在做的兩倍,而使用宏。 我正在學習C,我無法弄清楚原因。預先感謝任何幫助!

+0

其良好的自我學習,但其預定ü[R以下...? –

+4

OP的問題不在於操作的順序。這是關於宏觀擴張。 – ArjunShankar

+1

不要將宏看作函數調用 - 將其視爲通過複製/粘貼進行擴展。 –

回答

7

宏在編譯之前會逐字重寫源程序。如您所示,您的代碼是:

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

請參閱每行中的雙重++?它每次增加i兩次。使用函數,參數會被評估一次,所以每次增加一次i

+10

我認爲值得補充的是,這個表達式無論如何都會導致未定義的行爲。 –

1

增量操作正在進行兩次,因爲一個宏或多或少是一個文本替換,就像您發現的那樣。因此,多次使用的任何宏參數將被多次評估。

This SO answer有一些技巧可以幫助避免這個問題。

-1

這樣做是因爲當預處理器執行宏擴展時,可以認爲它就像在編譯之前進行文本替換一樣。每當它看到x時,它會將其替換爲您放置的內容。所以x - >i++++i。這就是爲什麼增量每次發生兩次。

2

在宏替換中,宏的使用是字面上的在編譯前用宏的內容替換。

我想給這可以如何去可怕的錯誤時無法正常使用不同例子。我們希望,這也顯示了我(和其他答案)的意思 '字面上取代'

您寫道:

#define PRODUCT(x) (x*x) 

如果你這樣做:

PRODUCT(a + b) 

這將成爲,對取代後:

(a + b*a + b) 

不一樣:

(a+b) * (a+b) 
0

答案就在你的最後一個例子中。

void main() 
{ 
    int i = 3, j, k; 
    j = (i++*i++); 
    k = (++i*++i); 
    printf("%d, %d\n", j,k); 
} 

看看這樣說:

i = 3, i = 3 
3 x 3 = 9 

i++ = 4 
i++ = 5 

++i = 6 
++i = 7 

7 x 7 = 49. 
0

評價我++或之後++我,我的新的價值將在這兩種情況下的相同。預增和後增的區別在於表達式中的評估結果。

i ++評估爲i的舊值,並遞增i。

++我增加i並評估爲i的新值。

在代碼中,

J =(I ++ * I ++);

表達式計算I(即)3和第一我+ + i遞增到4和第二我+ + i遞增到5

你的第一個語句的計算結果爲

舊值j = 3 * 3;

所得Ĵ值爲9

此語句之後,i的值是5

然後,

K =(++我* ++ⅰ);

第一++我遞增i到6和第二i ++在增量i到7和表達計算I(即)的新值7.

你的第二語句評估爲

k = 7 * 7;

結果k值爲49

請參考以下鏈接: http://en.wikipedia.org/wiki/Increment_and_decrement_operators

+0

但編譯器給出了12 49作爲答案。 (x)(x * x) main(){i = 3,j = 0,k = 0; j = PRODUCT(i ++); k = PRODUCT(++ i); 012fprintf(「%d%d」,j,k); } – Pran

相關問題