打印位类型为整数?如何转换?

时间:2012-08-07 23:21:18

标签: c bit

该计划是:

typedef struct xp {
        int a:2;
        int b:2;
        int c:1;
} xp;

int main(void)
{
        xp x;
        memset(&x, 0, sizeof(xp));

        x.a = 1;
        x.b = 3;
        x.c = 1;

        printf("%d\n",x.a);
        printf("%d\n",x.b);
        printf("%d\n",x.c);

        return 0;
}

我得到1 -1 -1,为什么? a,b和c如何存储在x中? printf(“%d \ n”,x.a);被执行了吗?

2 个答案:

答案 0 :(得分:5)

您正在为您的位域使用带符号的类型,这意味着您已经创建了两个两位有符号整数和一个一位有符号整数。

两位有符号整数(二进制补码)的可能值为:-2,-1,0和1:

一位有符号整数(二进制补码)的可能值为-1和0。

通过存储“不适合”的值,就像您在这些行中所做的那样:

x.b = 3;
x.c = 1;

您将会遇到奇怪的行为,因为您存储的位模式在读取时会有不同的解释。您可以通过以下方式获得类似的体验:

char x = 58147;

在具有8位char类型的计算机上,该值不适合,因此在访问x时您会看到不同的内容。

答案 1 :(得分:2)

int类型的位字段属于signed int类型或unsigned int类型。选择是实现定义的。这是出于历史原因。这是intsigned int可能不同的唯一背景。

这在C标准的第6.7.2节(C99 draftC11 draft)中指定,遵循类型说明符列表:

  

每个以逗号分隔的多重集都指定相同的类型,除了   对于位字段,它是实现定义的   说明符int指定与signed int相同的类型或相同的类型   为unsigned int

解决方案是避免对位字段使用普通int;始终将它们声明为signed intunsigned int。 (后者几乎总是更有意义。)