C/C++ では、anunsigned char
は何に使用されますか? レギュラーとどう違うのchar
?
16 に答える
C++ には、3 つの異なる文字型があります。
char
signed char
unsigned char
textに文字タイプを使用している場合は、 unqualified を使用しますchar
:
'a'
orのような文字リテラルの型です'0'
(C++ のみ、C では型はint
)- のような C 文字列を構成する型です。
"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
。
C 標準では の符号付き性が定義されていないため、これは実装に依存しますchar
。プラットフォームによっては、 char がsigned
orになる場合があるため、実装がそれに依存しているかどうかunsigned
を明示的に確認する必要があります。これは、プラットフォームが文字列に入れるものと一致するため、文字列から文字を表す場合にのみ使用してください。signed char
unsigned char
char
との違いはsigned char
、unsigned char
ご想像のとおりです。ほとんどのプラットフォームでsigned char
は、 は から の範囲の 8 ビットの 2 の補数で、8 ビットの符号なし整数 (-128
から)127
になります。標準では、型が 8 ビットである必要はなく、 を返すことだけが必要であることに注意してください。inで char のビット数を取得できます。ただし、今日、これが 以外のものになるプラットフォームはほとんどありません。unsigned char
0
255
char
sizeof(char)
1
CHAR_BIT
limits.h
8
この問題のすばらしい要約がここにあります。
私がこれを投稿して以来、他の人が言及しているように、小さな整数を本当に表現したい場合はint8_t
、 andを使用する方がよいでしょう。uint8_t
本当に必要だと思うので、C と C++ のルールをいくつか述べたいと思います (この点では同じです)。まず、すべてのビットがunsigned char
unsigned char オブジェクトの値の決定に参加します。第二に、unsigned char
明示的に署名されていないと述べられています。
-1
int 型の値を に変換するとどうなるかについて、誰かと話し合いましたunsigned char
。unsigned char
彼は、結果のすべてのビットが 1 に設定されるという考えを拒否しました。しかし、そうである必要はありませんでした。変換が意図したとおりに行われるのは、この規則の直後です。
新しい型が符号なしの場合、値が新しい型の範囲内になるまで、新しい型で表現できる最大値よりも 1 多い値を繰り返し加算または減算することによって、値が変換されます。(
6.3.1.3p2
C99 ドラフトで)
それは数学的な説明です。C++ は、同じ規則に帰着するモジュロ計算の観点からそれを記述します。とにかく、保証されていないのは、整数のすべてのビットが-1
変換前に 1 であることです。unsigned char
では、結果のすべてのCHAR_BIT
ビットが 1 になったと主張するには、何が必要でしょうか?
- すべてのビットがその値の決定に関与します。つまり、オブジェクトにパディング ビットは発生しません。
- に1 回だけ追加
UCHAR_MAX+1
する-1
と、範囲内の値が得られます。つまり、UCHAR_MAX
実際、それで十分です!unsigned char
したがって、すべてのビットを 1 にしたいときはいつでも、
unsigned char c = (unsigned char)-1;
また、変換は単に上位ビットを切り捨てるだけではないこともわかります。2 の補数の幸運な出来事は、それが単なる切り捨てであることですが、他の符号表現については必ずしも同じではありません。
unsigned charの使用例:
unsigned char
は、コンピュータ グラフィックスでよく使用され、非常に頻繁に (常にではありませんが) 各カラー コンポーネントに 1 バイトが割り当てられます。RGB (または RGBA) カラーが 24 (または 32) ビットで表され、それぞれがunsigned char
. unsigned char
値は [0,255] の範囲にあるため、通常、値は次のように解釈されます。
- 0 は、特定の色成分がまったくないことを意味します。
- 255 は、特定の色顔料の 100% を意味します。
したがって、RGB 赤は (255,0,0) -> (100% 赤、0% 緑、0% 青) になります。
なぜ使用しないのsigned char
ですか?算術とビットシフトが問題になります。すでに説明したように、 asigned char
の範囲は基本的に -128 シフトされます。RGB をグレースケールに変換するための非常に単純で素朴な (ほとんど使用されていない) 方法は、3 つの色成分すべてを平均化することですが、色成分の値が負の場合に問題が発生します。赤 (255, 0, 0) は、算術演算を使用すると平均して (85, 85, 85) になりunsigned char
ます。ただし、値がs (127,-128,-128) の場合、最終的に (-99, -99, -99) になり、空間ではsigned char
(29, 29, 29) になり、これは正しくありません。 unsigned char
.
signed char
範囲は -128 ~ 127 です。unsigned char
範囲は 0 ~ 255 です。
char
コンパイラに応じて、signed char または unsigned char と同等になりますが、異なる型です。
C スタイルの文字列を使用している場合は、単にchar
. 算術演算に char を使用する必要がある場合 (非常にまれです)、移植性のために明示的に signed または unsigned を指定してください。
unsigned char
正の値のみを取ります.... 0から255のように
一方
signed char
-128から+127のように、正と負の両方の値を取ります
char
またunsigned char
、すべてのプラットフォームで8ビットタイプであることが保証されているわけではありません。8ビット以上であることが保証されています。一部のプラットフォームには、9ビット、32ビット、または64ビットバイトがあります。ただし、今日最も一般的なプラットフォーム(Windows、Mac、Linux x86など)には8ビットバイトがあります。
Anunsigned char
は、符号なしバイト値(0〜255)です。「キャラクター」という意味で考えているかもしれませんがchar
、実は数値です。レギュラーchar
は署名されているため、128個の値があり、これらの値はASCIIエンコードを使用して文字にマップされます。ただし、どちらの場合でも、メモリに格納しているのはバイト値です。
unsigned char
すべてのビットトリックの中心です。すべてのプラットフォームのほぼすべてのコンパイラで、 anは単なる 1バイトであり、(通常は) 8 ビットの符号なし整数であり、小さな整数またはビットのパックとして扱うことができます。unsigned char
さらに、他の誰かが言ったように、標準は char の符号を定義していません。、、 の3 つの異なるchar
タイプがあります。char
signed char
unsigned char
直接値に関しては、値が間にあることがわかっている場合と、符号なし文字が正の端の2倍の範囲を提供する場合に、通常の文字が使用されCHAR_MIN
ますCHAR_MAX
。たとえば、CHAR_BIT
が8の場合、通常の範囲はchar
[0、127](符号付きまたは符号なし)であることが保証されますが、[0、255 unsigned char
]およびsigned char
[-127、127]になります。
用途に関しては、標準ではPOD(プレーンな古いデータ)のオブジェクトをunsignedcharの配列に直接変換することが許可されています。これにより、オブジェクトの表現とビットパターンを調べることができます。安全な型のパンニングの同じ保証は、charまたはsignedcharには存在しません。
さまざまなタイプの特定の長さと符号を使用するのが好きな場合は、、、、などを使用したほうがよいでしょうuint8_t
。int8_t
なぜならuint16_t
、それらが正確に言うことを実行するからです。
何人かのグーグルがこれを見つけました、そこで人々はこれについて議論しました。
unsignedcharは基本的に1バイトです。したがって、1バイトのデータが必要な場合はこれを使用します(たとえば、Windows APIでよく行われるように、関数に渡されるフラグのオンとオフを設定するために使用する場合があります)。
unsigned char は、通常の char の符号用に予約されているビットを別の数値として使用します。これにより、範囲が [-128 - 127] ではなく [0 - 255] に変更されます。
通常、符号が必要ない場合は unsigned char が使用されます。これは、ビットをシフトする(シフトは符号を拡張する)などのことを行う場合や、charを数値として使用するのではなくバイトとして扱う場合に違いを生みます。
signed char
どちらも 1 バイトをunsigned char
表しますが、範囲が異なります。
Type | range
-------------------------------
signed char | -128 to +127
unsigned char | 0 to 255
signed char
を考えてみると、ではchar letter = 'A'
'A' は 65 の 2 進数を表してASCII/Unicode
いるので、 65 が格納できれば -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