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

Mr.*_*uff 55 c++

这个:

const char * terry = "hello";
cout<<terry;
Run Code Online (Sandbox Code Playgroud)

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

pax*_*blo 75

这样做的原因是std::cout将a char *作为指向C风格字符串(的第一个字符)的指针并将其打印出来.如果你想要地址,你可以把它转换成一个没有被处理过的指针,例如:

cout << (void *) terry;
Run Code Online (Sandbox Code Playgroud)

(或者const void *如果你担心丢掉常量,可以使用演员表,这在某些情况下不是问题).


如果你更像一个纯粹主义者而不是实用主义者,那么你也可以使用C++ static_cast,其方式如下:

cout << static_cast <const void *> (terry);
Run Code Online (Sandbox Code Playgroud)

虽然在这种特殊情况下没有必要,但是施放到一个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;
}
Run Code Online (Sandbox Code Playgroud)

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

hello
0x8048870
0x8048870
0x8048870
Run Code Online (Sandbox Code Playgroud)

注意,在使用时static_cast,你应该确保你不要试图抛弃constness static_cast <void *>(那const_cast是为了什么).这是较新的C++强制转换所做的检查之一,而旧式强制转换没有此限制.

  • 你谈论懒惰,好像它是一个_bad_事物.如果有实际的减量效果,那就唯一不好,否则它被称为效率.在这种特殊情况下使用旧式强制转换没有任何问题,并且它们与其他任何东西一样都是C++语言的一部分(即使像cstdio这样的东西也可以接受,只要你理解这些问题). (7认同)
  • 对那些不知道自己在做什么的人来说,这是危险的.在这种情况下,删除constness是无关紧要的,因为你没有对指针做任何事情.是的,如果你施放指针然后关闭并错误地使用它,我同意,但我希望某种语言的实践者学习如何安全地使用它.我没有让儿子开始使用我更危险的工具,直到他证明他知道他们的问题:-) (3认同)
  • 它不会将“char*”值视为 C 风格字符串;它将其视为指向 C 样式字符串(的第一个字符)的“指针”。 (2认同)
  • 我只看到在C ++中使用C样式强制转换的两个原因:1.强制转换为不可访问的基类;2.懒惰再输入几个字符。 (2认同)
  • 但是,我看到我不太可能说服您。纯粹主义者和实用主义者之间的斗争似乎在这里抬头,双方都有自己的观点,但是我们不妨讨论vi与emacs :-)所以我建议您投票赞成自己的良心,让人民决定。我将添加较新的样式作为一个选项,但是在这种情况下,我仍然认为没有必要。 (2认同)

Kei*_*son 19

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

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

const char * terry = "hello";
cout << terry; // prints "hello"
Run Code Online (Sandbox Code Playgroud)

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

cout << *terry;   // prints "h"
cout << terry[0]; // the same
Run Code Online (Sandbox Code Playgroud)

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

cout << static_cast<const void*>(terry); // prints something like 0x4008e4
Run Code Online (Sandbox Code Playgroud)

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

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


sas*_*hka 9

您应该将代码更改为:

cout << static_cast<const void*>(terry);
Run Code Online (Sandbox Code Playgroud)

问题是<<运算符被重载以指向C样式的字符串以打印字符串的内容.如果将其转换为原始指针,则将具有使用iostreams打印指针的默认行为.


Ill*_*ack 5

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

值得注意的是这一行:

template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
                                     const char* s );
Run Code Online (Sandbox Code Playgroud)

当您<<与 类型的参数一起使用时,会选择此选项char*

任何其他非 char 指针类型的情况如下

basic_ostream& operator<<( const void* value );
Run Code Online (Sandbox Code Playgroud)

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