在结构体中使用位(bit)和整型(int)的方法

6
   #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到底是干什么用的?请解释一下。
4个回答

5
由于它是二进制补码,最高位用于表示符号。通过写a:4,您要求仅分配4位内存,这会为实际数字留下3位。因此,我们的有效范围是[-8,7]。由于所有1都是-1,负面还有一个额外的数字。有关更多解释,请参见上面的链接。
9在(无符号)二进制中为:1001。当您将其放入a(有符号)中时,由于初始1,您将得到a为负数,并且由于以下数字为001,因此我们将最大负数加1,从而给出-7。
如果您想仅使用4位存储数字9,则需要使用unsigned int,这将为您提供[0,15]的范围。

编辑:
如果有人不明白为什么1001带符号的结果是-7,请考虑以下内容:

由于1111等于-1,让变量value=-1

要确定负(带符号)int num的值,请将xinum中表示如下:

xi:{0,1},其中i=0表示最低有效位。

然后,对于每个xi=0,从value中减去2i

例如:

1001

value = -1 - 21 - 22 = -7


在位字段中的int默认可能是unsigned int。在OP的情况下似乎不是这样,但阅读文档从来没有坏处。 - Carl Norum
好问题,非常好的答案!我验证了无符号类型将给出预期的答案。 - lsk
1
我更喜欢将MSB的值视为-2^3 + 2^0,这样所有非MSB都具有其通常的值。 - Doug Currie
是的,这就是我在编辑之前考虑的方式,但我也想展示一种替代方案。 - Steve P.

4
你的字段是一个4位有符号整数。对于有符号整数来说,最高位是符号位,这意味着你只有3位用于实际数字。你可以存储在该字段中的数字范围是-8到7(假设使用2的补码存储)。
9的位模式为1001,它的第4位被设置,这意味着它被解释为负数,这就是为什么它打印出来是-7的原因。如果你期望得到-1,你需要阅读关于2的补码的资料
如果你想在该字段中存储9,将a设置为unsigned int

3

你只为该字段保留了4位,其中1位用于符号,因此仅剩下3位可用于正数。因此,你只能存储最多7的值。


2
请用二进制表示法解释一下,可以吗? - Raja Narayan

2

确实需要使用无符号 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接