2017-07-17 46 views
-1

我在C的簡單代碼結束看如果三個相同字符數組所有端與'\0'一些字符數組不與「 0」

int main(){ 
    char a[4] = "1234"; 
    char b[4] = "1234"; 
    char c[4] = "1234"; 


    if(a[4] == '\0') 
      printf("a end with '\\0'\n"); 
    if(b[4] == '\0') 
      printf("b end with '\\0'\n"); 
    if(c[4] == '\0') 
      printf("c end with '\\0'\n"); 

    return 0; 
} 

但輸出顯示,只有數組b端終止者'\0'。這是爲什麼?我認爲所有的字符陣列都必須以'\0'結束。

輸出:

B端側與 '\ 0'

+4

你用4個字節的空格聲明瞭數組,但你試圖讀取字節5. – Ryan

+1

購買一本好的初學者書。當你完成所有練習時,你可以開始在編譯器中查找錯誤:D –

+1

「我認爲所有的char陣列都必須以'\ 0'結尾。」 - 不。所有_strings_必須以'\ 0'終止符結束,但沒有空終止符的字符數組是完全可以接受的。 –

回答

6

的主要問題是,對於像char a[4] = ....定義(大小4種元素)的陣列,使用if (a[4] ....)已經關閉並且導致undefined behavior

您想檢查a[3],因爲這是最後的有效的元素。

這就是說,在你的情況下,你沒有空間終結者!

C11,§6.7.9強調報價,

字符類型的數組,可以用字符串文字或UTF-8字符串文字進行初始化,任選在大括號。字符串文字的連續字節(包括終止空字符(如果有空間或數組未知大小)初始化數組的元素。

所以,你需要或者

  • 使用具有空間空終止
  • ,或者使用未知大小的數組,像char a[ ] = "1234";其中,數組大小的數組的大小由所提供的初始值設定的長度自動地確定(包括空終止符。)
+1

很高興看到downvote,請也添加評論,我堅持。 –

+1

我不明白,你的答案絕對正確! –

+0

謝謝!我認爲這是答案。 –

4

它是未定義的行爲因爲你必須試圖訪問數組越界。

不要指定用字符串文字初始化的字符串的邊界,因爲編譯器會自動爲整個字符串文字分配足夠的空間,包括終止空字符。

C標準(C11 - 6.7.9:第14段)表示:

字符類型的數組,可以用一個字符串被初始化 字面或UTF-8字符串文字,任選包封在括號。 字符串文字的連續字節(包括終止空字符 ,如果有空間或者數組未知大小) 初始化數組的元素。

所以,在數組initialize中沒有指定字符數組的邊界。

char a[] = "1234"; 
3

您需要在數組末尾再加一個地方來存儲\0。聲明長度爲5的陣列。

如果數組有n元素,則可以訪問數組的第n個元素。這裏的數組的大小是4字節,並且當您執行類似if(a[4] == '\0')的操作時,您試圖獲得第5個字節(因爲C中的數組索引從0開始)。