2016-09-27 2 views
3

ビットマスキングやビットオーバーフローの処理に苦労しています。ビットマスキング(char)(0xFFFFFFB8&0xFF)がCで機能しません

データストリームからデータを取得し、それはchar型バッファに格納されており、バッファの特定のインデックスにアクセスする必要があります。私がそうしようとすると、予期せぬ結果が出ます。以下のような

何か..

char buffer[BUFFER_SIZE]; 

/* ...recv from network stream performed... */ 

printf("buffer[index] = 0x%x\n", buffer[index]); /* => 0xFFFFFFB8 */ 

char dummyChar = buffer[index] & 0x000000FF; 
printf("dummyChar = 0x%x\n", dummyChar); /* => 0xFFFFFFB8 */ 

バッファがcharタイプです。バッファ[インデックス]を印刷すると、なぜ32ビットサイズになるのですか?

また、buffer[index]を0x000000FFでマスクしましたが、まだ0xFFFFFFB8を取得しています。どうして?

私は0xB8を取得したいだけ、誰かが私にどのように伝えることができますか?

+0

裸の 'char'の代わりに' unsigned char'を使用してください。 –

+0

ありがとうございます。それは今働きます! :) –

+1

この種のプログラミングを行うときは、stdint.h型をどこでも使用してください。 – Lundin

答えて

2

マスクしようとしている文字のbuffer[index]は、char型がマシン上で署名されているため、負の値は-72です。 16進表現は0xB8です。

引数buffer[index]がprintf関数に渡されると、整数昇格が実行されます。つまり、char型の型はint型に昇格されます。 int型の-72の表現は、マシン上のchar型の-72の表現と異なります。

char型では、-72は0xB8として表されます。 int型で

は、-72は、値を変更せず、ビット単位の演算を行う0xFFFFFFB8

のように表される:

char dummyChar = buffer[index] & 0x000000FF; 

ため1:0xFFで& 0xB8 == 0xB8。文字dummyCharは、同じ値-72を持ちます。次にdummyCharがprintf呼び出しに渡され、同じプロモーション手順が上記のように行われます。


整数キャンペーンはまた、ビット単位演算子で発生するので、実際の現実はわずかに異なっているが、結果は同じです。両方のタイプはビット単位次いで、intに昇格され、実行されると、結果が暗黙的にchar型に変換される:

0xFFFFFFB8 & 0x000000B8 == 0x000000B8 
0x000000B8 == 0xB8 

それが動作する前にあった同じ値を残します。

+0

負の値を持つ '%x'を使うのは未定義の振る舞いです。 –

+0

議論の余地があります。私は同意すると思うが、それはこの質問の話題ではない。 – 2501

+0

@ M.M、いいえ、それは完全に定義された動作です。 '-72'は整数' -72'に変換され、16進数の '-72'は' 0xFFFFFFB8'です。 –

4

intより小さい整数型を渡すと、自動的にint(値が符号拡張される)に昇格されるという2つの理由があります。 2番目の理由は、printfのフォーマット"%x"は、バイトではなく、unsigned intの値を出力するためです。 符号なしバイト(unsigned char)あなたは"%hhx"のように修飾hhを使用する必要がありますについては

。次に、printfは、渡された値が実際には単一の符号なしバイトであり、完全なunsigned intではないことを認識します。

詳細については、上記のリンク先の参考文献を参照してください。

+0

私はあなたの提案を試みたが、うまくいかなかった。そしてバッファのインデックスのすべてが0xFFFFFFのもので印刷されるわけではありません。いくつかのバイトが正しい方法で印刷されます。私が(int)(buffer [index]&0x000000FF)をキャストしたとき、0xB8を返しました... –

+1

あなたのリンクは ''%x "'が 'int'ではなく' unsigned int'を必要としていると言います。 – mch

関連する問題