C语言中的布尔数组和按位运算

时间:2019-04-09 10:35:45

标签: c arrays

我必须实现一组带有8个输出的串行移位寄存器。输出连接到开关,所以我目前在C中使用布尔数组,它们将开关打开(true)或关闭(false)。

因此,每个移位寄存器都有8个布尔值的数组,实际上是8位无符号整数。我可以继续使用数组,但是我认为那要慢得多,然后只是按位操作整数。将整数传递到SPI接口也比数组容易得多。

是否有一种简单的方法可以将布尔数组转换为整数或以与操作数组相同的方式来操作整数?

即:

bool switch[8];
switch[0] = True; //Switch 1 on
switch[1] = False; //Switch 2 off
...

相同
uint8_t switch;
switch = 0b00000001;

但是在思考单个开关时更难阅读和编程。

性能是关键,因为我的SPI需要非常快。

5 个答案:

答案 0 :(得分:2)

您不能使用数组语法(这将需要操作符重载,这在C ++中是可能的)。但是您可以使用一些辅助功能来设置和获取位(/ 8和%8已针对位移位和ands进行了优化,请注意,对于int而言,这与索引类型不同)

typedef uint8_t bit_mem_t;

static inline void set_bit(bit_mem_t* array, unsigned index, bool value) {
    array[index/8] = (array[index/8] | 1 << (index%8)) ^ !value << (index%8);
}

static inline bool get_bit(bit_mem_t const* array, unsigned index) {
    return (array[index/8] & 1 << (index%8)) != 0;
}

static inline void flip_bit(bit_mem_t* array, unsigned index) {
    array[index/8] ^= 1 << (index%8);
}

/*static inline size_t bit_array_size(size_t bit_count) {
    return (bit_count+7) / 8;
}*/
#define bit_array_size(bit_count) (((size_t)(count)+7)/8)

int main() {
    bit_mem_t array[bit_array_size(3)] {}; // clear it to 0s

    set_bit(array, 0, true);
    set_bit(array, 1, false);
    set_bit(array, 2, !get_bit(array, 1));
}

答案 1 :(得分:2)

使用uint8_t存储8位与硬件相关的数据,即周期。如果它是内存映射的硬件寄存器,则还需要经过volatile认证。

如果您希望命名单个引脚,则可以使用define:

#define SWITCH3 (1u << 3);

按位运算符访问。

uint8_t switch = 0;
switch = SWITCH1 | SWITCH3;   // set all bits
switch |= SWITCH3;            // set a specific bit
switch &= (uint8_t)~SWITCH3;  // clear a specific bit

答案 2 :(得分:1)

使用宏:

if (radioButton5.Checked)
{
    AddToScore(5); //Adds 5 points to score
    label1.Text = _score.ToString();
}

并用作:

uint8_t sw;
#define SW_ON(s)    sw=(sw|(1u<<(s)))
#define SW_OFF(s)   sw=(sw&(~(1u<<(s))))

答案 3 :(得分:1)

#define SWITCH1 1U
#define SWITCH2 2U
#define SWITCH3 4U
#define SWITCH4 8U
#define SWITCH5 16U
#define SWITCH6 32U
#define SWITCH7 64U
#define SWITCH8 128U


unsigned int switches = 0x0U;

要打开开关,请说开关4。

switches = (switches | SWITCH4)

要关闭开关,请说开关4。

switches = (switches & ~SWITCH4)

答案 4 :(得分:0)

您可以使用这样的位域:

union {
     struct {
          unsigned char s1:1,
                        s2:1,
                        s3:1,
                        s4:1,
                        s5:1,
                        s6:1,
                        s7:1,
                        s8:1
     } sw;
    unsigned char nr[1];
} u;

您可以分别访问交换机的字段(u.sw.s1-u.sw.s8),也可以访问u.nr [0]中的整数。

也许也可以使用unsigned char nr代替具有1个成员的数组,但是该标准仅声明它对char arrays 有效,因此最好放心使用。