我在我的C ++刷牙和问候字符串,字符数组跨一个奇怪的行为迷迷糊糊的,空字符( '\0'
)。 下面的代码:
#include <iostream>
using namespace std;
int main() {
cout << "hello\0there"[6] << endl;
char word [] = "hello\0there";
cout << word[6] << endl;
string word2 = "hello\0there";
cout << word2[6] << endl;
return 0;
}
产生输出:
> t
> t
>
这是怎么回事幕后? 为什么字符串文字和声明的字符数组存储't'
在索引6(后的内部'\0'
),但声明的字符串不?
从我记得,前两个是在本质上只是一个数组并打印字符串的方式是继续打印,直到\0
是encounterd。 因此,在前两个例子中,你开始在该点的字符串中的第6个字符的偏移,但在你的情况下,要打印出第6个字符是t
。
什么与发生string
类,它使字符串拷贝到它自己的内部缓冲区,并通过复制数组的开始串到第一这样做\0
找到。 因此, t
没有被存储,因为它涉及后的第一个\0
。
因为std::string
构造函数,一个const char*
把它作为一个C风格的字符串参数。 它只是从它复制,直到遇到空终止,然后停止复制。
所以,你的最后一个例子实际上是调用未定义的行为; word2[6]
变为过去的字符串的末尾。
您正在构建从一个字符串char*
(或东西腐烂这一点)。 这意味着,C字符串公约适用。 也就是说他们是'\0'
终止。 这就是为什么word2
只包含"hello"
。
问题是,你是不是打印字符串在所有 - 要打印单个字符。
char word [] = "hello\0there";//Array of char...
cout << word[6] << endl; //So word[6] is the char't' (NOT a string)
string word2 = "hello\0there"; //std::string...
cout << word2[6] << endl; //so word2[6] is the char 't' (NOT a string as well)
所以,要调用的“字符”重载,而不是“字符*”或“串”超载可言,和NULL字符有什么用它做的一切:你只是打印字的第6个字符,并WORD2的第6个字符。
如果我正确地读你的意图,你的测试应改为:
cout << &(word[6]) (char*, should print "there")
cout << &(word2[6]) (char* as well, undefined behaviour pre-C++11)
在C ++ 11后来这也将打印“有” ,并明确定义