C/C++では、どのunsigned char
が使われていますか?通常のchar
とどう違うのですか?
C++では、3つのdistinct文字タイプがあります。
char
signed char
unsigned char
textに文字タイプを使用している場合は、修飾されていないchar
を使用してください。
'a'
や'0'
のような文字リテラルの型です。"abcde"
のようなCの文字列を構成する型です数値としても機能しますが、その値が符号付きとして扱われるか符号なしとして扱われるかは指定されていません。不等式による文字比較には注意してください - 自分自身を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
を持っているという意味.
C標準ではchar
の符号付きを定義していないため、これは実装に依存します。プラットフォームによっては、charがsigned
またはunsigned
なので、実装に依存している場合は、明示的にsigned char
またはunsigned char
を要求する必要があります。あなたのプラットフォームが文字列に入れるものと一致するので、あなたが文字列から文字を表現するつもりならばchar
を使用してください。
signed char
とunsigned char
の違いはご想像のとおりです。ほとんどのプラットフォームでは、signed char
は-128
から127
までの範囲の8ビットの2の補数で、unsigned char
は8ビットの符号なし整数(0
から255
)です。規格はchar
型が8ビットであることを要求していません、sizeof(char)
が1
を返すことだけを注意してください。 CHAR_BIT
のlimits.h
でcharのビット数を取得できます。ただし、これが8
以外のものになるプラットフォームは今日ではほとんどありません。
この問題についての良い要約があります ここ 。
私がこれを投稿してから他の人が言ったように、あなたが本当に小さい整数を表現したいのであればint8_t
とuint8_t
を使うほうが得策です。
私はそれが本当に求められていると思うので、私はちょうどCとC++のいくつかの規則を述べたい(これらはこの点で同じである)。まず、unsigned char
のall bitsが、符号なしcharオブジェクトがあればその値の決定に参加します。次に、unsigned char
は符号なしで明示的に述べられています。
さて、int型の値-1
をunsigned char
に変換するとどうなるかについて、誰かと話し合った。彼は符号表現について心配していたので、結果のunsigned char
はすべてのビットが1に設定されているという考えを拒否しました。しかし、彼はする必要はありません。意図したとおりの変換が行われるのは、この規則のすぐ後に続きます。
新しい型が符号なしの場合、値が新しい型の範囲内になるまで、新しい型で表すことができる最大値よりも1つ多い値を加算または減算することによって、値が変換されます。 (C99ドラフトの
6.3.1.3p2
)
それは数学的な説明です。 C++ではこれをモジュロ計算で記述していますが、これは同じ規則に従います。とにかく、notが保証されているのは、整数-1
のすべてのビットが変換前の1であることです。それで、私たちは何を持っているので、結果のunsigned char
はすべてのCHAR_BIT
ビットが1になっていると主張することができますか?
UCHAR_MAX+1
に-1
を1回だけ追加すると、範囲内の値、つまりUCHAR_MAX
が得られます。これで十分です。そのため、unsigned char
のすべてのビットを1にしたい場合はいつでも
unsigned char c = (unsigned char)-1;
また、変換は、上位ビットを切り捨てるだけのnotになります。 2の補数の幸運な出来事は、それがただの切り捨てであるということですが、他の符号表現についても同じことが必ずしも当てはまるわけではありません。
例えば unsigned char の使い方は:
unsigned char はコンピュータグラフィックスでよく使用されますが、これは非常に頻繁に(常にではありませんが)各色成分に1バイトを割り当てます。 RGB(またはRGBA)色が24(または32)ビットで表され、それぞれ unsigned char となるのが一般的です。 unsigned char の値は[0,255]の範囲にあるため、値は通常次のように解釈されます。
ですから、(255,0,0) - >(100%赤、0%緑、0%青)のようにRGB赤になります。
なぜ signed char を使わないのですか?算術演算とビットシフトは問題になります。すでに説明したように、 signed char の範囲は基本的に-128だけシフトされます。 RGBをグレースケールに変換するための非常に単純で素朴な(ほとんど未使用の)方法は、3つの色成分すべてを平均化することですが、色成分の値が負の場合、これが問題になります。 unsigned char 算術演算を使用した場合、赤(255、0、0)の平均は(85、85、85)です。しかし、値が signed char s(127、-128、-128)の場合、(-99、-99、-99)となり、(29、29、29)となります。私たちの unsigned char spaceでは、これは正しくありません。
文字を小さな整数として使いたい場合、最も安全な方法はint8_t
とuint8_t
型を使うことです。
signed char
の範囲は-128から127です。 unsigned char
の範囲は0から255です。
char
は、コンパイラに応じてsigned charまたはunsigned charのいずれかと同等になりますが、区別できる型です。
Cスタイルの文字列を使用している場合は、char
を使用してください。算術に文字を使う必要がある場合(ごくまれですが)、移植性のために符号付きまたは符号なしを明示的に指定してください。
char
とunsigned char
はすべてのプラットフォームで8ビット型であることを保証されているわけではありません - それらは8ビット以上であることが保証されています。プラットフォームによっては、 9ビット、32ビット、または64ビットのバイト があります。しかし、今日最も一般的なプラットフォーム(Windows、Mac、Linux x86など)は8ビットバイトを持っています。
直接値に関しては、値がCHAR_MIN
とCHAR_MAX
の間にあることがわかっている場合は通常のcharが使用されますが、符号なしcharは正の端で範囲を2倍にします。たとえば、CHAR_BIT
が8の場合、通常のchar
の範囲は[0、127]であることが保証されているだけです(符号付きまたは符号なしの可能性があるため)。一方、unsigned char
は[0、255]、signed char
は[-127、127]です。 ]。
それが何のために使われているかという点では、標準はPOD(plain old data)のオブジェクトが直接unsigned charの配列に変換されることを可能にします。これにより、オブジェクトの表現とビットパターンを調べることができます。安全な型のパニングの同じ保証は、charまたはsigned charには存在しません。
unsigned char
は正の値だけを取ります.... 0 から 255 のように
どこで
signed char
は正と負の両方の値を取ります.... -128 から +127 のように
Unsigned charは(符号なし)バイト値(0から255)です。あなたは "文字"であるという意味で "char"を考えているかもしれませんが、それは本当に数値です。通常の "char"は符号付きなので、128個の値があり、これらの値はASCIIエンコーディングを使用して文字にマッピングされます。しかしどちらの場合でも、あなたがメモリに保存しているのはバイト値です。
さまざまなタイプの特定の長さと符号を使用したい場合は、単にuint8_t、int8_t、uint16_tなどを使用する方がおそらくいいでしょう。それは、単にそれらが言うとおりの動作をするからです。
Unsigned charは、通常のcharの符号用に予約されているビットを別の数値として使用します。 [-128 - 127]ではなく、[0 - 255]に範囲が変わります。
あなたがサインをしたくないときは、一般的にunsigned charが使われます。これは、ビットをシフトする(shiftは符号を拡張する)などのことを行うときや、charを数値として使用するのではなくバイトとして扱うときに他のことを行うときに違いが生じます。
unsigned charは、あらゆる面倒なトリックの核心です。 ALLプラットフォーム用のほぼALLコンパイラでは、符号なしcharは単純にBYTEです。 (通常)8ビットの符号なし整数。それは小さな整数またはビットのパックとして扱うことができます。
中毒では、他の誰かが言ったように、規格はcharの符号を定義しません。つまり、char、signed char、unsigned charの3つの異なる「char」型があります。
一部のグーグルは this を見つけました、そこで人々はこれについて議論しました。
符号なしcharは基本的にシングルバイトです。そのため、1バイトのデータが必要な場合はこれを使用します(たとえば、Windows APIでよく行われるように、関数に渡すフラグのオンとオフを設定するために使用します)。
unsigned charは正の値のみを取ります。0〜255 signed charは正および負の値を取ります:-128〜+ 127
"Cプログラミング言語"の本からの引用
修飾子signed
またはunsigned
は、charまたは任意の整数に適用できます。符号なし数値は常に正またはゼロであり、算術法2 ^ nの法則に従います。ここで、nは型のビット数です。したがって、たとえば、charが8ビットの場合、unsigned char変数の値は0から255の間で、signed charの値は-128から127の間です(2の補数のマシンで)。に依存しますが、印刷可能文字は常に正です。