7

程序是:

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",xa); 时发生了什么 被执行?

4

2 回答 2

5

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

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

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

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

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

你会得到奇怪的行为,因为你存储的位模式在读取时会被不同地解释。您可以通过执行以下操作获得类似的体验:

char x = 58147;

在具有 8 位char类型的机器上,该值不适合,因此您在访问x.

于 2012-08-07T23:25:50.213 回答
2

type 的位域int要么是 typesigned int要么是 type unsigned int。选择是实现定义的。这是出于历史原因。这是唯一可以不同int的上下文。signed int

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

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

解决方案是避免int对位字段使用plain;总是将它们声明为signed int或 as unsigned int。(后者几乎总是更有意义。)

于 2012-08-07T23:31:40.870 回答