2013-10-19 61 views
1

/*我觀察到的是:爲什麼這個數組是分配給非指定的數組?

  1. 當我給串像 「AB」 以B(陣列)
    則輸出是: 「AB」, 「幫助」, 「哥們」
  2. 當我給「ABC」
    然後輸出爲: 「ABC」 「」 「哥們」
  3. 如果我給 「ABCD」 然後輸出爲: 「ABC」, 「d」, 「哥們」

    等*/

    #include<stdio.h> 
        main() 
        { 
         char a[5]="help",b[3],c[10]="dude"; 
        scanf("%s",b); 
        printf("\t%s",b); 
        printf("\t%s",a); 
        printf("\t%s",c); 
        } 
    
        /* what i dont get is : 
        Here iam gaving a string to b(array), why, if the string has more than the 
        required no. of charecters, its printing those charecters in other arrays 
        (though i had not assiged scanf to other arrays)? 
    
+1

這是未定義的行爲。 – chris

+0

什麼!我沒有得到它? – Srinadh

+0

'scanf(「%s」,&b);'你不需要'&',''b'已經是一個指針了 –

回答

1

你的陣列被放置在存儲器中按以下順序

C [10],B [3],A [5]

因此,如果數組b將包含更多的字符比它可以容納然後一些其字符將重疊數組a, 考慮這兩個數組b和a,因爲它們在內存中

b [0] b [1] b [2] a [0] a [1] a [2] a [3] a [4]

當你在b中加入「abc」時,你得到了

b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4] 
'a' 'b' 'c' '\0' 'e' 'l' 'p' '\0' 

所以在執行語句

printf("\t%s",b); 
printf("\t%s",a); 

輸出

"abc" "" 

因爲[0]包含 '\ 0'

當你輸入 「ABCD」 你有

b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4] 
'a' 'b' 'c' 'd' '\0' 'l' 'p' '\0' 

並且輸出是

"abcd" "d" 

因爲一個[0]包含 'd' 和[1]包含 '\ 0'

+0

瞭解,謝謝老兄:) – Srinadh

0

b[3]是一個由3個字符組成的數組。然而字符串abc由4個字符組成,最後一個字符是\0,表示字符串結束。所以,如果你想是能夠存儲abc,你需要的時候你給abc輸入您的陣列b被填充到至少聲明的4個字符數組,而不是3

+0

好的,我編輯了那個&b;但是我想知道的是一個地址,b,c是不同的,當我調用printf與數組的關係時,它應該打印什麼數據存儲在那裏,而不是它的打印數據,我給b,離開調用另一個數組說,那是我的問題爲什麼它發生那樣的 – Srinadh

0

(因爲它只有3個名額)並沒有空間留下\0字符。因此,當您嘗試將其打印出來作爲字符串..它溢出並導致錯誤

對於可打印的字符串,它必須是以下格式: stringtext\0但是當您用完所有陣列中的空間b你沒有留下任何空間\0,當您打印出來的結果,存在誤差

而且這種說法是錯誤的代碼:

scanf("%s",&b); 

它應該是:

scanf("%s",b); 
+0

好的,我編輯過&b;但我想知道的是a,b,c的地址是不同的,當我調用printf與數組的關係時,它應該打印出什麼數據存儲在那裏,而不是它的打印數據,我給b,離開打電話給其他陣列說一個,這就是我的問題爲什麼它發生的那樣 – Srinadh

+0

@Srinadh ..我不明白你的問題 – sukhvir

0

將「abc」放入b[3]時,它將超出數組的末尾。 abc字符串是四個字節,因爲它在末尾有一個nul終止符。

由於它是未定義的行爲,任何事情都可以在技術上發生,但實際發生的事情是,字符串末尾的nul將覆蓋內存中下一個變量的第一個字符,使其成爲空字符串。

迅速的解決辦法是,以確保您的字符數組足夠大來存儲所有字符加上終結者:

char b[4] = "abc"; 

或者讓編譯器處理它爲這個特殊的簡單情況:

char b[] = "abc"; 
+0

好的,我編輯過&b;但我想知道的是a,b,c的地址是不同的,當我調用printf與數組的關係時,它應該打印出什麼數據存儲在那裏,而不是它的打印數據,我給b,離開打電話給其他陣列說一個,這就是我的問題,爲什麼它發生這樣的 – Srinadh

+0

@Srinadh,我沒有提到運營商的地址。你所需要做的就是確保你的數組足夠大。 – paxdiablo

5

請記住,C中的字符串需要空終止符。如果沒有空間,打印將繼續「到下一個節點」。這裏是你的記憶力如何看待初始化:

h e l p \0 \0 \0 \0 d u d e \0 
^   ^  ^
a    b   c 

當您在一個字符串ab中的位置由b指出閱讀:

h e l p \0 a b \0 d u d e \0 
^   ^ ^
a    b  c 

,一切都很好。但abc給出:

h e l p \0 a b c \0 u d e \0 
^   ^ ^
a    b  c 

,並在打印b你會得到abc;打印c將不會給你任何東西(第一個字符是'\0')。

最後,隨着abcd輸入你

h e l p \0 a b c d \0 d e \0 
^   ^ ^
a    b  c 

和印刷c將導致"d" - 完全按照你所看到的。

事實上,事物存儲在內存中的順序並不是「定義」的,儘管通常編譯器會做類似於上面的事情。所以,雖然你知道你不能寫出不屬於你的記憶,但你不能確定當你這樣做時會發生什麼(如你的情況)。這就是爲什麼它被稱爲「未定義的行爲」。你不能依靠其他編譯器給你相同的結果 - 甚至相同的編譯器給你相同的結果...

有意義嗎?

解決方案當然是爲b分配更多空間。這將導致更多'\0'bc之間,並且沒有被覆蓋。

編輯 - 我只是意識到,這似乎在其中存儲ba順序是倒着從我剛纔怎麼描述它 - 因爲它是a,不c被覆蓋掉了。這表明編譯器可以隨心所欲地命令,並且在我寫出詳細的答案時我應該戴上眼鏡。但是原理完全一樣 - 所以我會「把剩下的作爲學生的練習」。

+0

+1人非常精細。 –

+0

所以你說的是一些編譯器並排排列數組,如果我給出額外的數據,那麼它會覆蓋它的相鄰日期,對吧? – Srinadh

+0

@Srinadh - 是的,這正是我所說的。 – Floris

0

所以真正發生的是你正在超出數組的末尾並覆蓋內存。

當您提供'ab'作爲b的輸入時,它的工作原理是因爲b足夠大以存儲'ab'和\0,正如其他人所提及的。

當您提供「ABC」輸入,b沒有足夠的空間分配給商店ABC和null所以只商店「ABC」,然後將空似乎得到寫入a陣列的第一個字節,這意味着它只是一個空字符串......或者它不是,這是未定義的部分。誰知道存儲在陣列外部的是什麼。只是碰巧你可能會很幸運,因爲你定義的數組很可能在連續的內存中。

當您提供'abcd'作爲輸入時,dnull被寫入a陣列。

很多時候在不太簡單的程序中,你會得到一個像這樣的編程錯誤的SEGV。

0

這只是未定義行爲的情況之一。 b[3]可以存儲三個字符的字符串(包括\0),但是當您的輸入爲abc時,它是四個字符的字符串,並且不能將其存儲在數組b中。你會得到任何東西。

相關問題