web-dev-qa-db-ja.com

printfで `%p`はどこで便利ですか?

結局のところ、これらのステートメントは両方とも同じことをします...

int a = 10;
int *b = &a;
printf("%p\n",b);
printf("%08X\n",b);

例(異なるアドレス):

0012FEE0
0012FEE0

%xを使用してポインタを希望どおりにフォーマットするのは簡単です。したがって、%pオプションを使用する方法はありますか?

56
Moeb

彼らは同じことをしません。後者の printf ステートメントはbunsigned intとして解釈しますが、bはポインターであるため間違っています。

ポインターとunsigned intsは常に同じサイズではないため、これらは互換性がありません。それらが同じサイズではない場合(64ビットCPUとオペレーティングシステムが一般的になるにつれて、ますます一般的なケース)、%xはアドレスの半分のみを出力します。 Mac(およびおそらく他のシステム)では、そのwillはアドレスを台無しにします。出力は間違っています。

ポインターには常に%pを使用します。

123
Peter Hosey

少なくとも珍しいことではない1つのシステムでは、同じものは印刷されません。

~/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を使用します。

8
unwind

%pプレフィックスを表示する0xに依存することはできません。 Visual C++では、そうではありません。 %#pを使用して移植可能にします。

5
Mauritius

ポインターのサイズは、intのサイズとは異なる場合があります。また、%pを使用すると、実装はアドレスの単純な16進値表現よりも優れた結果を生成できます。

4
Tronic

xは符号なし16進整数(32ビット)

pはポインターアドレスです

C++リファレンスのprintf を参照してください。たとえ両方が同じものを書いたとしても、私は%pポインタを印刷します。

2
Filip Ekberg

デバッグする必要があるときは、%pオプションを指定してprintfを使用すると非常に便利です。 NULL値がある場合、0x0が表示されます。

0
albttx