char を正の値として出力しようとしています:
char ch = 212;
printf("%u", ch);
しかし、私は得る:
4294967252
どうすれば212
出力に入ることができますか?
ch
あなたを宣言する
unsigned char ch = 212 ;
そしてあなたのprintfはうまくいきます。
これは、この場合、char
タイプがシステムで署名されているためです*。これが発生すると、デフォルトの変換中にデータが符号拡張され、可変数の引数でデータが関数に渡されます。212 は 0x80 より大きいため、負として扱われ%u
、数値を大きな正の数として解釈します。
212 = 0xD4
符号拡張FF
すると、番号の前に s が追加されるため、次のようになります。
0xFFFFFFD4 = 4294967252
これは、印刷される番号です。
この動作は実装に固有のものであることに注意してください。C99 仕様によると、すべてのchar
型は (signed) に昇格されます。これは、 は、符号付きまたは符号なしの a のすべての値を表すことができるint
ためです。int
char
6.1.1.2:
int
が元の型のすべての値を表すことができる場合、値はint
;に変換されます。それ以外の場合は、に変換されますunsigned int
。
int
これにより、が必要なフォーマット指定子%u
にが渡されますunsigned int
。
プログラムで未定義の動作を回避するには、次のように明示的な型キャストを追加します。
unsigned char ch = (unsigned char)212;
printf("%u", (unsigned int)ch);
char
、実装にまでの署名が残されています。詳細については、この質問を参照してください。
このコードには 2 つのバグがあります。まず、signed を使用するほとんどの C 実装では、 212 が 8 ビットの signed に適合せず、C 標準では動作が完全に定義されていないためchar
、問題があります (動作を定義するには実装が必要です)。代わりに次のようにする必要があります。char ch = 212
char
unsigned char ch = 212;
2 番目の in はprintf("%u",ch)
、通常の C 実装ではch
an に昇格されます。int
ただし、%u
指定子は を想定してunsigned int
おり、C 標準では、間違った型が渡された場合の動作を定義していません。代わりに次のようにする必要があります。
printf("%hhu", ch);
( の場合%hhu
、通常の C 実装では に昇格された がprintf
期待されます。)unsigned char
int
何らかの理由で宣言を変更できない場合は、次のことができます。
char ch = 212;
printf("%d", (unsigned char) ch);