80

这个:

const char * terry = "hello";
cout<<terry;

打印hello而不是'h'. 为什么会这样?

4

6 回答 6

98

这样做的原因是std::cout将 achar *视为指向 C 样式字符串(的第一个字符)的指针并将其打印出来。如果您想要该地址,则可以将其转换为未以这种方式处理的指针,例如:

cout << (void *) terry;

(或者const void *如果您担心抛弃 constness,则使用演员表,在这种特殊情况下这不是问题)。


如果您是纯粹主义者而不是实用主义者,您还可以使用 C++ static_cast,如下所示:

cout << static_cast <const void *> (terry);

尽管在这种特殊情况下没有必要,但转换为 avoid *将正常工作。以下示例代码显示了所有这些选项的作用:

#include <iostream>
int main (void) {
    const char *terry = "hello";
    std::cout << terry << '\n';
    std::cout << (void *) terry << '\n';
    std::cout << (const void *) terry << '\n';
    std::cout << static_cast<const void *> (terry) << '\n';
    return 0;
}

输出(地址在您的环境中可能不同):

hello
0x8048870
0x8048870
0x8048870

请注意,在使用 时static_cast,您应该确保不要尝试用static_cast <void *>( 这就是const_cast目的) 抛弃 constness。这是较新的 C++ 转换所做的检查之一,而旧式转换没有此限制。

于 2013-07-23T14:46:04.280 回答
25

<<运算符 on已std::cout重载。它的行为取决于右操作数的类型。(实际上是几个不同的函数,都命名为operator<<;编译器决定调用哪一个。)

如果给它一个char*or const char*,它会将操作数视为指向 C 样式字符串(的第一个字符)的指针,并打印该字符串的内容:

const char * terry = "hello";
cout << terry; // prints "hello"

如果你给它一个char值,它会将该值打印为一个字符:

cout << *terry;   // prints "h"
cout << terry[0]; // the same

如果你给它一个 type 的指针void*,它会打印那个指针值(以某种实现定义的方式,通常是十六进制):

cout << static_cast<const void*>(terry); // prints something like 0x4008e4

char*orconst char*视为指向 C 样式字符串的指针是一种特殊情况,并且是唯一一种(我能想到的)导致operator<<打印操作数值以外的内容的情况。其原因可以追溯到 C++ 在 C 中的根源,它没有“字符串”类型,而是通过char*指针操作字符串。

operator<<对于各种整数和浮点数字类型,对于,还有许多其他重载,std::string等等。

于 2013-07-23T14:59:42.243 回答
12

您应该将代码更改为:

cout << static_cast<const void*>(terry);

问题是<<运算符重载了指向 C 样式字符串的指针以打印字符串的内容。如果您将其转换为原始指针,您将拥有使用 iostreams 根据需要打印指针的默认行为。

于 2013-07-23T14:43:06.157 回答
4

std::cout被定义为std::ostream这个定义一样operator<<

值得注意的是这一行:

template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
                                     const char* s );

当您<<与 type 的参数一起使用时,它会被选中char*

任何其他非字符指针类型的情况都在这里

basic_ostream& operator<<( const void* value );

这继续std::num_put用于格式化数值。因此,指针像%pC 格式化函数一样以数字方式解释。

于 2019-01-18T15:03:45.650 回答
2

cout被重载,所以当你给它 a 时char*,它将打印为指向 C 样式字符串的指针。因此,它会打印出字符,直到遇到空终止字符。

如果您使用printf而不是cout,您将看到地址。您还可以将指针转换为另一种类型,例如(void*),您还将获得地址。

于 2013-07-23T14:52:55.183 回答
-2

"hello" 是一个字符串,即 char 数组。const char*是一个指向这个数组的指针,所以当你取消引用这个指针时,你会得到第一个元素的值。

就像如果你有

int a[] = {1, 2, 3};
int *b = a;
cout << *b << endl;

你只是1打印出来的。

于 2013-07-23T14:43:15.800 回答