计算<< with char* argument prints string, not pointer value

问题描述 投票:0回答:6

这个:

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

打印

hello
而不是
'h'
的内存地址。为什么会这样?

c++
6个回答
106
投票

原因是

std::cout
会将
char *
视为指向 C 风格字符串(的第一个字符)的指针,并以此打印它。如果您想要 address,您可以将其转换为一个 没有 那样处理的指针,例如:

cout << (void *) terry;

(或者,如果您担心放弃常量,则使用

const void *
转换,在这种特殊情况下这不是问题)。


如果你更像是一个纯粹主义者而不是实用主义者,你也可以使用 C++

static_cast
,如下所示:

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

虽然在这种特殊情况下没有必要,但转换为

void *
会很好。以下示例代码显示了所有这些选项的实际操作:

#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;
}

outputing(地址可能在你的环境不同):

hello
0x8048870
0x8048870
0x8048870

请注意,在使用

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


29
投票

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

如果你给它一个

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

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

如果你给它一个

char
值,它会将该值打印为一个字符:

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

如果你给它一个

void*
类型的指针,它会打印该指针值(以某种实现定义的方式,通常是十六进制):

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

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

对于

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


12
投票

您应该将代码更改为:

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

问题是

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


5
投票

std::cout
被定义为
std::ostream
this
operator<<
的定义。

值得注意的是这一行:

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

当您使用

<<
和类型为
char*
的参数时,这会被选中。

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

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

这继续到

std::num_put
,它是为格式化数值而制作的。因此,指针在 C 格式化函数中以数字方式解释为
%p


2
投票

cout
被重载,因此当您给它一个
char*
时,它将打印为指向 C 风格字符串的指针。因此,它会打印出字符,直到遇到空终止字符。

如果您使用

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


-2
投票

"hello" 是一个字符串,即 char 数组。

const char*
是指向此数组的指针,因此当您取消引用此指针时,您将获得第一个元素的值。

就像你有

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

你只是

1
印刷。

© www.soinside.com 2019 - 2024. All rights reserved.