位域的概念
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",pa,pb,pc); return 0; }
输出为:-2,-2,1
在C complier和C ++编译器中输出上面的代码会是什么? 为什么?
你的系统似乎使用了2的补码 。 保持2
2-bit
位字段将是10
的二进制,在2的补码系统中是-2
。 同样地,对于2的补码中的3-bit
表示, 110(6)
是-2
。 1
是平原1
另请参阅此处的有符号位字段
我的C编译器得到-2 -2 1。 问题是您的位字段对于您要存储的数字而言太小。 在前两种情况下,最左边的位是1,因此它们被解释为负数。 为了解决这个问题,要么:
- 让你的位字段更大
- 将您的位字段声明为无符号整数而不是整数
- 在打印前转换为unsigned int并使用%u进行打印。
你得到这些答案的原因与此程序相同:
#include #include int main(void) { int32_t a = 4294967294; printf("%d\n", a); return 0; }
有输出-2
。 初始化带有太大而不适合的数字的带符号变量会导致对其进行不同的解释。 从规格:
否则,新类型将被签名,并且值无法在其中表示; 结果是实现定义的,或者引发实现定义的信号。
现在让我们看看究竟发生了什么。 让我们从给定的代码开始:
struct A { int a:3; }; int main() { struct A p = {5}; printf("%d",pa); }
在3比特内,该值将是101(5),因为该3比特组的符号比特是1,因此是负值。 因此,我们需要找到101的赞美,即011(3)。 因此,通过应用上述逻辑,我们将输出为-3。 同样可以certificate其他人。
例如,对于1001(9),我们将得到3位值,因为a:3。 因此它将是001(1)。 因为这里没有设置符号位,即1,所以不需要使用2的补码。 直截了当的回答是1.同样可以做其他事。