1

我从教科书中得到了这段代码:

#include <iostream>
using namespace std;
int main(){
    char str1[]="hello,world!", str2[20], *p1, *p2;
    p1=str1; p2=str2;
    /*
    for(;*p1!='\0';p1++,p2++){
      cout<<"p1="<<*p1<<endl;
      *p2=*p1;cout<<"p2="<<*p2<<endl;
    }
    *p2='\0';
    p1=str1; p2=str2;
    */   
    cout<<"p1="<<p1<<endl;
    cout<< "p2="<<p2<<endl;  

    return 0;
}

我运行了这段代码,它会输出p1=hello,world!p2= 我能理解的。

但是如果我取消注释 for 循环,输出显示在这里我很困惑,为什么在 for 循环之后,为什么它显示p1=而不是显示p1=hello,world!,以及 for 指针p2,即使在 for 循环中赋值后,它仍然显示p2=

但是在我取消注释p1=str1; p2=str2;这一行之后,输出是p1=hello,world!, p2=hello,world!,为什么它会这样工作?

以及写这行的原因是*p2='\0';什么,这行注释掉与否都没有关系,之前的输出不会改变。

谁能告诉我这里的 char 指针是如何工作的?

4

4 回答 4

2

循环修改p1,使其指向字符串末尾的空终止符。这就是空字符串的定义。p2同样指向字符串末尾的空终止符。

如果您重置它们p1p2原始值,您可以看到字符串的原样。

于 2013-05-03T04:05:56.603 回答
1

这是我从运行该代码的 VS2010 中看到的输出,其中注释部分未注释:

p1=h
p2=h
p1=e
p2=e
p1=l
p2=l
p1=l
p2=l
p1=o
p2=o
p1=,
p2=,
p1=w
p2=w
p1=o
p2=o
p1=r
p2=r
p1=l
p2=l
p1=d
p2=d
p1=!
p2=!
p1=hello,world!
p2=hello,world!

这几乎是我所期望的!基本上,这段代码通过直接指针操作将 str1 的内容复制到(未初始化的)char 数组 str2 中,一次将每个字符从 str1 复制到 str2 中。

要回答你的最后一个问题,原因是

*p2='\0';

以便 for 循环“创建”的第二个字符串将正确地以空值终止。如果没有该行,它将只是一个不能被视为“C”字符串的 char 数组。

总体而言,这是一个非常人为/不可靠的示例,因为一旦我们的第一个字符串的长度超过 20 个字符,它将无法工作,因为 str2[] 被声明为只有 20 个字符的大小。

于 2013-05-03T04:16:38.253 回答
1

该代码用于复制str1str2.

在 C++ 中,'\0'用于结束字符串。当您尝试打印 char 指针(例如ptr)时,编译器会打印从*ptr(指针指向的字符)开始的字符串。当编译器找到'\0'时,它会停止打印。

开始时,p1指向 的第一个字符str1p2指向 的第一个字符str2。如果您不做任何其他事情就打印它们,编译器将完全打印出两个字符串。所以输出将是p1=hello,world!p2=.

for 循环通过and进行p1andp2前进。最后,指向 末尾的 \0并指向末尾的。所以如果在for循环结束后直接打印或者直接打印,编译器会立即找到并停止打印。所以,你得到了输出。str1str2p1str1p2'\0'str2p1p2'\0'p1=p2=

取消注释p1=str1; p2=str2;将使两个字符串再次指向第一个字符,因此现在打印它们将导致打印整个字符串。所以你得到了输出p1=hello,world!p2=hello,world!(因为str1被复制到str2for 循环中)。

*p2 = '\0'仅用于以str2结尾'\0'。如果您的代码在没有该行的情况下工作,则意味着编译器会自动初始化str2to的所有字符'\0'。但是,编译器不能保证这样做,因此您应该始终'\0'在程序中终止字符串。

于 2013-05-03T04:30:34.637 回答
0

C++ 字符串实际上是一个 char *,p1 和 p2 都指向同一个字符串,因为它们是递增的,它们会遍历字符串 "*p2='\0';" 的字符。将字符串设置为空字符,它对程序没有影响,因为它无论如何都会在后面的行中被重置。

于 2013-05-03T04:13:16.053 回答