为什么打印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++ 中。
我是 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++ 中。