-6

Can someone explain to me what flags and bitfields are. They seems to be related to each other, or mabye i got the wrong idea. I kinda grasp bits and pieces of what they do and are but I would like to get them fully explain and I can't really find any good tutorials or guides.

I would be really thankful if someone could give some good examples on how to use them etc... For instance i see these kinds of expressions all the time and I dont fully understand them. Just that they are some kind of logical operators or something

  VARIABLE1 | VARIABLE2

Thanks in advance!

4

4 回答 4

4

可以在这里找到按位运算的介绍:http: //www.codeproject.com/Articles/2247/An-introduction-to-bitwise-operators

当它们应用于标志时,按位运算的优势在于它们非常快并且节省空间。您可以使用互斥位将对象的许多不同状态存储在单个变量中。IE

0001 // property 1 (== 1, 0x01)
0010 // property 2 (== 2, 0x02)
0100 // property 3 (== 4, 0x04)
1000 // property 4 (== 8, 0x08)

这些可以代表对象的四个不同属性(这些是“掩码”)。我们可以使用以下方法将属性添加到对象的标志状态or

short objState = 0; // initialize to 0
objState |= 0010;

这通过“或”将 0010 与 0000 添加到 objState 中,结果为 0010。如果我们像这样添加另一个标志/属性:

objState |= 0100;

我们最终得到 objState = 0110。

现在我们可以检查对象是否设置了属性 2 的标志,例如,使用and

if (objState & 0010) // do something

and当且仅当两个位都为 1 时为 1,因此如果位 2 为 1,则上述操作保证为非零。

正如我所提到的,这种处理对象属性/标志的方式的优点是速度和效率。可以这样想:您可以使用此方法将一组属性存储在单个变量中。

例如,假设您有一个文件类型,并且您希望使用位掩码跟踪属性(我将使用音频文件)。也许位 0 - 3 可以存储文件的位深度,位 4 - 7 可以存储文件类型(Wav、Aif 等),等等。然后,您只需要将这个变量传递给不同的函数,并可以使用您定义的位掩码进行测试,而不必跟踪可能的几十个变量。

希望至少能对按位运算的这一应用有所了解。

于 2013-03-10T01:18:21.203 回答
0

整数值的位可以用作布尔值。

http://msdn.microsoft.com/en-us/library/yszfawxh(v=vs.80).aspx

用 制作|和检索&

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
}
于 2013-03-10T00:57:53.287 回答
0

“标志”是一个可以设置或不设置的概念对象,但不是 c++ 语言的一部分。

位域是一种语言结构,用于使用可能不构成可寻址对象的位集。单个位的字段是一种——通常非常好的——实现标志的方式。

于 2013-03-10T01:09:56.070 回答
0

“双域”是“字”(即,一个 或 )中的一组一个或多个位intlong它们char一起存储在一个变量中。

例如,您可以在某些动物身上有“无”、“斑点”和/或“条纹”,它也可以有“无、短、中或长”尾巴。

所以,我们需要两个位来表示尾巴的长度:

enum tail
{
   tail_none = 0,
   tail_short = 1, 
   tail_medium = 2, 
   tail_long = 3
};

然后我们将这些作为位存储在“属性”中:

enum bits_shifts
{
   tail_shift = 0,    // Uses bits 0..1
   spots_shift = 2,   // Uses bit 2
   stripes_shift = 3
};


enum bits_counts
{
   tail_bits = 2,    // Uses bits 0..1
   spots_bits = 1,   // Uses bit 2
   stripes_bits = 1
};

我们现在假设我们已经从某个输入中获取了 tail_size 和 has_stripes、has_spots 变量。

int attributes;

attributes = tail_length << tail_shift;

if (has_spots)
{
   attributes |= 1 << spots_shift;
}

if (has_stripes)
{
   attributes |= 1 << stripes_shift;
}

稍后我们想弄清楚属性是什么:

switch((attributes >> tail_shift) & (1 << tail_bits)-1))
{
   case tail_none:
     cout << "no tail";
     break;

   case tail_short:
     cout << "short tail";
     break;

   case tail_medium:
     cout << "medium tail";
     break;

   case tail_short:
     cout << "long tail";
     break;
 }

 if (attributes & (1 << stripes_shift))
 {
    cout << "has stripes";
 }


 if (attributes & (1 << spots_shift))
 {
    cout << "has spots";
 }

现在,我们将所有这些存储在一个整数中,然后再次“捞出”。

你当然也可以这样做:

enum bitfields
{
    has_widget1 = 1,
    has_widget2 = 2,
    has_widget3 = 4, 
    has_widget4 = 8, 
    has_widget5 = 16,
    ...
    has_widget25 = 16777216, 
    ...
}

int widgets = has_widget1 | has_widget5;

... 

if (widgets & has_widget1)
{
  ... 
}

这实际上只是将几个东西打包到一个变量中的一种简单方法。

于 2013-03-10T01:16:12.327 回答