ベストアンサー
何かのアドレスを出力する必要がある場合、またはポインタ変数の内容、それを行うための唯一の真に移植可能な方法は、%p形式指定子を使用することです。 C標準では、出力される文字は実装定義であると規定されていますが、実際には、ほとんどのCライブラリ実装は、アドレスを表す16進数のシーケンスを生成します。
%uおよび%x形式指定子は、符号なし整数を想定しています。値をそれぞれ10進数と16進数で出力します。 アドレスを期待していません。
%uまたは%x(または%p以外)を使用してアドレスを出力すると、一部の環境では動作するように見える場合がありますが、実際には未定義の動作 spanになります>および非移植可能。ポインタのサイズが符号なし整数(またはその他の整数データ型)のサイズと同じであると想定することはできません。たとえば、多くの64ビット環境では、符号なし整数は32ビットです。ポインタのビット数が環境内の符号なし整数のビット数と一致せず、%uまたは%xを使用してアドレスを出力しようとすると、誤った出力が返され、後続の出力が返されます。 printfへの同じ呼び出しの項目も正しくない可能性があります。
したがって、アドレスを出力する場合は、未定義の動作を回避する移植可能なコードとして、常に%p形式指定子を使用してください。ポインタのサイズが他のCデータ型のサイズと同じであると思い込まないでください。
回答
\%p
のみ変換はポインタを正しく理解します。 \%p
変換は、実装固有の方法でポインターを出力します。
\%u
および\%x
変換はunsigned int
またはint
タイプ用であり、ポインタータイプと同じサイズである場合とそうでない場合があります。 \%u
変換は符号なし10進整数を出力し、\%x
は符号なし16進整数を小文字で出力します。
To \%u
または\%x
のいずれかを使用してポインターを出力するには、ポインターをint
またはunsigned int
。 sizeof(void *) > sizeof(int)
の場合、そのキャストは情報を失う可能性があります。