如何在 C++ 中实现可配置位为 0 或 1 的消息类?

Posted

技术标签:

【中文标题】如何在 C++ 中实现可配置位为 0 或 1 的消息类?【英文标题】:How to implement message class with configurable bit as either 0 or 1 in C++? 【发布时间】:2021-12-30 12:31:09 【问题描述】:

我正在尝试创建一个可配置为 0 或 1 的消息类,例如这样

1 Byte, unit 8
Bit 0: Port A, 1 connected, 0 disconnected
Bit 1: Port A, 1 connected, 0 disconnected
Bit 2: Port A, 1 connected, 0 disconnected
Bit 3, 4, 5, 6, 7: Reserved

这我已经能够在 C++ 中使用联合和类型双关来实现,但这在 C++ 中被视为未定义的行为。

union Msg
    uint8_t bitfield;
    struct 
        uint8_t PORTA : 1;
        uint8_t PORTB : 1;
        uint8_t PORTC : 1;
        uint8_t : 5;
     msg;
;

如何在 C++ 中做到这一点?

是否可以创建一个函数来将数据打包到这个结构中?

【问题讨论】:

只使用位移和掩码 使用位运算符,<<>>&|~。网上有很多关于位操作的指南。 对不起,我无法捕捉到你想要的东西!你会用“信息”实现什么?是否应该像打开/关闭端口引脚,端口和端口引脚应该是消息的一部分?由于您对 PORT A/B/C 有点了解,因此每个引脚似乎都不是一点点或类似的东西……完全不清楚您在说什么! 有什么东西不能使用 bitset 吗? cplusplus.com/reference/bitset/bitset 【参考方案1】:

您可以使用按位运算。首先,定义一些获取/设置的辅助函数:

bool get_bit(uint8_t bits, uint8_t index) 
    return bool((bits >> index) & 1U);

uint8_t set_bit(uint8_t bits, uint8_t index, bool value) 
    return (bits & ~(1U << index)) | (uint8_t(value) << index);

然后,您可以使用uint8_t 代替Msg 或将Msg 定义为uint8_t 的别名。

// Msg is an alias for uint8_t
using Msg = uint8_t;
Msg message = 0;

message = set_bit(message, 0, true); // Setting the PORT A on
message = set_bit(message, 1, true); // Setting the PORT B on
message = set_bit(message, 2, false); // Setting the PORT C off
// You can use 1 or 0 instead of true or false
message = set_bit(message, 0, 0); // Setting the PORT A off

bool port_b = get_bit(message, 1);

或者,您可以使用 std::bitset (docs) 为您进行位操作:

// You choose the number of bits at compile-time
std::bitset<3> ports;
ports[0] = true;
ports[1] = false;
ports[2] = ports[1];

【讨论】:

以上是关于如何在 C++ 中实现可配置位为 0 或 1 的消息类?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 RealmRecyclerViewAdapter 中实现可过滤

如何在 Flutter 中实现可扩展面板?

我们如何以编程方式在 Android Q OS 中实现可搜索的进度条?

如何在 Flutter 中实现可滚动的画布?

如何在 UIScrollView 中实现可拖动的 UIView 子类?

如何使用 Rx 在 Angular 2 中实现可拖动的 div