C++ cout << with char* 参数打印字符串,而不是指针值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17813423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:27:45  来源:igfitidea点击:

cout << with char* argument prints string, not pointer value

c++

提问by Mr.Puff

This:

这个:

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

prints helloinstead of the memory address of the 'h'. Why is this happening?

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

回答by paxdiablo

The reason for that is that std::coutwill treat a char *as a pointer to (the first character of) a C-style string and print it as such. If you want the addressinstead, you can just cast it to a pointer that isn'ttreated that way, something like:

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

cout << (void *) terry;

(or use the const void *cast if you're worried about casting away constness, something that's not an issue in this particular case).

(或者,const void *如果您担心抛弃常量,则使用强制转换,这在这种特殊情况下不是问题)。



If you're more of a purist than pragmatist, you can also use the C++ static_cast, along the lines of:

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

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

though it's unnecessary in this particular case, the cast to a void *will work fine. The following sample code shows all these options in action:

尽管在这种特殊情况下没有必要,但对 a 的强制转换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;
}

outputting (the address may be different in your environment):

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

hello
0x8048870
0x8048870
0x8048870

Note that, when using the static_cast, you should ensure you don't try to cast away the constness with static_cast <void *>(that's what const_castis for). This is one of the checks done by the newer C++ casts and the old-style cast does not have this limitation.

请注意,在使用 时static_cast,您应该确保不要试图抛弃常量性static_cast <void *>(这就是为什么const_cast)。这是由较新的 C++ 强制转换完成的检查之一,旧式强制转换没有此限制。

回答by Keith Thompson

The <<operator on std::coutis overloaded. Its behavior depends on the type of the right operand. (It's actually several different functions, all named operator<<; the compiler decides which one to call.)

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

If you give it a char*or const char*, it treats the operand as a pointer to (the first character of) a C-style string, and prints the contents of that string:

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

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

If you give it a charvalue, it prints that value as a character:

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

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

If you give it a pointer of type void*, it prints that pointer value (in some implementation-defined way, typically hexadecimal):

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

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

Treating a char*or const char*as a pointer to a C-style string is a special case, and the only one (that I can think of) that causes operator<<to print something other than the value of the operand. The reason for this goes back to C++'s roots in C, which doesn't have a "string" type and manipulates strings via char*pointers.

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

There are numerous other overloads for operator<<, for various integer and floating-point numeric types, for std::string, and so forth.

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

回答by sasha.sochka

You should change your code to this:

您应该将代码更改为:

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

The problem is that <<operator is overloaded for pointers to C-style strings for printing the content of the string. If you cast it to the raw pointer instead, you will have the default behaviour of printing pointer using iostreams as you want.

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

回答by IllidanS4 wants Monica back

std::coutis defined as std::ostreamwith thisdefinition of operator<<.

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

Notably this line:

值得注意的是这一行:

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

This gets selected when you use <<with an argument of type char*.

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

The case of any other non-char pointer type goes here:

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

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

This continues to std::num_putwhich is made for formatting numeric values. Therefore, the pointer is interepreted numerically like %pin C formatting functions.

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

回答by Richard Fung

coutis overloaded so that when you give it a char*, it will print as a pointer to a C-style string. So, it prints out the characters until it hits a null terminating character.

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

If you used printfinstead of cout, you would see the address. You could also cast the pointer to another type, say (void*)and you would also get the address.

如果您使用printf代替cout,您将看到地址。你也可以将指针转换为另一种类型,比如说(void*),你也会得到地址。

回答by Ivan Smirnov

"hello" is a string, i.e. the char array. const char*is a pointer to this array, so when you dereference this pointer, you get the value of the first element.

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

It is like if you have

就像如果你有

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

you get just 1printed.

你只是被1打印出来。