我正在复习我的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
>
幕后发生了什么?为什么字符串文字和声明的字符数组在索引6(内部'\0'
之后)存储't'
,而声明的字符串不存储?
据我所知,前两个本质上只是一个数组,打印字符串的方式是继续打印,直到遇到\0
。因此,在前两个示例中,您从字符串中第6个字符的点偏移开始,但在您的示例中,您打印的是第6个字符,即t
。
string
类的作用是将字符串复制到它自己的内部缓冲区中,并将字符串从数组的开始复制到它找到的第一个\0
。因此,t
不会被存储,因为它位于第一个\0
之后。
因为接受const char*
的std::字符串
构造函数将其参数视为C样式字符串。它简单地从它复制,直到它遇到空终止符,然后停止复制。
最后一个例子实际上是调用未定义的行为word2[6]
超过字符串的末尾。
您正在从字符*
(或衰减为该字符的内容)构造字符串。这意味着C字符串的约定适用。也就是说,它们被'\0'
终止。这就是为什么word2
只包含“hello”
。