这个:
const char * terry = "hello"; cout<<terry;
打印 hello而不是 'h'的内存地址。为什么会发生这种情况?
hello
'h'
您应该将您的代码更改为:
cout << static_cast<const void*>(terry);
问题是,对于指向 C 样式字符串以打印字符串内容的指针,<<运算符被重载。如果将其强制转换为原始指针,那么将具有使用 iostream 打印指针的默认行为。
<<
“ hello”是一个字符串,也就是字符数组。const char*是一个指向这个数组的指针,因此当您取消引用这个指针时,将得到第一个元素的值。
const char*
就好像
int a[] = {1, 2, 3}; int *b = a; cout << *b << endl;
你只能打印 1。
1
原因是 std::cout将 char *视为指向 C 样式字符串(第一个字符)的指针,并将其作为指针打印出来。如果你想要的是 地址,你可以直接把它转换成 不是这样处理的指针,比如:
std::cout
char *
cout << (void *) terry;
(或者使用 const void *强制转换,如果您担心抛弃常量,这在本例中不是问题)。
const void *
如果你是一个纯粹主义者而不是实用主义者,你也可以使用 C + + static_cast,如下所示:
static_cast
cout << static_cast <const void *> (terry);
尽管在这种情况下没有必要,但是对 void *的强制转换可以很好地工作。下面的示例代码显示了所有这些操作选项:
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; }
输出(地址在您的环境中可能不同) :
hello 0x8048870 0x8048870 0x8048870
请注意,在使用 static_cast时,您应该确保不要尝试抛弃 static_cast <void *>的常量(这就是 const_cast的用途)。这是较新的 C + + 强制转换所做的检查之一,而旧式强制转换没有这个限制。
static_cast <void *>
const_cast
cout是重载的,因此当您给它一个 char*时,它将作为指向 C 样式字符串的指针打印。因此,它打印出字符,直到遇到一个空终止字符。
cout
char*
如果使用 printf而不是 cout,您将看到地址。您还可以将指针强制转换为另一种类型,比如 (void*),您还可以获得地址。
printf
(void*)
std::cout上的 <<操作符被重载。它的行为取决于正确操作数的类型。(它实际上是几个不同的函数,全部命名为 operator<<; 编译器决定调用哪个函数。)
operator<<
如果给它一个 char*或 const char*,它将操作数作为指向 C 样式字符串(第一个字符)的指针,并打印该字符串的内容:
const char * terry = "hello"; cout << terry; // prints "hello"
如果给它一个 char值,它会将该值打印为一个字符:
char
cout << *terry; // prints "h" cout << terry[0]; // the same
如果给它一个类型为 void*的指针,它将输出该指针值(以某种实现定义的方式,通常是十六进制) :
void*
cout << static_cast<const void*>(terry); // prints something like 0x4008e4
将 char*或 const char*作为指向 C 样式字符串的指针是一种特殊情况,并且是唯一一种(我能想到的)导致 operator<<打印操作数值以外的内容的情况。其原因可以追溯到 C + + 在 C 中的根,它没有“ string”类型,并且通过 char*指针操作字符串。
对于 operator<<、各种整数和浮点数字类型、 std::string等等,还有许多其他重载。
std::string
std::cout定义为 std::ostream,这个定义为 operator<<。
std::ostream
值得注意的是这句话:
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。
std::num_put
%p