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

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

本文关键字:字符串 输出 index 打印 为什么 address of 样式      更新时间:2023-10-16

我对C++相当陌生,在使用指向字符数组(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 *重载(。

回到过去,当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', '' };
std::cout << text << 'n';

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

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

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

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

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

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

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

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