c++ - 使用位字段以 4 位增量访问给定类型的各个位组

标签 c++ c bit-fields

如何使用位字段以 4 位增量访问给定的 8 字节数据类型? 我如何用 C 和 C++ 对此进行编程?

最佳答案

作为序言,我将向您展示如何在 C++ 中

虽然看起来你应该能够只用位域来做到这一点,但由于位域必须在元素方面进行初始化,所以你不能使用位域。查看更多here on how to use bitfields在 C++ 中。要了解为什么要尝试执行以下操作:

struct S{
   std::uint32_t x : 16;
   std::uint32_t y : 16;
}
// 65536 = 0001 0000 0000 0000 0000 in binary
S s = {65536};
std::cout << s.x << std::endl;
std::cout << s.y << std::endl;
// >>> 0
// >>> 0
// since the first parameter actually only initializes x, and not y.

//you also cannot do the following
S s = 65536 // Error! no conversion between S and uint32_t!

哇,那我怎么把基类型设置到位域呢!为了解决这个问题,我们需要使用 unions .我将向您展示使用 union 解决此问题的最简单答案,然后使用 anonymous unions and structures 链接到更复杂但紧凑的解决方案。 .

这基本上就是您需要为您的问题做的事情:

   struct nibble64bitField{
    uint64_t A:4;
    uint64_t B:4;

    uint64_t C:4;
    uint64_t D:4;

    uint64_t E:4;
    uint64_t F:4;

    uint64_t G:4;
    uint64_t H:4;

    uint64_t I:4;
    uint64_t J:4;

    uint64_t K:4;
    uint64_t L:4;

    uint64_t M:4;
    uint64_t N:4;

    uint64_t O:4;
    uint64_t P:4;
};

union split8bytes{
    std::uint64_t integer;
    nibble64bitField bitfield;
};

int main() {
    // note this is 255 + 256, or  0000 1111 1111 + 0001 0000 0000
    uint64_t eightbyte_value = 511;
    split8bytes split = {eightbyte_value};
    std::cout << split.bitfield.A << " should be 15" << std::endl;
    std::cout << split.bitfield.B << " should be 15" <<std::endl;
    std::cout << split.bitfield.C << " should be 1" << std::endl;
    std::cout << split.bitfield.D << " should be 0" << std::endl;
    std::cout << split.integer << " should be 511" << std::endl;
    return 0;
}

这里你使用了union。现在为什么我们在这里使用 union ? union 允许您将给定 union 称为 union 内的任何成员,但只占用与最大字节大小成员一样多的空间。这允许我们将 splitbytes 设置为一个整数值,但从该整数访问单个半字节(4 位或半字节的组)。

正如所 promise 的那样,另一位用户尝试与您进行相同的操作,但在代码审查中结束了。他们的解决方案是手动进行此转换,而另一个用户提出使用 union 结构范式进行转换(不是同一个问题,它不是重复的)。 Here匿名结构与编译器编译指示一起使用以确保打包性(但仅在某些编译器上)

关于c++ - 使用位字段以 4 位增量访问给定类型的各个位组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43789629/

相关文章:

转换为较小类型时 C++ 截断

C++17 表达式求值顺序和 std::move

c - 函数和函数指针声明的宏?

c++ - 用户输入(cin) - 默认值

c - 返回 C 中未知大小的数组并使用终止值

c - Keil Arm 编译器 : Is there a way to hook in the same function for two interrupts without modifying the Interrupt Vector Table?

c - 当位域大于字节大小时,字节顺序如何影响位域

c++ - C++14 中的有符号位域

c++ - 将字符串变量分配给 unsigned char 变量

带有 std::enable_if 的 C++ 可变参数模板部分模板特化