微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 `cout` 没有输出,但 `printf` 可以

如何解决为什么 `cout` 没有输出,但 `printf` 可以

为了清楚地说明问题,这里是一个最小的代码。为什么我的行 cout << z << endl; 没有输出?我在 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<< 没有 int* 指针的重载,所以表达式 cout << y 最终调用了 void* 重载,它打印出指针所在的内存地址指着。它不会尝试访问所指向的数据。与 printf("%x",z) 相同。

operator<< 确实有一个 unsigned char* 指针的重载,它将指针视为指向以空字符结尾的字符串,与 char* 重载相同。但是 z 不是指向以空字符结尾的字符串的指针,因此您的代码在尝试以这种方式打印 z 时具有 undefined 行为。要打印 z 指向的地址,您需要对 void* 进行显式类型转换,例如:

cout << static_cast<void*>(z)

话虽如此,您的代码不会完全失败的原因是因为作为 int 的数值 15(十六进制 0x0F)恰好包含几个 0x00 字节(其中 3 ,如果 int 的大小为 4 个字节,就像在大多数平台上一样)。根据字节序,int 将在内存中排列为 0F 00 00 0000 00 00 0F。因此,尝试将 z 打印为以空字符结尾的字符串将遇到这些 0x00 字节之一并将其解释为空终止符。如果首先遇到 0x0F 字节,它将被简单地解释为没有视觉表示的 ASCII 控制字符。无论哪种方式,您都不会看到任何内容打印到控制台。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。