ルーツはコンパイラの歴史にあります。80 年代には、本質的に 2 つの C 方言がありました。
- プレーン char が署名されている場所
- プレーン char が署名されていない場合
これらのうち、C89 が標準化すべきものはどれですか? C89 はどちらも標準化することを選択しませんでした。それは、標準化された人々がインストール ベースと呼ぶ、既に記述された C コードで行われた多数の仮定が無効になるためです。したがって、C89 は K&R と同じことを行いました。プレーン char の署名を実装定義のままにします。特定の署名が必要な場合は、char を修飾します。最近のコンパイラでは通常、オプションで方言を選択できます (例: gcc の-funsigned-char
)。
(un)signed char とプレーン char の違いを無視した場合に発生する可能性のある「ひどい」ことは、これらの詳細を考慮せずに算術演算とシフトを行うと、予期しないときに符号拡張が発生する可能性があることです。逆もまた同様です(またはシフト時の未定義の動作でさえ)。
また、明示的な符号付きまたは符号なし修飾子を使用して常に文字を宣言することを推奨する愚かなアドバイスもあります。これは、そのような修飾された型へのポインターのみを操作する限り機能しますが、文字列と文字列関数を扱うとすぐに醜いキャストが必要になります。これらはすべて、プレーン文字へのポインターで動作します。キャスト。そのようなコードは、突然、骨の折れる大量の醜いキャストで埋め尽くされます。
文字の基本的なルールは次のとおりです。
- 文字列にplain
char
を使用し、プレーンcharを取る関数にポインタを渡す必要がある場合
unsigned char
バイトのビット調整とシフトを行う必要がある場合に使用します
signed char
小さな符号付きの値が必要な場合に使用しますがint
、スペースが問題にならない場合は使用を検討してください