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