C位字段变量正在打印意外值

时间:2013-01-15 11:44:50

标签: c bit

struct m

{
   int parent:3;

   int child:3;

   int mother:2;
};

void main()
{

   struct m son={2,-6,5};

   printf("%d %d %d",son.parent,son.child,son.mother);
}

任何人都可以帮忙说出为什么程序的输出是2 2 1

7 个答案:

答案 0 :(得分:3)

childmother的位字段大小太小,无法包含您分配给它们的常量值,而且它们会溢出。

答案 1 :(得分:3)

您可以注意到,在编译阶段,您将收到以下警告:

test.c: In function ‘main’:
test.c:18:11: warning: overflow in implicit constant conversion
test.c:18:11: warning: overflow in implicit constant conversion

那是因为你已经将变量定义为int中的3位而不是整个int。溢出意味着无法将值存储到3位内存中。

因此,如果您使用以下结构定义,您将避免编辑中的警告,您将获得正确的值:

struct m

{
   int parent;

   int child;

   int mother;
};

答案 2 :(得分:2)

你不能只用3位代表-6;同样,你不能只用两位代表5。

parentchildmother是否需要为位字段?

答案 3 :(得分:2)

child需要至少4位才能保留-61010)。 mother要求至少4位才能保留50101)。

printf仅考虑child的最后3位,因此其打印2并且仅考虑mother的最后2位,因此其打印1。< / p>

您可能认为child只需要3位来存储-6,但它实际上需要4位,包括符号位。负值用于存储在2的补码模式中。

Binary equivalent of 6 is 110
one`s complement of 6 is 001
two`s complement of 6 is 010
sign bit should be added at MSB.

因此-6的值为1010printf省略了符号位。

答案 4 :(得分:1)

首先:

5是二进制的101,因此它不适合2位。

-6也不适合3位。

答案 5 :(得分:1)

您的位字段太小。另外:这只是一个练习,还是你想(过早地)优化?你不会对结果感到满意......它会很慢。

答案 6 :(得分:0)

我终于在应用思想后找到了原因: - )

2以二进制表示为0010

-6 as 1010

和5为0101

现在2可以仅使用3位来表示,因此它将存储为010

-6将以3位存储为010

和5将以2位存储为01

所以最终的输出是2 2 1

感谢大家的回复!!!!