为什么打印c风格字符串的'address of index n'会导致输出子串

Why does printing the 'address of index n' of c style strings lead to output of substring

我是 C++ 的新手,在使用指向 char 数组(C 样式字符串)的指针时,我对其与 ostream 对象的行为感到困惑。

const char* items {"sox"};
cout << items << endl;
cout << items[0] << endl;
cout << *items << endl;
cout << &items << endl;
cout << &items[1] << endl;

运行 这导致:​​

sox
s
s
0x7fff2e832870
ox

与其他数据类型的指针相反,打印变量不输出地址,而是整个字符串。据我了解,这是由于 << 运算符为 char 数组 重载以将它们视为字符串。

我不明白的是,cout << &items[1] 从索引 1 开始打印字符串 (ox),而不是索引 1 处 char 的地址。是这也是由于 << 运算符被超载或这种行为的原因是什么?

&items[1]的类型是const char *。因此使用 operator <<const char * 重载,它从索引 1 开始打印字符串。

OTOH,&items 的类型是 const char **,不存在特定的重载,因此打印了 items 的地址(通过 const void * 重载) .

items[1] 是数组的第二个字符及其地址,即 &items[1],也是指向第二个字符(索引为 1)的指针。因此,使用您为 operator << 提到的相同规则,打印字符串的第二个字符直到结尾。

昔日,C运行的世界,还没有std::string,程序员只能凑合用char的数组来管理文本。当 C++ 带来启蒙(和 std::string)时,旧习惯依然存在,仍然使用 char 的数组来管理文本。由于这种传统,您会发现 许多char 数组的行为与任何其他类型的数组不同。

所以,

const int integers[] = { 1, 2, 3, 4 };
std::cout << integers << '\n';

打印数组中第一个元素的地址。

但是,

const char text[] = { 'a', 'b', 'c', '[=11=]' };
std::cout << text << '\n';

打印数组text中的text,直到最后的0:abc

同样,如果您尝试打印数组内的地址,您会得到不同的行为:

std::cout << &integers[1] << '\n';

打印数组中第二个元素的地址,但是

std::cout << &text[1] << '\n';

从数组的第二个字符开始打印 text:bc

而且,正如您所怀疑的那样,那是因为 operator<< 有一个重载,它接受 const char* 并从指针指向的位置开始复制文本,并继续到第一个 0 它看到。这就是 C 字符串的工作方式,并且这种行为会延续到 C++ 中。