web-dev-qa-db-ja.com

Cで%uと%dを使用してメモリアドレスを印刷することの違いは?

C本を読んでいます。変数のメモリアドレスを出力するために、本では次のものを使用することがあります。

printf("%u\n",&n);

時々、著者は書きました:

printf("%d\n",&n);

結果は常に同じですが、2つの違いがわかりません(符号なしの%uは知っています)。

誰かこれについて詳しく教えてもらえますか?

どうもありがとう。

12
ipkiss

%uは整数を符号なしとして扱い、%dは整数を符号付きとして扱います。整数が0〜INT_MAX(2の場合)31-1(32ビットシステムの場合)、出力はどちらの場合も同じです。

整数が負の場合(符号付き入力の場合)またはINT_MAX+1UINT_MAXの間(例:231 と232-1)。その場合、%d指定子を使用すると負の数が返されますが、%uを使用すると大きな正の数が返されます。

アドレスは符号なしの数値としてのみ意味があるため、符号付きの数値として出力する理由はありません。さらに、それらが印刷されるとき、それらは通常、10進数ではなく16進数(%x形式指定子を使用)で印刷されます。

ただし、実際にはアドレスには%p形式指定子を使用する必要があります。すべての有効なポインターで機能することが保証されています。 32ビット整数で64ビットポインターのシステムを使用している場合、llの長さなしで%d%u、または%xのいずれかでポインターを印刷しようとすると修飾子を使用すると、その結果と後で出力されるその他の結果が間違ったものになります(printfは、ポインター引数の8バイトのうち4バイトしか読み取らないため)。 llの長さ修飾子を追加すると、32ビットシステムに移植できなくなります。

結論:ポインター/アドレスを出力するには、常に%pを使用します。

printf("The address of n is: %p\n", &n);
// Output (32-bit system): "The address of n is: 0xbffff9ec"
// Output (64-bit system): "The address of n is: 0x7fff5fbff96c"

正確な出力形式は実装定義(C99§7.19.6.1/ 8)ですが、ほとんどの場合、通常は先頭に0xが付いた符号なし16進数として出力されます。

38
Adam Rosenfield

%dおよび%uは、最上位ビットが設定されていなくても同じ結果を出力します。ただし、これはまったく移植性のないコードであり、優れたスタイルではありません。あなたの本がこの例から思われるよりも良いことを望みます。

1
Raph Levien

どのような価値を試しましたか?ご存じのとおり、符号なしと符号付きの違い。それで、それは何をし、あなたは何を期待しましたか?

正の符号付き値は符号なしと同じように見えるので、テストに小さい値を使用したと思いますか?負の値はどうですか?

最後に、変数のアドレスを印刷しようとしている場合(表示されているように)、代わりに%pを使用します。

0
Jonathan Wood

すべてのアドレスは、マシンに応じて32ビットまたは64ビットの符号なしです(負のアドレスに書き込むことはできません)。 %dの使用は適切ではありませんが、通常は機能します。 %uまたは%ulを使用することをお勧めします。

0
steveo225

そのような違いはありません。ポインタの学習を始めたばかりの場合は混乱しないでください。 %uは署名されていないもので、%dは署名されたものです

0
Faraz Malik