【问题标题】:values changed in bitfields in structure [closed]结构中位域中的值发生了变化[关闭]
【发布时间】:2013-06-10 09:36:51
【问题描述】:

谁能解释一下输出,值是如何存储和计算的?

#include<stdio.h>
struct bitfield
{
    unsigned f1:1;
    unsigned f2:2;
    unsigned   :3;
    unsigned f4:4;
    unsigned f5:5;
    unsigned f6:6;
    unsigned f7:1;
    unsigned f8:8;
} bf;

main()
{
    bf.f1 = 1;
    bf.f2 = 0x3;
    bf.f4 = 0xff;
    bf.f5 = -4;
    bf.f6 = 0377;
    printf("%d %d %d %d %d %d", bf.f1, bf.f2, bf.f4, bf.f5, bf.f6, bf.f8);
}

输出1 3 15 28 63 0

【问题讨论】:

  • 我更改了代码的格式以使其更具可读性。
  • 有什么需要解释的?这不是一个非常有用的问题。这就像说“1 + 1 = 2——有人能解释一下吗?”。这一切看起来都很明显,所以除非你说出你不明白的部分,否则很难回答这个问题。
  • f1 有 1 位,为 1。f2 有 2 位,可以存储 0x3。 f4 有 4 位(范围 0-15),存储 0xff 将其设置为最大值(15)。 f5 有 5 位,4 = 00100,-4 = 11100(二进制补码),这是二进制等于 28。f6 有 6 位,最大值 = 63。0377(oktal)= 255 dec。所有 6 位设置为 1,因此其值为 63。f8 从未设置。

标签: c++ c struct unsigned bit-fields


【解决方案1】:

非常短的纲要。

首先,bf 是一个未初始化的全局变量。这意味着它将最终出现在 .bss 段中,该段通常在启动时初始化为零(尽管您可以将 -fno-zero-initialized-in-bss 传递给 GCC 以阻止此操作,但不确定 MSVC,当然这取决于您的 crt0 )。这解释了f8 的值,因为您还没有写信给它。

f1 是 1。你给它赋值 1。那很明显。与 f2 相同(因为 hex 3 是 dec 3)。

f4 是因为 f4 的字段只有 4 位宽。 0xFF 是一个全为 1 的 8 位模式,然后被截断为 4 位,因此是 15(可以用 4 位表示的最大值)。

f5 是由于有符号/无符号转换。 -4 的 5 位二进制补码表示是 11100。如果您将该值解释为无符号(或者更确切地说,只是一个普通的二进制 -> 十进制转换),您会得到 28。

f6 是 63,因为是八进制转换。任何以零开头的 C 文字数字都被视为八进制。八进制 377 是十进制 255(即 8 位的 11111111),然后将其截断为 6 位,留下111111。这是 63 岁。

【讨论】:

  • 全局变量由 C++ 标准保证初始化为 0。
【解决方案2】:

值存储在您指定的字段中。然而,由于在某些情况下,例如bf.f4 = 0xff;,该值不适合,它将丢失高位,因此它打印 15 (0x0F)。类似地,-4 作为 32 位整数存储在 f5 -4 = 0xFFFFFFFC 中,但当存储为无符号 5 位整数时,它变为 0x1C,即 28。同样的原理适用于 f6

f2f4 之间还有一个使用未命名成员的 3 位“间隙”。

在内部,编译器将通过使用 AND、SHIFT 和 OR 操作来执行此操作。

请注意,我们无法知道 f1 是存储字段的整个值的最高位还是最低位。这是编译器实现将决定的东西 - 只要它完成相同每次的方式。

【讨论】:

    【解决方案3】:
    unsigned fx:n; // Only use the least significant n bits.
    
                   //                        Binary    Decimal
    bf.f1 = 1;     // 1    == [0000 0001]:1   == 1      == 1
    bf.f2 = 0x3;   // 0x3  == [0000 0011]:2   == 11     == 3
    bf.f4 = 0xff;  // 0xff == [1111 1111]:4   == 1111   == 15
    bf.f5 = -4;    // -4   == [0xfffffffc]:5  == 11100  == 28
    bf.f6 = 0377;  // 0377 == [1111 1111]:6   == 111111 == 63
    

    【讨论】:

      【解决方案4】:
      unsigned f1:1;           // 1 bit is allocated. 
      bf.f1=1;                 // you are storing 1 works fine.
      
      unsigned f2:2;           // 2 bit is allocated.
      bf.f2=0x3;               // 3 == '11' in binary so 2 bits are enough so when you print 3 is printed.
      
      unsigned   :3;
      
      unsigned f4:4;          // 4 bit is allocated.
      bf.f4=0xff;             // ff is represented as 1111 1111 in binary, 
      // but only 4 bits are allocated so only f which is 1111 
      // in binary gets stored in this. when you print using %d, 15 is getting printed.
      
      
      unsigned f5:5;         // 5 bits are allocated
      bf.f5=-4;              // -4 in binary for 5 bits is 11100 but you are printing it as %d so it will print 28. and so on...
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2013-05-11
        • 2014-10-19
        • 2022-11-08
        • 2013-07-27
        • 2010-11-14
        • 1970-01-01
        • 2014-10-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多