回答:
C ++には、3つの異なる文字タイプがあります。
charsigned charunsigned charテキストに文字タイプを使用している場合は、修飾なしを使用しますchar。
'a'orのような文字リテラルのタイプです'0'。"abcde"数値としても機能しますが、その値が符号付きとして扱われるか、符号なしとして扱われるかは不定です。不等式による文字比較に注意してください。ただし、ASCII(0〜127)に限定すると、安全です。
数値として文字タイプを使用している場合は、次を使用します。
signed char、少なくとも -127から127の範囲を提供します。(-128から127が一般的)unsigned char、これにより、少なくとも 0〜255の範囲が得られます。「少なくとも」。これは、C ++標準では、各数値型がカバーする必要のある値の最小範囲のみを提供するためです。sizeof (char)1(つまり1バイト)である必要がありますが、1バイトは理論的にはたとえば32ビットにすることができます。sizeofそれでもとしてそのサイズを報告されるだろう1あなたがいることを意味- 可能性が持っていますsizeof (char) == sizeof (long) == 1。
sizeof関数ではなく演算子なので、後にスペースを置くのが一般的です。変数のサイズをとるときに括弧を省略すると、さらに良いスタイルになります。sizeof *pまたはsizeof (int)。これは、それが型または変数に適用される場合、すぐに明確になります。同様に、の後に括弧を置くことも冗長returnです。関数ではありません。
char:'a'またはのような文字リテラルのタイプです'0'。」C ++ではtrueですが、Cで'a'はありません。Cでは、ですint。
C標準ではの符号付きが定義されていないため、これは実装に依存しますchar。プラットフォームによっては、charがsignedまたはのunsigned場合があるため、明示的に要求するsigned charかunsigned char、実装がそれに依存しているかどうかを確認する必要があります。charこれは、プラットフォームが文字列に入力するものと一致するため、文字列の文字を表す場合にのみ使用します。
違いsigned charとは、unsigned charあなたが期待通りです。ほとんどのプラットフォームでは、signed char範囲の8ビットの2の補数になり-128まで127、およびunsigned char8ビットの符号なし整数(あろう0に255)。標準では、char型が8ビットである必要はなく、それだけがsizeof(char)返されることに注意してください1。あなたはと文字のビット数で取得することができますCHAR_BITでlimits.h。ただし、これが以外のプラットフォームになる今日のプラットフォームはほとんどありませ8ん。
この問題の良い要約がここにあります。
私がこれを投稿して以来他の人が述べたように、あなたは使用int8_tしたほうがよく、uint8_t本当に小さな整数を表現したいのなら。
CHAR_BIT規格では少なくとも8ビットである必要があります。
私はそれが本当に求められていると感じているので、CとC ++のいくつかの規則を述べたいだけです(これらに関しては同じです)。まず、のすべてのビットがunsigned char、符号なしcharオブジェクトの値の決定に参加します。第二に、unsigned char署名されていないことが明示的に述べられています。
ここで、-1int型の値をに変換するとどうなるかについて誰かと話し合いましたunsigned char。彼は、結果のunsigned charすべてのビットが1に設定されているという考えを拒否しました。これは、彼が符号の表現について心配していたためです。しかし、彼はそうする必要はありません。変換が意図したとおりに行われるのは、このルールの直後です。
新しい型が符号なしの場合、値は、値が新しい型の範囲内になるまで、新しい型で表すことができる最大値よりも1だけ多く加算または減算することによって変換されます。(
6.3.1.3p2C99ドラフト)
それは数学的な説明です。C ++では、同じ規則が得られるモジュロ計算の観点から説明しています。とにかく、整数のすべてのビットが変換前は1 であることは保証されていません-1。それで、結果にunsigned charはすべてのCHAR_BITビットが1になっていると主張できるように、何がありますか?
UCHAR_MAX+1する-1と、範囲内の値、つまりUCHAR_MAX実際はそれで十分です!つまり、unsigned charすべてのビットを1にしたいときはいつでも、
unsigned char c = (unsigned char)-1;
また、変換では上位ビットが切り捨てられるだけではありません。2の補数の幸運な出来事は、単なる切り捨てであるということですが、他の符号表現については必ずしもそうではありません。
UCHAR_MAXですか?
(unsigned type)-1イディオムのいくつかの種類です。~0そうではありません。
int x = 1234とchar *y = &x。のバイナリ表現は1234 です00000000 00000000 00000100 11010010。私のマシンはリトルエンディアンなので、逆にして、11010010 00000100 00000000 00000000LSBを最初にメモリに格納します。今本編。私が使用する場合printf("%d" , *p)。printf最初のバイトを読みますと、11010010出力のみである-46が、11010010ある210、それは印刷しない理由そう-46。私は本当に混乱しています.charからintegerへの昇格が何かをしていると思いますが、わかりません。
unsigned charの使用例として:
unsigned charコンピュータグラフィックスでよく使用されます。(常にではありませんが)多くの場合、各カラーコンポーネントに1バイトを割り当てます。RGB(またはRGBA)カラーが24ビット(または32ビット)で表されるのが一般的unsigned charです。以来unsigned charの値が[0,255]の範囲に入る、値は典型的に解釈されます。
したがって、RGB赤は(255,0,0)->(100%赤、0%緑、0%青)になります。
なぜ使用しないのsigned charですか?算術演算とビットシフトは問題になります。すでに説明したように、a signed charの範囲は基本的に-128シフトします。RGBをグレースケールに変換するための非常にシンプルで素朴な(ほとんど使用されていない)方法は、3つのカラーコンポーネントすべてを平均化することですが、これはカラーコンポーネントの値が負の場合に問題になります。unsigned char算術を使用すると、赤(255、0、0)は平均して(85、85、85)になります。ただし、値がsigned chars(127、-128、-128)の場合、最終的には(-99、-99、-99)となり、unsigned char空間では(29、29、29)となりますが、これは正しくありません。 。
文字を短整数として使用したい場合、最も安全な方法はint8_tおよびuint8_tタイプを使用することです。
int8_tでuint8_tはありません。また、オプションであり、バイトサイズが正確に8ビットではないアーキテクチャでは定義されていません。逆に、signed charそしてunsigned char少なくとも8ビットで常に利用可能と保持することが保証されています。一般的な方法かもしれませんが、最も安全ではありません。
signed charとunsigned char?それとも、その特定のケースでより良い「より安全な」代替手段をお勧めしますか?たとえば、「実際の」整数型に固執するためにsigned int、unsigned int代わりに何らかの理由で?
signed charと、unsigned char準拠するすべての実装に移植可能であり、ストレージスペースを節約できますが、コードサイズが多少大きくなる可能性があります。場合によっては、ビットフィールドまたは通常の整数型の単一ビットに小さな値を格納することで、より多くのストレージスペースを節約できます。この質問に対する絶対的な答えはありません。このアプローチの適切性は、目前の特定のケースに依存します。そして、この答えはとにかく質問に対処していません。
charまたunsigned char、すべてのプラットフォームで8ビット型であるとは限りません。8ビット型以上であることが保証されています。一部のプラットフォームには、9ビット、32ビット、または64ビットのバイトがあります。ただし、現在最も一般的なプラットフォーム(Windows、Mac、Linux x86など)のバイト数は8ビットです。
アンは、unsigned char符号なしバイト値(0〜255)です。あなたはchar「キャラクター」であると考えているかもしれませんが、それは実際には数値です。レギュラーcharは署名されているため、128個の値があり、これらの値はASCIIエンコーディングを使用して文字にマッピングされます。ただし、どちらの場合も、メモリに格納しているのはバイト値です。
直接値に関しては、値が中間CHAR_MINであることがわかっている場合に通常の文字が使用されCHAR_MAX、符号なし文字の場合は正の端の範囲が2倍になります。たとえば、CHAR_BITが8の場合、レギュラーの範囲は[0、127 ]であることがchar保証されます(署名付きまたは署名なしのため)unsigned char。ただし、signed char[0、255 ]であり、[-127、127]になります。
それが何のために使用されるかという点では、標準により、POD(プレーンな古いデータ)のオブジェクトをunsigned charの配列に直接変換できます。これにより、オブジェクトの表現とビットパターンを調べることができます。安全な型パンニングの同じ保証は、charまたはsigned charには存在しません。
unsigned charない、配列特異的に、および任意の「変換」は唯一の正式によって定義されるコピー実際の対象物から、宣言された配列のunsigned char&次いで後者を検査します。ORがそのような配列として直接再解釈できるかどうか、ポインタの算術を考慮に入れて、つまり==この使用法で「シーケンス」「配列」が可能かどうかは明確ではありません。これが明確になることを期待して開かれたコア問題#1701があります。ありがたいことに、最近この曖昧さが本当に私を悩ませています。
unsigned char++ptrmemcpy
unsigned charあらゆるトリックの中心です。ALLプラットフォームのほとんどすべてのコンパイラでunsigned charは、これは単なるバイトであり、(通常)8ビットの符号なし整数であり、短整数またはビットのパックとして扱うことができます。
中毒では、誰かが言ったように、標準はcharの符号を定義していません。あなたが3つの異なる持っているcharタイプを:char、signed char、unsigned char。
unsigned charは、通常のcharの符号用に予約されているビットを別の数値として使用します。これにより、範囲が[-128-127]ではなく[0-255]に変更されます。
通常、署名が不要な場合は、署名されていない文字が使用されます。これは、ビットをシフトする(シフトが符号を拡張する)などのことや、charを数値として使用するのではなく、バイトとして扱う場合に違いをもたらします。
signed charそして、unsigned charの両方が1バイトを表しますが、彼らは異なる範囲を持っています。
Type | range
-------------------------------
signed char | -128 to +127
unsigned char | 0 to 255
ではsigned char、我々は検討している場合char letter = 'A'、「A」は65のバイナリを表すであるASCII/Unicode65を格納することができた場合は、-65も保存することができます。に負のバイナリ値はありませんASCII/Unicode負の値を気にする必要ありません。
例
#include <stdio.h>
int main()
{
signed char char1 = 255;
signed char char2 = -128;
unsigned char char3 = 255;
unsigned char char4 = -128;
printf("Signed char(255) : %d\n",char1);
printf("Unsigned char(255) : %d\n",char3);
printf("\nSigned char(-128) : %d\n",char2);
printf("Unsigned char(-128) : %d\n",char4);
return 0;
}
出力-:
Signed char(255) : -1
Unsigned char(255) : 255
Signed char(-128) : -128
Unsigned char(-128) : 128