【问题标题】:difference between printf() and std::cout with respect to pointersprintf() 和 std::cout 在指针方面的区别
【发布时间】:2020-03-26 13:40:39
【问题描述】:

我是指针新手,但我无法弄清楚一件简单的事情。

   int main ()
{
    char *str1="pointer";
    printf("%p \n", str1);
    cout << str1<<endl;
    return 0;
}

输出如下:

0000000000409001
pointer

谁能解释一下这里的区别。 为什么 cout 不打印内存地址?如何让 cout 打印 str1 的地址?

【问题讨论】:

  • 这里的差异是由您提供的printf的格式说明符(%p)造成的。
  • 虽然洪流发生在下面,你能详细说明你的困惑点吗?很清楚你已经知道%pprintf 做了什么。您是否感到困惑,为什么std::cout &lt;&lt; str not 打印指针值,而是打印字符串内容?如果是这样,这是由于输出流上的运算符重载,其中库提供的rhs char* 重载将钻入字符串并实际打印内容而不仅仅是地址。跨度>
  • 简短回答:在 C++ 中,当您使用 &lt;&lt;cout 打印某些内容时,您会得到一个旨在最大程度地有用和方便的默认格式。对于int,您会得到类似%d 的信息。对于char *,您会得到类似%s 的信息。要获得更像%p 的内容,请参阅下面@tmlen 的答案。
  • @SteveSummit 非常感谢。

标签: c++ c pointers printf cout


【解决方案1】:

格式说明符%p 打印void *,(不正确:所以char * 隐式转换为void *char * 在打印前转换为void *。 (但这实际上是未定义的行为,请参阅 cmets。正确的做法是 printf("%p", (void *) str1);)相应的 C++ 代码是 std::cout &lt;&lt; (void *) str1 &lt;&lt; '\n';

代码std::cout &lt;&lt; str1;str1 打印为空终止字符串。对应的 C 代码为 printf('%s', str1);

【讨论】:

  • 在将指针传递给%p 格式时,您需要显式地将指针转换为void *,以避免未定义的行为,顺便说一句。
  • "char * 在打印前被隐式转换为 void *" --> 在 C 中,no 发生了隐式转换。 char *void* 恰好有相同的编码。最好按照@Shawn 使用void * 进行显式转换。
【解决方案2】:

指针是指向内存中某个位置的地址。

"pointer" 是内存中的 C 字符串,8 个字节用于字母和一个终止 NULL 字节。 str1 是指向第一个字母'p' 的字节的指针。


printf("%p", str1) 打印指针本身的值,即内存地址(在本例中为 0000000000409001)。

printf("%s", str1) 将打印pointer,即位于str1 位置的C 字符串的内容。


cout &lt;&lt; str1 &lt;&lt; endl 还打印 C 字符串的内容。这是char* 类型指针的默认行为,因为它们通常是字符串。

cout &lt;&lt; static_cast&lt;void*&gt;(str1) &lt;&lt; endl 会再次打印指针的地址。

【讨论】:

  • 我认为使用 &str 而不是 (void*)str 会打印出指针本身的地址,而不是第一个元素的地址('p ' 在“指针”中)。
【解决方案3】:

char* 是指向字符数组开头的指针。

cout“识别”一个 char* 并将其视为字符串。

您明确告诉 printf() 使用 %p 格式化程序打印出指针地址的十进制表示。

您明确告诉 printf() 使用 %p 格式化程序打印出指针地址的表示

编辑:根据评论进行编辑以确保准确性

【讨论】:

  • 而不是“打印出十进制表示”更像是“打印出一些表示,也许是十六进制”
  • @chux-ReinstateMonica 感谢您的评论。为准确性而编辑。
猜你喜欢
  • 1970-01-01
  • 2015-11-27
  • 2013-03-24
  • 1970-01-01
  • 2015-01-13
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
  • 2011-09-22
相关资源
最近更新 更多