[Все языки, C++] Побитовые операторы [1 часть] - Форум Cheat-Master.ru
  • Страница 1 из 1
  • 1
Модератор форума: Sanoxxx, Alowir  
[Все языки, C++] Побитовые операторы [1 часть]
Голубь Дата: Воскресенье, 10.08.2014, 13:21 | Сообщение # 1
Авторитет
Сообщений: 2137
Статус: Offline
На создание этой темы меня вдохновил один человек, под ником "T** N*****" (не буду называть его ника)

На пример возьмем один прием: Упаковка нескольких параметров в 1
Вот код:
Код

#define CN_IVANKOV 1 << 0
#define CN_FAD 1 << 1
#define CN_CAPONE 1 << 2
#define CA_HEAD 1 << 3
#define CA_YAXTA 1 << 4
#define CA_COLA 1 << 5

void ShowSampInfo(unsigned long dwFlags)
{
     char szText[64];
     unsigned long dwLastFlag;
     memset(szText, 0x0, sizeof(szText));
     if (dwFlags & CN_IVANKOV)
     {
      strcat(szText, "Vyacheslav_Ivankov ");
      dwLastFlag = (dwFlags & (~CN_IVANKOV));
     }
     else if (dwFlags & CN_FAD)
     {
      strcat(szText, "Flazy_Fad ");
      dwLastFlag = (dwFlags & (~CN_FAD));
     }
     else if (dwFlags & CN_CAPONE)
     {
      strcat(szText, "El_Capone ");
      dwLastFlag = (dwFlags & (~CN_CAPONE));
     }

     switch (dwLastFlag)
     {
      case CA_HEAD:
      {
       strcat(szText, "моет голову");
       break;
      }
      case CA_YAXTA:
      {
       strcat(szText, "купил яхту");
       break;
      }
      case CA_COLA:
      {
       strcat(szText, "возит колу");
       break;
      }
     }
     printf(szText);
}

int _tmain(int argc, _TCHAR* argv[])
{
     setlocale(LC_ALL, "ru-RU");
     ShowSampInfo(CN_FAD | CA_YAXTA);
     getchar();
     return 0;
}


Нам даст текст: Flazy_Fad купил яхту

Объясню как это работает.
Кол-во параметров, которое можно передать - ограничено размером переменной, в которой упакованы параметры.
#define CN_IVANKOV 1 << 0 // в бинарном виде 00000001
#define CN_FAD 1 << 1 // в бинарном виде 00000010
#define CN_CAPONE 1 << 2 // в бинарном виде 00000100
#define CA_HEAD 1 << 3 // в бинарном виде 00001000
#define CA_YAXTA 1 << 4 // в бинарном виде 00010000
#define CA_COLA 1 << 5 // в бинарном виде 00100000

Теперь рассмотрим то, как вызывается функция

ShowSampInfo(CN_FAD | CA_YAXTA);

| - это побитовый оператор ИЛИ, он заменяет бит на "1", если хотя бы один операнд имеет в этом бите "1"
Теперь вспомним наши дефайны:
Код

#define CN_FAD 1 << 1 // в бинарном виде 00000010
#define CA_YAXTA 1 << 4 // в бинарном виде 00010000


Теперь смотрим что получится:
00000010
|
00010000
=
00010010.
Так получилось потому-что 2 бит в первом операнде был равен 1(true, истина).
Теперь зайдем в тело функции.
Код
char szText[64];
     unsigned long dwLastFlag;
     memset(szText, 0x0, sizeof(szText));

Тут думаю все понятно, а теперь нам бросается в глаза знак & - что он делает?
Код
if (dwFlags & CN_IVANKOV)

Рассмотрим как работает это условие:
1) Пусть мы передали параметр CN_FAD | CA_YAXTA
2) В прошлом шаге в dwFlags мы получили: 00010010, а CN_IVANKOV равен 00000001.
А теперь рассмотрим, что делает &.
& - это побитовый оператор И, он заменяет бит на "0", если хотя бы один операнд имеет в этом бите "0"
3) Снова вернемся к нашим дефайнам и dwFlags: В dwFlags мы получили: 00010010, а CN_IVANKOV равен 00000001.
4) Теперь смотрим что получится:
00010010
&
00000001
=
0
Так получилось потому-что все биты в обоих операндах не были равны 0(false, ложь).

Переходим к следующему условию.
Код
else if (dwFlags & CN_FAD)

Рассмотрим как работает это условие:
1) Пусть мы передали параметр CN_FAD | CA_YAXTA
2) В знакомом нам уже dwFlags мы получили: 00010010, а CN_FAD равен 00000010.
3) Что мы видим! Второй бит обоих операндов равен "1", как вы уже поняли, условие не будет ложно!
4) Выполним расчет: 00010010
&
00000010
=
00000010
5) Условие истинно.
Код
  strcat(szText, "Flazy_Fad "); // тут думаю понятно
      dwLastFlag = (dwFlags & (~CN_FAD));

Но теперь видим новый знак - "~".
"~" - это побитовое НЕ, оно заменяет все "1" на "0", а "0" на "1"
1) Пусть в знакомом нам уже dwFlags мы получили: 00010010, а CN_FAD равен 00000010
2) Начнем с (~CN_FAD)
~00000010
=
11111101
3) Далее, получаем наконец уже dwLastFlag использую полученное в прошлом шаге значение и dwFlags
00010010
&
11111101
=
10000
Так как, мы упаковали всего два, параметра, мы получили параметр, который остался.
10000 - тут у нас побитовый сдвиг влево на 4 байта.
Что такое << и >> побитовый сдвиг влево/вправо, это когда биты перемещаются влево или вправо.
Например. Имеем число 000001, сдвинем его влево на 3 бита. Получим: 0001000, а теперь вправо на 2 бита, получим 0000010.
У нас в наших дефайнах сдвиг на 4 байта в дефайне
Код
#define CA_YAXTA 1 << 4

Следовательно, в
Код
switch (dwLastFlag)

выполнится кейс CA_YAXTA!
И в итоге получаем текст: Flazy_Fad купил яхту
А если мы не хотим, чтобы Flazy_Fad плавал на яхте, то ShowSampInfo(CN_FAD | CA_YAXTA); меняем на ShowSampInfo(CN_FAD | CA_HEAD); и будет текст: Flazy_Fad моет голову.

Статью подготовил: Голубь
При копировании укажите источник: Cheat-Master.Ru


(Ответы принимаются до 12.08.2014) А теперь приз 50 рублей на WMR за правильный ответ на вопрос:
Найдите две переменных, где более правильней будет использование типа BYTE.

Победитель: [CM]MishaN - получает 50 рублей на WMR
Цитата [CM]MishaN ()
Наверно dwFlags и dwLastFlags, т.к. в вариантах нету значения больше байта.


двач
https://vk.com/povargek
petro123456 Дата: Воскресенье, 10.08.2014, 13:24 | Сообщение # 2
Новичок
Сообщений: 11
Статус: Offline
не плохо
[CM]MishaN Дата: Воскресенье, 10.08.2014, 16:01 | Сообщение # 3
Cheat-Master
Сообщений: 1308
Статус: Offline
Цитата Голубь ()
Найдите две переменных, где более правильней будет использование типа BYTE.

Наверно dwFlags и dwLastFlags, т.к. в вариантах нету значения больше байта.


100$ баланса за регистрацию на Digital Ocean [только по данной ссылке] (один из лучших хостингов)
RakBot - Качай аккаунты не напрягаясь!
Мои товары в CM Shop (NEW!!!)
Голубь Дата: Воскресенье, 10.08.2014, 16:40 | Сообщение # 4
Авторитет
Сообщений: 2137
Статус: Offline
Цитата [CM]MishaN ()
Наверно dwFlags и dwLastFlags, т.к. в вариантах нету значения больше байта.


WMR в скайп


двач
https://vk.com/povargek
Sergo_bro2 Дата: Воскресенье, 10.08.2014, 17:59 | Сообщение # 5
Coder
Сообщений: 892
Статус: Offline
Из этого урока я понял как переводить в биты

CS:GO RANK: SUPREME*Клац*
[b][+]Skype: sergeiplugatyr

  • Страница 1 из 1
  • 1
Поиск:
Статистика Форума
Лучшие пользователи
Admin [39113]

GеNius [7210]

[CM]Russel [5557]

kenlo763 [4952]

[CM]AGRESSOR [4639]

Snake_Firm [4452]

Сэс [4416]

Artem_Buero [4223]

[CM]Durman [3204]

[CM]Рафаэль [3080]

iMaddy [2855]

sky_Woker [2854]

getrekt [2745]

Новые пользователи
billienq1 [01:47]

staciah1 [01:15]

maksmovictimofej [00:18]

jamiedv6 [21:25]

billieds7 [20:51]

aprilez9 [15:57]

am9350450 [14:36]

dcvfre [11:04]

Sheroz [10:38]

dominiquevp60 [08:59]

derrickuy11 [05:48]

leannaaw60 [04:45]

nonaxn11 [23:52]