簡體   English   中英

關於 c 處理字符串的方式的困惑

[英]confusion about the way c handles strings

為什么不

   char *name = "asd";
   printf("%p\n%p", (void *)&name, (void *)&name[0]);

給出相同的輸出

char name[] = "asd";
printf("%p\n%p", (void *)&name, (void *)&name[0]);

我讀過 c 將字符串作為指向它們的第一個字符的指針,直到它到達\\0但上面的代碼不喜歡它,所以它讓 ac 初學者感到困惑

首先,讓我們為您的兩個變量指定不同的名稱和內容,以便我們可以清楚地區分它們。

char *namep = "asd";
char name[] = "zxc";

這些導致數據結構可能如下所示:

       +-------+
namep: |   *   |
       +---|---+
           |
          /
         |
         V
       +---+---+---+----+
       | a | s | d | \0 |
       +---+---+---+----+

       +---+---+---+----+
namea: | z | x | c | \0 |
       +---+---+---+----+

現在讓我們看看你的兩個printf調用:

printf("%p\n%p", (void *)&namep, (void *)&namep[0]);

現在, &namep為您提供了namep指針的地址。
但是&namep[0]為您提供了指向字符串 ( a ) 中第一個字符的地址。 如果你已經打印

printf("%p\n", (void *)namep);

你會看到同樣的事情。

printf("%p\n%p", (void *)&namea, (void *)&namea[0]);

在這里, &namea為您提供數組的地址。
&namea[0]給你它的第一個字符 ( z ) 的地址——這是同一個地方。 事實上,由於特殊處理(數組“衰減”為指針),如果你說過

printf("%p\n", (void *)namea);

你也會看到同樣的事情。

你問:

我讀過 c 將字符串作為指向它們第一個字符的指針,直到它到達 \\0

沒錯。

假設你寫了代碼

char *p;
for(p = namep; *p != '\0'; p++)
    putchar(*p);

這將打印您的namep字符串asd 這里沒有什么神秘之處。 namep已經是一個指針,指向字符串的第一個字符,所以這段代碼采用自己的指針p ,它開始指向namep指向的位置,並打印指向的字符,直到它到達終止\\0

也許更令人驚訝的是,您可以使用namea完全相同的事情:

char *p;
for(p = namea; *p != '\0'; p++)
    putchar(*p);

這也可以打印zxc ,如果您不相信我,我鼓勵您將它輸入到您的 C 編譯器中並嘗試一下。

現在,您可能會問,如果p是一個指針而namea是一個數組,那么循環初始化p = namea是如何工作的? 這又是由於指向指針的數組的“衰減”。 同樣,當你嘗試像這樣使用namea的值時,你得到的——分配給p的值——自動是一個指向namea的第一個元素的指針。 當然,這正是您想要的。 p從那里開始,並打印字符 ' 直到找到\\0 ,從而打印zxc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM