【问题标题】:Array of Bit_fields in CC中的位域数组
【发布时间】:2014-10-31 05:27:55
【问题描述】:

我在 C 中有一个 8 位的标志,我想使用如下的位域逐位访问它:

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

int main(void) {
    struct flags{
        uint8_t bits1:1;
        uint8_t bits2:1;
        uint8_t bits3:1;
        uint8_t bits4:1;
        uint8_t bits5:1;
        uint8_t bits6:1;
        uint8_t bits7:1;
        uint8_t bits8:1;
    };
    struct flags *my_flags;
    uint8_t x=6,i;

    my_flags=(struct flags *)&x;
    printf("%u\t",my_flags->bits5);
    printf("%u\t",my_flags->bits6);
    printf("%u\t",my_flags->bits7);
    printf("%u\t",my_flags->bits8);
    printf("%u\t",my_flags->bits1);
    printf("%u\t",my_flags->bits2);
    printf("%u\t",my_flags->bits3);
    printf("%u\t",my_flags->bits4);
    return 0;
}

我得到了预期的输出:0 0 0 0 0 1 1 0

但这有点编码太多了。

  1. 难道没有类似位域数组或任何其他解决方法吗? (或)
  2. 在 C my_flags-&gt;bits_i 中是否有类似的东西,其中 i 将成为循环中的计数器?

我知道默认情况下两者都不存在于 C 中。但是有没有其他方法可以达到同样的效果?

【问题讨论】:

    标签: c bit-fields


    【解决方案1】:

    您可以使用具有匿名内部结构的联合 (C11):

    union flags
    {
        unsigned char u;
        struct
        {
            uint8_t bits1:1;
            uint8_t bits2:1;
            uint8_t bits3:1;
            uint8_t bits4:1;
            uint8_t bits5:1;
            uint8_t bits6:1;
            uint8_t bits7:1;
            uint8_t bits8:1;
        };
    };
    

    例如,您可以这样使用:

    union flags x = {0x42};
    
    for (i = CHAR_BIT - 1; i >= 0; i--)
    {
        printf("%d\t", (x.u >> i) & 1);
    }
    
    printf("\n");
    

    并访问特定位:

    x.bits8 = 1;
    printf("%d\n", x.bits8);
    

    匿名内部结构也可以作为 C89 和 C99 的 GNU 扩展。

    【讨论】:

    • 我以前从未使用过这样的联合。您能否解释一下这里发生了什么以便更好地理解?
    • @RatDon 它是两个成员之间的联合:unsigned char 和匿名结构。匿名结构允许您直接从联合对象访问其成员,例如我的回答:x.bits8
    • CHAR_BIT 为 16 的平台呢?如果你使用uint8_t,那么你最好使用8而不是CHAR_BIT
    • @barakmanos OP 正在使用uint8_t,这确实意味着它的系统具有8CHAR_BIT,所以我没有考虑使用CHAR_BIT16 来处理这种奇异的系统。现在使用CHAR_BIT 代替幻数8 更清楚地表明意图。
    【解决方案2】:
    1. 没有。您不能创建位域数组
    2. 您可以使用&gt;&gt;&amp; 提取每个位

      int main() {
          int i, x=45;
          for(i=0; i<8; i++) {
              printf("%d", (x>>(7-i))&1);
          }
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-18
      • 2010-09-06
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多