C++ “%p”在哪里对printf有用?

C++ “%p”在哪里对printf有用?,c++,c,printf,C++,C,Printf,毕竟,这两种说法的作用是一样的 int a = 10; int *b = &a; printf("%p\n",b); printf("%08X\n",b); 例如(使用不同的地址): 按照需要使用%x格式化指针很简单,因此%p选项是否有一些好的用途?x是无符号十六进制整数(32位) p是指针地址 看。即使他们两个写的都一样,我也会用%p来打印指针。他们做的事情不一样。后一条语句将b解释为无符号int,这是错误的,因为b是指针 指针和无符号ints的大小并不总是相同的,因此它们不能互换。

毕竟,这两种说法的作用是一样的

int a = 10;
int *b = &a;
printf("%p\n",b);
printf("%08X\n",b);
例如(使用不同的地址):


按照需要使用
%x
格式化指针很简单,因此
%p
选项是否有一些好的用途?

x
是无符号十六进制整数(32位)

p
是指针地址


看。即使他们两个写的都一样,我也会用
%p
来打印指针。

他们做的事情不一样。后一条语句将
b
解释为
无符号int
,这是错误的,因为
b
是指针

指针和
无符号int
s的大小并不总是相同的,因此它们不能互换。当它们的大小不同时(随着64位CPU和操作系统变得越来越普遍,这种情况越来越普遍),
%x
将只打印地址的一半。在Mac(可能还有其他一些系统)上,这会破坏地址;输出将是错误的


始终使用
%p
作为指针。

指针的大小可能与
int
的大小不同。另外,当您使用
%p

x
用于以十六进制打印t指针参数时,实现可能会产生比简单的十六进制值更好的地址表示形式


使用
%x
打印时的典型地址看起来像
bffc6e4
,使用
%p
打印的正常地址至少在一个并不罕见的系统上是
0xbffc6e4
,它们不打印相同的地址:

~/src> uname -m
i686
~/src> gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
[some output snipped]
gcc version 4.1.2 (Gentoo 4.1.2)
~/src> gcc -o printfptr printfptr.c
~/src> ./printfptr
0xbf8ce99c
bf8ce99c

例如,请注意指针版本如何添加
0x
前缀。始终使用%p,因为它知道指针的大小以及如何最好地将它们表示为文本。

您不能依靠
%p
显示
0x
前缀。在Visual C++中,它没有。使用
%#p
可移植。

当需要调试时,使用printf和
%p
选项非常有用。当你有一个空值时,你会看到0x0。

是的,我已经浏览了那个页面。我想知道的是,为什么要
使用%p打印指针
。无论如何,Peter Hosey的回答回答了我的疑问。%p还将为平台的指针使用适当的纹理表示。在通常使用十六进制表示指针的平台上,只要大小正确,这并没有什么区别,但对于分段体系结构(还记得DOS吗?)它可能使用段:偏移表示法。还需要使用
%p
格式将
b
转换为
void*
——这是C语言中少数需要转换的实例之一。“全世界都是VAX!”syndrome.Adding to@AlokSinghal comment:for GCC如果使用
-Wextra
标志编译,您将在
printf
中获得不正确类型的适当警告。为了使警告消失,需要使用正确的格式,并将其转换为 Value*/Cuff>。这可以帮助您。通过使用'%P’,您可以打印变量中的地址,“空穴*指针参数以十六进制打印(好像是%x x或%x x x)。”在C++中,可以使用(空*)类型转换符:看到这是在什么地方记录的吗?我找不到关于与%p一起使用的#的任何信息。我已经检查过了:PC Lint不喜欢它,但它在visualstudio中工作。不幸的是,它的前缀是“0X”而不是“0X”,这使得实际值很难读取。这可能是由于缺少“%P”变量造成的。总而言之,这个格式说明符遇到了所有“依赖于平台”的实现的问题,即您无法真正控制将要获得的内容。我使用“0x%p”的风险是在开始时得到一个双0x0X。相反,这会破坏使用它的效果,因为您确切地知道使用%x会得到什么。这似乎根本不可移植,即使在VC版本之间也是如此。例如,VS 2013(12.0.40629.00更新5)为“%#p”添加了前缀“0X”,但没有为“%p”添加前缀。但VC 19.00.23506没有前缀“%p”或“%#p”。然后,G++5.4.0的前缀为“%p”和“%#p”(使用“%#p”会发出G++警告)。简而言之,您根本不能依赖此格式。不,
%x
用于以十六进制打印类型为
无符号int
的值。绝对不能保证
unsigned int
的大小与
void*
的大小相同,在代码中这样假设是个坏主意。“…这并不少见”。Nice:)在gcc(至少4.4.7)上,空值显示为
(nil)
——包括括号。
%p
~/src> uname -m
i686
~/src> gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
[some output snipped]
gcc version 4.1.2 (Gentoo 4.1.2)
~/src> gcc -o printfptr printfptr.c
~/src> ./printfptr
0xbf8ce99c
bf8ce99c