以下代码:
int number = 65;
char *ptr = reinterpret_cast< char* >(&number);
cout << *ptr << endl;
*ptr
打印A
和ptr
打印A
。为什么他们都打印相同的结果?
答案 0 :(得分:4)
流正在重载<<
,因此无论如何都会隐式地为char
完成解除引用。
更具体地说:由于char *
是C的string
,ostream
会尝试读取它,即它取消引用指针并读取char
s直到找到它为止一个零字节。 (这仅适用于正确的Endianness。)
考虑以下代码:
#include <iostream>
int main(void) {
char c = 'A';
int i = 66;
std::cout << c << '\n';
std::cout << &c << '\n';
std::cout << i << '\n';
std::cout << &i << '\n';
return 0;
}
在我的机器上(不是全部!)打印
A
AB
66
0x7fff0d1db1bc
因为c
打印正确,但&c
被解释为字符串。但是c
不是以空值终止的,因此ostream
继续读取,找到i
的第一个字节,然后最后一个空字节,因为i
的值太小了,我们只使用其四个字节中的一个。
但是,i
和&i
按预期打印。此行为仅针对char
实现,因为对其他类型没有意义。
答案 1 :(得分:1)
两者都打印相同的结果,因为:
ostream::operator<<
包含char*
和char
的重载(请参阅here和here)。char*
重载将参数解释为指向null-terminated byte string的指针,而不是指向单个char
的指针。sizeof(char) < sizeof(int)
(与==相对)。这意味着number
占用的内存在被解释为char
的数组时,是值{65的char
,后跟一个或多个空char
。因此,当number
被解释为以空字符结尾的字节字符串时,它包含值为65的单个字符。因此,当您流式*ptr
char
时,char
重载会打印出指向的值为65的字符。当您流式传输ptr
时,在char*
类型中,char*
重载打印指向的以空字符结尾的字节字符串,其中包含值为65的单个字符,因此再次打印单个字符。
关于第3点的进一步说明:
请注意,给定sizeof(char) < sizeof(int)
,您可以保证得到一个以空字符结尾的字节字符串,其中只有一个字符,因为CHAR_BIT
是at least 8。即值65不可能不适合单个char
。
也许你的机器有sizeof(char) == sizeof(int)
(在这种情况下,endianess无关紧要),number
之后的内存是空字符只是巧合,再次构建一个看起来像是以null结尾的字节字符串。我说看起来像是因为只有你被允许读取终止空字符才真的是一个。由于大多数系统CHAR_BIT
为8(required by POSIX},并且由于标准要求int
为at least 32 bits,因此您的计算机极不可能sizeof(char) == sizeof(int)
}。