Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.05.2017, 11:35   #1
седьмой
Форумчанин
 
Регистрация: 17.07.2012
Сообщений: 140
Подмигивание Помогите пожалуйста разобраться с <<?

В книгах полистал написано что это сдвиг, но куда сдвиг и зачем как то не уложилось, вопрос наверно простой. Но разобраться самостоятельно не могу, поэтому решил попытаться обратиться на форум. В программе этот символ встречается в разных вариациях, я сейчас их перечислю и если вы поясните, то мне кажется должно все проясниться
1.
Код:
if (int_num[bcnum] == 2 &&  bc_aw1 == ((rtadr<<11) | RTFL_MASK) && 1)
Первая часть у Ифа понятна, там значение массива проверяется равно 2 или нет, дальше идет логическое И, а вот следующее действие совсем не понимаю, проверяется равно ли значение переменной bc_aw1 сдвинутое влево на 11 разрядов или равно Маске и при этом еще есть логическое И с 1. Совершенно не могу понять как это все должно работать, логики не вижу.
2. Вот еще пример кода
Код:
   buffer[0] = base | (base<<8);
тут в массив записывается число через ИЛИ, причем второй аргумент со сдвигом. Тут два вопроса, что запишется в переменную Base или Base<<8 и как программа выберет что ей записать, то или другое, и какое это будет второе число?
3.
Код:
  ci_field = 0x1F<<5;
Тут непонятно зачем сдвигать константу, можно ведь сразу вычислить что получится после сдвига и это записать в переменную, почему надо сперва сдвигать , а только потом это записывать?
4. Тут вот еще запутаннее
Код:
   bcputw(0, (rtadr<<11) | RT_TRANSMIT | (subadr<<5) | (len & 0x1F));
  bcputw(0, ~RT_DIR_MASK & ((rtadr<<11) | ci_field | SYNC));
    buffer[0] = (page<<14) | (subadr<<8) | (page<<6) | subadr | 0x2020;
тут во 2й строке еще тильда появилась

PS. это готовый драйвер к плате, который писали 20 лет назад, привет из прошлого под досом
Если хоть что то поясните буду очень признателен.
седьмой вне форума Ответить с цитированием
Старый 10.05.2017, 12:07   #2
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Код:
bc_aw1 == ((rtadr<<11) | RTFL_MASK) && 1)
тут походу опечатка, причем ломающая всю логику. В данном случае, если MASK не ноль, то выражение всегда 1 (может это и есть ваш отот вечный баг пару бит, и достаточно тут исправить?)

Думаю, нада бы так

Код:
bc_aw1 == ((rtadr<<11) | RTFL_MASK) & 1)
Тогда, это выглядит, как проверка младшего бита результата сдвига + маска.

Код:
 buffer[0] = base | (base<<8);
тут все ясно - младшие 8 бит принудительно "плюсуются" в старшие 8 бит.

...походу вы путаете логический и битовый операторы. & - &&, | - ||. Двойной знак - это логическое вычисление, его результат всегда 0 или не ноль(обычно 1). Одинарный знак - это битовое вычиселение, производится операция над каждой парой бит двух значений.

Цитата:
Тут непонятно зачем сдвигать константу, можно ведь сразу вычислить что получится после сдвига и это записать в переменную, почему надо сперва сдвигать , а только потом это записывать?
Потому что лень, пусть компилер считает, он это сам, на этапе компиляции просчитает. А человеку нагляднее.

Цитата:
тут во 2й строке еще тильда появилась
Битовое отрицание - все биты числа меняются на обратные.

Код:
  bcputw(0, (rtadr<<11) | RT_TRANSMIT | (subadr<<5) | (len & 0x1F));
Ну здесь формируется число по битовому шаблону, например, младшие 5 бит такого числа будут равны младшим 5 битам len, потом идет 5 бит subadr скорее всего, при условии, что subadr не содержит 6го и следующих бит никогда, иначе ошибка, вернее было бы

Код:
((subadr & 0x1F)<<5)
Т.е. такая вот конструкция (subadr & 0x1F) гарантирует, что в числе будут только 5 младших бит, остальные станут всегда 0 и при сложении, после сдвига, не будут никак влиять на последущие биты. Вобщем плохой у вас код. С кучей не явных предположений, например, если subadr >=32, то вся эта логика сломается и будет работать не так, как думалось.


https://ru.wikipedia.org/wiki/%D0%9E...%D0%B8_C%2B%2B

Последний раз редактировалось alexzk; 10.05.2017 в 12:25.
alexzk вне форума Ответить с цитированием
Старый 10.05.2017, 13:08   #3
седьмой
Форумчанин
 
Регистрация: 17.07.2012
Сообщений: 140
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
...походу вы путаете логический и битовый операторы. & - &&, | - ||. Двойной знак - это логическое вычисление
Спасибо большое, похоже именно в этом я и запутался
седьмой вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите разобраться, пожалуйста! ПетрИванов Помощь студентам 0 10.11.2015 21:54
Помогите пожалуйста разобраться.... ИриSка-147 Помощь студентам 15 18.01.2015 10:41
Помогите пожалуйста разобраться. Ryjik Общие вопросы C/C++ 0 22.10.2009 14:07
помогите разобраться пожалуйста Aronax Общие вопросы C/C++ 2 04.07.2009 11:14
Пожалуйста помогите разобраться) Atij1 Общие вопросы C/C++ 4 13.04.2008 20:32