c++字符数组结束符问题

#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
void main(){
char a[]="wearehere!",b[11];
reverse(a,a+10);
copy(a,a+10,ostream_iterator<char>(cout));
cout<<endl;
copy(a,a+11,b);
sort(a,a+10);
cout<<a<<endl;
cout<<b<<endl;
reverse_copy(a,a+10,b);
cout<<b<<endl;
reverse(b+2,b+8);
copy(b+2,b+8,ostream_iterator<char>(cout));
cout<<endl;
}

这个程序的 copy(a,a+11,b);和
reverse(b+2,b+8);
copy(b+2,b+8,ostream_iterator<char>(cout));
这两句不是很懂,为什么是a+11,而不是a+10是结束符的原因么?
那么(b+2,b+8)的输出为什么是eeeehr而不是aeeeehr

你这个问题问得很好,我们知道实际上一个字符串在进行赋值的时候,例如: char *p="hello world";这样赋值是允许的。那么这并不代表"hello world"这个就是一个指针,实际上我们的这一动作,编译器在幕后为我们做了很多事,首先在常量区分配一个字符数组,然后将"hello world"这个字符串中的字符(包括最后的'\0'字符。)拷贝到此数组(其实此数组我们可以看成是一个匿名数组,因为没有数组名)。然后返回数组首元素的地址,将此地址赋值给字符指针变量p。我们知道在c语言中没有字符串这种类型,在c语言中的字符串是通过字符数组来实现的,而且必须要求此字符数组具有'\0'结束符。这就是字符串与一般的字符数组不同的地方。

话说回来,你问到为什么char *p="hello world"; cout<<p<<endl;打印出来的是字符串,而不是地址。其实当初我也想到过类似的问题,没有找到权威的答案,但是我能够猜出几分。C++语言是兼容C语言的,所以在输出C串的时候是直接以给出的首地址,输出,直到遇到结束符'\0'结束。为什么会这样呢,我想着应该是语言的特性,或者是编译器的特性。既然C语言中字符串是通过带'\0'的字符数组实现的,那么请问如果编译器是由你来实现的,或者是printf()函数是你写的,要输出一个字符串的话你会怎么样呢,你是不是会输出指针的地址呢,cout<<p<<endl;这样的形式让读者一目了然,我要输出的就是一个字符串,而实际上p就是一个字符指针变量而已,为什么输出字符串,这在于cout的实现了,cout的实现我不的而知,但是可以肯定的是cout确实在遇到字符指针的时候会将做出这样的行为:将此指针当做首地址,向下输出字符,直到遇到'\0'结束为止。 这就是cout的行为,没有为什么。 其实你自己可以写一个自己的cout函数,输出地址而不是按照cout的默认行为。当然要实现cout的功能,必须要了解很多底层知识。

我们可以通过这样的方式输出字符指针的值,而不是输出以其为首地址的字符串。例如char a='A'; char *p=&a; cout<<(int)(p)<<endl; 只需要将指针的值(地址值实际上在内存中就是一个整数,标识了内存的地址,只不过编译器认为其实指针类型罢了,实际上从本质上来说,计算机中的任何类型在内存中都是以二进制的形式存在的,根本没有所谓的类型之分。为什么有类型,这就是编译器将底层抽象的结果)。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-01-22
原因在于迭代器(iterator)迭代(循环)的起点(通常用begin()表示),是该序列的第一个元素,但是循环的终止点(通常用end()表示),并非是最后一个元素,而是最后一个后面紧挨着的位置,通常该位置不可操作,因此reverse(a,a+10);实际上颠倒的就是从a+0到a+9位置
同样的copy(a,a+11,b);实际上操作的就是a数组的a+0到a+10位置,注意a+10就是字符数组结束符号
同样的(b+2,b+8)实际操作的就是b+2到b+7范围本回答被提问者采纳
第2个回答  2011-01-22
a+10已经到结束符了。但你要先弄清楚函数的用法,a[10]的范围是 a+0 ~ a+9 ,a+10是结束符号,上面的reverse就是操作入界和出界的,而a+2就是入界,a+10就是出界,表示该函数的操作的范围是0~9但不包括10。这种是编程很多地方默认的规定,就像for(int i=0;i<10;i++)那样,只操作数组的10个元素而已,好多初学者都会疑问为什么不写成for(int i=0;i<=9;i++)一样,其实这个写法是有好处的,到你日后编程经验多了就会体会到,很多递归或者循环写成入界和出界的形式在实现算法的时候更简洁和效率更好。
相似回答