- •Часть 1
- •1. Основы программирования на языке Си
- •1.1. Структура программы на языке Си.
- •1.2. Структура простейшей одномодульной программы
- •1.2.1. Комментарии в программе на языке Си
- •1.2.2. Начальные сведения о препроцессоре
- •1.2.3. Определение функции main().
- •1.2.4. Пример простейшей программы
- •1.3. Алфавит, синтаксис и семантика
- •1.4. Алфавит языка Си
- •1.5. Понятие о типе
- •1.6. Система типов языка Си
- •1.7. Понятие об объекте
- •1.8. Лексемы
- •1.9. Зарезервированные слова
- •1.10. Идентификаторы
- •1.11. Литералы
- •1.11.1. Целочисленные литералы
- •1.11.2. Литерал вещественного типа
- •1.11.3. Символьные литералы
- •1.11.4. Строковый литерал
- •1.12. Переменные
- •1.13. Символические константы в языке Си
- •1.14. Операторы, выражения и инструкции. Общие сведения.
- •1.14.1. Классификация операторов
- •1.14.2. Приоритет и ассоциативность операторов.
- •1.14.3. Побочные эффекты при вычислении выражений
- •1.14.4. Порядок вычисления выражений
- •1.15. Арифметические операторы и выражения
- •1.15.1. Унарные операторы
- •1.15.2. Бинарные операторы
- •1.15.3. Преобразования типа при выполнении бинарных операторов
- •1.15.3.1. Автоматическое преобразование типов
- •1.15.3.2. Явное преобразование типа
- •1.15.4. Математические функции
- •1.16. Оператор присваивания и инструкция присваивания
- •1.16.1. Простой оператор присваивания
- •1.16.2.Множественное присваивание
- •1.16.3. Составной оператор присваивания
- •1.16.4. Преобразование типа при присваивании
- •1.17. Начальные сведения об указателях. Выходные параметры функции
- •1.18. Принятие решений и логические величины. Операторы отношения и сравнения на равенство
- •1.18.1. Логические операторы
- •1.18.2. Поразрядные операторы
- •1.19. Условные выражения (оператор ?:)
- •1.20. Оператор запятая
- •1.21. Оператор sizeof
- •1.22.4. Инструкция return
- •1.23. Составная инструкция
- •1.24. Инструкция if else
- •1.24.1. Полная и сокращенная формы инструкции if
- •1.24.2. Вложенные инструкции if
- •1.25. Инструкция switch
- •1.25.1. Синтаксис инструкции switch
- •1.25.2. Использование инструкции switch
- •1.26. Функциональные компоненты цикла
- •1.27. Арифметические и итерационные циклы
- •1.27.1. Задачи, приводящие к арифметическим циклам
- •1.27.2. Задачи, приводящие к итерационным циклам
- •1.28. Циклические управляющие инструкции
- •1.29. Цикл, управляемый инструкцией for
- •2. Примеры решенных задач
- •2.1. Линейные вычислительные процессы
- •2.2. Организация разветвлений
- •2.2.1. Простейшие разветвления
- •2.2.2. Многовариантные разветвления
- •2.2.2.1. Использование переключателя switch
- •2.2.2.2. Использование вложенных инструкций if else if
- •2.2.2.3. Использование вложенных инструкций if ... If
- •2.2.2.4. Использование сокращённых форм инструкции if
- •2.2.3. Рекомендации по программированию
- •2.3. Организация циклов
- •2.3.1. Простые циклы
- •2.3.2. Циклы и разветвления
- •2.3.2.1. Разветвление до цикла
- •2.3.2.2. Разветвление внутри цикла
- •2.3.2.3. Разветвление после цикла
- •2.3.2.4. Циклы в ветвях разветвлений.
- •2.3.3. Рекомендации по программированию
- •Содержание
- •1. Основы программирования на языке Си
- •Литература
2.2.2.2. Использование вложенных инструкций if else if
Это один из наиболее часто используемых на практике способов построения многовариантного разветвления. Поясним существо этого метода на примере вычисления значения функции, имеющей несколько областей задания. Постараемся найти такой подход к решению этой задачи, которым можно было бы воспользоваться при любом количестве областей задания. В качестве исходного примера подойдёт любая функция, имеющая больше двух областей задания.
Постановка задачи.
Вычислить значение функции y = f(x), заданной следующим образом

Решение.
Рассматриваемая функция имеет три точки ветвления (x == 0, x == 5 и x == 10) и четыре области задания. Множество операций, из которых требуется выполнить выбор, может быть представлено четырьмя инструкциями присваивания. Для реализации разветвления потребуются три инструкции if...else. Одну из них назовём основной и две вложенные в неё инструкции. Общее количество инструкций if...else определяется количеством точек ветвления. В данном примере таких точек ветвления три. Каждая из инструкций if...else “проверяет” одну точку ветвления. Начать проверки следует с любой крайней точки: левой или правой. Затем следует проверять последовательно одну точку за другой, двигаясь к другой крайней точке.
Выберем в качестве исходной точки для проверки крайнюю левую точку x == 0. Эта точка задана двумя условиями. Выберем такое из этих двух условий, при выполнении которого в инструкции if...else удалось бы выбрать первое присваивание (y = 0). Таким условием будет x <= 0. Таким образом, в логике основной (внешней) инструкции if...else надо проверять условие x <= 0. Начало вложенных инструкций будет выглядеть следующим образом
if(x <= 0) y = 0 ; else
Теперь после else необходима новая проверка. Здесь следует записать новую инструкцию, которая должна проверять следующую точку ветвления x == 5. При этом можно воспользоваться результатами первой проверки (при x == 0). Дело в том, что в той точке программы, где будет располагаться следующая инструкция, автоматически выполняется условие x > 0, противоположное тому условию, которое проверяет внешняя инструкция. Выстроив цепочку
if(x <= 0) y = 0; else if(x <= 5)
можно выделить вторую операцию: y = 2 * x; . В результате получим
if(x <= 0) y = 0; else if(x <= 5) y = 2 * x; else
Применив эти же соображения к последней точке ветвления (x == 10) окончательно получим разветвление следующего вида
if(x <= 0) y = 0; else if(x <= 5) y = 2 * x; else if(x <= 10) y = x + 5; else y = -3 * x + 45;
Естественно, что подобный подход может быть распространен на любое количество точек ветвления.
К достоинствам полученного решения можно отнести следующее:
▪ условие, обеспечивающее выбор, расположено в непосредственной близости к выбранному действию,
▪ после выполнения выбранного действия последующие проверки не производятся.
К недостаткам приведённого решения следует отнести то обстоятельство, что последовательность проверок здесь жестко фиксирована. Такое ограничение не позволяет начать проверки с наиболее часто встречающегося условия. Последнее положение требует некоторого дополнительного пояснения. Представим себе большую программу, в которой часто приходится вычислять значения рассматриваемой функции. Предположим, что значения аргумента этой функции чаще всего отвечают условию 5 < x ≤ 10. С проверки именно этого условия и следовало бы начать цепочку проверок. Путём усложнения проверяемых условий и введения одной дополнительной проверки можно устранить этот недостаток. В основе изменённого подхода лежит отказ от использования результатов проверок, полученных в инструкциях, расположенных на внешнем уровне. Применительно к нашей задаче такой подход требует использования логических операторов. Приведём решение, в котором используются логические операторы.
if(x <= 0) y = 0; else if(x <= 5 && x > 0) y = 2 * x; else if(x <= 10 && x > 5) y = x + 5; else if(x > 10) y = -3 * x + 45;
