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