我从教科书中得到了这段代码:
#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指针是如何工作的?
答案 0 :(得分:2)
循环修改p1
,使其指向字符串末尾的空终止符。这是空字符串的定义。 p2
同样指向字符串末尾的空终止符。
如果您将p1
和p2
重置为原始值,则可以查看字符串。
答案 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循环使p1
和p2
前进到str1
和str2
。最后,p1
指向str1
末尾的\ 0和p2
指向'\0'
末尾的str2
。因此,如果在for循环结束后直接打印p1
或p2
,编译器将立即找到'\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';”的字符。将字符串设置为空字符,它对程序没有任何影响,因为它在以后的行中被重置。