Ответ 1
Используйте std::bitset
По этот сайт, я хочу представить лабиринт с 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 и т.д.)? Должен ли я использовать перечисление?
См. также Как вы устанавливаете, очищаете и переключаете один бит?.
Используйте std::bitset
Если вы хотите использовать бит-поля, то это простой способ:
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.
Используйте шестнадцатеричные константы/перечисления и побитовые операции, если вам небезразлично, какие конкретные биты означают что.
В противном случае используйте битовые поля С++ (но имейте в виду, что порядок битов в целых будет зависящим от компилятора).
Узнайте свои побитовые операторы: &, |, ^ и!.
В верхней части большого количества файлов C/С++ я видел флаги, определенные в шестнадцатеричном формате, чтобы замаскировать каждый бит.
#define ONE 0x0001
Чтобы узнать, включен ли бит, вы И с ним 1. Чтобы включить его, вы ИЛИ его с 1. Чтобы переключиться как переключатель, XOR это с 1.
Чтобы управлять наборами битов, вы также можете использовать....
std::bitset<N>
std::bitset<4*4> bits;
bits[ 10 ] = false;
bits.set(10);
bits.flip();
assert( !bits.test(10) );
Вы можете сделать это с шестнадцатеричными флагами или перечислениями, как вы предложили, но наиболее читаемые/самодокументированные, вероятно, будут использовать так называемые "битовые поля" (подробнее см. Google для C++ bitfields
).
Да, хороший способ - использовать шестнадцатеричный десятичный знак для представления битовых шаблонов. Затем вы используете побитовые операторы для управления вашими 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
Я не большой поклонник битрейта. Я просто набираю текст на мой взгляд. И это не скрывает, что вы делаете. Вам все еще нужно и && | биты. Если вы не набираете только 1 бит. Это может работать для небольших групп флагов. Не то, чтобы нам нужно было скрыть то, что мы делаем. Но цель класса - это, как правило, сделать что-то проще для пользователей. Я не думаю, что этот класс выполнит это.
Скажем, например, у вас есть система флагов с 64 флагами. Если вы хотите протестировать.. Я не знаю.. 39 из них в 1, если утверждение, чтобы посмотреть, все ли они включены... использование битполей - огромная боль. Вы должны набрать все. Курс. Я исхожу из предположения, что вы используете только функциональные возможности битовых полей, а не методы смешивания и сопоставления. То же самое с битрейтом. Если я не пропустил что-то с классом.., что вполне возможно, так как я редко его использую. Я не вижу способа, которым вы можете протестировать все 39 флагов, если вы не наберете предмет отверстия или не примените "стандартные методы" (используя перечисление флагов или определенное значение для 39 бит и использование оператора битов & &). Это может начать запутываться в зависимости от вашего подхода. И я знаю.. 64 флага звучат как много. И хорошо. Это... в зависимости от того, что вы делаете. Лично говоря, большинство проектов, с которыми я связан, зависят от систем флагов. Так что на самом деле.. 64 не так неслыханно. Хотя 16 ~ 32 гораздо более распространены в моем опыте. Я действительно помогаю в проекте прямо сейчас, когда одна система флагов имеет 640 бит. Это в основном система привилегий. Поэтому имеет смысл организовать их все вместе... Однако.. по общему признанию.. Я хотел бы немного сломать это... но... э... Я помогаю... не создаю.