0

次のコード

char buffer[BSIZE];
...
if(buffer[0]==0xef)
...

「データ型の範囲が限られているため、比較は常に false です」というコンパイラ警告を表示します。チェックを次のように変更すると、警告が消えます

if(buffer[0]==0xffffffef)

これは非常に直感に反するように感じます。char16 進数の特定のバイト値に対して aをチェックする正しい方法は何ですか? (無署名にする以外)

4

5 に答える 5

6

どうしたの:

if (buffer[0] == '\xef')

?

于 2011-07-11T07:45:07.433 に答える
4

buffer[0] == 0xefが警告をトリガーする理由と警告をトリガーしない理由を理解するbuffer[0] == 0xffffffefには、その式で何が起こっているかを正確に理解する必要があります。

まず、==演算子は、基になる表現ではなく、2 つの式の0xefを比較します。これは数値 239 であり、その数値と等しい値のみを比較します。同様0xffffffefに 4294967279 という数字があり、それと等しいだけと比較されます。

0xef定数と239C に違いはありません。どちらも型intと同じ値を持ちます。charの範囲が -128 ~ 127 の場合、 を評価するbuffer[0] == 0xefbuffer[0]は に昇格されint、その値は変更されません。したがって、 と等しいと比較することはできない0xefため、警告は正しいです。

ただし、定数と 4294967279の間に潜在的な違いがあります。0xffffffef10 進数の定数は常に符号付きですが、16 進数の定数は符号なしの場合があります。お使いのシステムでは、符号なしの型を持っているようです - おそらくunsigned int(値が に格納するには大きすぎますが、 に格納するにはint十分小さいためunsigned int)。を評価するbuffer[0] == 0xffffffefと、buffer[0]は に昇格しunsigned intます。これにより、正の値は変更されませんが、負の値はUINT_MAX + 1それらに加算することによって変換されます。-128 ~ 127 の範囲を持つ a のchar場合、プロモートされた値は 0 ~ 127 または 4294967168 ~ 4294967295 のいずれかの範囲になり ます。0xffffffefこの範囲内にあるため、比較で true が返される可能性があります。


数値ではなくビットパターンを保存している場合はunsigned char、最初に使用する必要があります。または、オブジェクトへのポインタを にキャストして、オブジェクトのビット パターンを検査することもできますunsigned char *

if (((unsigned char *)buffer)[0] == 0xef)

(これは、 type の別の変数を使用することで明らかにより便利に行われますunsigned char *)。

PaulRが言うように、使用することもできます。これは、ビット パターン 0xef を持つオブジェクトが int に変換されたときに持つ値を持つ定数として定義されてbuffer[0] == '\xef'いるため、機能します。例えば。符号付きの 2 の補数システムでは、値が -17 の定数です。'\xef'intchar'\xef'

于 2011-07-11T14:45:24.370 に答える
3

これは、bufferコンテンツがタイプであるために発生していcharます。それらを作るunsigned charとうまくいきます:

if ((unsigned char) (buffer[0]) == 0xef)
于 2011-07-11T07:46:10.340 に答える
2

他の負の数と同じように行います。

if (buffer[0]== -0x6f)

ただし、通常は、データ型としてunsignedcharを使用します。

unsigned char buffer[BSIZE];
...
if(buffer[0]==0xef)

符号付き文字を使用する理由は非常にまれです。さらにまれなのは、さまざまなプラットフォームで符号付きまたは符号なしの「符号なしの文字」を使用する理由です。

于 2011-07-11T08:16:01.117 に答える
2

理由を明示的に説明するには:char署名されているか署名されていないかは実装定義です。コンパイラがcharデフォルトで署名付きとして扱う場合、可能な最大値(127 または)0xefよりも大きくなるため、比較は常に false になります。したがって、警告。signed char0x7f

考えられる解決策は、他の回答によって提供されます。

于 2011-07-11T09:18:40.690 に答える