【问题标题】:Concept of bit field位域的概念
【发布时间】:2012-04-25 17:28:18
【问题描述】:
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++ 编译器中的输出是什么? 为什么?

【问题讨论】:

  • 看看这里:ideone.com/o817J
  • 是的,答案与输出一致。
  • 位域只对无符号值表现良好(不确定有符号值的行为是未定义还是未指定)。
  • 为什么,这是signedunsigned 整数之间的区别。你可能想要unsigned
  • @WilliamPursell,位域对于有符号值来说是完美定义的。

标签: c bit-fields


【解决方案1】:

您的系统似乎在使用2's complement。持有22-bit 位域在二进制中是10,在2 的补码系统中是-2。同样,110(6)-2,用于 2 的补码中的 3-bit 表示。而1 是普通的1

另请阅读有关有符号位字段here

【讨论】:

    【解决方案2】:

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

    1. 让你的位域更大
    2. 将位字段声明为无符号整数而不是整数
    3. 在打印前转换为 unsigned int 并使用 %u 进行打印。

    【讨论】:

      【解决方案3】:

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

      #include <stdio.h>
      #include <stdint.h>
      
      int main(void)
      {
          int32_t a = 4294967294;
          printf("%d\n", a);
          return 0;
      }
      

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

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

      【讨论】:

        【解决方案4】:

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

        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。 其他类似的也可以。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-09
          • 1970-01-01
          相关资源
          最近更新 更多