Что такое флаги и битовые поля?

Может кто-нибудь объяснить мне, что такое флаги и битовые поля. Кажется, они связаны друг с другом, или, может быть, я неправильно понял. Я немного разбираюсь в том, что они делают и чем занимаются, но я хотел бы получить их полное объяснение, и я не могу найти какие-либо хорошие учебники или руководства.

Я был бы очень благодарен, если бы кто-то мог привести несколько хороших примеров того, как их использовать и т. Д. Например, я все время вижу подобные выражения и не до конца их понимаю. Просто они какие-то логические операторы или что-то

  VARIABLE1 | VARIABLE2

Заранее спасибо!

-6

Решение

Введение в побитовые операции можно найти здесь: 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 путем «или» -ing-0010 с 0000, что приводит к 0010. Если мы добавим еще один флаг / свойство, например, так:

objState |= 0100;

мы в конечном итоге с objState = 0110.

Теперь мы можем проверить, установлен ли у объекта флаг для свойства 2, например, используя and:

if (objState & 0010) // do something

and равен 1, если и только если оба бита равны 1, поэтому, если бит 2 равен 1, вышеуказанная операция гарантированно будет ненулевой.

Итак, как я уже говорил, преимуществами этого способа обработки свойств / флагов объекта являются как скорость, так и эффективность. Подумайте об этом так: вы можете сохранить набор свойств в одной переменной, используя этот метод.

Допустим, например, что у вас есть тип файла, и вы хотите отслеживать свойства, используя битовые маски (я буду использовать аудио файлы). Возможно, биты 0–3 могут хранить битовую глубину файла, биты 4–7 могут хранить тип файла (Wav, Aif и т. Д.) И т. Д. Затем вам просто нужна эта одна переменная для передачи различным функциям, и вы можете тестировать, используя ваши определенные битовые маски, вместо того, чтобы отслеживать потенциально десятки переменных.

Надеюсь, что это проливает некоторый свет на хотя бы одно применение побитовой операции.

2

Другие решения

биты целочисленного значения могут использоваться как 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
}
0

«Двойное поле» представляет собой набор из одного или нескольких битов в «слове» (то есть, скажем, 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)
{
...
}

Это действительно простой способ упаковать несколько вещей в одну переменную.

0

«Флаг» — это условный объект, который может быть установлен или не установлен, но не является частью языка c ++.

Битовое поле — это языковая конструкция для использования наборов битов, которые могут не составлять адресуемый объект. Поля одного бита — это один, часто очень хороший, способ реализации флага.

0