有人可以向我解释一下标志和位域是什么。他们似乎彼此相关,或者说我错了想法。我有点掌握他们所做的事情,但是我想让他们完全解释,我找不到任何好的教程或指南。
如果有人可以提供一些关于如何使用它们的好例子,我会非常感激...例如,我一直看到这些表达式并且我不完全理解它们。只是他们是某种逻辑运算符或其他东西
VARIABLE1 | VARIABLE2
提前致谢!
答案 0 :(得分:3)
可以在此处找到按位操作的介绍:http://www.codeproject.com/Articles/2247/An-introduction-to-bitwise-operators
当它们应用于标志时,按位操作是有利的,因为它们非常快并且节省空间。您可以使用互斥位将对象的许多不同状态存储在单个变量中。即
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;
这将上面的属性2添加到objState by“或”-ing 0010 with 0000,结果为0010.如果我们添加另一个标志/属性,如下所示:
objState |= 0100;
我们最终得到了objState = 0110。
现在我们可以检查对象是否具有属性2集的标志,例如,使用and
:
if (objState & 0010) // do something
当且仅当两个位都为1时, and
为1,因此如果位2为1,则上述操作保证为非零。
正如我所提到的,这种处理对象属性/标志的方法的优点是速度和效率。可以这样想:您可以使用此方法将一组属性存储在单个变量中。
例如,假设您有一个文件类型,并希望使用位掩码跟踪属性(我将使用音频文件)。也许位0-3可以存储文件的位深度,位4-7可以存储文件类型(Wav,Aif等),等等。然后,您只需要将这一个变量传递给不同的函数,并且可以使用您定义的位掩码进行测试,而不必跟踪可能的数十个变量。
希望至少对这种按位操作的应用有所了解。
答案 1 :(得分:0)
整数值的位可以用作bools。
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
}
答案 2 :(得分:0)
“flag”是可以设置或不设置的名义对象,但不是c ++语言的一部分。
位域是一种语言结构,用于使用可能不构成可寻址对象的位组。单个字段是一个 - 通常非常好 - 实现标志的方式。
答案 3 :(得分:0)
“bifield”是“word”中的一个或多个位(即,int
,long
或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)
{
...
}
这实际上只是将一些东西打包成一个变量的简单方法。