Tw-city.info

IT Новости
7 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Два знака равно в программировании

Урок №42. Операторы сравнения

Обновл. 29 Дек 2019 |

В C++ есть 6 операторов сравнения:

Сравнение чисел типа с плавающей точкой

Сравнение значений типа с плавающей точкой с помощью любого из этих операторов — дело опасное. Почему? Из-за тех самых небольших ошибок округления, которые могут привести к неожиданным результатам.

В программе выше, d1 = 0.0100000000000005116 , а d2 = 0.0099999999999997868 . Оба этих числа очень близки к 0.1 , но d1 больше d2 . Они не равны.

Иногда сравнение чисел типа с плавающей точкой бывает неизбежным. В таком случае следует использовать операторы > , , >= и только если значения не очень близки. А вот если два операнда очень близки по значениям, то результат уже может быть неожиданный. В примере выше последствия неправильного результата незначительны, а вот с оператором равенства дела обстоят хуже, так как даже при самой маленькой неточности результат сразу меняется на противоположный ожидаемому. Не рекомендуется использовать операторы == или != с числами типа с плавающей точкой. Вместо них лучше использовать функцию, которая вычисляет, насколько близки эти два числа. Если они «достаточно близки», то мы считаем их равными. Значение, используемое для представления термина «достаточно близки», называется эпсилон. Оно, обычно, небольшое (например, 0.0000001 ).

Очень часто начинающие разработчики пытаются писать свои собственные функции определения равенства чисел:

Хоть это и рабочий вариант, но он не идеален. Эпсилон 0.00001 подходит для чисел около 1.0, но будет слишком большим для чисел типа 0.0000001 и слишком малым для чисел типа 10 000. Это означает, что каждый раз, при вызове функции, нам нужно будет выбирать наиболее соответствующий входным данным функции эпсилон.

Дональд Кнут, известный учёный, предложил следующий способ в своей книге «Искусство программирования, том 2: Получисленные алгоритмы» (1968):

Второй вызов не сработал так, как ожидалось. Математика просто ломается, когда дело доходит до нулей.

Но и этого можно избежать, используя как абсолютный эпсилон (то, что мы делали в первом способе), так и относительный (способ Кнута) вместе:

С удачно подобранным absEpsilon , функция approximatelyEqualAbsRel() обрабатывает нулевые значения правильно.

Сравнение чисел типа с плавающей точкой — сложная тема, и нет одного идеального алгоритма, который подойдёт в любой ситуации. Однако, для большинства случаев, с которыми вы будете сталкиваться, функции approximatelyEqualAbsRel() должно быть достаточно.

Курсы «C#.NET Developer»

Курсы «Java Developer»

Курсы «Frontend Developer»

Курсы «JavaScript Developer»

Курсы «Python Developer»

Курсы «Unity/Game Developer»

Поделиться в социальных сетях:

Урок №41. Условный тернарный оператор, sizeof() и Запятая

Комментариев: 18

А почему нельзя взять взять за вычисляемый эпсилон среднее арифметическое абсолютных значений сравниваемых величин умноженное на эпсилон? Код вроде попроще будет.

Можно и так наверно, но мне кажется тут берется большее число, потому что всегда надо рассматривать худший случай

Если при сравнении чисел указать тип float вместо double, то результатом будет true, даже при обычном сравнении. Это специфика компилятора или есть еще что-то?

Я тоже заметил что float точный, думаю нужно просто запомнить что double и long double имеют такие костыли.

Возможно, вы удивитесь, но результат:

Второй вызов не сработал так, как ожидалось. Математика просто ломается, когда дело доходит до нулей.
Почему?

Потому что почти 1(допустим 0.9) — 1 = -0.1. Да это действительно меньше нуля и функция по логике должна возвращать true, но если посмотреть внимательнее можно заметить. что там берется модуль. То есть: fabs(-0.1) = 0.1, а это уже больше нуля

Тяжеловата тема, но интересно.
Наибольшая сложность — не знаешь сразу куда применять.

Тема интересная, но не сразу дается. Код понял «примерно» т.е. поверхностно, чует сердце, буду к нему еще возвращаться. Принцип понятен сразу: как в тестере крутилка: 2 вольта, 20 вольт, 200 вольт и т.д. Воспоминание о аналоговых входах МК меня немного огорчило: там как раз и надо сравнивать небольшие напряжения. Например АКБ -зарядился или нет, сел или еще пойдет… теперь понимаю, почему так часто врут индикаторы заряда батарей. Спасибо, очередной интересный урок!

Пожалуйста 🙂 Главное — не зацикливайтесь, если что — вернётесь позже к этому уроку.

интересно для написания торгового робота на криптобирже нужно применять функцию approximatelyEqualAbsRel() или нет?

Вы пишете ботов на С++ для криптобирж?

Первый урок, который я вообще не понял :). Видимо, из-за того, что не выспался. Код вообще не понятен. Пытаюсь — не выходит(

Алло, Дед Максим! Ты когда пишешь рукой на листочек строку текста и приближаешься к правому краю и видишь, что последнее слово (если будешь продолжать таким же почерком) не помещается в строку, что делаешь? Правильно. Прижимистей буквы друг к другу тулишь. Это аналоговое представление значений. Цифровое же (то, которое в ЭВМ) — это когда все знаки и расстояния между ними строго одинаковы. И теперь представь себе, что точность — это ширина листа (если листок в клеточку, вообще, идеальная аналогия цифрового представления значений!) И вот тебе надо сравнить заряд электрона и заряд бозона. Что надо сделать? Правильно! Взять листочки по-ширше, т е. установить по-больше точность, иначе не влезающие цифры пропадут и вместо сравниваемых значений вообще какая-то дурь осядет. Но это ещё пол-беды! Подоплёка машинных «мансов» в том, что ЭВМ втихаря дописывает в клеточки левые цифры для заполнения пустующих после значащих цифр клеточек. Ну естественно результаты сравнения 100 — 99.99 и 10 — 9.99 с такими мансами будут не корректными! Да, дык о чём это я? А, вот пример: Требуется сравнить две трёхлитровых банки с жидкостью (молоко, самогон — по вкусу:-). Задаёмся граничным условием — если разница залитых объёмов не превышает одну пипетку (эпсилон) принимаем объёмы как равные. Пипетка — это абсолютный эпсилон, а объём пипетки/объём банки — это относительный эпсилон. А если объёмы сопоставимы с пипеткой (близки нулю)? Тогда Гулливер ловит лилипута, аннексирует у него пипетку (absEpsilon) и если разница меньше этого absEpsilon, то значения объёмов за «ноль» сойдут — не похмелишься (не наешься)!

Радует то, что в реальной жизни чаще требуется сравнивать целые числа. А когда доходит до чисел с плавающей точкой, то там почти всегда не важно «>» или «>=».

Ну это в реальной жизни 🙂 Та и в реальной жизни бывают исключения.

Кажется у меня отключился мозг после строчки: «Очень часто начинающие разработчики пытаются писать свои собственные функции определения равенства чисел:»

Операторы сравнения

Многие операторы сравнения известны нам из математики:

  • Больше/меньше: a > b , a .
  • Больше/меньше или равно: a >= b , a .
  • Равно: a == b . Обратите внимание, для сравнения используется двойной знак равенства = . Один знак равенства a = b означал бы присваивание.
  • Не равно. В математике обозначается символом ≠ . В JavaScript записывается как знак равенства с предшествующим ему восклицательным знаком: a != b .

Результат сравнения имеет логический тип

Операторы сравнения, как и другие операторы, возвращают значение. Это значение имеет логический тип.

  • true – означает «да», «верно», «истина».
  • false – означает «нет», «неверно», «ложь».

Результат сравнения можно присвоить переменной, как и любое значение:

Сравнение строк

Чтобы определить, что одна строка больше другой, JavaScript использует «алфавитный» или «лексикографический» порядок.

Другими словами, строки сравниваются посимвольно.

Алгоритм сравнения двух строк довольно прост:

  1. Сначала сравниваются первые символы строк.
  2. Если первый символ первой строки больше (меньше), чем первый символ второй, то первая строка больше (меньше) второй.
  3. Если первые символы равны, то таким же образом сравниваются уже вторые символы строк.
  4. Сравнение продолжается, пока не закончится одна из строк.
  5. Если обе строки заканчиваются одновременно, то они равны. Иначе, большей считается более длинная строка.

В примерах выше сравнение ‘Я’ > ‘А’ завершится на первом шаге, тогда как строки «Кот» и «Код» будут сравниваться посимвольно:

  1. К равна К .
  2. о равна о .
  3. т больше чем д . На этом сравнение заканчивается. Первая строка больше.
Читать еще:  Программа для создания программ без программирования

Приведённый выше алгоритм сравнения похож на алгоритм, используемый в словарях и телефонных книгах, но между ними есть и различия.

Например, в JavaScript имеет значение регистр символов. Заглавная буква «A» не равна строчной «a» . Какая же из них больше? Строчная «a» . Почему? Потому что строчные буквы имеют больший код во внутренней таблице кодирования, которую использует JavaScript (Unicode). Мы ещё поговорим о внутреннем представлении строк и его влиянии в главе Строки.

Сравнение разных типов

При сравнении значений разных типов JavaScript приводит каждое из них к числу.

Логическое значение true становится 1 , а false – 0 .

Возможна следующая ситуация:

  • Два значения равны.
  • Одно из них true как логическое значение, другое – false .

С точки зрения JavaScript, результат ожидаем. Равенство преобразует значения, используя числовое преобразование, поэтому «0» становится 0 . В то время как явное преобразование с помощью Boolean использует другой набор правил.

Строгое сравнение

Использование обычного сравнения == может вызывать проблемы. Например, оно не отличает 0 от false :

Та же проблема с пустой строкой:

Это происходит из-за того, что операнды разных типов преобразуются оператором == к числу. В итоге, и пустая строка, и false становятся нулём.

Как же тогда отличать 0 от false ?

Оператор строгого равенства === проверяет равенство без приведения типов.

Другими словами, если a и b имеют разные типы, то проверка a === b немедленно возвращает false без попытки их преобразования.

Ещё есть оператор строгого неравенства !== , аналогичный != .

Оператор строгого равенства дольше писать, но он делает код более очевидным и оставляет меньше мест для ошибок.

Сравнение с null и undefined

Поведение null и undefined при сравнении с другими значениями – особое:

При строгом равенстве ===

Эти значения различны, так как различны их типы.

Эти значения равны друг другу и не равны никаким другим значениям. Это специальное правило языка.

Значения null/undefined преобразуются к числам: null становится 0 , а undefined – NaN .

Посмотрим, какие забавные вещи случаются, когда мы применяем эти правила. И, что более важно, как избежать ошибок при их использовании.

Странный результат сравнения null и 0

Сравним null с нулём:

С точки зрения математики это странно. Результат последнего сравнения говорит о том, что » null больше или равно нулю», тогда результат одного из сравнений выше должен быть true , но они оба ложны.

Причина в том, что нестрогое равенство и сравнения > = работают по-разному. Сравнения преобразуют null в число, рассматривая его как 0 . Поэтому выражение (3) null >= 0 истинно, а null > 0 ложно.

С другой стороны, для нестрогого равенства == значений undefined и null действует особое правило: эти значения ни к чему не приводятся, они равны друг другу и не равны ничему другому. Поэтому (2) null == 0 ложно.

Несравнимое значение undefined

Значение undefined несравнимо с другими значениями:

Почему же сравнение undefined с нулём всегда ложно?

На это есть следующие причины:

  • Сравнения (1) и (2) возвращают false , потому что undefined преобразуется в NaN , а NaN – это специальное числовое значение, которое возвращает false при любых сравнениях.
  • Нестрогое равенство (3) возвращает false , потому что undefined равно только null и ничему больше.

Как избежать проблем

Зачем мы рассмотрели все эти примеры? Должны ли мы постоянно помнить обо всех этих особенностях? Не обязательно. Со временем все они станут вам знакомы, но можно избежать проблем, если следовать простому правилу.

Просто относитесь к любому сравнению с undefined/null , кроме строгого равенства === , с осторожностью.

Не используйте сравнения >= > с переменными, которые могут принимать значения null/undefined , если вы не уверены в том, что делаете. Если переменная может принимать эти значения, то добавьте для них отдельные проверки.

Два знака равно в программировании






! — восклицательный знак — помимо создания восклицательных предложений, данный символ используется в шаблонах, где знак обозначает один символ, например, “Rab!.txt” — обозначает файл с именем, в котором находятся символы “Rab”, затем какой-либо символ и далее “.txt”. То есть, могут быть файлы “Raba.txt”, “Rab1.txt”, “Rab9.txt”, “Rab0.txt” и т. д., но не “Rab21.txt”, так как здесь имеется два символа (21) вместо восклицательного знака.

!= — не равно — в некоторых языках программирования используется в логических выражениях и означает не равно.

# — символ номера — используется для определения шаблона, в которых находятся числа. Например, ##.### означает, что в данном месте будет выведено число, которое имеет две цифры до запятой и три цифры после.

$ — символ доллара — 1. стандартное использование данного символа заключается в определении денежных сумм, выраженных в долларах, например, $1 000 означает тысячу долларов. 2. используется в некоторых языках программирования, например, в языке Бейсик для обозначения переменных, например, I1$ — имя переменной.

& — амперсант — 1. данный символ обозначает соединительный союз “и”, 2. логическое “ИЛИ” в некоторых языках программирования.

() — скобки — данные символы часто встречаются в математических формулах для обозначения первенства операций. Например, 2*3+1=7 и 2*(3+1)=8 дают разный результат, так как при отсутствии скобок вначале выполняются операции умножения или деления, а потом операции сложения и вычитания.

* — звездочка — 1. часто используется как символ умножения, 2. в шаблонах обозначает, что на данном месте может быть любое количество определенных символов, например, *.* обозначает имя файла, в котором до и после точки может находиться любое символьное название.

. — точка — помимо знака конца предложения означает также, разделение чего-либо, например, целой части числа от дробной (например, 3.55); разделение имени файла от его расширения в системе ДОС (например, Rab.txt); разделение элементов в адресе при работе в сети, например, www.aaa.com.

: — двоеточие — используется для определения логического устройства, например, А:, С:.

; — точка с запятой — помимо знака пунктуации, обозначает начала комментариев в командных файлах и в некоторых языках программирования. То есть, все, что находится за данным символом, будет восприниматься как текст, который при выполнении, будет игнорироваться.

@ — знак “при” — 1. используется в командных файлах как комментарий. 2. используется в имени почтового домена.

[ ] — квадратные скобки — при описании синтаксиса команд обозначают необязательный параметр, например, запись Dir_[/P] обозначает, что можно использовать команду Dir без параметров и с параметром /P (Dir_/P).

обратная косая черта — используется для разделения имен каталогов при описании их имени, например, WindowsTmp.

^ — крыша — обозначает нажатие на клавишу Ctrl, например ^С обозначает одновременное нажатие на две клавиши: Ctrl и С (в книге Ctrl+С). Часто, в некоторых языках программирования обозначает символ возведения в степень. Например, 2^3-8. Кроме того, является специальным знаком над символом в некоторых мировых языках (циркумфлекс).

_ — подчеркивание — часто используется в именах файлов в системе ДОС для разделения нескольких слов, где нельзя использовать пробел, например, No_print. Используется также в языках программирования в названии переменных для тех же целей.

< >— фигурные скобки — при описании синтаксиса команд обозначают, что должен быть выбран один из параметров, которые находятся внутри скобок, например, запись обозначает, что должно быть выбрано одно из значений: “ON” или “OFF”.

| — вертикальная черта — используется при описании синтаксиса команды как символ обозначающий “или”, например, запись обозначает, что должно быть выбрано одно из значений: “ON” или “OFF”.

— тильда — в словарях обозначает слово или группу слов, которые указаны ранее как ключевые. Кроме того, в некоторых языках программирования обозначает знак отрицания, например,

Читать еще:  Квантовые языки программирования

True-False (отрицание истины обозначает ложь).

+ — плюс — помимо операции сложения, знак плюс обозначает также соединение файлов в системе ДОС, например, Rab.txt+Rab2.txt — означает, что два файла будут рассматриваться как один, то есть, за концом одного файла будет находиться начало другого.

<> — не равно — в некоторых языках программирования обозначает не равно.

> — знак больше — помимо своего значения больше, обозначает также символ перенаправления вывода в системе ДОС. Например, >Rab.txt означает, что вывод будет происходить не на экран монитора, а в файл с именем Rab.txt.

0.28 micron technology — 0.28 — микронная технология — технология производства интегральных микросхем, где компоненты имеют размер 0.28 микрон. Чем меньше технология, тем больше компонент можно поместить на микросхеме и тем меньше требуется напряжения для их работы, следовательно, меньше выделяется тепла и требуется меньшее охлаждение. В настоящее время уже произошел переход к 0.35-микронной технологии и происходит переход к 0.28-микронной технологии.

0.35 micron technology — 0.35 — микронная технология — технология производства интегральных микросхем, где компоненты имеют размер 0.35 микрон.

0.5 micron technology — 0.5 — микронная технология — технология производства интегральных микросхем, где компоненты имеют размер 0.5 микрон.

101-key keyboard — 101-клавишная клавиатура — наиболее распространенный вид клавиатуры в настоящее время.

10 Basexx – варианты реализации сетей Ethernet со скоростью передачи данных 10 мб/сек. Может быть хх — F , T , 2, 5, означающие разные варианты реализации сети с разным расстоянием между станциями от 90 метров и выше. Варианты 100 Basexx обозначают сеть со скоростью передачи данных до 100 мб/сек, где хх — разные варианты реализации, то есть первые цифры обозначают скорость передачи, а хх — модификация.

14-inch monitor — 14 дюймовый монитор — монитор, который имеет размер экрана по диагонали 14 дюймов. На самом деле видимая область дисплея с Электронно-Лучевой Трубкой (ЭЛТ), на которую выводится информация несколько меньше 14 дюймов, точнее чуть больше 13 дюймов. В тоже время для жидкокристаллического монитора указывается, как правило, размер выводимой области экрана, то есть, при указании 14 дюймов он будет соответствовать 15 дюймовому экрану с ЭЛТ трубкой.

15-inch monitor — 15 дюймовый монитор — монитор, который имеет размер экрана по диагонали 15 дюймов. См. также 14-inch monitor.

16-bit mashine — 16-разрядная машина — компьютер, центральный процессор которого обрабатывает информацию порциями по 16 бит (80286).

16-bit microprocessor — 16-разрядный микропроцессор — тоже, что и 16-bit mashine.

17-inch monitor — 17 дюймовый монитор — монитор, который имеет размер экрана по диагонали 17 дюймов. См. также 14-inch monitor.

21-inch monitor — 21 дюймовый монитор — монитор, который имеет размер экрана по диагонали 21 дюймов. Данный тип монитора используется часто для настольно-издательских систем. См. также 14-inch monitor.

286 — серия компьютеров с процессором 80286. —

3 1/2 inch disk — 3.5 дюймовый диск — гибкий диск, который имеет в диаметре размер 3.5 дюйма. В настоящее время наиболее распространенными являются диски емкостью 1.44 мегабайт. Существуют также менее распространенные 2.88 мегабайт и в перспективе выйдут более емкие диски.

32-bit mashine — 32-разрядная машина — компьютер, центральный процессор которого обрабатывает информацию порциями по 32 бит (80386).

32-bit microprocessor — 32-разрядный микропроцессор — тоже, что и 32-bit mashine.

32-bit operating system — 32 битная операционная система — операционная система, которая разработана специально для 32-битных процессоров. Система Windows 3.1 разработана для 16-битных процессоров, дальнейшие системы, начиная с Windows 95 работают уже как 32-битная система.

386 — серия компьютеров с процессором 80386. –-

3 COM – название одной из крупнейших компаний по производству компьютерного оборудования.

486 — серия компьютеров с процессором 80486. —

4x — четырехскоростной. Кроме того, имеются 8х, 12х, 16х, 32х и пр., где цифра обозначает кратность скорости, чем больше цифра, тем быстрее работает устройство (для CD-ROM) .

5 1/4-inch disk — 5.25 дюймовый диск — гибкий диск, который имеет в диаметре размер 5.25 дюйма. В настоящее время практически не используется. Имел распространение в начале 90х годах.

586 — серия компьютеров с процессором Pentium.

64-bit mashine — 64-разрядная машина — компьютер, центральный процессор которого обрабатывает информацию порциями по 64 бит, например, в серии Pentium.

64-bit microprocessor — 64-разрядный микропроцессор — тоже, что и 64-bit mashine.

68ххх — серия центральных процессоров фирмы Motorola, которые используются для компьютеров Макинтош.

8-bit mashine — 8-разрядная машина — компьютер, центральный процессор которого обрабатывает информацию порциями по 8 бит (8086).

8-bit microprocessor — 8-разрядный микропроцессор — тоже, что и 8-bit mashine.

80286 — первые компьютеры, имеющие одноименный процессор — 80286.

80287 — сопроцессор для процессора 80286.

80386 — компьютеры, имеющие одноименный процессор — 80386.

80386DX — компьютеры, имеющие одноименный процессор — 80386.

80386SX — компьютеры, имеющие одноименный процессор — 80386SX. Более дешевые и медленные, чем 80386. Фактически урезанный вариант 386-го процессора.

80387 — сопроцессор для процессора 80386.

80486 — компьютеры, имеющие одноименный процессор — 80486.

80486DX — компьютеры, имеющие одноименный процессор — 80486.

80486SX — компьютеры, имеющие одноименный процессор — 80486SX. Более дешевые и медленные, чем 80486. Фактически урезанный вариант 486-го процессора.

80487 — сопроцессор для процессора 80486.

8086 — первые компьютеры, имеющие одноименный процессор — 8086.

8087 — сопроцессор для процессора 8086.

84-key keyboard — 84-клавишная клавиатура — старый вид клавиатуры, который был разработан для компьютеров серии АТ.

Два знака равно в программировании

Все уроки по C# расположены здесь

На этом уроке мы отойдем от арифметики и кинем первый взгляд на логический тип данных C# и его операторы. Логические данные широко используются в программировании, и понимание их особенностей имеет больше значение.

Обзор типа данных Boolean

На третьем уроке по основам C#, я показал логический тип данных. Логическая переменная может хранить только два значения, true или false. В следующем примере показано простое задание булевых переменных, которые объявлены с помощью bool.

Логический тип данных имеет свой собственный набор логических операторов. Они позволяют проверить или изменить значение булевой переменной. Результирующие значения могут быть использованы в условных операторах, чтобы определить направление кода. Условное программирование будет рассмотрено позже в учебнике. В следующих разделах описываются различные доступные операторы.

Эквивалентность или равенство — данный оператор является бинарным оператором, он работает над двумя значениями или операндами. Оператор equivalence сравнивает два операнда и возвращает логическое значение, указывающее, совпадают ли они точно. Символом оператора для эквивалентности является знак двойного равенства (==).

Оператор неравенства сравнивает два операнда и возвращает true, если два значения различны. Оператор предоставляет оператору эквивалентности противоположную функциональность. Символ оператора — восклицательный знак и знак равенства (!=). Это читается как «не равно».

Оператор NOT является унарным оператором, так как действует на один операнд. Оператор NOT инвертирует значение логического значения. Если исходное значение true, то возвращаемое значение false; если исходное значение false, возвращаемое значение true. Операцию иногда называют двоичным дополнением.

Используется для сравнения двух логических значений. Возвращает значение true, если оба операнда имеют значение true. В таблице ниже показаны исходные операнды и результат AND.

Оператор AND представлен символом амперсанда

OR используется, чтобы сравнить два значения типа boolean. Оператор OR возвращает значение true, если один из операндов имеет значение true. Это может быть представлено следующей таблицей:

Оператор OR представлен символом бара (|)


Автор этого материала — я — Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML — то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

Читать еще:  Программирование для windows 10

статьи IT, Уроки по си шарп, си шарп, операторы

Два знака равно в программировании

  • Уроки
  • Программирование
  • Сравнения и условия

Сравнение

В языке C++ (как и пожалуй во всех языках) есть такое понятие, как логическая величина, которая принимает два значения: правда и ложь, true и false, 1 и 0. В качестве типа данных по работе с логическими величинами у нас есть boolean, который может принимать значения 0 (false) или 1 (true). Точно такое же значение возвращает результат сравнения двух чисел или переменных, для сравнения у нас есть несколько операторов сравнения:

  • == равенство (a == b)
  • != неравенство (a != b)
  • >= больше или равно (a >= b)
  • больше (a > b)
  • b) вернёт значение false, потому что a меньше b. А например (a != b) вернёт true, т.к. а действительно не равно b. Для связи нескольких логических величин используются логические операторы:

  • ! логическое НЕ, отрицание. Есть аналог – оператор not
  • && логическое И. Есть аналог – оператор and
  • || логическое ИЛИ. Есть аналог – оператор or

Результаты операторов сравнения можно использовать для работы с условиями, а также для цикла while (речь о нём пойдёт в следующем уроке)

Сравнение float

Со сравнением float чисел всё не так просто из за особенности самой модели “чисел с плавающей точкой” – вычисления иногда производятся с небольшой погрешностью, из за этого сравнение может работать неверно! Пример из урока про вычисления:

Будьте внимательны при сравнении float чисел, особенно со строгими операциями == , >= и

Условный оператор if (англ. “если”) позволяет разветвлять выполнение программы в зависимости от логических величин, т.е. результатов работы операторов сравнения, которые мы рассмотрели выше, а также напрямую от логических переменных.

Оператор else (англ. “иначе”) работает в паре с оператором if и позволяет предусмотреть действие на случай невыполнения if:

Также есть третья конструкция, позволяющая ещё больше разветвить код, называется она else if:

Посмотрим на все эти операторы в действии в большом примере:

Вот так и работает условный оператор if, позволяя управлять программой и создавать разветвлённые действия в зависимости от разных условий. Обратите внимание на последний блок в примере выше, там где используется else if для выбора действия в зависимости от значения одной и той же переменной. Существует оператор выбора (switch), позволяющий сделать код более красивым. О нём поговорим чуть ниже.

Особенность boolean

В уроке о типах данных я упоминал о том, что boolean принимает значение true, если присвоить ему отличное от нуля число, то есть оператору if можно скормить любое число, и он вернёт true в любом случае, кроме нуля . Это бывает удобно в некоторых случаях, но также может и приводить к ошибкам, которые трудно отловить. if (50) <> – да, выполнится код по этому условию.

Порядок условий

Порядок условий играет очень большую роль при оптимизации кода и попытке сделать его более быстрым в некоторых случаях. Суть очень проста: логические выражения/величины проверяются слева направо, и если хоть одно значение делает всё выражение неверным (ложью), дальнейшая проверка условий прекращается. Например если в выражении

хотя бы а имеет значение false, проверка остальных выражений (b и c) уже не выполняется. Когда это может быть важно: например, есть какой-то флаг и выражение, которое вычисляется прямо в условии и сразу проверяется. В таком случае если флаг опущен, микроконтроллер не будет тратить время на лишние вычисления. Например:

Если флаг опущен, микроконтроллер не будет тратить лишние 100 мкс на работу с АЦП, и сразу проигнорирует остальные логические выражения. Это конечно очень мало, но иногда и 100 мкс решают, просто помните о том, что порядок условий имеет значение.

Оператор ?

Оператор знак вопроса (?) является более коротким аналогом для записи конструкции if-else. Действие с оператором ? имеет следующий вид:

условие ? выражение1 : выражение2

Это работает так: вычисляется условие, если оно истинно, то вычисляется выражение1 и всё действие получает это значение (возвращает), а если оно ложно, то вычисляется выражение2 и всё действие получает это значение. Пример:

Вот для сравнения аналогичная конструкция на if-else

Аналогичным образом можно использовать оператор ? для вывода данных и текста в последовательный порт (подробнее о нём позже):

А можно ли сделать на операторе ? более сложную конструкцию, типа else if? Можно!

Оператор выбора

Оператор выбора switch позволяет создать удобную конструкцию, разветвляющую действия в зависимости от значения одной переменной. Синтаксис такой:

Наличие оператора default не обязательно. Наличие оператора break обязательно, иначе сравнение пойдёт дальше, как показано для case 2, 3 и 4. Рассмотрим более живой пример:

При помощи условных операторов и операторов выбора строится логика работы программы. Условный оператор поможет сравнить значение с датчика и принять решение, что делать дальше. Оператор выбора отлично справится с изменяющимися режимами работы программы или опросом кнопок, нажатых на ИК пульте.

Условные директивы #if #else

Помимо директивы #define, сообщающей препроцессору о необходимости замены набора символов набором символов, есть ещё условные директивы, позволяющие заниматься так называемой условной компиляцией: обладая такой же логикой, как if-else, данные конструкции позволяют делать некоторый выбор перед компиляцией самого кода. Отличным примером является само “ядро” Ардуино – большинство функций написаны со спецификой каждого процессора, и перед компиляцией кода из множества вариантов реализации функции выбирается тот, который соответствует текущему выбранному микроконтроллеру. Проще говоря, условная компиляция позволяет по условиям включать или исключать тот или иной код из основной компиляции, т.е. сначала препроцессор анализирует код, что-то в него включается, что-то нет, и затем проходит компиляция.

Также например мы не можем объявить какую-либо константу или макро через #define более одного раза, это приведёт к ошибке. Условная компиляция позволяет сделать ветвящуюся конструкцию, где такое возможно. Для условной компиляции нам доступны директивы #if, #elif, #else, #endif, #ifdef, #ifndef

  • #if – аналог if в логической конструкции
  • #elif – аналог else if в логической конструкции
  • #else – аналог else в логической конструкции
  • #endif – директива, завершающая условную конструкцию
  • #ifdef – если “определено”
  • #ifndef – если “не определено”
  • defined – оператор, который не подсвечивается в коде, но работает так: возвращает true если указанное в скобках слово “определено” через #define, и false – если нет

Как ими пользоваться давайте посмотрим на примере:

Таким образом мы получили задефайненную константу VALUE, которая зависит от “настройки” TEST. Конструкция позволяет включать или исключать куски кода перед компиляцией, вот например кусочек про отладку:

Таким образом при помощи настройки DEBUG можно включить или исключить любой кусок кода.

Есть у препроцессора ещё две директивы: #ifdef, #ifndef, они позволяют включать или исключать участки кода по условию: ifdef – определено ли? ifndef – не определено ли? Определено или не определено – речь идёт конечно же о #define

Именно на условной компиляции строится вся универсальность библиотек для Arduino, ведь при выборе автоматически “создаётся” дефайн на название микроконтроллера, выглядят они так:

  • __AVR_ATmega32U4__
  • __AVR_ATmega2560__
  • __AVR_ATmega328P__
  • И далее в этом стиле

Это позволяет создавать универсальный код, используя конструкцию с #ifdef или #if defined:

Таким образом микроконтроллерам (платам Arduino) разных моделей будет доступен персональный кусок кода, который будет передан компилятору при выборе этой платы из списка плат.

Видео

Ссылка на основную публикацию
Adblock
detector