Строка 357: |
Строка 357: |
| | | |
| = Битовые операции = | | = Битовые операции = |
| + | |
| + | Иногда полезно упаковать несколько флагов в одну переменную. Примером этого является переменная mob.sight. Каждый флаг представлен одним битом включения/выключения в значении. Например, в случае с mob.sight возможны следующие значения: |
| + | |
| + | (Не слишком привязывайтесь к специфике этой переменной. Тому это не нравится, и у меня есть ощущение, что он может устроить еще одно восстание, чтобы подавить его. Бессердечный демагог! Без него DM так и остался бы простым языком ассемблера.) |
| + | |
| + | #define BLIND 1 //binary 00001 |
| + | #define SEEINVIS 2 //binary 00010 |
| + | #define SEEMOBS 4 //binary 00100 |
| + | #define SEEOBJS 8 //binary 01000 |
| + | #define SEETURFS 16 //binary 10000 |
| + | |
| + | Каждое значение является степенью двойки, что позволяет нам генерировать уникальные числа путем их комбинации. |
| + | |
| + | Чтобы упростить работу с отдельными битами, существует ряд побитовых операторов (унаследованных от C). При использовании этих операторов аргументами должны быть 16-битные целые числа (в диапазоне от 0 до 65535). (65535 - это просто шестнадцать 1 в двоичном исчислении; это самое большое 16-битное число). Все, что выходит за пределы этого диапазона, будет обрезано. |
| + | |
| + | == ~ побитовое NOT (НЕ) == |
| + | |
| + | Оператор ~ выполняет побитовое НЕ для своего аргумента. Для каждого из 16 битов аргумента, если этот бит равен 1, соответствующий бит в результате будет равен 0, и наоборот. Это очень похоже на оператор !, только в последнем случае неважно, какие биты включены - важно, чтобы хотя бы один бит был включен. Оператор ! также работает с другими значениями, кроме 16-битных целых чисел. |
| + | |
| + | ~ expression |
| + | |
| + | == & побитовое AND (И) == |
| + | |
| + | Оператор & выполняет побитовое AND своих аргументов. Для каждой пары битов в аргументах соответствующий бит в результате будет равен 1, если они оба равны 1, и 0 в противном случае. Обратите внимание, что это аналог логического оператора &&, за исключением того, что он обрабатывает каждый бит по отдельности, а не значение в целом. |
| + | |
| + | expression1 & expression2 |
| + | |
| + | Оператор & чаще всего используется для проверки того, установлен ли определенный битовый флаг. Например, mob.sight & SEEINVIS будет ненулевым (т. е. истинным), если флаг SEEINVIS установлен, и 0 в противном случае. |
| + | |
| + | == | побитовое OR (ИЛИ) == |
| + | |
| + | Оператор | выполняет побитовое ИЛИ своих аргументов. Для каждой пары битов в аргументах соответствующий бит в результате будет равен 1, если один из них равен 1, и 0 в противном случае. Обратите внимание, что этот оператор аналогичен логическому оператору ||, за исключением того, что он обрабатывает каждый бит по отдельности, а не значение в целом. |
| + | |
| + | expression1 | expression2 |
| + | |
| + | Оператор | чаще всего используется для объединения нескольких битовых флагов. Например, mob.sight может быть установлен в SEEMOBS | SEEOBJS, чтобы дать кому-то рентгеновское видение предметов сквозь стены. На самом деле, для этой цели можно использовать и +, если не включать один и тот же флаг более одного раза. |
| + | |
| + | == ^ побитовый XOR (исключающее ИЛИ) == |
| + | |
| + | Оператор ^ выполняет побитовое исключающее ИЛИ своих аргументов. Для каждой пары битов в аргументах соответствующий бит в результате будет равен 1, если один из них равен 1, и 0 в противном случае. |
| + | |
| + | expression1 ^ expression2 |
| + | |
| + | Оператор ^ чаще всего используется для переключения битового флага. Например, mob.sight = mob.sight ^ SEEINVIS включит флаг SEEINVIS, если он выключен, и наоборот. |
| + | |
| + | == Сдвиг битов == |
| + | |
| + | Операторы << и >> выполняют сдвиг битов влево и вправо. Они почти никогда не используются в программах DM, но включены, поскольку являются стандартными операторами языка C. При использовании вне выражения (в операторе) эти операторы имеют совсем другое значение (унаследованное от C++); в этом случае они служат операторами ввода/вывода. Вы почти всегда будете использовать их в этом виде. |
| + | |
| + | == Порядок побитовых операций == |
| + | |
| + | Порядок, в котором оцениваются побитовые операторы, приведен на рисунке 6.11 - от старшего к младшему. Операторы, расположенные в одной строке, имеют одинаковый приоритет и поэтому оцениваются слева направо по мере их появления в выражении. |
| + | |
| + | Рисунок 6.11: Порядок побитовых операций |
| + | |
| + | ( ) ~ |
| + | << >> |
| + | & |
| + | ^ |
| + | | |
| | | |
| = Операторы присваивания = | | = Операторы присваивания = |