程序是:
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("%dn",x.a);
printf("%dn",x.b);
printf("%dn",x.c);
return 0;
}
我得到 1 -1 -1,为什么?a、b 和 c 是如何存储在 x 中的?当 printf("%d",x.a);被执行?
您正在为位字段使用有符号类型,这意味着您已经创建了相当于两个两位有符号整数和一个一位有符号整数的内容。
两位有符号整数(二进制补码)的可能值为:-2、-1、0 和 1:
一位有符号整数(二进制补码)的可能值为 -1 和 0。
通过存储"不适合"的值,就像您在以下行中所做的那样:
x.b = 3;
x.c = 1;
你会得到奇怪的行为,因为你存储的位模式在读取时被不同的解释。 您可以通过执行以下操作来获得类似的体验:
char x = 58147;
在具有 8 位 char
类型的计算机上,该值不适合,因此在访问 x
时会读到不同的内容。
int
的位字段是 signed int
或 unsigned int
类型。选择是实现定义的。 这是出于历史原因。 这是int
和signed int
可能不同的唯一上下文。
这在 C 标准(C99 草案、C11 草案)的第 6.7.2 节中指定,以下为类型说明符列表:
每个逗号分隔的多集指定相同的类型,但 对于位字段,它是实现定义的 说明符
int
指定与signed int
相同的类型或相同的类型 如unsigned int
.
解决方案是避免对位字段使用纯int
;始终将它们声明为 signed int
或 unsigned int
。 (后者几乎总是更有意义。