a[0]和&a[0]在字符串中有什么区别?

7
string a = "asdf";
cout<<&a[0];
cout<<a[0];

为什么这两个输出不同?为什么&a[0]不是地址而是整个字符串?

你可以获取字符串中的基础char *,在这个答案中详细说明。 - mty
3个回答

13

&a[0]的类型是char *。流运算符<<被有意地重载为处理const char *参数,以输出从该地址开始的以零结尾的字符串(C风格字符串)。例如,如果您执行

const char *p = "Hello World!";
cout << p;

这是 << 的过载版本,确保将字符串 "Hello World!" 发送到输出,而不是指针值。

这正是使你的代码输出整个字符串的原因。自 C++11 开始,std::string 对象需要将它们的数据存储为以零结尾的字符串,而 &a[0] 不过是指向存储在你的a对象中的字符串开头的指针。


附注:使用&a[0]而不是a的性能较差,无法处理嵌入的零... - Deduplicator

1

当将指向标准库输出流的指针打印时,如果它是char*const char*类型,则将打印指向的以空字符结尾的字符串而不是地址本身。如果您想要打印地址:

cout << static_cast<const void*>(&a[0]);

(趣闻:如果指针类型无法转换为const void*,因为它是一个函数指针或成员指针或它是易失性的,则会将其转换为bool。)

1

&a[0] 产生类型为 char* 的结果。这是一个重载了 operator<<() 的类型。这个特定的重载会打印从该地址开始的字符,直到找到空字符 '\0'。它不会像你期望的那样打印地址。

由于你需要地址,标准库中有 std::addressof() 函数:

std::cout << std::addressof(a[0]);

您还可以将其转换为 void*,这与上述变量几乎相同:

std::cout << static_cast<void*>(&a[0]);

std::addressof(a[0]) 在这里和 &a[0] 是完全相同的,对吗? - M.M
@MattMcNabb 是的,它们都有相同的效果。但是 std::addressof() 不会考虑用户定义类型的重载 operator& - David G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接