2010-04-10 79 views
2

我的代碼這部分工作正常:需要一些幫助理解一個奇怪ç行爲

#include <stdio.h> 

int main(){ 
    //char somestring[3] = "abc"; 
    int i, j; 
    int count = 5; 

    for((i=0) && (j=0); count > 0; i++ && j++){ 
     printf("i = %d and j = %d\n", i, j); 
     count--; 
    } 

    return 0; 
} 

預期輸出:

i : 0 and j : 0 
i : 1 and j : 1 
i : 2 and j : 2 
i : 3 and j : 3 
i : 4 and j : 4 

事情變得奇怪,當我取消對焦炭字符串聲明函數體的第一行。

#include <stdio.h> 

int main(){ 
    char somestring[3] = "abc"; 
    ... 
} 

輸出:

i : 0 and j : 4195392 
i : 1 and j : 4195393 
i : 2 and j : 4195394 
i : 3 and j : 4195395 
i : 4 and j : 4195396 

什麼是這背後的邏輯是什麼?我在Ubuntu 9.10上使用gcc 4.4.1。

+4

怎麼了i = 0 && j = 0?不應該是i = 0,j = 0嗎?類似於i ++ && j ++ – 2010-04-10 20:09:23

+5

字符串'「abc」'需要4個字節,而不是3.一個用於末尾的'\ 0'終止符。讓大小離開數組,並讓編譯器填充它。 – GManNickG 2010-04-10 20:09:41

+0

@GMan:非常好,從未見過那個。 @Mahesh:至於奇怪的語法,我只是想用布爾值來玩一下,因爲我從第一個例子中得到了一些誤判,我沒有注意j未被初始化。謝謝大家。 – 2010-04-10 20:20:29

回答

18

j永遠不會被初始化,因爲&&short-circuiting behaviour。由於(i=0)的計算結果爲false,因此(j=0)從未得到執行,因此j會得到一個隨機值。在第一個例子中,恰好爲零。

你應該說i=0, j=0達到你想要的。

i++ && j++有同樣的問題;它應該是i++, j++

而且,這樣的:

char somestring[3] = "abc"; 

是保留一個字節數太少,因爲字符串中的尾隨NULL字符的, - 你需要四個字節。但是如果你不打算修改字符串,你不需要指定字節數 - 你可以簡單地說:

char *somestring = "abc"; 

改爲。

+0

最後一行最好寫成''char somestring [] =「abc」;''因爲它仍然是一個數組並且可以修改,而您已經將'somestring'轉換爲指向不可修改區域的指針。它取決於如何使用變量。在初始化階段,你可以寫''i = j = 0''。好的答案,否則。 – 2010-04-10 20:42:16

+0

你的'somestring'是一個指針,而原來的'somestring'(mike's)是一個數組。一個不會破壞現有代碼的更好的解決方案就是定義'char somestring [] =「abc」;',這樣'sizeof'仍然會返回一個有意義的值等.. – conio 2010-04-10 21:03:39

+0

@Jonathan,@conio:好點,但我認爲邁克不太可能依賴可寫的字符串。除非我知道我需要寫信給他們,否則我會在將字符串放入只寫內存方面犯錯。無論如何,修改答案。 – RichieHindle 2010-04-10 21:47:33

1

for((i=0) && (j=0)...似乎已經不正確。
i=0已經是0的值,所以j=0的評價是不需要的,所以它被跳過。

(i++) && (j++)由於相同的原因,第一次迭代似乎也是不正確的。

2

如果您使用& &,只有第一個參數被評估,如果它是假的。 I = 0是假的,所以j沒有被置爲0。您應該使用KOMMA操作:

for((i=0) , (j=0); count > 0; i++, j++){ [...] 
0

您正在使用(i==0) && (j==0)初始化在循環兩個變量。

但是,& &的屬性是,如果第一個操作數的計算結果爲FALSE(即0),則第二個操作數永遠不會執行。所以,因爲我是0,所以j沒有初始化。在您的第一次運行中,您只是幸運它碰巧包含值0.

0

您的變量i & j未初始化。 (i=0) && (j=0)是什麼意思? 編譯器將生成一個快捷方式,並且只會分配i=0 j仍會以您描述的效果未初始化。