位域的概念

时间:2012-04-25 17:28:18

标签: c bit-fields

struct A
{
 int a:2;
 int b:3;
 int c:3;
};

int main()
{
 struct A p = {2,6,1};
 printf("\n%d\n%d\n%d\n",p.a,p.b,p.c);
 return 0;
}    

输出是:     -2,-2,1

C编译器和C ++编译器中上面代码的输出是什么? 为什么?

4 个答案:

答案 0 :(得分:5)

您的系统似乎使用2's complement。持有2-bit的{​​{1}}位字段将为二进制2,在2的补码系统中为10。同样,-2110(6),代表2的补码中的-23-bit1

另请阅读有关已签名的位字段here

答案 1 :(得分:3)

我的C编译器得到-2 -2 1。问题是您的位字段对于您要存储的数字而言太小。在前两种情况下,最左边的位是1,因此它们被解释为负数。要解决这个问题,请:

  1. 让您的位字段变大
  2. 将您的位字段声明为无符号整数而不是整数
  3. 在打印前转换为unsigned int并使用%u进行打印。

答案 2 :(得分:1)

您获得这些答案的原因与此程序相同:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    int32_t a = 4294967294;
    printf("%d\n", a);
    return 0;
}

输出-2。初始化带有太大而不适合的数字的带符号变量会导致对其进行不同的解释。来自规范:

  

否则,新类型已签名且值无法在其中表示;结果是实现定义的,或者引发实现定义的信号。

答案 3 :(得分:1)

现在让我们看看究竟发生了什么。让我们从给定的代码开始:

struct A
{
 int a:3;
};
int main()
{
 struct A p = {5};
 printf("%d",p.a);
}

在3位内,值为101(5),因为该3位组的符号位为1,因此为负值。因此,我们需要找到101的赞美,即011(3)。 因此,通过应用上述逻辑,我们将输出为-3。同样,其他人也可以证明。

e.g。对于1001(9),由于a:3,我们将取3位值。因此它将是001(1)。由于此处符号位未设置为1,因此不需要使用2的补码。直截了当的回答是1。 同样,其他人也可以完成。