2015-11-22 94 views
0

我開始明白指針,以及如何解除引用他們等我一直在練習與int s,但我想char將表現相似。使用*取消引用,使用&訪問內存地址。爲什麼我可以在字符的內存地址中存儲字符串?

但在下面的示例中,使用相同的語法來設置char的地址並將字符串保存到相同的變量。這個怎麼用?我想我一般都很困惑,也許我正在推翻它。

int main() 
{ 
    char *myCharPointer; 
    char charMemoryHolder = 'G'; 
    myCharPointer = &charMemoryHolder; 
    printf("%s\n", myCharPointer); 
    myCharPointer = "This is a string."; 
    printf("%s\n", myCharPointer); 

    return 0; 
} 

回答

6

首先,你需要了解如何「串」工作C.

「字符串」存儲爲字符的內存中的數組。由於沒有辦法確定字符串的長度,所以在字符串後面追加NUL字符'\0',以便我們知道它的結束位置。

因此,舉例來說,如果你有一個字符串「foo」,它可能看起來像這樣的記憶:

-------------------------------------------- 
| 'f' | 'o' | 'o' | '\0' | 'k' | 'b' | 'x' | ... 
-------------------------------------------- 

'\0'後的東西只是東西,恰好被放置在字符串之後,這可能是可能不會被初始化。

當你給一個類型爲char *的變量賦值一個「字符串」時,會發生什麼變量會指向字符串的開始,所以在上面的例子中它會指向'f'。 (換句話說,如果你有一個字符串str,那麼str == &str[0]總是如此。)當你給一個char *類型的變量賦值一個字符串時,實際上是將該字符串的第零個字符的地址賦值給該變量。

當您將此變量傳遞給printf()時,它將從指向地址開始,然後逐個遍歷每個字符,直到看到'\0'並停止。例如,如果我們有:

char *str = "foo"; 

,你把它傳遞給printf(),它將執行以下操作:

  1. 提領str(這給'f'
  2. 提領(str+1)(這給'o'
  3. Dereference (str+2)(它給出了另一個'o'
  4. 解除引用(str+3)(它給出'\0',這樣過程停止)。

這也得出結論,你目前的行爲實際上是錯誤的。在你的代碼有:

char charMemoryHolder = 'G'; 
myCharPointer = &charMemoryHolder; 
printf("%s\n", myCharPointer); 

printf()看到%s符,它的推移myCharPointer到指向的地址,在這種情況下,它包含'G'。然後它會嘗試獲得'G'之後的下一個字符,這是未定義的行爲。它可能時不時給你正確的結果(如果下一個內存位置碰巧包含'\0'),但一般來說你不應該這樣做。

2

幾點意見

在C
  1. 靜態字符串被視爲一個(字符*)爲空終止 字符數組。例如。 「ab」本質上是一個char *,與97 98 0的一塊內存有關。 (97爲'a',98爲'b',0爲無效終止。)
  2. 您的代碼myCharPointer = &charMemoryHolder;後面跟着printf("%s\n", myCharPointer)不是安全。 printf應該傳遞一個以空字符結尾的字符串,並且不能保證內存中的值0緊跟在字符charMemoryHolder後面。
0

在C中,字符串文字計算爲指向只讀數組的字符的指針(除了用於初始化char數組時)。這是C語言中的一種特殊情況,並不會推廣到其他指針類型。一個char *變量可以保存變量的單個地址或者一個字符數組的起始地址。在這種情況下,數組是一串已存儲在靜態內存區域中的字符。

0

charMemoryHolder是一個變量,它在內存中有一個地址。

"This is a string."是一個字符串常量,存儲在內存中,也有一個地址。

這兩個地址都可以存儲在myCharPointer並取消引用以訪問第一個字符。

printf("%s\n", myCharPointer)的情況下,指針將被解除引用並顯示字符,然後指針遞增。它重複這個直到找到一個空(零值)字符並停止。

希望您現在想知道當您指向單個'G'字符時會發生什麼情況,該字符不像字符串常量那樣以空字符結尾。答案是「未定義的行爲」,很可能會打印隨機垃圾,直到它在內存中找到一個零值,但可以精確打印正確的值,因此「未定義的行爲」。使用%c打印單個字符。

相關問題