私は次のコードを持っています:
#include <stdio.h>
int main() {
unsigned int a = -1;
int b = -1;
printf("%x\n", a);
printf("%x\n", b);
printf("%d\n", a);
printf("%d\n", b);
printf("%u\n", a);
printf("%u\n", b);
return 0;
}
出力は次のとおりです。
ffffffff
ffffffff
-1
-1
4294967295
4294967295
値は、printf
関数に渡された値に応じて、符号付きまたは符号なしとして解釈されることがわかります。どちらの場合も、バイトは同じです(ffffffff
)。それでは、unsigned
Wordは何のためですか?
_int -1
_をunsigned
に割り当てます。_-1
_は_[0...UINT_MAX]
_の範囲に収まらないため、答えが範囲内になるまで_UINT_MAX+1
_の倍数が追加されます。明らかに_UINT_MAX
_はOPのマシンではpow(2,32)-1 or 429496725
であるため、a
の値は4294967295。
_ unsigned int a = -1;
_
_"%x"
_、_"%u"
_指定子には、一致するunsigned
が必要です。これらは一致しないため、「変換仕様が無効の場合、動作は未定義です。引数が対応する変換仕様の正しい型でない場合、動作は未定義です。」 C11§7.21.6.19. printf指定子はb
を変更しません。
_ printf("%x\n", b); // UB
printf("%u\n", b); // UB
_
_"%d"
_指定子は、一致するint
を予期しています。これらは一致しないため、さらに[〜#〜] ub [〜#〜]。
_ printf("%d\n", a); // UB
_
未定義の動作を考えると、結論はサポートされていません。
どちらの場合も、バイトは同じです(ffffffff)。
同じビットパターンであっても、異なるタイプは異なる値を持つ場合があります。 ffffffff
としてのunsigned
の値は4294967295です。int
としては、符号付き整数エンコーディングに応じて、-1、-2147483647またはTBDの値があります。 float
として [〜#〜] nan [〜#〜] になる場合があります。
署名のないWordは何のためにあるのですか?
unsigned
は、範囲_[0 ... UINT_MAX]
_の整数を格納します。負の値を持つことはありません。コードに負でない数が必要な場合は、unsigned
を使用します。コードに+、-、または0のカウント数が必要な場合は、int
を使用します。
更新:署名されたint
をunsigned
に割り当てることに関するコンパイラの警告を回避するには、以下を使用します。これは、否定されるunsigned
_1u
_です-これは上記のように明確に定義されています。効果は_-1
_と同じですが、コンパイラーに直接的な意図を伝えます。
_unsigned int a = -1u;
_
変数宣言にunsigned
を含めると、プログラマー自身にとってより便利です。変数を負として扱わないでください。お気づきのとおり、_-1
_と_4294967295
_の両方は、4バイト整数に対してまったく同じビット表現を持っています。それは、あなたがどのようにtreatまたはseeにしたいかについてです。
ステートメント_unsigned int a = -1;
_は、2の補数で_-1
_を変換し、a
のビット表現を割り当てています。 printf()
指定子x
、d
およびu
は、変数a
に格納されたビット表現が異なる形式でどのように見えるかを示しています。
unsigned int a to -1;
を初期化すると、2's
の補数-1
を格納していることを意味します)a
のメモリに。
これは0xffffffff
または4294967295
に他なりません。
したがって、%x or %u
形式指定子を使用して印刷すると、その出力が得られます。
変数の符号付きを指定して、保存できる値の最小値と最大値を決定します。
unsigned int
と同様:範囲は0 to 4,294,967,295
およびint
から:範囲は-2,147,483,648 to 2,147,483,647
から
署名の詳細については、 this を参照してください