为什么cout打印字符数组与其他数组不同?

20

我正在使用C++理解指针的工作原理。我有一段使用数组的代码,我只是用它来理解相应的指针代码是如何工作的。

int main() {    
    int arr[10] = {1,2,3};    
    char arr2[10] = {'c','i','a','o','\0'};
    cout << arr << endl;
    cout << arr2 << endl;
}

然而,当我运行这段代码时,arr 输出的是 int 数组的第一个元素的地址(符合预期),但 arr2 并没有输出 char 数组的第一个元素的地址;它实际上打印了 "ciao"。

我缺少什么知识或者还没学到这方面的东西吗?

4个回答

32
是运算符<<被重载了,对于const void*和const char*类型的变量。你的char数组被转换为const char*并传递给该重载函数,因为它比传递给const void*更加匹配。而int数组则被转换为const void*并传递给该版本的函数。接收const void*的版本只输出地址。而接收const char*的版本会把它当作C字符串处理并输出每个字符,直到遇到终止符号。如果不想要这样的结果,在向运算符<<传递char数组时,需要显式地将其转换为const void*。
cout << static_cast<const void*>(arr2) << endl;

1
根据这里的说明,它只对void*进行了重载。这是否意味着它能够确定指针是否指向字符,并且如果是,则查找终止字符并打印字符串?(仍然有点困惑) - rmp251
4
您是否错过了这些内容?这里是相关的参考资料。 - Ben Voigt

5
因为cout的<<操作符被重载为输出字符串的char*类型,而arr2与之匹配。如果你想获取地址,尝试将字符数组强制转换为void指针。

1

有一个标准的char*重载,可以输出以NUL结尾的字符串。


1

虽然强制类型转换可能是更有意义的方法,但您也可以使用addressof运算符:

cout << &arr2 << endl;

这里可能需要使用&arr2[0]而不是&arr2 - D.Shawley
这些是相同的地址,Shawley。 - Rob Kennedy
在C/C++中,数组只是一系列内存位置。因此,数组的地址就是第一个元素的地址。不知道为什么这个被投票否决了。 - Mystic
2
主要是因为它没有解释这个想法——char[10]不能转换为char - MSalters

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