Kernighan & Ritchie では、「符号付きまたは符号なしの char データ型がマシンに依存する場合、すべての印刷可能な文字は正である」と述べています。
誰かがこの行の意味を説明できますか? 私のシステムは文字に署名しましたが、-90 などの負の値を使用しても、printf は文字を出力します (あまりなじみのある文字ではありません)。
Kernighan & Ritchie では、「符号付きまたは符号なしの char データ型がマシンに依存する場合、すべての印刷可能な文字は正である」と述べています。
誰かがこの行の意味を説明できますか? 私のシステムは文字に署名しましたが、-90 などの負の値を使用しても、printf は文字を出力します (あまりなじみのある文字ではありません)。
ASCII 文字セットは、 から0x00
までのコードポイントを定義し0x7F
ます。この範囲は両方に共通であるため、これらが符号なしまたは符号付きバイト値で表されているかどうかは問題ではありません。
印刷可能な文字は と の間0x20
で0x7E
、すべて ASCII の一部です。印刷可能な文字という用語は、世界で印刷可能なすべての文字を定義しているわけではありません。むしろ、ASCII の領域内で定義されます。
0x80
から~のバイト値0xFF
は ASCII で定義されておらず、さまざまなシステムがこの範囲の値にさまざまな文字を割り当てているため、ASCII 範囲は同じでもこの範囲が異なる多くの異なるタイプのコードページが生成されます。これは、符号付きバイトと符号なしバイトの値が異なる範囲でもあります。
の実装は、入力でキーにprintf
遭遇すると、1 バイト値を探します。このバイト値は、関数%c
の呼び出し元としての観点からは符号付きまたは符号なしの場合がありますが、これはわかりません。これらの 8 ビットを接続先の出力ストリームに渡すだけで、そのストリームはおよび内の文字を出力します。printf
printf
0x00
0xff
記号の概念は、文字が出力される出力パイプライン内では意味がありません。255
したがって、aまたは aのどちらを送信しても、特定のコードページで-1
マップされた文字が出力されます。0xFF
-90 は符号付き char として再解釈され、符号なし char として再解釈されます。この場合、値は 166 です (-90 と 166 はどちらも 16 進数で 0xA6 です)。
それは正しい。2 進数はすべて正です。それをネガティブに捉えるかどうかは、あなたの解釈です。共通の 2 つの褒め言葉を使用します。
8 ビット数: 10100110 は正の 166 であり、128 (最大の正の符号付き 8 ビット数) より大きくなります。
符号付き演算を使用すると、数値 166 は -90 になります。
ascii 値が 166 の文字が表示されています。
これを例として使用します。
signed char x = -90;
printf("%c", x);
整数昇格規則は、 に引数として渡す前に に変換x
します。(注、他の回答はこの詳細に言及しておらず、いくつかはへの引数がまだ署名された文字であることを暗示しています)。int
printf
printf
標準のセクション7.21.6.1.6(私はC11標準を使用しています)は、%c
フラグ文字について次のように述べています。
l 長さ修飾子が存在しない場合、int 引数は unsigned char に変換され、結果の文字が書き込まれます。
したがって、整数-90
は unsigned char に変換されます。つまり (6.3.1.3.2):
...値が新しい型の範囲内になるまで、新しい型で表現できる最大値よりも 1 多い値を繰り返し加算または減算することにより、値が変換されます。
システムの unsigned char が 0 から 255 の値を取る場合 (ほぼ確実にそうなります)、結果は -90 + 256 = 166 になります。これは圧倒的に一般的ですが、C 標準では保証されていません)。
次に、文字 166 が stdout に書き込まれ、端末によって解釈されます。