Версия:
Аннотация
Как выполнить неоднократно в зависимости от некого условия отличные от основной программы действия.
Цель: Необходимость в обработки произвольного количества данных, а также вычисление некой последовательности по индукции, в частности, поиск некого значения с необходимой точностью.
Предварительная версия.
Необходимость в многократном выполнении части команд, более того, часто при заранее неизвестном их количестве.
Для обработки заранее не обговоренного количества данных. В частности, вычисление суммы введенных чисел.
Многократное выполнение определенного действия, пока будет выполнено или не выполнено некое условие. В частности, поиск нужного члена последовательности по индукции.
В первом подразделе описывается применение циклов. В втором подразделе дается продвинутое описание логических выражений, которое позволяет лаконичнее записывать код программы. В третьем – рассмотрены разновидности частных конструкций циклов.
Цикла пока самый общий. Им можно задать любые другие виды циклов. Так, при написании программ можно им только и пользоваться.
Языковая конструкция while Цикл while – языковая конструкция языка Си, которая позволяет выполнять команду (см. 9) пока истинно соответствующее (см. 8) основное условие.
Обращаю внимание на отсутствие символа конца команды – символа ; в конце строчки с while (см. стр. 8). Данный символ, если и ставится, то только в конце целевой команды (см. стр. 9). Так, он в обще может отсутствовать.
Упражнение. Поиграйся с кодом. Замени число 1, на 2, на 3, на 0. В последнем случае пригодится комбинация Ctrl-C для принудительного завершения программы при работе в консоли. Пойми правильность результата работы, в том числе числового, программы.
Упражнение. Что будет, если убрать присвоение я переменным s и i? (см. стр. 7)
В данном фрагменте кода показаны главные составные части при написании цикла. К написанию цикла можно отнестись как к методу индукции, а именно – первый шаг (инициализация переменных) и шаг, обеспечивающий шаг индукции. При выполнении этих свойств цикл корректен. В дополнении к этому в программе есть проверка на необходимость продолжения индукции (условие цикла): иначе говоря задает момент завершения цикла.
На первом шаге производится инициализация переменных, а именно – задание части переменным первоначального (до момента входа в цикл) значения. В противном случае, нет гарантии, что "индукция"будет успешно выполнена. В частности, если в данном фрагменте убрать (см. стр. 7) присвоение 0 переменной s, то как понимать строчку 9 при первом выполнении целевого действия цикла? Как к новому значению прибавить предыдущие, если оно ещё не было задано? Так вот, по этой причине перед началом цикла и необходимо задавать значения всем актуальным переменным (см. стр. 7). В данном случае, переменные нужно положить равными 0.
Шаг индукции, который соответствует сути цикла (см. стр. 9), пишется из предположения, что все актуальные переменные имеют корректное значение и их можно использовать в арифметических и логических выражениях. В данном случае, если действительно перед началом цикла присвоить значение переменной s, то все встает на свои места, так как при первом проходе цикла в стр. 9 старое значение переменной s будет равным .
Как и в условных конструкция, одиночную команду естественно можно заменить на фрагмент когда:
Цикл выполняется пока истинно основное условие. Данное обстоятельство настолько важно, что рассмотрим его отдельно.
Условие цикла Для начала анекдот:
Читают инструкцию к шампуню:
Анекдот показывает важность правильно и корректного написания условия завершения.
Поэтому не забывай об условии завершения цикла. Убедись, что оно когда-нибудь да сработает, иначе твоя программа будет работать "бесконечно". Последнее означает, что если мы таких гарантий дать не можем, то может потребоваться просто ограничить сверху то количество раз, которое выполняется цикл. В итоге в нашем случае один из вариантов правильного условия звучит как: "пока волосы не будут скрипеть, но не более 2х раз последнее на случай, если шампунь "испортился".
Команда break Команда, позволяющая "досрочно"выйти из цикла. Так, обычно проверка условия проводится перед началом выполнения тела цикла. В случае успеха, выполняется цикл, иначе цикл больше не выполняется. Так вот, инструкция break, вызываемая внутри тела цикла, позволяет сразу, не дожидаясь проверки условия, выйти из цикла. Обычно используется для быстрого (аварийного) выхода из цикла.
Пример...
Можно переписать цикл и без использования break.
Упражнение. Перепиши цикл так, что условием цикла и будет факт успешного считывания. Лишнюю печать можно убрать.
Должно было получиться:
Упражнение. Найдите среднее значение вводимых чисел.
Последнее показывает, что без break можно обойтись, и иногда это упрощает код. Но бывает, что код наоборот усложняется.
Упражнение. Теперь восстанови вывод текста как он был в первоначальной программе. Вывод программы должен совпадать в точности. В чем неудобство?
Тем не менее, при правильном использовании break программа обычно упрощается.
Команда continue Команда continue (см. стр. 10), выполняемая в теле цикла, позволяет сразу выйти на проверку условия цикла (см. 2), т.е. на его самое начало. Обычно используется при проверке данных на некое условие (корректность), которое не влечет выхода из цикла.
Можно обойтись и без continue.
Видно, что программа "усложнилась"(текст сдвинулся в право).
Упражнение. Убери break ещё раз. Лишний вывод при необходимости тоже можно убрать.
Рассмотрим следующий фрагмент кода:
Отмечу, что порядок команд и, в частности, проверок важен. Так, сначала необходимо попробовать считать число (см. стр. 3). В случае ошибки ввода программа завершает работу (см. стр. 6) предварительно выведя причину ошибки (см. стр. 5). Иначе число считывается успешно и программа продолжает работу со строчки 8.
По аналогии проверяется корректность считаного числа (то что оно неотрицательное). Важно то, что нельзя проверить в параллель, тем более, заранее корректность числа, т.е. код должен выполнятся строго последовательно.
Проблема в данном коде то, что он громоздкий: так не принято в идеологии языка Си. Мы могли бы условия конструкций if объединить в единое логическое выражение посредством операции ИЛИ и получить код:
Оно истинно, если истинно хотя-бы одно из выражений. Но есть нюанс.
Рассмотрим случай, когда введена чепуха и, соответственно, scanf не удалось считать число и было возвращено 0е значение (т.е. истинно первое подвыражение). В таком случае переменной a не было ничего присвоено, и в лучшем случае она содержит мусор. Тогда вторая проверка некорректна, ведь переменной a не было ничего присвоено и поэтому, вообще говоря, мы не имеем право её использовать в выражениях (результат не будет детерминирован). Но, логические выражения, построенные на основе связок И и ИЛИ, на самом деле, обладают одним интересным свойством.
Напомню, что операция ИЛИ истинна тогда и только тогда, когда хотя бы один из операндов истинен. Поэтому, если какой-либо из них оказался истинным, то в общем-то нет смысла в проверке второго, так как он уже не способен изменить итоговый результат данной операции. Аналогично, если в связке И один из операндов ложен, то по тем же причинам, что и ранее, нет причин для проверки ложности второго (он уже в целом будет ложен).
Осталось вспомнить, что программа выполняется последовательно, т.е. она не может выявить истинность обоих операндов одновременно. Поэтому, необходимо установить четкий порядок, в котором будут проверяться операнды, а именно – они проверяются в порядке их появления в тексте программы (точнее в логическом выражении).
Исходя из выше написанного становится понятно, что ничего криминального не будет в случае, если переменная a не будет считана, так как в этом случае второе условие, в приведенном ранее фрагменте, просто не будет проверятся – для вычисления итоговой истинности выражения достаточно, что истинно перовое подвыражение.
В дальнейшем это будет использовано.
Пример с циклами!!!
Можно обойтись циклом while, но иногда для краткости или большей четкости, цикл можно записать через более частные конструкции. На самом деле они все взаимозаменяемые. Тот или иной цикл применяется исходя из вложенного в него смысла.
Цикл for Предполагает явное использование счетчиков, что фактически основное выражение цикла выполняет действия со значения a по значение b. Но это все необязательно. Первый пример из циклов преобразуется так:
Инициализация переменных переносится в качестве первой группы внутри for конструкции (см. стр. 8). Выражение становится второй группой. Третья группа это простые арифметические действия, т.е. там, например, не может быть конструкции if, а присваивать переменным значения можно. В данном примере программа сократилась до одной строчки.
Программу можно записать иначе:
Теперь мы тоже действие делаем явно в основном действии (см. 9).
Можно делать и больше одного действия:
Действия перечисляются через запятую, но if и других более сложных конструкций нет и быть не может.
Но можно было записать программу длиннее.