C ++,通过使用指针复制char数组的奇怪行为

时间:2013-05-03 04:00:12

标签: c++ pointers char

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

#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!,以及指针p2 ,即使在for循环中赋值后,它仍会显示p2=

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

写这行*p2='\0';的原因是什么,这条线是否被注释无关紧要,以前的输出不会改变。

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

4 个答案:

答案 0 :(得分:2)

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

如果您将p1p2重置为原始值,则可以查看字符串。

答案 1 :(得分: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个字符大小。

答案 2 :(得分:1)

代码用于将str1复制到str2

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

开始时,p1指向str1的第一个字符,p2指向str2的第一个字符。如果你打印它们而不做任何其他事情,编译器将完全打印出两个字符串。因此输出将为p1=hello,world!p2=

for循环使p1p2前进到str1str2。最后,p1指向str1末尾的\ 0和p2指向'\0'末尾的str2。因此,如果在for循环结束后直接打印p1p2,编译器将立即找到'\0'并停止打印。因此,您获得输出p1=p2=

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

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

答案 3 :(得分:0)

c ++字符串是一个char *,p1和p2都指向同一个字符串,因为它们递增后会经过字符串“* p2 ='\ 0';”的字符。将字符串设置为空字符,它对程序没有任何影响,因为它在以后的行中被重置。