2014-10-09 67 views
4

最近我一直在學習所有關於C語言,並且很困惑,使用何時使用char a []通過char p *,反之亦然?

char a[]; 

char *p; 

,當涉及到字符串操作。例如,我可以像這樣的字符串分配給他們兩個:

char a[] = "Hello World!"; 
char *p = "Hello World!"; 

,並查看/訪問他們都喜歡:

printf("%s\n", a); 
printf("%s\n", p); 

和操縱他們都喜歡:

printf("%c\n", &a[6]); 
printf("%c\n", &p[6]); 

所以,我錯過了什麼?

+3

首先,使編譯器警告 – 2014-10-09 13:33:45

+0

使用無論你想...只是語法糖en.wikipedia.org/wiki/Syntactic_sugar – zambotn 2014-10-09 13:34:11

+0

你錯過了最重要的一點是在內存釋放,多久你希望你的對象a住在你的節目中。 – Martin 2014-10-09 13:34:33

回答

9
char a[] = "Hello World!"; 

這種分配修改陣列只是大足以容納字符串字面量(包括終止NUL字符)。然後它用字符串文字的內容初始化數組。如果它是一個局部變量,那麼這意味着它在運行時會執行memcpy,每次創建局部變量時都會如此。

當您需要修改字符串時使用此選項,但不需要將其設置得更大。

此外,如果您有char *ap = a;,那麼當a超出範圍時ap將成爲懸掛指針。或者,同樣的事情,當a對於那個函數是局部的時候,你不能做return a;,因爲返回值將懸掛指針到現在被銷燬的那個函數的局部變量。

請注意,恰好使用這一點很少見。通常情況下,你不需要一個數組與字符串文字的內容。這是更爲常見的有類似:

char buf[100]; // contents are undefined 
snprintf(buf, sizeof buf, "%s/%s.%d", pathString, nameString, counter); 

char *p = "Hello World!"; 

這定義指針,並初始化它指向字符串文字。需要注意的是字符串字面量(正常)不可寫入的,所以你真的應該這個:

const char *p = "Hello World!"; 

使用此當你需要指向不可修改的字符串。

與上面a,如果你有const char *p2 = p;或做return p;,這些都很好,因爲指針指向字符串中程序的常量數據的文字,有效期爲程序的整個執行。


字符串文字本身的文字withing雙引號,構成該字符串的實際字節,在編譯時創建並通常被放置與該應用程序內的其他常量數據。然後在代碼中字符串文字具體指這個常量數據blob的地址。

+2

一個澄清可能會有所幫助(或者可能會造成混淆)。無論哪種情況,編譯器都會創建一個字符串文字並將其添加到可執行文件中。在數組的情況下,數組在運行時初始化(例如,您引用的'memcpy'在運行時發生,而字符串的創建則在編譯時發生。)指針也在運行時初始化,但是初始化不會複製字符串 - 只是它的地址。 – 2014-10-09 13:38:31

+0

@WilliamPursell根據你的建議編輯了一下 – hyde 2014-10-09 13:58:28

+0

因此,如果我想將它與PHP(比較熟悉)進行比較,那我認爲'''char * p;''類似於PHP常量和'''char a [];'''是一個普通的PHP變量? – 2014-10-09 15:54:48

2

char *字符串是隻讀的。字符串可以是char[],但不能修改。

char *str = "hello"; str[0] = 't'; // This is an illegal operation

char str[] = "hello"; str[0] = 't'; // Legal, string becomes tello

+2

「'char *'字符串是隻讀的」只有當你設置它們等於一個字符串文字(正如他在例子中所做的那樣)。否則它們是完全可寫的。 – wolfPack88 2014-10-09 13:38:29

+1

char *'從不是隻讀的,因爲它不是'const char const *',但可以指向'const char',它當然是只讀的。一如既往:指定存儲類別使得全部清除 – 2014-10-09 14:13:27

相關問題