如何在C语言中一次清除多个位?

4
我该如何将所有内容简化为一行?
    REG &= ~BITA;
    REG &= ~BITB;
    REG &= ~BITC;
    REG &= ~BITD;
    REG &= ~BITE;

任何一本C语言教材都应该涵盖如何设置、清除、切换和测试位。同时,可以将其想象成二进制:右侧的1保留了位的值,0则清除了位的值。可以使用尽可能多的位数,但不要超过左侧可以存储的范围。 - U. Windl
这是一个超级重复的问题。为什么它被回答了?它应该被关闭。什么是规范问题? - Peter Mortensen
3个回答

11
你可以使用 |(按位或)运算符。
REG &= ~(BITA | BITB | BITC | BITD | BITE);

1

@MikeCAT的答案是正确的,这里有一点需要补充。有一个简单的规则A & B = ~A || ~B。因此,您可以将问题扩展为:

REG &= ~BITA & ~BITB & ~BITC & ~BITD & ~BITE; // 10 operations

你可以将它缩减为:

你可以将其缩减为:

REG &= ~(BITA | BITB | BITC | BITD | BITE);  // 6 operation

这样你可以通过提取公因式来减少操作数量。你可以将这种简化类比于数学中的方法:
A += B * -55 + C * -55 + D * -55
A += -55B - 55C - 55D
A += -55(B + C + D)

想要了解更多布尔代数的知识(在这种情况下非常重要),请点击这里

如果我找到更多好的参考资料,我会在这里链接它。


在编译时进行优化时,也可以减少操作次数。有时为了更好的可读性,最好编写扩展(更多)指令。只有在运行时位没有改变时,才会减少处理操作。如果位是常量,则预处理器将把 ~((1<<7) | (1<<6)) 更改为 0b0011_1111,因此编译后操作 REG &= ~(BITA | ...) 将需要大约3个指令。 - sunriax
@sunriax 我同意,不知道 OP 在用什么编译器?我在 MikCAT 的回答上进行了扩展。 - user5550963
减少操作是否标准化? - user5550963
我不能确切地说每个预处理器都会自动简化常量并且编译器进行优化,但在我使用的环境中,“优化级别(O1)”通常是开启的。 - sunriax
@sunriax,本质上我同意。 - user5550963

0

通过位移也可以按位置清除位:

REG &= ~((1<<7) | (1<<6) | ...);

或者使用预定义的位位置:

#define BITA 7
#define BITB 6

REG &= ~((1<<BITA) | (1<<BITB) | ...);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接