Как вы используете побитовые флаги в С++?

По этот сайт, я хочу представить лабиринт с 2-мерным массивом из 16-битных целых чисел.

Каждое 16-битное целое число должно содержать следующую информацию:

Здесь один из способов сделать это (это далеко не единственный путь): сетка лабиринтов 12x16 может быть представлена ​​как массив m [16] [12] из 16-битных целых чисел. Каждый элемент массива будет содержать всю информацию для одной соответствующей ячейки в сетке, причем целочисленные биты отображаются следующим образом:

alt text http://www.mazeworks.com/mazegen/mazetut/tut5.gif

Чтобы сбить стену, установить границу или создать конкретный путь, все, что нам нужно сделать, это перебросить биты в один или два элемента массива.

Как использовать побитовые флаги для 16-битных целых чисел, поэтому я могу установить каждый из этих битов и проверить, установлены ли они.

Я хотел бы сделать это легко читаемым способом (например, Border.W, Border.E, Walls.N и т.д.).

Как это вообще делается на С++? Я использую hexidecimal для представления каждого из них (например, Walls.N = 0x02, Walls.E = 0x04 и т.д.)? Должен ли я использовать перечисление?


См. также Как вы устанавливаете, очищаете и переключаете один бит?.

Ответ 1

Используйте std::bitset    

Ответ 2

Если вы хотите использовать бит-поля, то это простой способ:

typedef struct MAZENODE
{
    bool backtrack_north:1;
    bool backtrack_south:1;
    bool backtrack_east:1;
    bool backtrack_west:1;
    bool solution_north:1;
    bool solution_south:1;
    bool solution_east:1;
    bool solution_west:1;
    bool maze_north:1;
    bool maze_south:1;
    bool maze_east:1;
    bool maze_west:1;
    bool walls_north:1;
    bool walls_south:1;
    bool walls_east:1;
    bool walls_west:1;
};

Затем ваш код может просто проверить каждый из них для истины или false.

Ответ 3

Используйте шестнадцатеричные константы/перечисления и побитовые операции, если вам небезразлично, какие конкретные биты означают что.

В противном случае используйте битовые поля С++ (но имейте в виду, что порядок битов в целых будет зависящим от компилятора).

Ответ 4

Узнайте свои побитовые операторы: &, |, ^ и!.

В верхней части большого количества файлов C/С++ я видел флаги, определенные в шестнадцатеричном формате, чтобы замаскировать каждый бит.

#define ONE 0x0001

Чтобы узнать, включен ли бит, вы И с ним 1. Чтобы включить его, вы ИЛИ его с 1. Чтобы переключиться как переключатель, XOR это с 1.

Ответ 5

Чтобы управлять наборами битов, вы также можете использовать....

std::bitset<N>

std::bitset<4*4> bits;
bits[ 10 ] = false;
bits.set(10);
bits.flip();
assert( !bits.test(10) );

Ответ 6

Вы можете сделать это с шестнадцатеричными флагами или перечислениями, как вы предложили, но наиболее читаемые/самодокументированные, вероятно, будут использовать так называемые "битовые поля" (подробнее см. Google для C++ bitfields).

Ответ 7

Да, хороший способ - использовать шестнадцатеричный десятичный знак для представления битовых шаблонов. Затем вы используете побитовые операторы для управления вашими 16-битными ints.

Например:

if(x & 0x01){} // tests if bit 0 is set using bitwise AND
x ^= 0x02;     // toggles bit 1 (0 based) using bitwise XOR
x |= 0x10;     // sets bit 4 (0 based) using bitwise OR

Ответ 8

Я не большой поклонник битрейта. Я просто набираю текст на мой взгляд. И это не скрывает, что вы делаете. Вам все еще нужно и && | биты. Если вы не набираете только 1 бит. Это может работать для небольших групп флагов. Не то, чтобы нам нужно было скрыть то, что мы делаем. Но цель класса - это, как правило, сделать что-то проще для пользователей. Я не думаю, что этот класс выполнит это.

Скажем, например, у вас есть система флагов с 64 флагами. Если вы хотите протестировать.. Я не знаю.. 39 из них в 1, если утверждение, чтобы посмотреть, все ли они включены... использование битполей - огромная боль. Вы должны набрать все. Курс. Я исхожу из предположения, что вы используете только функциональные возможности битовых полей, а не методы смешивания и сопоставления. То же самое с битрейтом. Если я не пропустил что-то с классом.., что вполне возможно, так как я редко его использую. Я не вижу способа, которым вы можете протестировать все 39 флагов, если вы не наберете предмет отверстия или не примените "стандартные методы" (используя перечисление флагов или определенное значение для 39 бит и использование оператора битов & &). Это может начать запутываться в зависимости от вашего подхода. И я знаю.. 64 флага звучат как много. И хорошо. Это... в зависимости от того, что вы делаете. Лично говоря, большинство проектов, с которыми я связан, зависят от систем флагов. Так что на самом деле.. 64 не так неслыханно. Хотя 16 ~ 32 гораздо более распространены в моем опыте. Я действительно помогаю в проекте прямо сейчас, когда одна система флагов имеет 640 бит. Это в основном система привилегий. Поэтому имеет смысл организовать их все вместе... Однако.. по общему признанию.. Я хотел бы немного сломать это... но... э... Я помогаю... не создаю.