C++ if (mask & VALUE) 或 if ((mask & VALUE) == VALUE)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4649231/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
if (mask & VALUE) or if ((mask & VALUE) == VALUE)?
提问by aschepler
You're probably familiar with the enum
bitmask scheme, like:
您可能熟悉enum
位掩码方案,例如:
enum Flags {
FLAG1 = 0x1,
FLAG2 = 0x2,
FLAG3 = 0x4,
FLAG4 = 0x8,
NO_FLAGS = 0,
ALL_FLAGS = FLAG1 | FLAG2 | FLAG3 | FLAG4
};
f(FLAG2 | FLAG4);
I've seen a lot of code that then tests for a certain bit in the mask like
我看过很多代码,然后测试掩码中的某个位,例如
if ((mask & FLAG3) == FLAG3)
But isn't that equivalent to this?
但这不就等同于这个吗?
if (mask & FLAG3)
Is there some reason to use the first version? In my opinion, the second shorter version is more legible.
有什么理由使用第一个版本吗?在我看来,第二个较短的版本更清晰。
Maybe leftover habits from C programmers who think true values should be converted to 1
? (Though even there, the longer version makes more sense in an assignment or return
statement than in a conditional statement test.)
也许 C 程序员的遗留习惯认为应该将真正的值转换为1
? (尽管如此,较长的版本在赋值或return
语句中比在条件语句测试中更有意义。)
回答by David Gelhar
The construct if ((mask & FLAG3) == FLAG3)
tests if allbits in FLAG3 are present in mask; if (mask & FLAG3)
tests if anyare present.
该构造if ((mask & FLAG3) == FLAG3)
测试FLAG3 中的所有位是否都存在于掩码中;if (mask & FLAG3)
如果测试任何存在。
If you know FLAG3 has exactly 1 bit set, they are equivalent, but if you are potentially defining compound conditions, it can be clearer to get into the habit of explicitly testing for all bits, if that's what you mean.
如果您知道 FLAG3 恰好设置了 1 位,则它们是等效的,但是如果您可能定义复合条件,那么养成显式测试所有位的习惯可能会更清楚,如果这就是您的意思。
回答by Benoit
When it is for a bitset, so you have to compare just a singlebit, it is okay to have if(mask & value)
.
当它是一个bitset,所以你要比较只是一个单一的位,它是好的有if(mask & value)
。
But, suppose that you have an IP address stored on ant int32
and you want to know whether it is 192.168.*
, then you will have to do:
但是,假设您在 ant 上存储了一个 IP 地址,int32
并且您想知道它是否是192.168.*
,那么您必须执行以下操作:
if((ip & 0xFFFF0000) == 0xC0A80000) // assuming some endianness representation.
回答by EboMike
Your condition will be true if the result is non-zero. In your example, the result of both operations would be equivalent, and the second option could even be slightly faster because some CPUs can test for zero easier than other arbitrary numbers, BUT:
如果结果非零,则您的条件为真。在您的示例中,两个操作的结果将是等效的,第二个选项甚至可以稍微快一点,因为某些 CPU 可以比其他任意数字更容易测试零,但是:
Obviously, you can't do the second option if the value you're checking for consists of more than one bit. In that case, you have to use the first option. That obviously also applies if you're checking for several bits at the same time.
显然,如果您要检查的值包含多个位,则不能执行第二个选项。在这种情况下,您必须使用第一个选项。如果您同时检查多个位,这显然也适用。
回答by Konrad Rudolph
Even for the single-bit value where these statements are actually equivalent, I always favour the explicit comparison.
即使对于这些语句实际上等效的单位值,我也总是喜欢显式比较。
It makes the intent clearer. We really areinterested in comparing flags.
(x & Flag) == Flag
is an established pattern and I can process and recognize it at the blink of an eye.I usually prefer explicit over implicit conversions. I make an exception for fail states (e.g. I write
if (file)
instead ofif (file.good())
) but when working with numbers, 0 is not a “fail state”, it's a number like any others. I don't like treating it differently in a boolean context.
它使意图更加清晰。我们真的是希望比较标志。
(x & Flag) == Flag
是一种既定的模式,我可以在眨眼间处理和识别它。我通常更喜欢显式转换而不是隐式转换。我对失败状态做了一个例外(例如,我用
if (file)
代替if (file.good())
)但是在处理数字时,0 不是“失败状态”,它和其他数字一样是一个数字。我不喜欢在布尔上下文中区别对待它。
回答by Charles Merriam
The first construct, if (mask & FLAG3)
means "if at least one common bit is in the flag and mask". For example, if (formats & supported_formats)
would be true if anybit were in common between formats and supported_formats.
第一个构造if (mask & FLAG3)
表示“如果标志和掩码中至少有一个公共位”。例如,if (formats & supported_formats)
如果formats 和supported_formats 之间有任何位相同,则为真。
The second construct, if (mask & FLAG3) == FLAG3
means "if all set bits in FLAG3 are set in the mask". For example, if (things_you_have & things_required) == things_required
would be true if allthings_required were in things_you_have.
第二个构造if (mask & FLAG3) == FLAG3
表示“如果 FLAG3 中的所有设置位都设置在掩码中”。例如, if (things_you_have & things_required) == things_required
如果所有things_required 都在 things_you_have 中,则为真。
Here's a quick hit of some special cases:
以下是一些特殊情况的快速介绍:
- For
FLAG_WITH_EXACTLY_ONE_BIT_SET
, both cases work. - For
OBSOLETE_FLAG_SET_TO_ZERO
, the first case always returns false. - For
FLAG_WITH_MULTIPLE_BITS_REQUIRED
, orFLAG_WHICH_IS_REALLY_TWO_FLAGS_COMBINED_WITH_AN_OR
, the first case returns true when it should not. The second case returns correctly.
- 对于
FLAG_WITH_EXACTLY_ONE_BIT_SET
,两种情况都有效。 - 对于
OBSOLETE_FLAG_SET_TO_ZERO
,第一种情况总是返回 false。 - 对于
FLAG_WITH_MULTIPLE_BITS_REQUIRED
, orFLAG_WHICH_IS_REALLY_TWO_FLAGS_COMBINED_WITH_AN_OR
,第一种情况不应该返回 true 。第二种情况正确返回。
If you have the case of a FLAG_WITH_EXACTLY_ONE_BIT_SET, you should code with the second construct to avoid strange problems when the flag value gets changed. Be explicit unless your profiler tells you to squeeze out every operation.
如果您有 FLAG_WITH_EXACTLY_ONE_BIT_SET 的情况,您应该使用第二个构造进行编码,以避免在标志值更改时出现奇怪的问题。除非你的分析器告诉你要挤出每一个操作,否则要明确。
回答by Daniel Daranas
if
takes a boolean (bool
). The former expression is directly of type bool
, whereas the latter is a numeric value which will be implicitly converted to bool
.
if
接受一个布尔值 ( bool
)。前一个表达式是直接类型的bool
,而后一个表达式是一个将被隐式转换为bool
.