операторы 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);
 }

, 👍5

Обсуждение

Arduino использует язык программирования C++ со специальными библиотеками и конвертацией .ino-файлов в C++ http://www.cplusplus.com/doc/tutorial/, @Juraj


2 ответа


Лучший ответ:

6

О недостающих условиях, например:

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


4
  1. if (something) то же самое, что и if(something!=0), если условие имеет ненулевое значение, оно считается выполненным условием, подробнее об Условные предложения — правда или ложь
  2. Для однострочных операторов фигурные скобки не нужны. Однако их использование делает код более читабельным и менее подвержен ошибкам
,

Стоит отметить, что фигурные скобки в однострочных операторах определённо могут помочь предотвратить некоторые коварные ошибки: помните [знаменитую ошибку 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