繁体   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