到目前为止,要打印出指针(地址)的值,我(正确或不正确)使用了%u
格式说明符。在这方面,%p
说明符的含义是什么?它是否打印出仅void*
类型指针的值?我试过这个%p
说明符打印出一个整数指针,看起来输出是一个六进制十进制值。使用%p
打印整数或字符指针值是错误的吗?请告诉我有关%p
格式说明符的信息。网络资源只让我感到困惑。
我从以下链接中找到了问题中的陈述:
答案 0 :(得分:4)
%u
格式'与sizeof(void *) == sizeof(unsigned)
一样长,对于32位代码通常是正确的,但对于64位代码则不然。如果您想要控制格式(您无法控制%p
的外观),那么您将需要使用C99中的<inttypes.h>
:
printf("0x%.8" PRIXPTR "\n", (uintptr_t)&object);
宏PRIXPTR为类型为uintptr_t
的值和转换说明符X
提供了正确的长度修饰符。类型uintptr_t
是一个足以容纳任何指针的整数类型。 .8
确保您至少打印8个十六进制数字,但如果地址是64位数量并且在该值的前导(最高有效)32位中设置了位,则更多。
严格地说,如果你打算使用%p
,那么(a)你应该通过强制转换确保堆栈上的值实际上是void *
(因为fprintf()
等等可变参数函数和转换不会自动发生),以及(b)格式没有跨平台标准。它通常等同于小写十六进制,没有0x
前缀;一些系统生成0x
前缀。在实践中,您通常可以安全地传递int *
。
理论上,在标准C中,没有办法打印函数指针;不能保证函数指针的大小与数据指针的大小相同。幸运的是,POSIX介入并确实声明在POSIX系统上,函数指针的大小应与数据指针的大小相同。因此,至少在Unix系统上,事实上在Windows系统上,您可以安全地打印数据指针和函数指针。
答案 1 :(得分:2)
是的,它用于打印指针所包含的地址。它适用于任何指针类型。
答案 2 :(得分:1)
void*
表示:“指向内存中某处的指针,但我不知道它指向的是哪种类型的内存。”这就是%p
说明符为void*
的原因,因为您不关心类型只有内存地址。它旨在用于打印地址。另一方面,%u
期望数据为unsigned int
,而这可能在实践中有效,void*
和unsigned int
可能有不同的大小等等。所以不应该使用它。另外,正如另一个答案中所提到的,即使所有指针都可以转换为void*
,printf
和可变函数族在技术上也不会执行此转换,因此应该转换为void*
:
printf("%p", (void*)&x);