#include<stdio.h>
struct a
{
int a:4;
};
main(){
struct a aa;
aa.a=9;
printf("a=%d\n",aa.a);
return 0;
}
ここでは、出力は -7 です。なぜそうなのですか?int a:4 は正確には何をしますか? 説明してください
2の補数であるため、最上位ビットが符号に使用されます。書くa:4
ことで、メモリの 4 ビットのみを割り当てるように言っているため、実際の数値には 3 ビットが残ります。したがって、有効範囲は[-8,7]
です。1 はすべて -1 なので、負の側に余分な数があります。詳細については、上記のリンクを参照してください。
9、(符号なし) バイナリは: 1001
. これをa
(signed) に入れるとa
、最初の 1 により負になり、次の数値は001
であるため、負の最大数に 1 を追加し、-7 になります。
数値 9 を 4 ビットのみで格納する場合は、 を使用する必要があります。unsigned int
これにより、 の範囲が得られます[0, 15]
。
編集: signed がどのように -7 を与えるかを理解するの
に苦労している場合は、次のことを考慮してください。1001
1111
は -1 なので、いくつかの変数value = -1
.
負の (符号付き) の値を計算するためにint num
、 x i inを示しnum
ます。
x i : {位置 i の 0,1、ここで i=0 は最下位ビット)}、
次に、すべての x i = 0 について、から2 iを引きvalue
ます。
例:
1001
:
value
= -1 - 2 1 - 2 2 = -7
フィールドは 4 ビットの符号付き整数です。符号付き整数の場合、上位ビットは符号ビットです。つまり、実際の数値には 3 ビットしかありません。フィールドに格納できる数値の範囲は -8 から 7 です (2 の補数格納を想定)。
9 のビット パターンは 1001 で、4 番目のビットが設定されています。つまり、負の数として解釈されるため、-7 として出力されます。-1 を予想していた場合は、2 の褒め言葉を読む必要があります。
フィールドに9を格納できるようにしたい場合はa
、unsigned int
フィールド用に 4 ビットのみを予約しました。符号には 1 ビットが使用されるため、正の値には 3 ビットしか残りません。したがって、最大 7 までの値しか保存できません。
実際にunsigned intを使用する必要があります:
#include<stdio.h>
struct a
{
unsigned a:4; // <-- unsigned indeed int, then work good
};
main(){
struct a aa;
aa.a=9;
printf("a=%d\n",aa.a);
return 0;
}
出力:
a=9