我想一点一点地组装消息,然后将消息作为无符号字符的 vector 处理(例如计算 CRC)
我可以使用 std::vector<bool>
组合消息 OK或 std::bitset
我可以将组装的消息复制到 std::vector 中一点一点地。 (注意:消息被填充,使其长度为整数字节)
// assemble message
std::vector<bool> bitMessage;
...
// copy the bits one by one into bytes and add them to the message
std::vector<unsigned char> myMessage;
// loop over bytes
for (int kbyte = 0;
kbyte < bitMessage.size() / 8;
kbyte++)
{
unsigned char byte = 0;
// loop over bits
for (int kbit = 0;
kbit < 8;
kbit++)
{
// add bit to byte
byte += bitMessage[8 * kbyte + kbit] << kbit;
}
// add byte to message
myMessage.push_back(byte);
}
这有效。
但是它看起来非常慢!我想使用 std::memcpy
.
对于“正常” vector ,我会这样做
memcpy(
myMessage.data(),
bitMessage.data(),
bitMessage.size() / 8 );
或
memcpy(
&myMessage[0],
&bitMessage[0],
bitMessage.size() / 8 );
但是这两种方法都不适用于 vector<bool>
或 bitset
问题: 有没有办法获取指向存储位的内存的指针?
答案是:不带std::vector<bool>
或 std::bitset
然而,有了一些提示,尤其是来自@Ayxan Haqverdili 的提示,可以编写一个小类来接受单个位并构造一个有礼貌的 std::vector<unsigned char>
随着我们的前进。
/** Build a message bit by bit, creating an unsigned character vector of integer length
*
* Hides the messy bit twiddling required,
* allowing bits to be added to the end of the message
*
* The message is automatically padded at the end with zeroes
*/
class cTwiddle
{
public:
std::vector<unsigned char> myMessage;
cTwiddle() : myBitLength(0) {}
/** add a bit to end of message
* @param[in] bit
*/
void add(bool bit)
{
// check if message vector is full
if (!(myBitLength % 8))
{
// add byte to end of message
myMessage.push_back(0);
}
// control order bits are added to a byte
int shift = 7 - (myBitLength % 8); // add bits from left to right ( MSB first )
// int shift = (myBitLength % 8); // add bits from right to left ( LSB first )
myMessage.back() += (1 & bit) << shift;
myBitLength++;
}
private:
int myBitLength;
};
最佳答案
显然,这些类都没有定义布局。只需编写您自己的类并定义您想要的布局:
template <int size>
class BitSet final {
private:
unsigned char buffer[size / 8 + (size % 8 != 0)] = {};
public:
constexpr bool get(size_t index) const noexcept {
return (buffer[index / 8] >> (index % 8)) & 1U;
}
constexpr void set(size_t index) noexcept {
buffer[index / 8] |= (1U << (index % 8));
}
constexpr void clear(size_t index) noexcept {
buffer[index / 8] &= ~(1U << (index % 8));
}
};
Memcpy-ing 这个类非常好。否则,您还可以提供对字节数组的直接访问。
或者,您可以动态分配缓冲区:
#include <memory>
class DynBitSet final {
private:
size_t size = 0;
std::unique_ptr<unsigned char[]> buffer;
public:
explicit DynBitSet(size_t bitsize)
: size(bitsize / 8 + (bitsize % 8 != 0)),
buffer(new unsigned char[size]{}) {}
bool get(size_t index) const noexcept {
return (buffer[index / 8] >> (index % 8)) & 1U;
}
void set(size_t index) noexcept { buffer[index / 8] |= (1U << (index % 8)); }
void clear(size_t index) noexcept {
buffer[index / 8] &= ~(1U << (index % 8));
}
auto bitSize() const noexcept { return size * 8; }
auto byteSize() const noexcept { return size; }
auto const* byteBuffer() const noexcept { return buffer.get(); }
};
关于c++ - 访问内存中的位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70568513/