2011-11-23 67 views
10

如果我寫:初始化字符數組與規模較小的字符串文字

char arr[8] = "abc"; 

有沒有在什麼arr[4]可能是任何規範?我用 Clang做了一些測試,似乎數組中剩餘的字符都設置爲空。 另外,char arr[8] = "";每個字節爲零。不知道這是否是編譯器方便,標準的行爲,純粹的巧合還是我弄錯了。


void a() 
{ 
    char arr[8] = "abc"; /* breakpoint here, line 3 */ 
    strcpy(arr, "1234567"); 
} 
int main() 
{ 
    a(); 
    a(); 
    return 0; 
} 

調試成績單:

 
Breakpoint 1, a() at str.c:3 
3   char arr[8] = "abc"; 
(gdb) s 
Current language: auto; currently minimal 
4   strcpy(arr, "1234567"); 
(gdb) p arr 
$1 = "abc\000\000\000\000" 
(gdb) c  
Continuing. 

Breakpoint 1, a() at str.c:3 
3   char arr[8] = "abc"; 
(gdb) p arr 
$2 = "1234567" 
(gdb) s 
4   strcpy(arr, "1234567"); 
(gdb) p arr 
$3 = "abc\000\000\000\000" 
+0

@Lundin - 實際上,編曲[3]設置爲空終止,所以他有權要求有關ARR [4] –

+0

@JamesCaccese似乎是一個錯字...無論如何,這一切都在我發佈的答案中解釋。 – Lundin

+0

@Lundin - 誰是錯字,你的或者是sidyll的?您的評論arr [4]之上的設置爲空終止,因爲「」爲false。 arr [3]被設置爲空終止,因爲「」,arr [4]被設置爲零,因爲它沒有被明確初始化。你的回答是正確的,但你的評論是關閉的,它會混淆這個問題。既然你不能編輯評論,你應該刪除它。 –

回答

16

這是標準的行爲。

arr[3]被初始化爲0,因爲終止0是字符串文字的一部分。

所有其餘元件都被初始化爲0太 - ISO/IEC 9899:1999,6.7.8。,21:

如果在一個大括號內的列表更少初始化值多於一個集合體的元件或部件 ,或用於初始化數組的已知大小的數組的字符串字符數少於數組中的元素,聚合的其餘部分應爲 隱含地初始化與具有靜態存儲持續時間的對象相同。

而且char靜態存儲對象初始化爲0

+0

感謝您的標準參考。 – sidyll

+0

...但這只是爲大括號包含的列表定義的,這不是被質疑的代碼使用的,不是? – kusma

+1

不,「字符串文字...中的字符數......」或更少。 –

3

這是標準的行爲。如果在聲明中初始化了數組的任何前綴,則未明確初始化的數組中的每個元素都被初始化爲默認值('\0',對於char)。通過a[9]

int a[10] = {1}; 

零出a[1]:這也適用於其他類型。

0

根據標準,超出了規定的將被設爲零/零的所有指標。在this SO post

7
char arr[8] = "abc"; 

更多信息是完全等效於

char arr[8] = {'a', 'b', 'c', '\0'}; 

ISO C 6.7.8§21指出

如果在一支柱封閉更少初始化列表比 是元素或聚合的成員,或者更少的字符在 用於初始化已知大小的數組的字符串常量,其中 是數組中的元素,聚合的其餘部分應爲 ,隱含地初始化爲具有靜態存儲的持續時間爲 的對象。

用簡單的英語,這意味着在你的數組結束的所有值將被設置爲0,所以標準保證你的代碼等同於:

char arr[8] = {'a', 'b', 'c', '\0', 0, 0, 0, 0}; 

現在當然,「\ 0'恰好也是零值。

此規則適用於所有數組,而不僅限於字符串。同樣,初始化一個結構體時也是如此,但只是明確地設置了一些結構體(6.7.8§18)。


這就是爲什麼可以像

char arr[8] = ""; 

在這個例子中寫的代碼,所述陣列的所述第一元件被初始化顯式地以「\ 0」,而其餘條目的隱含零。編譯器把這

char arr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 
+0

具有靜態存儲時間的對象是什麼意思?我無法理解這部分規範。你能解釋一下嗎? –