使用out类型转换我如何填充位字段

时间:2015-03-20 09:08:38

标签: c++ casting bit-fields

#include <iostream>
#include <bitset>

typedef struct
{
    int i;
    char a[4];
    uint8_t j:1;
    uint8_t k:1;
} abctest;

int main()
{
    abctest tryabc;
    memset(&tryabc, 0x00, sizeof(tryabc));
    std::bitset<1> b;
    b = false;
    std::cout << b << '\n';
    b = true;
    std::cout << sizeof(b) << '\n';
}

我的疑问就像我有一个char数组,它基本上是一个模块中收到的结构,在这个结构中我也有位字段,我可以使用memcpy但我不能 键入将缓冲区强制转换为结构(例如,如果我的char* arr实际上是struct abc类型,我就无法abc* temp = (abc*)arr) 我所能做的只是memcpy,所以我想通过类型转换知道如何填充位字段。

2 个答案:

答案 0 :(得分:0)

为什么不能将char数组转换为abctest指针?我对它进行了测试,一切运行良好:

typedef struct
{
    int i;
    char a[4];
    uint8_t j:1;
    uint8_t k:1;
} abctest;

int main(int argc, char **argv)
{
  char buf[9];
  abctest *abc = (abctest*)buf;
  memset(buf, 0x00, sizeof(buf));
  printf("%d\n", abc->j);
}

然而,虽然你肯定可以将一个char数组转换为一个abctest指针,但它并不意味着你应该这样做。我认为你应该学习数据序列化和反序列化。如果要将复杂数据结构转换为字符数组,则类型转换不是解决方案,因为数据结构成员在64位计算机上可能具有与在32位计算机上不同的大小或对齐约束。此外,如果将char数组类型转换为struct指针,则对齐可能不正确,这可能导致使用RISC处理器时出现问题。

您可以通过以下方式序列化代码:将i写成网络字节顺序的32位整数,a为4个字符,j和k为一个字符中的两个位(其余6个未使用)。然后当你反序列化它时,你从网络字节顺序的32位整数读取i,从4个字符读取a,剩下的字符给出j和k。

答案 1 :(得分:0)

如果您知道文字数据类型及其大小(以字节为单位),则可以使用变量来将位移存储并提取到数组中。这是一个低级函数,仍然存在于C ++中,但与C的低级编程风格更相关。

另一种方法是使用除法和模2的幂来在精确位置编码位。我建议你先查看二进制是如何工作的,然后弄清楚向右移动1实际上除以2。

干杯!