4
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",p.a,p.b,p.c);
 return 0;
}    

输出为:-2,-2,1

以上代码在 C 编译器和 C++ 编译器中的输出是什么?为什么?

4

4 回答 4

5

您的系统似乎使用2's 补码2-bit位域保持将210二进制,-2在 2 的补码系统中。同样110(6)用于2-23-bit补码表示。而且1很朴素1

还可以在此处阅读有关带符号位字段的信息

于 2012-04-25T17:51:13.863 回答
3

我用我的 C 编译器得到 -2 -2 1 。问题是您的位字段对于您要存储的数字来说太小了。在前两种情况下,最左边的位是 1,因此它们被解释为负数。要解决此问题,请执行以下任一操作:

  1. 让你的位域更大
  2. 将您的位字段声明为无符号整数而不是整数
  3. 打印前转换为 unsigned int 并使用 %u 打印。
于 2012-04-25T17:43:10.477 回答
1

您得到这些答案的原因与该程序相同:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    int32_t a = 4294967294;
    printf("%d\n", a);
    return 0;
}

有输出-2。使用太大而无法适应的数字初始化有符号变量会导致对其进行不同的解释。从规范:

否则,新类型是有符号的,值不能在其中表示;结果是实现定义的,或者引发了实现定义的信号。

于 2012-04-25T17:43:18.273 回答
1

现在让我们看看到底发生了什么。让我们从给定的代码开始:

struct A
{
 int a:3;
};
int main()
{
 struct A p = {5};
 printf("%d",p.a);
}

在 3 位内,值将为 101(5),因为这 3 位集合的符号位为 1,因此为负值。因此,我们需要找到 2 对 101 的补码,即 011(3)。因此,通过应用上述逻辑,我们将输出为 -3。同样可以证明其他的。

例如,对于 1001(9),由于 a:3,我们将采用 3 位值。因此它将是 001(1)。由于此处未设置符号位,即 1,因此无需使用 2 的补码。直截了当的答案是 1。同样可以做其他事情。

于 2012-04-26T15:18:50.903 回答