C++ 什么是标志和位字段?
有人能给我解释一下什么是标志和位域吗。他们似乎是有关系的,或者说我的想法错了。我有点了解他们的工作和现状,但我想让他们充分解释,我真的找不到任何好的教程或指南 如果有人能给出一些关于如何使用它们的好例子,我将非常感激。。。例如,我经常看到这种表达方式,但我并不完全理解它们。只是它们是某种逻辑运算符之类的C++ 什么是标志和位字段?,c++,flags,bit-fields,C++,Flags,Bit Fields,有人能给我解释一下什么是标志和位域吗。他们似乎是有关系的,或者说我的想法错了。我有点了解他们的工作和现状,但我想让他们充分解释,我真的找不到任何好的教程或指南 如果有人能给出一些关于如何使用它们的好例子,我将非常感激。。。例如,我经常看到这种表达方式,但我并不完全理解它们。只是它们是某种逻辑运算符之类的 VARIABLE1 | VARIABLE2 提前谢谢 整数值的位可以用作布尔值 使用|生成,使用和检索 enum { ENHANCED_AUDIO = 1, BIG_SPEAKERS =
VARIABLE1 | VARIABLE2
提前谢谢 整数值的位可以用作布尔值 使用
|
生成,使用和检索
enum { ENHANCED_AUDIO = 1, BIG_SPEAKERS = 2, LONG_ANTENNA = 4};
foo(HAS_CAR | HAS_SHOE); // equiv to foo(3);
void processExtraFeatures(flags) {
BOOLEAN enhancedAudio = flags & ENHANCED_AUDIO; // true
BOOLEAN bigSpeakers = flags & BIG_SPEAKERS; // true
BOOLEAN longAntenna = flags & LONG_ANTENNA; // false
}
一个“标志”是一个可以被设置或不设置的概念对象,但不是C++语言的一部分。p>
位域是一种语言构造,用于使用可能不构成可寻址对象的位集。一个位的字段是实现标志的一种——通常是非常好的方式。
一个“双字段”是一个“字”(即,一个int
、long
或char
)中的一个或多个位的集合,存储在一个变量中
例如,在某些动物身上可以有“无”、“斑点”和/或“条纹”,也可以有“无、短、中或长”尾巴
因此,我们需要两个比特来表示尾部的长度:
enum tail
{
tail_none = 0,
tail_short = 1,
tail_medium = 2,
tail_long = 3
};
然后,我们将其作为位存储在“属性”中:
现在我们假设我们已经从一些输入中获取了tail_大小和has_条纹,has_斑点变量
int attributes;
attributes = tail_length << tail_shift;
if (has_spots)
{
attributes |= 1 << spots_shift;
}
if (has_stripes)
{
attributes |= 1 << stripes_shift;
}
这实际上只是一种简单的方法,可以将多个内容打包到一个变量中。按位操作的介绍可以在这里找到:
当它们应用于标志时,按位操作的优势在于它们非常快并且节省空间。通过使用互斥位,您可以在单个变量中存储对象的许多不同状态
0001 // property 1 (== 1, 0x01)
0010 // property 2 (== 2, 0x02)
0100 // property 3 (== 4, 0x04)
1000 // property 4 (== 8, 0x08)
这些可以表示对象的四个不同属性(这些是“掩码”)。我们可以使用或将属性添加到对象的标志状态:
short objState = 0; // initialize to 0
objState |= 0010;
这将通过“或”-将0010与0000匹配,将上述属性2添加到objState,从而得到0010。如果我们添加另一个类似的标志/属性:
objState |= 0100;
我们最终得到objState=0110
现在,我们可以检查对象是否设置了属性2的标志,例如,使用和:
if (objState & 0010) // do something
和
为1当且仅当两位均为1时,因此如果位2为1,则上述操作保证为非零
正如我所提到的,这种处理对象的属性/标志的方法的优点是速度和效率
比方说,你有一个文件类型,你希望使用位掩码跟踪属性(我将使用音频文件)。也许位0-3可以存储文件的位深度,位4-7可以存储文件类型(Wav、Aif等),等等。然后,您只需要将这一个变量传递给不同的函数,就可以使用定义的位掩码进行测试,而不必跟踪可能的几十个变量
希望这至少能为位运算的这一应用提供一些启示。你读过维基百科关于这一主题的文章吗?请参阅
short objState = 0; // initialize to 0
objState |= 0010;
objState |= 0100;
if (objState & 0010) // do something