2011-07-23 54 views
55

有人可以解釋爲什麼這工作與指針:爲什麼可以將字符串分配給char *指針,而不是char []數組?

char * str1; 

str1 = "Hello1"; 

str1 = "new string"; 

// but not this 
char str2 [] = "hello"; 
str2 = "four"; 

// or this 
char str3 []; 
str3 = "hello"; 
str3 = "hello"; 
+1

[這個問題](http://stackoverflow.com/questions/164194)涵蓋了同樣的理由,只是措辭不同。我不確定這是否足夠重複以關閉,但答案在那裏適用。 –

+4

@Tim Post:所謂的重複問題及其答案是與這個問題無關的IMO,因爲這個問題是編譯時的事情,另一個問的是運行時的東西 –

回答

71

爲什麼它的工作原理與指針:
當你說用C char * str1,你是在分配內存的指針。當您編寫str1 = "Hello";時,您正在內存中創建一個字符串字面值,並使指針指向它。當您創建另一個字符串文字"new string"並將其分配給str1時,您所做的只是更改指針指向的位置。

爲什麼不能使用數組:
當你說char str2 [] = "Hello",要創建一個字符串,其定義中把它在數組中。數組計算它並附加一個'\0'即可。如果不調整大小,您不能重新分配任何內容。這就是爲什麼str2 = "four"不起作用。

str3情況下,它是相同的情況下。您尚未在定義中定義數組的大小,因此它將其大小計算爲0.如果不調整數組大小,則不能指定任何新數據。

+0

乾杯,TryUrBest。我看過的大多數C書都是從字符串,指針和數組中做出一個非常重要的事情。在str1(指針)的情況下是這樣做的嗎?不要擔心「我是否正確地做到了100%」,只是指出字符串並像上面那樣使用它們?你說,第一種方法移動指針,是原點。數據被破壞了,還是泄漏? – nick

+0

忘了@。謝謝 – nick

+0

@tryurbest:我可以再補充一個問題嗎?在使用char * str =「某個字符串」的情況下,這個字符串被認爲是一個固定大小的字符串。如果稍後,該指針被處理以添加更多字符串。會產生內存訪問衝突嗎?謝謝!實際上,我已經測試過並看到錯誤。但我不確定部分「固定大小字符串」或「恆定字符串」是否超出 –

19

數組和指針是不同的東西,這就是原因。 您可以分配給指針,但不能分配給數組。一個特殊的例外是用字符串文字初始化char數組。

char a[] = "Hello"; //initialize a char array with string literal. Special case, OK 
char* p = "Hello"; //initializa a pointer with an array(which gets converted to pointer) 
p = "My"; //assign pointer to point to another value. OK 
a = "My"; //error, arrays cannot be assigned to. Use `strcpy` 

字符串(例如 「Hello」)具有類型char[N]其中N是字符數(包括終止'\0')。一個數組可以轉換爲指向其第一個元素的指針,但數組和指針並不是一回事,無論一些不好的書或老師可能會說什麼。

+2

不要忘了'const'作爲一個問題在這裏。 – Puppy

+4

@DeadMG:C字符串文字中的AFAIK不是'const char [N]'。他們是char [N]'。這就是爲什麼我們(習慣於)在C++中隱式轉換爲字符串文字的char *。我錯了嗎? –

+0

@阿門:不,它們不是'const char [N]',但實際上它們通常是。大多數編譯器將字符串文字放在只讀內存中。這意味着用戶通常不應該嘗試執行'* p ='A';'。 –

5

簡言之,由於陣列是不是在C/C的第一類對象++。分配給數組的唯一方法是使用str(n)cpy或memcpy。

雖然陣列坍縮成當傳遞給函數的指針,它不能夠分配給數組,除了在編譯時間的初始化。

3

原因很簡單,當你寫這樣的代碼:

char str2 [] = "hello"; 

甚至:

int arr[] = {1,2,4,4,5}; 

它創建str2arr作爲一個常量指針。這就是爲什麼你不能重新分配這些指針的任何其他值,而在後面的情況下,你正在創建一個正常的指針,你可以給它分配任何東西。

2

使用指針 它的工作原理,因爲當你指定喜歡str1="Hello",你實際上是在創建一個字符串名爲招呼在內存的某個地方分配它,指針分配文字的第一個字符的地址的情況下, ,並且由於指針不是常量,您可以使用不同的地址重新指定它。還有一點需要注意的是,所創建的字符串文字在只讀存儲器中。

與字符數組 情況下,你可以爲它分配一個字符串字面量,同時初始化爲由語言支持。不要將作業與初始化混淆。賦值時,由於它的字符數組必須逐個字符地更改值,因此您正嘗試將字符串文字的第一個地址設置爲數組的第一個字符(數組的名稱返回第一個元素的地址數組)。這顯然是不正確的,因爲第一個元素不是指針,它不能存儲地址。

相關問題