简体   繁体   English

为什么`cout`中没有output但`printf`可以

[英]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 0000 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM