web-dev-qa-db-ja.com

符号なしcharとは何ですか?

C/C++では、どのunsigned charが使われていますか?通常のcharとどう違うのですか?

427
Landon Kuhn

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を持っているという意味.

509
Fruny

C標準ではcharの符号付きを定義していないため、これは実装に依存します。プラットフォームによっては、charがsignedまたはunsignedなので、実装に依存している場合は、明示的にsigned charまたはunsigned charを要求する必要があります。あなたのプラットフォームが文字列に入れるものと一致するので、あなたが文字列から文字を表現するつもりならばcharを使用してください。

signed charunsigned charの違いはご想像のとおりです。ほとんどのプラットフォームでは、signed char-128から127までの範囲の8ビットの2の補数で、unsigned charは8ビットの符号なし整数(0から255)です。規格はchar型が8ビットであることを要求していません、sizeof(char)1を返すことだけを注意してください。 CHAR_BITlimits.hでcharのビット数を取得できます。ただし、これが8以外のものになるプラットフォームは今日ではほとんどありません。

この問題についての良い要約があります ここ

私がこれを投稿してから他の人が言ったように、あなたが本当に小さい整数を表現したいのであればint8_tuint8_tを使うほうが得策です。

79
Todd Gamblin

私はそれが本当に求められていると思うので、私はちょうどCとC++のいくつかの規則を述べたい(これらはこの点で同じである)。まず、unsigned charall bitsが、符号なしcharオブジェクトがあればその値の決定に参加します。次に、unsigned charは符号なしで明示的に述べられています。

さて、int型の値-1unsigned charに変換するとどうなるかについて、誰かと話し合った。彼は符号表現について心配していたので、結果のunsigned charはすべてのビットが1に設定されているという考えを拒否しました。しかし、彼はする必要はありません。意図したとおりの変換が行われるのは、この規則のすぐ後に続きます。

新しい型が符号なしの場合、値が新しい型の範囲内になるまで、新しい型で表すことができる最大値よりも1つ多い値を加算または減算することによって、値が変換されます。 (C99ドラフトの6.3.1.3p2

それは数学的な説明です。 C++ではこれをモジュロ計算で記述していますが、これは同じ規則に従います。とにかく、notが保証されているのは、整数-1のすべてのビットが変換前の1であることです。それで、私たちは何を持っているので、結果のunsigned charはすべてのCHAR_BITビットが1になっていると主張することができますか?

  1. すべてのビットがその値の決定に関与します。つまり、オブジェクト内にパディングビットは発生しません。
  2. 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]の範囲にあるため、値は通常次のように解釈されます。

  • 0は、特定の色成分がまったくないことを意味します。
  • 255は所与の着色顔料の100%を意味する。

ですから、(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では、これは正しくありません。

24
Zachary Garrett

文字を小さな整数として使いたい場合、最も安全な方法はint8_tuint8_t型を使うことです。

12
jbleners

signed charの範囲は-128から127です。 unsigned charの範囲は0から255です。

charは、コンパイラに応じてsigned charまたはunsigned charのいずれかと同等になりますが、区別できる型です。

Cスタイルの文字列を使用している場合は、charを使用してください。算術に文字を使う必要がある場合(ごくまれですが)、移植性のために符号付きまたは符号なしを明示的に指定してください。

5
James Hopkin

charunsigned charはすべてのプラットフォームで8ビット型であることを保証されているわけではありません - それらは8ビット以上であることが保証されています。プラットフォームによっては、 9ビット、32ビット、または64ビットのバイト があります。しかし、今日最も一般的なプラットフォーム(Windows、Mac、Linux x86など)は8ビットバイトを持っています。

5
bk1e

直接値に関しては、値がCHAR_MINCHAR_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には存在しません。

4
Julienne Walker

unsigned charは正の値だけを取ります.... 0 から 255 のように

どこで

signed charは正と負の両方の値を取ります.... -128 から +127 のように

4
munna

Unsigned charは(符号なし)バイト値(0から255)です。あなたは "文字"であるという意味で "char"を考えているかもしれませんが、それは本当に数値です。通常の "char"は符号付きなので、128個の値があり、これらの値はASCIIエンコーディングを使用して文字にマッピングされます。しかしどちらの場合でも、あなたがメモリに保存しているのはバイト値です。

3
Zac Gochenour

さまざまなタイプの特定の長さと符号を使用したい場合は、単にuint8_t、int8_t、uint16_tなどを使用する方がおそらくいいでしょう。それは、単にそれらが言うとおりの動作をするからです。

2
Dark Shikari

Unsigned charは、通常のcharの符号用に予約されているビットを別の数値として使用します。 [-128 - 127]ではなく、[0 - 255]に範囲が変わります。

あなたがサインをしたくないときは、一般的にunsigned charが使われます。これは、ビットをシフトする(shiftは符号を拡張する)などのことを行うときや、charを数値として使用するのではなくバイトとして扱うときに他のことを行うときに違いが生じます。

2
JasonOfEarth

unsigned charは、あらゆる面倒なトリックの核心です。 ALLプラットフォーム用のほぼALLコンパイラでは、符号なしcharは単純にBYTEです。 (通常)8ビットの符号なし整数。それは小さな整数またはビットのパックとして扱うことができます。

中毒では、他の誰かが言ったように、規格はcharの符号を定義しません。つまり、char、signed char、unsigned charの3つの異なる「char」型があります。

2
ugasoft

一部のグーグルは this を見つけました、そこで人々はこれについて議論しました。

符号なしcharは基本的にシングルバイトです。そのため、1バイトのデータが必要な場合はこれを使用します(たとえば、Windows APIでよく行われるように、関数に渡すフラグのオンとオフを設定するために使用します)。

1
dbrien

unsigned charは正の値のみを取ります。0〜255 signed charは正および負の値を取ります:-128〜+ 127

0
NL628

"Cプログラミング言語"の本からの引用

修飾子signedまたはunsignedは、charまたは任意の整数に適用できます。符号なし数値は常に正またはゼロであり、算術法2 ^ nの法則に従います。ここで、nは型のビット数です。したがって、たとえば、charが8ビットの場合、unsigned char変数の値は0から255の間で、signed charの値は-128から127の間です(2の補数のマシンで)。に依存しますが、印刷可能文字は常に正です。

0
ZhaoGang