unsigned int の出力が次のコードで負になる理由がわかりません。署名されたintのように。
uint32_t yyy=1<<31;
printf("%d\n",yyy);
出力は次のとおりです。
-2147483648
です-2^31
。
unsigned int の出力が次のコードで負になる理由がわかりません。署名されたintのように。
uint32_t yyy=1<<31;
printf("%d\n",yyy);
出力は次のとおりです。
-2147483648
です-2^31
。
のフォーマット指定子はではなくを%d
想定しているため、コードの動作は未定義です。C99 標準セクション7.19.6.1 から fprintf 関数:int
unsigned int
対応する変換指定に対して正しい型でない引数がある場合、動作は未定義です。
用途: %u
_unsigned int
uint32_t yyy=1u<<31;
printf("%u\n",yyy);
出力:
2147483648
これは、printf 引数が %d として暗黙的に数値を int に変換しているためです。
代わりに %u を使用してください。
%u
符号なし数値を出力するために使用します。
printf("%u\n", yyy);
整数は2 の補数形式で格納されます。これは、値を見ただけでは数値が符号付きか符号なしかを判断する方法がないことを意味します。使用する表現をマシンに伝え、それを自分で追跡する必要があります。
あなたの例では、 jjj
(型チェックのために) 署名されていないことをマシンに伝えますが、フォーマット文字列でprintf()
使用して署名済みとして扱うように要求し%d
ます (型情報を取得できません)。unsigned int を出力したい場合は、%u
代わりに使用してください。
printf
可変数の引数を取ります。あなたがそれを呼び出すと、コンパイラはそれらすべてを忠実にスタックに置きます。C であるため、リフレクションprintf
はありません。受け取ったものの型を後で推測することはできません。ビットレベルでは、符号付き整数を符号なし整数または浮動小数点数、適切に小さい構造体、大きな構造体の一部などと区別することはできません。
そのため、フォーマット文字列も指定する必要があります。printf
スタックから読み取るタイプとその順序を示します。そのフォーマット文字列に完全に依存しており、それを検証する機能はありません。
したがって、すでに投稿されている1行の回答に従って、フィールドを署名された数量として解釈するように指示すると、署名された数量として印刷されます。
unsigned int
フォーマット指定子を使用する必要があります。
printf("%u\n",yyy);
^^
間違ったフォーマット指定子を使用するprintf
と未定義の動作になります。これは、C99 ドラフト標準セクションでカバーされています。フォーマット指定子に関してもカバーする7.19.6.1
fprintf 関数は、次のように述べています。printf
変換指定が無効な場合、動作は未定義です。248)引数が対応する変換仕様の正しい型でない場合、動作は未定義です。
のcpp リファレンスページにprintf
は、使用可能な書式指定子を指定する優れた表があります。
署名済みとして印刷しているためです。%u
代わりに使用してください。