операторы if/else без операторов сравнения и фигурных скобок
Недавно я наткнулся на этот код в руководстве. Код работает, но этот синтаксис, похоже, сильно отличается от https://www.arduino.cc/reference/en/language/structure/control-structure/if/, поскольку в нём отсутствуют операторы сравнения и фигурные скобки для операторов. Может кто-нибудь объяснить, почему это работает?
for (int i = 0; i < 15; i++)
{
lcd.setCursor(i, 1);
if (pressed[i])
lcd.print("X");
else
lcd.print(" ");
if (justpressed[i])
digitalWrite(led, HIGH);
else
digitalWrite(led, LOW);
}
@Erik, 👍5
Обсуждение2 ответа
Лучший ответ:
О недостающих условиях, например:
if (pressed[i])
Если предполагается логическое значение, то это предпочтительный способ, при условии, что логическое значение равно нулю (0) при значении «ложь» и отлично от нуля при значении «истина». Это то же самое, что записать:
if (pressed[i] != 0)
Это обычно не делается для целых чисел, только для логических значений.
О скобках: если у вас всего один оператор, скобки можно опустить. Но это довольно плохая практика программирования, поскольку рано или поздно вы добавите оператор без скобок, и это приведёт к ошибке.
Если вы действительно хотите сократить его, то вместо
if (justpressed[i])
digitalWrite(led, HIGH);
else
digitalWrite(led, LOW);
использовать
digitalWrite(justpressed[i] ? HIGH : LOW);
Это называется Тернарным оператором.
обновление
Используя замечание Wonder, но с тернарной операцией ваш код может быть
for (int i = 0; i < 15; i++)
{
lcd.setCursor(i, 1);
lcd.print ( pressed [i] ? "X" : " ");
digitalWrite(led, justpressed[i] ? HIGH : LOW);
}
Ради интереса, даже вывод if/else можно значительно сократить: lcd.print(" X"[!!pressed[i]]);, @wondra
@wondra верно... но большинству приходится перечитывать несколько раз, чтобы понять, почему это работает... Я бы, наверное, изменил это на lcd.print(pressed[i] ? "X" : " ");, @Michel Keijzers
К сожалению, в большинстве случаев весело =/= умно. Полностью согласен: если код вообще нужно поддерживать, следует придерживаться максимально простого решения (каким бы оно ни было для бедняги, который его поддерживает)., @wondra
Правда, в организации, где я работаю, тернарная операция разрешена, но только в таких тривиальных случаях, как этот. Если же учитывать более крупные выражения, то следует использовать if/else. Кстати, чтобы сделать это короче, можно, наверное, даже всё поместить в оператор for (а не в цикл)., @Michel Keijzers
На самом деле он называется «Условный оператор». Просто так получилось, что это единственный тернарный оператор., @Alexander
@wondra Я не разбираюсь в Arduino, но если это действительно C++, как сказано в другом комментарии, то вы передадите lcd.print() тип char вместо строки. Это не проблема, если lcd.print — полиморфный метод, который также работает с char, но это не обязательно так, так что это может быть ошибкой. Стремитесь не писать простые идеи сложным образом, а писать сложные идеи простым способом., @JoL
Небольшая придирка: разве это не должно быть эквивалентно выражению if (pressed[i] == 1), а не if (pressed[i] != 0)?, @MCMastery
@McMastery На самом деле, это не одно и то же... существует соглашение (не всегда верное, особенно в C), что логическое значение FALSE равно 0, а значение TRUE отлично от нуля. В вашем случае, если TRUE будет равно 255, это будет ошибкой., @Michel Keijzers
@MichelKeijzers А, извините. Я почему-то думал, что на съезде всё наоборот., @MCMastery
- if (something) то же самое, что и if(something!=0), если условие имеет ненулевое значение, оно считается выполненным условием, подробнее об Условные предложения — правда или ложь
- Для однострочных операторов фигурные скобки не нужны. Однако их использование делает код более читабельным и менее подвержен ошибкам
Стоит отметить, что фигурные скобки в однострочных операторах определённо могут помочь предотвратить некоторые коварные ошибки: помните [знаменитую ошибку SSL от Apple](https://embeddedgurus.com/barr-code/2014/03/apples-gotofail-ssl-security-bug-was-easily-preventable/)? Фигурные скобки почти наверняка позволили бы этого избежать или, по крайней мере, более чётко обозначили бы место ошибки., @ke4ukz
@ke4ukz Думаю, страх повторения этой ошибки SSL преувеличен. Если вы собираетесь использовать встроенный оператор if, делайте это... в... строке. Не ставьте его на новую строку. if (someEarlyExitCondition()) return; никогда никому не повредит, если бы всё было в одной строке. Меня всегда сбивали с толку отступы и новая строка, которые люди добавляют при использовании встроенных операторов if. Это совершенно ни к чему!, @Alexander
@Александр Согласен: встроенный текст для встроенного текста, фигурные скобки для отступов/нескольких строк, @ke4ukz
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Печать string and integer LCD
- устаревшее преобразование из строковой константы в 'char*'
Arduino использует язык программирования C++ со специальными библиотеками и конвертацией .ino-файлов в C++ http://www.cplusplus.com/doc/tutorial/, @Juraj