0

偶数のインデックス付きバイトをすべて int にコピーするバイトのバッファーへのポインターがあります (データがバッファーに格納されるプロトコルのため、奇数サイクルが読み取り用であることがわかっています)。今私がこれをするとき

signed int a;
...
//inside a loop
a = buffer[2*i]; //buffer is unsigned

それは私に署名されていない番号を与えます。しかし、私がこれを行うとき

a = (int8_t)buffer[2*i]

番号は署名された形式で表示されます。そのため、特に上記のようなシナリオでは、c での符号拡張がどのように機能するかを再考する必要があります。私の理解では、署名済みとして宣言しているので、コンパイラは自動的に符号拡張を行います。なぜそうではないのかを説明するのに時間がかかる人はいますか?私はこのトラップで 1 時間過ごしましたが、今後同じトラップにはまりたくありません。

4

2 に答える 2

2

buffer符号なし 8 ビット整数の配列です (または 1 つとして機能します)。したがって、 の値はbuffer[2*i]0 から 255 (両端を含む) の範囲にあり、その範囲内のすべての値はints として表現できるため、

a = buffer[2*i];

値を保持し、より広いタイプへの昇格は、intゼロでパディングすることによって行われます。

int8_t代入する前にキャストすると、

a = (int8_t)buffer[2*i]

バッファ内の 127 より大きい値は、実装定義の方法で type に変換されますint8_t。ほとんどの場合、ビットパターンを符号付き 8 ビット整数として再解釈するだけで、-128 から -1 までの負の値になります。これらの値はints として表現できるため、代入で保持され、値を保持するより広い型への昇格がint符号拡張によって行われます。

于 2012-10-21T16:09:35.297 に答える
1

int_8 には 8 ビットしかありません。最上位ビットが 1 の場合、負の値が保持されます: 1xxxxxxx 。そのような値を signed int (32 ビットまたは 64 ビット) に割り当てると、もちろん負の値になります。int が長いほど、割り当て後に次のようになります11111111 11111111 11111111 1xxxxxxx。単純な xor だけで 00000000 ^ 1001 => 11111001 というトリックが実行されます。

于 2012-10-21T16:15:27.017 に答える