На данном занятии мы продолжим знакомство с различными операциями в языке C.
Пришла пора познакомиться немного с логикой, а также со сравнением величин в выражениях.
Для этого в языке C существуют операторы отношения (или как их ещё называют операторы сравнения), которые сравнивают две величины, которые могут быть также результатами тех или иных выражений, а также логические операторы. Я думаю, что с логикой мы все знакомы из курса информатики.
Начнём с операторов отношения. Вот их список:
«>» — больше,
«>=» — больше или равно,
«<» — меньше,
«<=» — меньше или равно,
«==» — равно,
«!=» — не равно.
Подобные операции мы совершали, когда в школе проходили курс математики. Правда некоторые из операторов там выглядели несколько иначе. Тем не менее я по возможности все равно постараюсь объяснить, каким образом себя ведут операции, которые мы будем совершать при написании нашего проекта, с использованием данных операторов.
Также существуют логические операции:
«&&» — «И»,
«||» — «ИЛИ»,
«!» — «НЕ».
Причём, надо заметить, что последний оператор является унарным, то есть он совершается над одним числом или результатом выражения, а все остальные вышеперечисленные операторы, включая и все операторы отношения, являются бинарными, то есть они выполняются над двумя величинами или результатами выражений.
Все операции, выполняемые с помощью всех этих операторов, используются, как правило, в условиях циклов, ветвлений и в прочих условиях выполнения или невыполнения кода.
А как себя ведут эти операции и к чему они ведут, мы уже посмотрим в нашей практической части, к которой мы сразу же и приступим. Кстати, заодно мы ещё лишний раз сегодня поработаем с циклами, так сказать, закрепив практически наши знания.
Проект с именем MYPROG07 был сделан из проекта прошлого занятия с именем MYPROG06.
Откроем файл main.c и в функции main(), как обычно, удалим весь код тела кроме возврата нуля, останется от него вот это
int main()
{
return 0; //Return an integer from a function
}
Давайте пока попробуем действие первого оператора — «больше«:
1 2 3 4 5 6 7 8 9 10 |
int main() { printf("\">\" =========================\r\n"); int i=10, j; while(i > 5) { printf("i = %d\r\n", i); i--; } //------------------------ |
В нашем коде мы сначала навели некоторую красоту, затем объявили две целочисленных переменных, одну из них проинициализировали сразу. Потом мы добавили цикл, а в условии данного цикла мы как раз использовали наш оператор, который сравнивает значение переменной i с числом 5, а, так как оператор у нас «больше«, то условие будет истинным только в том случае, когда выражение слева, а в нашем случае это значение переменной i будет больше числа 5, которое располагается от оператора справа.
Как именно работает цикл такого типа, мы уже прекрасно знаем. Внутри цикла мы выведем значение нашей переменной, а затем её уменьшим на 1 или продекрементируем.
Сохраним наш файл с исходным кодом, соберём проект и посмотрим результат выполнения нашей программы
Наш счётчик обратного отсчёта сначала начал свой счёт, и дойдя до 6, остановился, так как число 5 уже не больше 5 и наше условие перестало выполняться, то есть результат его выполнения перестал быть истинным, и мы уже не попали в тело цикла.
Попробуем теперь, как будет работать следующий оператор, который уже включает в себя и равенство левой и правой части условия
1 2 3 4 5 6 |
i--; } //------------------------ printf("\">=\" =========================\r\n"); for(i = 7; i >= 3; i--) printf("i = %d\r\n", i); //------------------------ |
Здесь мы для разнообразия использовали цикл типа for.
У нас также будет наша переменная декрементируется до тех пор, пока не достигнет значения 3, но теперь это значение уже будет входить в диапазон истинности, так как у нас в условии есть равенство. Причём, для разнообразия мы использовали цикл с телом без фигурных скобок. В этом случае телом является то, что находится после объявления цикла.
Посмотрим результат в консоли
Так и получилось — тройка вошла в список и отобразилась в нашей консоли.
Испытаем следующий оператор
1 2 3 4 5 6 7 8 9 10 |
printf("i = %d\r\n", i); //------------------------ printf("\"<\" =========================\r\n"); i=0; while(i < 5) { printf("i = %d\r\n", i); i++; } //------------------------ |
Здесь всё почти так же, как и в случае оператора «больше«, только используем мы операцию «меньше«, и переменная у нас инкрементируется в теле цикла. Как только значение нашей переменной достигнет 5, то условие цикла перестанет выполняться.
Посмотрим, так ли это
Так и есть, пятёрка в консоль уже не попала, так как она не меньше 5.
Испытаем следующий оператор
1 2 3 4 5 6 7 8 9 10 11 |
i++; } //------------------------ printf("\"<=\" =========================\r\n"); i=0; do { printf("i = %d\r\n", i); i++; } while(i <= 5); //------------------------ |
Здесь уже в диапазон истинности условия входит и равенство. И также для разнообразия мы использовали цикл типа do while. Наша переменная в цикле также будет инкрементироваться до тех пор, пока она не достигнет числа 5, только в этом случае цикл выполнится ещё раз, так как равенство у нас тоже в силе, а вот число 6 уже не будет удовлетворять условию и следующий раз тело цикла уже не будет выполняться. Кстати, каждое повторение тела цикла ещё называют итерацией.
Проверим результат выполнения нашего цикла
Всё произошло так, как мы и ожидали. Пятёрка вывелась в консоли, а шестёрка — нет.
Теперь проверим работу следующего оператора, который предусматривает только равенство правой и левой части условия
1 2 3 4 5 6 7 8 9 10 |
} while(i <= 5); //------------------------ printf("\"==\" =========================\r\n"); i=5; while(i == 5) { printf("i = %d\r\n", i); i++; } //------------------------ |
Из кода понятно, что у нас выведется только цифра 5.
Испытаем это, запустив нашу программу на выполнение
Так и получилось — вывелась только пятёрка.
Далее обратная операция — не равно
1 2 3 4 5 6 7 8 9 10 11 |
i++; } //------------------------ printf("\"!=\" =========================\r\n"); i=0; while(i != 5) { printf("i = %d\r\n", i); i++; } //------------------------ |
Повторение выполнения тела цикла будет происходить до тех пор, пока значение нашей переменной не будет равно 5, поэтому, выведутся в консоль у нас значения от 0 до 4
Перейдём теперь к логическим операторам.
Начнём с операции «И«
1 2 3 4 5 6 7 8 9 10 11 12 13 |
i++; } //------------------------ printf("\"&&\" =========================\r\n"); i = 0; j = 0; while((i <= 5) && (j <= 7)) { printf("i = %d\r\n", i); i++; j++; } //------------------------ |
Мы с помощью данной операции объединили два условия. В одном условии у нас проверяется значение переменной i, которое должно быть меньше или равно 5, а во втором, которое справа, — значение переменной j, которое не должно превысить 7. А выводить в консоли мы будем только значение переменной i. Логическая операция «И«, как мы знаем из курса информатики, предусматривает выполнение обоих выражений — и правого и левого, поэтому результат работы данного участка заранее известен. Счётчик досчитает до 5, первое условие перестанет выполняться, и, следовательно, тело цикла тоже выполняться перестанет
Так и получилось. Счётчик досчитал только до 5.
Кстати, как правило, уже в операциях условий или, как их называют ещё, ветвлений, с которыми мы будем знакомиться позже, операция «И» используется несколько по другому. Мы в условии проверяем чаще всего диапазон значений одной переменной, который должен быть истинным не до какого-то порога и не от какого-то порога по-отдельности, а сразу от одного порога до другого. Например, если нам надо чтобы значение i для выполнения условия находилось в диапазоне от 5 до 10, то мы уже в условии напишем вот так:
((i>=5)&&(i<=10))
Теперь добавим подобный код, но будем использовать уже оператор «ИЛИ«
1 2 3 4 5 6 7 8 9 10 11 12 13 |
j++; } //------------------------ printf("\"||\" =========================\r\n"); i = 0; j = 0; while((i <= 5) || (j <= 7)) { printf("i = %d\r\n", i); i++; j++; } //------------------------ |
Теперь у нас счётчик досчитает до 7, так как операция «ИЛИ» уже не предусматривает выполнение всех условий, а ей для истинности достаточно выполнение хотя бы одного из всех условий. Кстати, условий может быть не два, а сколько угодно, мы тогда после второго условия добавляем ещё один оператор «||» и добавляем следующее условие и так далее.
Проверим работу нашего кода
Счётчик досчитал до 7, как мы и ожидали.
Ну и последний на сегодня оператор — это оператор «!» (НЕ). Данный оператор позволяет нам считать истинным наше условие, когда оно, наоборот, имеет ложный или нулевой результат, то есть, операция с таким оператором делает результат условия или выражения, над которым она выполнятся обратным — истинный ложным, а ложный истинным. А, по большому счёту, данная операция превращает любое положительное значение выражения в ноль, а нулевое значение выражения — в единицу. Казалось бы, зачем это надо, но, уверяю вас, данный оператор мы будем использовать очень часто, намного чаще, чем мы ожидаем.
Добавим следующий код
1 2 3 4 5 6 7 8 9 10 11 12 13 |
j++; } //------------------------ printf("\"!\" =========================\r\n"); i=0; while(!(i > 5)) { printf("i = %d\r\n", i); i++; } //------------------------ printf("=========================\r\n"); //------------------------ |
У нас в условии в скобках после оператора «НЕ» находится то, что значение переменной i должно быть больше 5. Операция «НЕ» предусматривает то, что условие будет выполняться при ложном значении условия в скобках, то есть для того, чтобы тело цикла выполнялось, значение переменной i, наоборот, не должно быть больше 5, то есть, оно должно быть меньше или равно 5.
Проверим это, откомпилировав и запустив нашу программу
Так и получилось. Значение у нас не было больше 5.
Надеюсь, я понятно объяснил работу операторов отношения и логических операторов. Мне нет смысла объяснять непонятно и куда-то спешить. Так как в темах по программированию микроконтроллеров, а также в личку мне поступает огромное количество вопросов, связанных с проблемами незнания определённых тем по языку. Наша задача сейчас состоит в том, чтобы таких вопросов было как можно меньше. От этого станет легче всем. Ясное дело, что в рамках одного урока начинающему программисту будет тяжело полностью осознать, как работают те или иные операторы, всё обязательно придёт с практикой. И мы будем стараться как можно больше использовать в наших занятиях и по программированию на языке C и в программировании микроконтроллеров такой код, в котором будет проработка тех вопросов, которые больше всего непонятны большинству посетителей ресурса.
Итак, на сегодняшнем уроке мы познакомились с операторами сравнения или отношения, а также с логическими операторами.
Всем спасибо за внимание!
Предыдущий урок Программирование на C Следующий урок
Смотреть ВИДЕОУРОК (нажмите на картинку)
Доброе утро!
Огромное спасибо за уроки по Си.
Могли бы развить эту тему и рассказать как можно выставлять биты в регистрах микроконтроллера
Используя такие операторы:
^
~
|
<<
Здравствуйте!
Спасибо за интерес к ресурсу!
Это рубрика по языку. Но битовые операции мы проходить тут будем. Только не в регистрах контроллера, а в различных переменных, что в принципе одно и тоже, т.к. переменная целого типа — это участок памяти, а регистры МК — это тоже участок памяти.
Сердечно благодарен за курсы!
Спасибо большое!!!