【问题标题】:结构到位 c++
【发布时间】:2022-01-19 07:44:04
【问题描述】:

我正在学习C++,想知道是否可以将结构对象分解为位序列?

// The task is this! I have a structure
struct test {
  // It contains an array
    private:
    int arr [8];

    public:
    void init () {
      for (int i = 0; i <8; i ++) {
        arr [i] = 5;
     }

    }
};


int main () {
  // at some point this array is initialized
    test h;
    h.init ();

    // without referring to the arr field and its elements, we must convert the structure to this format
    // we know that int is stored there, and these are 32 bits -> 00000000 00000000 00000000 00000101. 00000000 00000000 00000000 00000101. - and there are 8 such pieces by number
    // elements in the array

  return -1;
}

好吧,我们也知道数组的大小。我们需要将结构对象转换为位序列:

00000000000000000000000000000101000000000000000000000000000001010000000000000000000000000000010100000000000000000000000000000101000000000000000000000000000001010000000000000000000000000000010100000000000000000000000000000000010100000000000000000000000000000101 P>

【问题讨论】:

  • 当然可以。只需创建一个函数来获取数组的每个元素并打印其位。或者您可以将结构对象 h 的内容复制到一个字节数组中并打印该数组中的位(但要注意填充!)。
  • 你试过什么?你研究过位运算符吗?您在尝试使用它们时遇到了什么问题?
  • 关键字是“序列化”,在运行时平台之间交换数据很常见

标签: c++ struct bit bitset


【解决方案1】:

将数字转换为位串的标准答案是std::bitset。我将使用更底层的方法。并使用位掩码和 & 操作来屏蔽单个位,然后将相应的字符分配给结果字符串。

使用位和运算符以及局部与运算屏蔽炒锅

Bit Mask      AND
0   0         0
0   1         0
1   0         0
1   1         1

你看,0 和 1 就是 0。而 1 和 1 就是 1。

这允许我们访问一个字节中的位。

Byte: 10101010
Mask: 00001111
--------------
      00001010  

我们将使用这种机制。

但是,我无法想象这是家庭作业,因为通过从外部访问结构将需要肮脏的reintepret_cast

无论如何。让我向您介绍这个解决方案。

我觉得它非常丑。

#include <iostream>
#include <bitset>

// The task is this! I have a structure
struct test {
    // It contains an array
private:
    int arr[8];

public:
    void init() {
        for (int i = 0; i < 8; i++) {
            arr[i] = 5;
        }
    }
};

// Convert an int to a string with the bit representaion of the int
std::string intToBits(int value) {

    // Here we will store the result
    std::string result{};

    // We want to mask the bit from MSB to LSB
    unsigned int mask = 1<<31;

    // Now we will work on 4 bytes with 8bits each
    for (unsigned int byteNumber = 0; byteNumber < 4; ++byteNumber) {
        for (unsigned int bitNumber = 0; bitNumber < 8; ++bitNumber) {

            // Mask out bit and store the resulting 1 or 0 in the string
            result += (value & mask) ? '1' : '0';

            // Next mask
            mask >>= 1;
        }
        // Add a space between bytes
        result += ' ';
    }
    // At the end, we do want to have a point
    result.back() = '.';
    return result;
}

int main() {
    // At some point this array is initialized
    test h;
    h.init();

    // Now do dirty, ugly, and none compliant type cast
    int* test = reinterpret_cast<int*>(&h);
 
    // Convert all bytes and show result
    for (unsigned int k = 0; k < 8; ++k) 
        std::cout << intToBits(test[k]) << ' ';

    return 0;
}

【讨论】:

  • 哦!好的,我会知道reinterpret_cast,我以前没听说过。是的,我同意,这种转换 - 变态 :) 最初认为有一种方法可以将结构或类对象转换为原始字节流。例如 char * 字节;然后检查字节中的位被提升并显示其值。
猜你喜欢
  • 1970-01-01
  • 2018-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 2015-10-02
  • 2016-08-30
相关资源
最近更新 更多