[英]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.