我有一个与C中位域相关的问题。这里我有这样的结构:
struct Register
{
int bit:1;
};
int main(void)
{
struct Register bit = {1};
printf("\nbit = %d", bit.bit);
return 0;
}
你能解释一下为什么我会得到:
位 = -1
如果您使用位域,则应该使用
unsigned int
。 signed int
是位域的问题。
使用 unsigned int ,它存储 0 和 1,
struct Register
{
unsigned int bit:1;
};
int main(void)
{
struct Register bit = {1};
printf("\nbit = %d", bit.bit);
return 0;
}
我不确定为什么接受的答案建议避免在位字段中使用有符号 int 类型。任何示例或细节表示赞赏。
cppreference:位字段也提到了带符号的位字段。
signed int,用于有符号位域(signed int b:3;范围为 -4..3)
hacks 和 Klas Lindbäck 的评论中很好地解释了代码意外结果的原因。
但是让我举一些例子来说明一下。
当位域大小为1时,有两个可能的值:
0b0
或0b1
,分别表示2的补码中的0
和-1
。就领域bit.bit
而言,struct Register bit = {1};
相当于bit.bit = 0b1
。
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
struct Register
{
int bit:1;
};
int main()
{
struct Register bit;
bit.bit = 0b0;
printf("bit = %d\n", bit.bit);
bit.bit = 0b1;
printf("bit = %d\n", bit.bit);
return 0;
}
输出将是
bit = 0
bit = -1
同样,这是位字段大小为 2 的示例。
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
struct Register
{
int bit:2;
};
int main()
{
struct Register bit;
bit.bit = 0b00;
printf("bit = %d\n", bit.bit);
bit.bit = 0b01;
printf("bit = %d\n", bit.bit);
bit.bit = 0b10;
printf("bit = %d\n", bit.bit);
bit.bit = 0b11;
printf("bit = %d\n", bit.bit);
return 0;
}
输出将是
bit = 0
bit = 1
bit = -2
bit = -1