[英]Why there is no output from `cout` but it is ok for `printf`
To clear illustrate the problem, here is a minimal code.为了清楚地说明问题,这里是一个最小的代码。 Why there is no output for my line
cout << z << endl;
为什么我的线路
cout << z << endl;
? ? I am running it on Mac OS, compiler is
Apple clang version 12.0.0 (clang-1200.0.32.29) Target: x86_64-apple-darwin20.3.0
我在 Mac OS 上运行它,编译器是
Apple clang version 12.0.0 (clang-1200.0.32.29) Target: x86_64-apple-darwin20.3.0
#include <iostream>
using namespace std;
int main() {
int x = 15;
int *y = &x;
unsigned char *z = (unsigned char *)&x;
cout << y << endl; //this line works OK
cout << z << endl; //no output of this line
printf("%x", z); // this line works OK
return 0;
}
operator<<
does not have an overload for an int*
pointer, so the expression cout << y
ends up calling the void*
overload, which prints the memory address that the pointer is pointing at. operator<<
没有int*
指针的重载,因此表达式cout << y
最终调用void*
重载,它打印指针指向的 memory 地址。 It doesn't try to access the data being pointed at.它不会尝试访问指向的数据。 Same with
printf("%x", z)
.与
printf("%x", z)
相同。
operator<<
does have an overload for an unsigned char*
pointer, which treats the pointer as pointing to a null-terminated string, same as the char*
overload does. operator<<
确实有一个unsigned char*
指针的重载,它将指针视为指向一个以 null 结尾的字符串,与char*
重载相同。 But z
is not a pointer to a null-terminated string, so your code has undefined behavior when trying to print z
this way.但是
z
不是指向以 null 结尾的字符串的指针,因此在尝试以这种方式打印z
时,您的代码具有未定义的行为。 To print the address that z
is pointing at, you need an explicit typecast to void*
, eg:要打印
z
指向的地址,您需要对void*
进行显式类型转换,例如:
cout << static_cast<void*>(z)
That being said, the reason your code doesn't just fail outright is because the numeric value 15 (hex 0x0F) as an int
happens to contain several 0x00
bytes in it (3 of them, if int
is 4 bytes in size, as it is on most platforms).话虽这么说,您的代码不只是完全失败的原因是因为作为
int
的数值 15(十六进制 0x0F)恰好包含几个0x00
字节(其中 3 个,如果int
的大小为 4 个字节,因为它在大多数平台上)。 Depending on endian, the int
will be laid out in memory as either 0F 00 00 00
or 00 00 00 0F
.根据字节序,
int
将在 memory 中布置为0F 00 00 00
或00 00 00 0F
。 So, trying to print z
as a null-terminated string will encounter one of those 0x00
bytes and interpret it as a null terminator.因此,尝试将
z
打印为以 null 结尾的字符串将遇到这些0x00
字节之一并将其解释为 null 终止符。 If the 0x0F
byte is encountered first, it will simply be interpreted as an ASCII control character that has no visual representation.如果首先遇到
0x0F
字节,它将被简单地解释为没有视觉表示的 ASCII 控制字符。 Either way, you won't see anything being printed to the console.无论哪种方式,您都不会看到任何内容被打印到控制台。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.