2016-05-12 167 views
-1

我有這樣的代碼初始化「的字符串」

#include<stdio.h> 
    #include<string.h> 

    int main(void) 
    { 
     size_t i; 
     char arr[5] = ""; 
     for(i = 0; i < 5; i++) 
      printf("%c ", arr[i]); 

     puts(""); 

     memset(arr, '0', 5); 
     for(i = 0; i < 5; i++) 
      printf("%c ", arr[i]); 
     return 0; 
} 

爲什麼第一個printf只打印空間,而第二打印歸零

這究竟是爲什麼?

+0

你期待第一個打印什麼?第二個呢? (真正的問題,它可能有助於他人回答他們的問題) –

+2

您正在將字符'0'替換爲空字節到內存中。只需用''0'替換''0''。 – H2O

+0

你爲什麼要這樣做?您的arr [5]僅包含「」和「\ 0」,並且您試圖最多打印五個索引。你對此有什麼期望? –

回答

-1

如果使用小於數組的字符串字面值初始化數組,則會將包括尾隨NUL的字符串複製到數組中。任何多餘的元素將根據用於初始化具有靜態存儲持續時間的變量的相同規則進行初始化,對於char0。 (q.v. C99 6.7.8/21)

第一個printf循環使用%c一次一個字符地打印陣列。 因此,當您在數組初始化爲""(相當於{'\0'})時,數組將被初始化爲全零:來自空終止符的第一個零和其他值,因爲這是具有靜態持續時間的char的默認值。由於零的十進制值表示NUL的ASCII值,因此printf會打印... NUL,它通常顯示爲空格。

對於第二個,您將數組設置爲ASCII 0,因爲您將所有值設置爲0,這是十六進制值0x30(我忘記了十進制轉換)。所以,既然你打印%c,將打印的ASCII 0

現在,如果你改變你的第一個printf打印%d,而不是%c,那麼它會打印存儲在數組中的整數值,這將全都是零。如果您更改第二個printf以打印%x,那麼它將打印一堆0x30。

閱讀%c,%d,%x和其他printf標誌之間的區別,以及它們如何表現。

+2

一個簡單的問題,爲什麼這個數組「*動態分配*」?另外,''''不是'NULL',它相當於'{'\ 0'}'''''''''是'null'而不是'NULL'。和'0x30' - >'3 * 16 == 48' !!!!! –

+1

大部分是正確的,但是應該是NUL或''\ 0'',而不是NULL。 NUL和''\ 0''代表一個ASCII 0(不要與ASCII'0'混淆,當然,因爲*是* 48)。 NULL特別是null *指針*常量,它也是0(或'(void *)0'),但在空指針常量的情況下,一旦它轉換爲指針類型,它不一定對應於地址0,但僅限於*某些不與任何非空指針進行比較的地址。所有這些都需要比空終止的字符串更迂腐,所以最好保持概念不同。 – Ray

+0

@Ray事實證明,它是'空',它是'NUL'。我像你一樣想到它。我知道我通常在大多數ascii表中看到'NUL',但根據[tag:c]標準它是'null'。 –