位设置和代码可读性

Ala*_*ore 4 c++ embedded performance arduino

我有一个Arduino应用程序(实际上是一个库),其中包含许多状态标志 - 最初我只是将它们声明为int(在这种情况下,uint8_t为8位无符号字符).但我可以将它们全部合并为一个整数,并使用位掩码操作来设置和测试状态.

前者的一个例子:

if (_shift == HIGH)
{
    _shift = LOW;
}
else
{
    _shift = HIGH;
}
Run Code Online (Sandbox Code Playgroud)

后者的一个例子

#define SHIFT_BIT 0

if (bitRead(_flags, SHIFT_BIT) == HIGH)
{
   bitWrite(_flags, SHIFT_BIT, LOW);
}
else
{
   bitWrite(_flags, SHIFT_BIT, HIGH);
}
Run Code Online (Sandbox Code Playgroud)

前者读得更好,但后者更有效(空间和时间).在这种情况下,空间和时间效率是否总能获胜?或者这是一种只在需要时才会发生的优化?

(添加)

为了完整性,这里是bitWrite等宏的接线定义:

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
Run Code Online (Sandbox Code Playgroud)

Dre*_*ins 7

看看Raymond Chen对这个问题的出色表现.总之,您需要进行一些详细的计算,以确定后一种情况是否实际上更有效,具体取决于有多少对象与实际设置这些状态的多少次调用.

就可读性而言,看起来你正在使用成员变量,这意味着你可能已经将它们封装在很好的函数中.在这种情况下,我并不关心可读性,因为至少使用该类的人的代码看起来不错.但是,如果需要考虑的话,您可以将其封装在私有函数中.

  • 当你的系统有2k ram和16Mhz处理器时,实际的实例数会从1000很快下降. (2认同)

Mar*_*ark 5

根据AVR-GCC编译器的合规性,我不确定,你可以做这样的事情并保持良好和干净.

struct flags {
    unsigned int flag1 : 1;  //1 sets the length of the field in bits
    unsigned int flag2 : 4;
}; 

flags data;

data.flag1 = 0;
data.flag2 = 12;

if (data.flag1 == 1)
{
    data.flag1 = 0;
}
else
{
    data.flag1 = 1;
}
Run Code Online (Sandbox Code Playgroud)

如果您还想一次访问整个标志int,那么:

union 
{
    struct {
        unsigned int flag1 : 1;  //1 sets the length of the field in bits
        unsigned int flag2 : 4;
    } bits;
    unsigned int val;
} flags;
Run Code Online (Sandbox Code Playgroud)

然后,您可以访问具有2个间接级别的位:variable.bits.flag1< - 返回单个位标志或单个级别以获得整个int值的标志:variable.val< - 返回int