2012-05-06 41 views
1
#include <stdio.h> 
int inc1(int x) { return x++; } 
int inc2(int *x) { return (*x)++; } 

int 
main(void) 
{ 
    int a; 
    a = 3; 
    printf("%d\n", inc1(a) + a); 
    printf("%d\n", inc2(a) + a); 
    return 0; 
} 

我正在通過過去的論文工作,其中一個問題是跟蹤第6和第9行之間所做的更改。我理解指針(指向內存位置),但如果有人可以跟我說話通過對整個這段代碼的改變,這將是非常棒的。C中指針和變量之間的區別?

+4

指針和變量之間的區別是,可能應該是'INC2(一)''上的main'最後一行? – zwol

+4

此代碼不能編譯。 –

+1

nope,我已經完全按照它在論文中的描述寫下了它。 – deanhet

回答

4

我會解釋這幾乎相同的代碼不包含在您的文章中的錯誤:

#include <stdio.h> 

int inc1(int x) { return x++; } 
int inc2(int *x) { return (*x)++; } 

int main(void) { 
    int a; 
    a = 3; 
    printf("%d\n", inc1(a) + a); 
    printf("%d\n", inc2(&a) + a); 
    return 0; 
} 

a初始化爲3,則一個的值傳遞給inc1(),它返回它並使用後遞增加1。這意味着返回的實際值仍然爲3.

接下來,的地址傳遞給inc2()。這意味着x中的值發生了什麼。同樣,後增爲用,還等什麼inc2()回報率是3,但通話結束後,a是4

然而,編譯器可以自由地計算表達式,如ainc2(&a),在序列點之間的任何順序。這意味着,對inc2(&a) + a右側的a可以是3或4(取決於a是否之前或int2(&a)後評價,所以程序可以輸出或者或。

+3

它與指針沒有任何關係,但是這個程序可能合法(即兩個選項都沒有指出編譯器中的錯誤)打印「6 7」或「6 8」。 (你知道爲什麼嗎?) – zwol

+0

@Zack如果在'inc2'之前評估了'a'(這是允許的嗎?),我可以看到'6 6',但我不確定'6 8'會發生什麼。說明? –

+1

它可以打印67或66. +表達式的評估順序未定義。 (只有短路東西纔會被評估)@Goldilocks:但'a'已經被評估過了。 – wildplasser

0

線調用inc1()將打印'6'(3 + 3)[前3是來自inc1(),由於後增加運算符增加的值不會返回]。此外,由於inc1()由值調用, a'不受功能影響

現在,如果在本文中調用inc2()的語句如下:

printf("%d\n", inc2(a) + a); 

那麼你的代碼將編譯(希望你能在「A」存儲的存儲位置),但它取決於值(如果「A = 3」)在運行時你會得到分段錯誤,因爲你正試圖解引用你的程序不應該訪問的內存位置3。

或者,如果語句如下:

printf("%d\n", inc2(&a) + a); 

然後INC2()將遞增的「a」到指針(地址)的值,但將返回的「一」舊值(3)仍由於它使用後增量運算符,但它會反過來增加'a',任何後續訪問'a'都會得到新的值。下一個'a'的值爲'4',因爲評估是從左到右完成的,因此它將打印7(3 + 4)。

我希望澄清了C.

相關問題