2013-03-27 53 views
0

我無法理解這段代碼。我不明白爲什麼sx,sa,sy的值是相同的,這意味着42。我知道它必須對指針做些什麼。如果有人可以解釋爲什麼值相同?

#include <stdio.h> 

static int sx; 
static int sa[100]; 
static int sy; 

int main() { 
    int *p; 
    for(p=&sx; p <=&sx+200; p++) 
    { 
     *p = 42; 
    } 
    printf("sx = \t%i\n",sx); 
    printf("sa[0] = \t%i\n",sa[0]); 
    printf("sa[109] = \t%i\n",sa[109]); 
    printf("sy = \t%i\n",sy); 

    getchar(); 
} 
+2

它被稱爲「未定義的行爲」。你很幸運,你沒有打開一個黑洞並殺死我們所有人。 – Cornstalks 2013-03-27 04:39:04

+0

爲了迴應現在刪除的評論,爲什麼它沒有給出錯誤:「未定義的行爲」意味着行爲是從字面上未定義的。也就是說,*由於所做的事情*會發生任何事情。如果C標準要求給出錯誤,那麼行爲將被定義爲*(not * un * defined)(它只會被定義爲給你一個錯誤)。未定義的行爲完全沒有定義當你做某事時會發生什麼。 – Cornstalks 2013-03-27 04:46:00

回答

2

你正在寫超過變量的範圍,所以它是未定義的行爲

for(p=&sx; p <=&sx+200; p++) 
{ 
    *p = 42; 
} 

該代碼段超出分配給sx的內存並導致未定義的行爲。注p是指向sx的指針,而sx只是一個整數而不是數組。該循環迭代並寫入超出分配給sx的內存。

未定義行爲不一定會導致程序崩潰,它只是意味着程序的輸出可以是任何東西。它可能看似工作或不顯示或顯示一些奇怪的結果,簡而言之,任何結果都是可能的。

+0

所以它不應該給出錯誤而不是給出正確的值? – Mani 2013-03-27 04:40:51

+0

@Mani:*未定義行爲*表示行爲未定義。它可能會給你一個錯誤,它可能不會。這完全沒有定義。 – Cornstalks 2013-03-27 04:41:29

+0

謝謝你我明白了! – Mani 2013-03-27 04:44:32

5

此代碼,您的靜態數據的內存佈局看起來像這樣的假設:

+----+-----------------------------+----+ 
| sx | sa .....     | sy | 
+----+-----------------------------+----+ 

因此,陣列「界」,由sxsy,使使用他們的地址作爲邊界包括所有sa的元素。在這種情況下,它使用&sx + 200,它可能覆蓋sa,然後再多一點(記住,指針算術是縮放的)。

嚴格來說,這是未定義的行爲,你不能依賴於此。但是,這就是爲什麼它適合你。

0

首先,你的覆蓋內存在那裏。所以,如果你想用三分球發揮改變這種:

for(p=&sx; p <=&sx+200; p++) 

到:

for(p=&sx; p <=&sy; p++) 

現在,你在做什麼有覆蓋sxsy之間的每個存儲位置值42。並且發生sx,sysa的每個元素都在那些存儲器地址中。

而且,BTW代碼對內存佈置做出了假設,這在每臺計算機中可能都不是這樣。

+0

僅僅執行'&sx <=&sy'也是未定義的行爲。驚喜。 – 2013-03-27 05:42:36