如何使用枚举类型与位标志?

25

我有一个使用位标志的枚举声明,但我无法确切地弄清楚如何使用它。

enum 
{
  kWhite   = 0,
  kBlue    = 1 << 0,
  kRed     = 1 << 1,
  kYellow  = 1 << 2,
  kBrown   = 1 << 3,
};
typedef char ColorType;

我应该把位运算符 OR 用在一起,才能将多个颜色存储在一个colorType中吗?

ColorType pinkColor = kWhite | kRed;

但是假设我想要检查 pinkColor 是否包含 kRed,我该如何做?

有人能否给我一个使用提供的 ColorType 示例的例子?

1个回答

33

是的,使用位或运算符(|)可以设置多个标志:

ColorType pinkColor = kWhite | kRed;

然后使用按位与(&)来测试标志是否已设置:

if ( pinkColor & kRed )
{
   // do something
}
&的结果仅在两个操作数相应位都被设置时才有任何位被设置。由于kRed中只有第1位被设置,如果另一个操作数没有设置这一位,则结果将为0。如果需要将特定标志作为BOOL获取而不仅仅是在if条件中测试它,请比较按位AND的结果与所测试的位。
BOOL hasRed = ((pinkColor & kRed) == kRed);

19
注意:这意味着如果pinkColorkRed,那么(pinkColor & kRed)将评估为kRed,而不是1或YES!这可能是在赋值给小类型(如BOOL)时的一个陷阱:如果该值大于1 <<(BOOL中位数),则它将超出范围。常见的解决方法是将结果与被测试的位进行比较:BOOL isPink = ((pinkColor & kRed) == kRed); 另一种方法是将结果转换为C99的bool类型:isPink = (bool)(pinkColor & kRed); 还有一种(诚然不常见)做法,它并不假设1在范围内,可以使用?:isPink = (pinkColor & kRed) ? YES : NO; - Peter Hosey
@PeterHosey 如果有人对你的评论感兴趣,可以参考以下进一步阅读:http://www.bignerdranch.com/blog/bools-sharp-corners/。顺便说一句,如果有人像我一样困惑为什么将其转换为C99的`bool`而不是`BOOL`会解决问题,答案是转换为`bool`是一种魔法,正如https://dev59.com/xHLYa4cB1Zd3GeqPdfKB中所讨论的那样。简而言之,`bool`是`_Bool`的别名,C99标准规定:“当任何标量值转换为_Bool时,如果该值与0相等,则结果为0;否则,结果为1。” - Mark Amery

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