Лекция 3. Операторы и выражения¶
Архитектура программы¶
Выражения и операторы¶
Понятие оператора¶
Существуют операторы преобразования данных и операторы управления работой программы.
Операции¶
Характеристики операций¶
Приоритет операций¶
Результат операций¶
В языке Си у операций могут быть следующие результаты:
Арифметические операции¶
| Знак | Операция |
| Умножение |
| / | Деление и целочисленное деление нацело |
| % | Деление по модулю и остаток от деления |
| Сложение |
| Вычитание |
Знак / всегда означает деление. Однако если с обеих сторон от этого знака стоят целые величины (константы, переменные или их комбинации), он означает целочисленное деление. Если в результате такого деления получается остаток, С++ его отбрасывает.
Знак % означает выделение остатка при целочисленном делении. Эта операция требует, чтобы с обеих сторон от ее знака стояли целые величины
Присваивание¶
Особенностью Си является возможность комбинирования операции присваивания с другими операциями, а также выполнение множественного присваивания.
Существуют два класса выражений:
l-value (левостороннее выражение. Может стоять слева от присваивания)
r-value (правостороннее выражение. Может стоять справа от присваивания)
Составное присваивание¶
Эта группа операций позволяет совместить арифметику и присваивание, что дает выразительность и удобочитаемость программам.
Преобразование типов¶
В различных выражениях могут встречаться данные как одного, так и разных типов. Компилятор может выполнять операцию приведения типов по-умолчанию, действуя согласно простого правила: короткие типы приводятся к длинным. Если необходимо изменить стандартное преобразование, то вводят явное приведение типов.
Сравнение¶
Операции сравнения являются бинарными и используются для сравнения двух значений
Значения операций¶
| Пример выражения | Результат |
| -4+6 | 2 |
| c=3+8 | 11 |
| 5>3 | 1 |
| 6+(c=3+8) | 17 |
| 6+c=3+8 | Ошибка! |
Инкремент и декремент¶
будет эквивалентен следующему
будет эквивалентен следующему
Операции инкремента/декремента¶
Что можно сказать о следующей программе?
Ошибка компиляции: l-value required as left operand of assignment
Неопределенное поведение¶
Определение (см. Википедию)
Неопределённое поведение (англ. undefined behaviour) — свойство некоторых языков программирования (наиболее заметно в Си), программных библиотек и аппаратного обеспечения в определённых маргинальных ситуациях выдавать результат, зависящий от реализации компилятора (библиотеки, микросхемы) и случайных параметров
При его выполнении переменная i может принять значения 13 или 14 для C/C++, 13 для Java, PHP и C#, 12 при реализации на LISP.
Неопределенность в языке C/C++ связана с тем, что согласно стандартам С и С++ побочные эффекты (то есть инкремент в данном случае) могут быть применены в любой удобный для компилятора момент между двумя точками следования (см. раздел Дополнительная информация).
Операторы¶
Основные алгоритмические конструкции¶
Основная теорема структурного программирования
Программа для решения любой задачи может быть составлена из комбинации следования, ветвления и цикла (Бойм-Якопини, 1966).
Классификация операторов¶
Оператор if¶
Оператор if¶
Примеры if¶
Несколько версий одной и той же программы
Удачные/неудачные конструкции¶
Удачные и неудачные конструкции¶
Среди всех приведенных конструкций наиболее удачной следует признать последнюю, так как она лишена нагромождений и воспринимается однозначно.
Если необходимо сравнить значение переменной с набором констант, то лучше отказаться от if в пользу switch
Сложные выражения¶
С позволяет конструировать очень сложные выражения. Эта сложность должна быть оправдана.
Оператор switch¶
Оператор switch¶
Вопрос: Чему будут равны значения переменных, если строка: babah!?
Оператор while¶
Операторы цикла¶
Оператор while¶
Ошибки при организации while¶
В чем состоит ошибка?
Оператор do while¶
Оператор do while¶
Это цикл с постусловием. Тело цикла выполняется как минимум 1 раз
Оператор for¶
Оператор for¶
Оператор for¶
Операторы управления¶
Оператор goto усложняет отладку программы и сильно портит стиль разработчика (‘’спагетти-код’‘)!
Спагетти-код¶
Пример спагетти кода на языке BASIC:
Тоже самое, но без goto:
Оператор break¶
Оператор continue¶
Дополнительная информация¶
Точка следования (англ. Sequence point) — в программировании любая точка программы, в которой гарантируется, что все побочные эффекты предыдущих вычислений уже проявились, а побочные эффекты последующих еще отсутствуют.
В C и C++ определены следующие точки следования:
Что такое выражение в программировании
Во всех языках программирования под выражением подразумевается конструкция, составленная из констант, переменных, знаков операций, функций, скобок. Выражение определяет порядок вычисления некоторого значения. Если это числовое значение, то такое выражение называют арифметическим. Вот несколько примеров арифметических выражений, записанных по правилам языка Си:
Три первых выражения имеют традиционную форму для языков программирования высокого уровня, поэтому их смысл очевиден. Следующие четыре выражения специфичны для языка Си.
Опишем набор операций, используемых в Си, а также правила записи и вычисления выражений. Напомним, что операция, применяемая к одному операнду, называется унарной, а операция с двумя операндами — бинарной.
— вычитание или унарный минус;
+ сложение или унарный плюс;
++ унарная операция увеличения на единицу (инкремент);
Все операции, кроме деления по модулю, применимы к любым числовым типам данных. Операция % применима только к целым числам.
Если хотя бы один из операндов имеет вещественный тип, то и результат будет вещественным. Например, операции 5./3, 5./3., 5/3. дадут вещественный результат 1.6666.
Различие проявляется при использовании префиксной и постфиксной форм в выражениях. Проиллюстрируем это на примерах. Первый пример:
В результате выполнения переменные получат следующие значения: а = 4, b = 3, с= 6. Второй пример:
Результаты будут такими: а = 4, b = 3, с=12.
По убыванию старшинства арифметические операции расположены в следующем порядке:
Одинаковые по старшинству операции выполняются в порядке слева направо. Д ля изменения порядка выполнения операций в выражениях могут применяться круглые скобки.
>= больше или равно, равно,
Как уже говорилось раньше, в стандарте Си нет логического типа данных. Поэтому результатом операции отношения является целое число: если отношение истинно — то 1, если ложно — то 0.
Результатом второго и третьего отношений будет 0 — ложь; результат четвертого отношения равен 1 — истина; результат первого отношения зависит от значения переменной а.
! операция отрицания (НЕ),
&& конъюнкция, логическое умножение (И),
| | дизъюнкция, логическое сложение (ИЛИ).
Например, логическое выражение, соответствующее системе неравенств 0 x
Обратите внимание на то обстоятельство, что здесь не понадобились круглые скобки для выделения операций отношения. В Си операции отношения старше конъюнкции и дизъюнкции. По убыванию приоритета логические операции и операции отношения расположены в следующем порядке:
Помимо рассмотренных в Си имеются поразрядные логические операции. Эти операции выполняются над каждой парой соответствующих двоичных разрядов внутреннего представления операндов. Их еще называют битовыми логическими операциями. Знаки битовых логических операций:
& поразрядная конъюнкция (И),
| поразрядная дизъюнкция (ИЛИ),
^ поразрядное исключающее ИЛИ,
поразрядное отрицание (НЕ).
Битовые логические операции вместе с операциями поразрядного сдвига влево ( >) позволяют добраться до каждого бита внутреннего кода. Чаще всего такие действия приходится выполнять в системных программах.
Операция присваивания. Знак операции присваивания =. Следствием отмеченного факта является то, что присваивание, как любой другой знак операции, может несколько раз входить в выражение. Например:
Присваивание имеет самый низкий приоритет (ниже только у операции «запятая»). Кроме того, операция присваивания — правоассоциативная. Это значит, что несколько подряд расположенных присваиваний выполняются справа налево. Поэтому в приведенном выше выражении первой выполнится операция сложения, затем переменной с присвоится значение суммы, затем это значение присвоится переменной b и в конце — переменной а.
а+=2 эквивалентно а=а+2,
х-=а+ b эквивалентно х=х-(а+ b ),
р/=10 эквивалентно р=р/10,
m*=n эквивалентно m=m*n,
г%=5 эквивалентно г=г%5.
Заметим, что вместо выражения а=а+2 предпочтительнее писать в программе а+=2, поскольку второе выражение будет вычисляться быстрее.
Операция явного преобразования типа (операция «тип»). Применение этой операции имеет следующий формат:
Операндом могут быть константа, переменная, выражение. В результате значение операнда преобразуется к указанному типу. Примеры использования преобразования типа:
По поводу последнего выражения заметим, что приоритет операции «тип» выше деления (и других бинарных арифметических операций), поэтому сначала значение переменной х приведется к целому типу (отбросится дробная часть), а затем выполнится деление по модулю.
Следующий фрагмент программы иллюстрирует одну из практических ситуаций, в которой потребовалось использовать преобразование типа:
В результате переменная с получит значение 0,5. Без преобразования типа ее значение стало бы равно 0.
sizeof (тип) и sizeof (выражение)
Результатом операции является целое число, равное количеству байтов, которое занимает в памяти величина явно указанного типа или величина, полученная в результате вычисления выражения. Последняя определяется также по типу результата выражения. Хотя по форме записи это похоже на функцию, однако sizeof является именно операцией. Ее приоритет выше, чем у бинарных арифметических операций, логических операций и отношений. Примеры использования операции:
sizeof (int) результат — 2
sizeof (1) результат — 2
sizeof (0.1) результат — 8
sizeof (1L) результат — 4
sizeof (char) результат — 1
sizeof (‘ a’) результат — 2
Операция «запятая». Эта необычная операция используется для связывания нескольких выражений в одно. Несколько выражений, разделенных запятыми, вычисляются последовательно слева направо. В качестве результата такого совмещенного выражения принимается значение самого правого выражения. Например, если переменная х имеет тип int, то значение выражения (х=3, 5*х) будет равно 15, а переменная х примет значение 3.
Данная операция реализует алгоритмическую структуру ветвления. Алгоритм ее выполнения следующий: первым вычисляется значение выражения 1, которое обычно представляет собой некоторое условие. Если оно истинно, т.е. не равно 0, то вычисляется выражение 2 и полученный результат становится результатом операции. В противном случае в качестве результата берется значение выражения 3.
Пример 1. Вычисление абсолютной величины переменной X можно организовать с помощью одной операции:
Пример 2. Выбор большего значения из двух переменных аи Ь:
Пример 3. Заменить большее значение из двух переменных аи b на единицу:
Правила языка в данном случае позволяют ставить условную операцию слева от знака присваивания.
Операции ( ) и [ ]. В языке Си круглые и квадратные скобки рассматриваются как операции, причем эти операции имеют наивысший приоритет. Их смысл будет раскрыт позже.
Подведем итог всему разговору об операциях Си/Си++, сведя их в общую табл. 2 и расположив по рангам. Ранг операции — это порядковый помер в ряду приоритетов. Чем больше ранг, тем ниже приоритет. В таблице отражено еще одно свойство операций — ассоциативность. Если одна и та же операция, повторяющаяся в выражении несколько раз, выполняется в порядке расположения слева направо, то она называется левоассоциа-тивной; если выполняется справа налево, то операция правоассоциативная. В таблице эти свойства отображены стрелками влево и вправо. Некоторые операции, присутствующие в таблице, пока не обсуждались.
