Зачем в этом коде "!!"?
- Войдите на сайт для отправки комментариев
Втр, 28/11/2017 - 03:36
Не могу понять, зачем в этой строке стоит два значка "!". Насколько мне известно, в программировании так обозначается символ логического отрицания (то есть не равно)!
digitalWrite(dataPin, !!(val & (1 << i)));
Однако если символов два, то в итоге получится то же самое разве нет?
Вот полный код, из которого я взял эту строку
/* wiring_shift.c - shiftOut() function Part of Arduino - http://www.arduino.cc/ Copyright (c) 2005-2006 David A. Mellis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ */ #include "wiring_private.h" uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) { uint8_t value = 0; uint8_t i; for (i = 0; i < 8; ++i) { digitalWrite(clockPin, HIGH); if (bitOrder == LSBFIRST) value |= digitalRead(dataPin) << i; else value |= digitalRead(dataPin) << (7 - i); digitalWrite(clockPin, LOW); } return value; } void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) { uint8_t i; for (i = 0; i < 8; i++) { if (bitOrder == LSBFIRST) digitalWrite(dataPin, !!(val & (1 << i))); else digitalWrite(dataPin, !!(val & (1 << (7 - i)))); digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW); } }
Кто разбирается, подскажите пожалуйста, зачем эти символы? Что делает эта строка? Заранее спасибо!
Было: "ноль" или "не ноль".
После !! стало: "ноль" или "единица".
Было: "ноль" или "не ноль".
После !! стало: "ноль" или "единица".
Чёт моя "думалка" зависла... не "ноль" -это и есть логическая "единица"== истина.
Или есть иной смысл в "!!" ?
Функция digitalWrite(uint8_t pin, uint8_t val)
Чёт моя "думалка" зависла... не "ноль" -это и есть логическая "единица"== истина.
Это у Вас "от многих знаний, много печали".
"Не ноль", это, например, 10 или 33.
Т.е. !! используется тогда, когда нужно гарантированно получить 0 или 1, а не просто 0 или "не 0".
"Не ноль", это, например, 10 или 33.
Т.е. !! используется тогда, когда нужно гарантированно получить 0 или 1, а не просто 0 или "не 0".
Евгений, это мне понятно, я имел ввиду конкретный код:
Обязательно ли в этом случае второй аргумент, передаваемый в функцию приводить к значению "ноль" или "единица"? Может ли без этого как-то нарушиться условие?
Нет, конечно, здесь ведь идёт правильная проверка "0 - не 0". СТрока 4 - прямое сравнение с 0, а строка 7 выполняется при любом "не нуле".
Нет, конечно, здесь ведь идёт правильная проверка "0 - не 0". СТрока 4 - прямое сравнение с 0, а строка 7 выполняется при любом "не нуле".
Спасибо. Значит в строке, о которой спрашивал ТС, есть лишнее-без чего можно обойтись.
digitalWrite(dataPin, !!(val & (1 << i))); // "!!" лишнее
Совершенно верно
Вполне возможно, что это архитектурное наследие (digitalWrite() было написано иначе) или же защита от багов при возможном последующем изменении digitalWrite(). Нужно итальянцам написать для выяснения.
Помогите пожалуйста разобраться, что делает этот кусочек кода!
Я только понял, что это проверка условия через оператор if! Если переменная val равна LOW, то выполняется эта строка
а иначе другая
Здесь куча каких-то странных символов? Помогите пожалуйста их расшифровать? Заранее спасибо!
Страуструп тебе может помочь более чем полностью
junior_developer,
может, пора уже какую-нибудь книжку почитать? Мы ответили на несколько Ваших вопросов, но если дело так пойдёт дальше, то это на годы. Давайте Вы прочтёте какую-нибудь книгу по языку.
А давайте ему расшифруем, че там :)
В строке 2 в ячкйке памяти находящейся по адресу out, остаются все биты яыляющимися активными в инверсном отображении переменной bit, а остальные сбрасываются.
В строке 4 в ячкйке памяти находящейся по адресу out, устанавливаются биты являющиеся активными в переменной bit.
Стало понятно ?
brokly, большое Вам спасибо, что не поленились прокомментировать каждую строчку так детально! Я погуглил по всем непонятным мне словам Вашего ответа, и в результате я понял!
Встретился мне вот сегодня ещё непонятный фрагмент. По идее он выполняет (точнее должен выполнять) чтение из памяти 4 байтного числа!
Я вижу здесь кучу символов "*". Это, скорее всего, означает, что с переменной работают через указатель!
Мне только непонятно, почему в каждой строке два символа * и всего один &.
Ведь они выполняют противоволожное действие! & берет адрес, а * возвращает по этому адресу значение?
то есть можно было бы написать
а написано
Почему там (uint8_t*)? Зачем этот символ?
junior_develope, не будьте таким принципиальным в получении знаний.Поступите как нормальные люди возьмите и изучите учебник.
ПС: На меня посмотрят, как на идиота если я спрошу: почему вы написали так много о
Мне только непонятно, почему в каждой строке два символа * и всего один &.
И наверно будут правы, потому что буквы о одинаковы, но в каждом случае у них разные роли. Так и со звездочками *
легко меняется на
EEPROM.get(0,counter);
https://www.arduino.cc/en/Reference/EEPROMGet
qwone, большое Вам спасибо, что объяснили так детально! Я всё понял, кроме этой строчки:
Не могли бы Вы подробнее написать, что это означает? Создать указатель типа byte на адрес переменной counter? Я Вас правильно понял?
quone, большое спасибо! Я наконец-то понял!
Хотя появился ещё вопрос: как правильно объявить переменную, которая будет храниться в этой памяти!
Где её инициализировать? Перед setup?
В setup или loop?
Дело в том, что если в ячейках памяти еще ничего не записано, то вообще непонятно, как будет работать программа?
Получается нужно присвоить сначала значение, а потом сразу же заменить значение переменной на другое (считанное из EEPROM)? То есть написать так:
Вот код:
Посмотрите пожалуйста, правильно ли я написал?
Там все не верно. Похоже бессыслено вас учить. У вас банально нет базовых знаний. А без них только .... Врач сказал в морг, значит в морг.
В коде нету обработчика нажатия кнопок! Вместо него я написал:
Я не добавлял ещё кучу кода, чтобы пример был легко читаем!
В итоге обработка нажатий по "флагам". Если установлен button1, то увеличить задержку, button2 - уменьшить, а button3
Это неправильно?
У Вас почему-то две различные переменные ledDelay и delayTime. Ну пусть две, раз так хочется, но тогда наверное одну другой присваивать где-то надо. По поводу строки 11. Понятно что объявить переменную нужно до использования, присваивать значение не обязательно. В каких-то случаях может понадобиться проверка после чтения значения - не ерунду ли какую считали. Ну и записывать можно не каждый раз, а только если значение изменилось, чего ячейку зря напрягать. Да и чего спрашиваете правильно/неправильно написано - залили и проверили!
Да, Вы правы я допустил ошибку, неправильно указав имя переменной! И по поводу проверки значения перед записью тоже правы! Большое спасибо Вам за подсказку!
Код я поправил! И отредактировал строку записи в память. Теперь она выглядит так
Код целиком:
junior_developer, ну Вы сами-то хоть чуть-чуть подумайте над тем, что пишете! Ну что за условие delayTime != delayTime ? Это же как 2 не равно 2.
delayTime != delayTime ? Это же как 2 не равно 2.
Ну, формально вполне допустимо, и при некоторых значения delayTime вполне может быть истинным :)))
Однако наверно придеться ввести ещё одну переменную
Правильно?
EEPROM.update(address, value)Записывает байт в EEPROM. Значение записывается, только если оно отличается от значения уже записанного по этому адресу.
http://radioprog.ru/post/117#p117-update
По ссылке, которую Вы дали, написано:
value: значение для записи, от 0 до 255 (byte)
Это значит, что обновляется только переменная размером 1 байт? А если у меня значение переменной например от 0 до 1000? То есть в байт оно не влезает! Разве EEPROM.update(address, value) подойдет?
Note
This function uses EEPROM.update() to perform the write, so does not rewrites the value if it didn't change.
Это про eeprom.put Если больше байта используйте put она сама вызовет апдейт.