Содержимое курса
Раздел 2. (21 час) Алгоритмы и программирование.
0/21
Информатика 8 класс

Урок №28

Цикл с условием.


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

У циклов выделяют заголовок и тело. Заголовок определяет, до каких пор или сколько раз тело цикла будет выполняться. Тело содержит выражения, которые выполняются, если в заголовке цикла выражение вернуло логическую истину (True, не ноль).

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

В языке программирования Паскаль существует три вида циклических конструкций.

Цикл for

Часто цикл for называют циклом со счетчиком. В Pascal этот цикл используется, когда число повторений не связано с тем, что происходит в теле цикла. То есть количество повторений известно заранее.

В заголовке цикла указываются два значения. Первое значение присваивается так называемой переменной-счетчику, от этого значения начинается отсчет количества итераций (повторений). Отсчет идет с шагом равным единице. Второе значение указывает, при каком значении счетчика цикл должен остановиться. Другими словами, количество итераций цикла определяется разностью между вторым и первым значением плюс единица. В Pascal тело цикла for не должно содержать выражений, изменяющих счетчик.

Цикл for существует в двух формах:

for счетчик := начало to конец do тело

for счетчик := начало downto конец do тело

Если между начальным и конечным значением счетчика указано ключевое слово to, то на каждом шаге цикла значение счетчика будет увеличиваться на единицу. Если же указано downto, то значение счетчика будет уменьшаться на единицу.

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

Количество итераций цикла for известно именно до его выполнения, но не до выполнения всей программы. Так в примере ниже, количество выполнений цикла определяется пользователем. Значение присваивается переменной, а затем используется в заголовке цикла. Но когда оно используется, уже точно известно, сколько раз цикл выполнится.

var
    i, n: integer;
begin
    write('Количество знаков: ');
    readln(n);
    for i := 1 to n do
        write('*');
    writeln;
end.

Примеры выполнения кода:

Количество знаков: 5
*****
Количество знаков: 13
*************

Цикл while

В Паскале цикл while является циклом с предусловием. В заголовке цикла находится логическое выражение. Если оно возвращает true, то тело цикла выполняется, если false — то нет.

Когда тело цикла было выполнено, то ход программы снова возвращается в заголовок цикла. Условие выполнения тела снова проверяется (находится значение логического выражения). Тело цикла выполнится столько раз, сколько раз логическое выражение вернет истину. Поэтому очень важно в теле цикла предусмотреть изменение переменной, которая используется в заголовке цикла, таким образом, чтобы когда-нибудь обязательно наступала ситуация логической лжи. Иначе произойдет так называемое зацикливание — одна из самых неприятных ошибок в программировании.



var
sum, n: integer; begin sum := 0; while sum < 100 do begin readln(n); sum := sum + n; end; writeln('Сумма: ', sum); end.

Примеры выполнения кода:

45
23
12
31
Сумма: 111
50
91
Сумма: 141

Цикл repeat

Цикл while может не выполниться ни разу, если логическое выражение в заголовке сразу вернуло false. Однако такая ситуация не всегда подходит. Бывает, что тело цикла должно выполниться хотя бы один раз, не зависимо оттого, что вернет логическое выражение. В таком случае используется цикл repeat — цикл с постусловием.

В цикле repeat логическое выражение стоит после тела цикла. Причем, в отличие от цикла while, здесь всё наоборот: в случае true происходит выход из цикла, в случае false — его повторение.


var sum, n: integer; begin sum := 0; repeat readln(n); sum := sum + n; until sum > 100; writeln('Сумма: ', sum); end.
35
71
Сумма: 106

Есть несколько видов таких циклов в зависимости от способа определения количества повторений:

  1. Цикл с заданным условием продолжения работы (цикл «ПОКА»). Тело цикла повторяется до тех пор, пока выполняется условие, в противном случае происходит выход из цикла. Часто для цикла «ПОКА» в условии задачи определяется признак окончания ввода.
  2. Цикл с заданным условием окончания работы (цикл «ДО»). В таком цикле тело цикла всегда выполняется хотя бы один раз, так как первая проверка условия происходит тогда, когда тело цикла уже выполнено.

Порядок выполнения цикла с заданным условием:

  1. Выполнение команд из тела.
  2. Проверка условия (сравнения определённой величины с заданной).
  3. Пока ответ на условие «Нет», повторять описанные в теле операции/шаги.
  4. Если ответ на условие положительный, закончить процедуру.

Некоторые особенности циклов с условием:

  • Если условие ни разу не выполняется, то команды из тела не будут выполнены ни разу.
  • Если условие всегда истинно, тело операции будут выполняться бесконечное число раз. Такое положение называется зацикливанием.

·     Примеры циклов с заданным условием окончания работы.

·     Запись циклов с заданным условием окончания работы на языке Pascal.

Рассмотрим алгоритм кипячения воды в чайнике и составим его блок-схему. Чтобы вскипятить воду в чайнике нужно:

1.  Налить в чайник воду.

2.  Закрыть крышку.

3.  Поставить чайник на плиту.

4.  Включить газ.

5.  Подождать несколько минут.

6.  Проверить закипела ли вода:

·     если вода не закипела – вернуться к пункту 5.

·     если вода закипела – выключить газ.

Блок-схема алгоритма

Обратим внимание на то, что получившаяся блок-схема не соответствует циклу с предусловием, так как в начале выполняется последовательность команд, содержащихся в цикле, то есть подождать несколько минут и лишь потом проверяется условие цикла.

Полученная блок-схема соответствует циклу с заданным условием окончания работы (с постусловием). Этот цикл организован таким образом, что сначала выполняется тело цикла, затем проверяется его условие. То есть тело цикло будет выполнено в процессе работы программы хотя бы один раз. Если условие цикла не выполняется, то снова возвращаемся в начало алгоритма, то есть снова выполняется тело цикла. Если же условие цикла выполняется, то цикл завершает свою работу и выполняются команды которые следуют после него.

Блок-схема цикла с постусловием

Рассмотрим, как же записывается цикл с постусловием на языке Паскаль. Для цикла с постусловием в языке Паскаль есть оператор, обозначающийся служебным словом repeat. После него со следующей строки, на расстоянии одного пробела следует тело цикла, которое представляет собой последовательность операторов. После тела цикла на одном уровне со словом repeat следует служебное слово until. После него следует условие цикла, которое представляет собой логическое высказывание. После условия следует точка с запятой. На русский язык эту конструкцию можно перевести как «Выполнять тело цикла, пока не условие». Обратим внимание, что служебные слова repeat и until сами играют роль логических скобок, то есть выделять тело цикла служебными словами begin и end не требуется.

repeat

<оператор 1>;

<оператор 2>;

until <условие>;

Описание цикла с постусловием в программе

Задача: Написать программу для расчёта суммы чисел, введённых пользователем. При этом пользователь вводит произвольное количество чисел, а для выхода из программы вводит ноль.

Составим блок-схему алгоритма решения этой задачи. Обозначим s – сумму чисел. В начале она должна быть равна 0. Присвоим ей это значение. Далее пользователь введёт с клавиатуры значение слагаемого, обозначим его n. После этого программа увеличит значение суммы на текущее слагаемое. Далее с помощью условного блока проверим, равно ли введённое слагаемое нулю. Если условие не выполняется, значит снова вернёмся к считыванию очередного слагаемого. Если же очередное слагаемое равно нулю, выведем на экран итоговое значение суммы. На этом программа завершит свою работу.

Блок-схема алгоритма

Теперь напишем программу по составленной блок-схеме. Назовём её summa.  Объявим две переменные: s и n. Так как в условии задачи не сказано, что пользователь вводит целые числа, переменные будут принадлежать к вещественному типу real. Запишем логические скобки. В начале программы будет следовать оператор writeln, который будет выводить на экран поясняющее сообщение о том, что это программа расчёта суммы слагаемых, вводимых пользователем. Дальше присвоим переменной s значение 0. После этого запишем оператор цикла с постусловием repeat. На следующей строке сразу запишем служебное слово until и условие цикла: n=0. То есть цикл будет повторяться до тех пор, пока очередное слагаемое не окажется равным 0. Теперь запишем тело цикла. В начале цикла будет следовать оператор write, который будет выводить запрос на ввод очередного слагаемого или 0 для выхода. Далее будет следовать оператор readln (n). Теперь запишем оператор присваивания s:=s+n. На этом написание цикла будет завершено. После цикла будет следовать оператор write, который будет выводить на экран сообщение о том, что работа программы завершена, и что итоговая сумма равна s.

program summa;

var

 s, n: real;

begin

writeln (‘Программа расчёта суммы чисел, введённых пользователем.’);

s:=0;

repeat

  write (‘Текущая сумма: ‘, s, ‘. Введите очередное слагаемое или 0 для выхода>>>’);

readln (n);

s:=s+n;

until n = 0;

write (‘Итоговая сумма: ‘, s);

end.

Исходный код программы

Запустим программу на выполнение. Введём числа: 22, 22.7, 17.4 и 37.9. В конце для выхода введём 0.

Итоговая сумма действительно равна 100. Программа работает правильно. Задача решена.

Задача: Рассчитать количество нечётных цифр в целом положительном числе, введённом с клавиатуры. Длина числа не более 9 цифр.

Составим блок-схему алгоритма решения задачи. Сначала пользователь вводит с клавиатуры число, обозначим его n. Обозначим k количество нечётных цифр. Так как мы их ещё не считали присвоим k значение ноль. Дальше будут следовать условный оператор, который будет проверять, является ли нечётной последняя цифра числа, но так как чётность или нечётность числа зависит от чётности или нечётности его последней цифры нам достаточно проверить, не равен ли 0 остаток от деления всего числа n на 2. Если условие выполняется, увеличим значение k на 1. В противном случае ничего делать не будем. Теперь нужно отбросить последнюю цифру числа, так как её чётность мы уже проверили. Для этого достаточно n без остатка разделить на 10. Теперь с помощью ветвления проверим равно ли число 0, если нет – вернёмся к проверке чётности его последней цифры. Когда мы проверим все цифры числа, переменная n станет равна 0 и нам останется лишь вывести на экран значение k. На этом работа нашей программы будет завершена.

Блок-схема алгоритма

Напишем программу по составленной блок-схеме. Назовём её nechet. В разделе описание переменных объявим две переменные: n и k. По условию задачи n – целое число, его значение ограничено 9 цифрами, поэтому укажем его тип integer. Количество цифр в числе всегда будет целым и неотрицательным, и так как количество цифр в числе не более 9, укажем k, принадлежащей к типу byte.

Запишем логические скобки. В начале будет следовать оператор writeln который будет выводить на экран сообщение о том, что это программа подсчёта количества нечётных цифр в числе и запрос на ввод числа. Далее будет следовать оператор readln, считывающий значение n. Теперь запишем оператор присваивания переменной k значения 0. Дальше будет следовать оператор цикла с постусловием repeat. Сразу же на следующей строке запишем служебное слово until с условием завершения работы цикла: n=0. Теперь запишем тело цикла. Оно будет начинаться с условного оператора if с условием: n mod 2 <> 0.  После слова then в нём будет следовать оператор присваивания k:=k+1. Дальше будет следовать оператор присваивания переменной n результата её безостаточного деления на 10. После цикла будет следовать оператор write, который будет выводить на экран сообщение о том, что в введённом числе содержится k нечётных цифр.

program nechet;

var

 n: integer;

k: byte;

begin

writeln (‘Программа расчёта количества нечётных цифр числа. Введите число.’);

readln (n);

k:=0;

repeat

  if mod 2 <> 0

then k:=k+1;

n:=n div 10;

until n = 0;

write (‘Количество нечётных цифр в введённом числе: ‘, k);

end.

Исходный код программы

Запустим программу на выполнение. Введём число 947 316.

В нём действительно 4 нечётных цифры. Программа работает правильно. Задача решена.

Решим ещё одну задачу. Написать программу, которая выводит на экран 2, идущих последовательно, члена ряда Фибоначчи, ближайших к целому n. Так чтобы первый из них был меньше, а второй – больше либо равен nn вводится с клавиатуры. Оно не меньше 2 и не превышает 2 000 000 000.

Рядом Фибоначи называется числовой ряд, в котором, каждый следующий член равен сумме двух предыдущих. Он начинается с двух единиц. Для решения задачи нам достаточно генерировать числа из этого ряда до тех пор, пока нам не встретится число больше либо равное n.

Составим блок-схему алгоритма решения задачи. В начале пользователь вводит с клавиатуры значение n. Нам известны первые 2 члена ряда Фибоначчи, назовём их текущий и предыдущий и обозначим t и p соответственно. В начале оба они равны единице. Присвоим им соответствующее значение. Дальше будем генерировать следующие члены ряда.  В начале вычислим сумму известных членов ряда и сохраним её в промежуточной переменной s. Это будет следующий член ряда. Так, как значение предыдущего члена ряда больше не нужно – присвоим переменной p значение t, а t – значение s. Теперь проверим условие: t>n. Если нет – сгенерируем следующий член ряда, то есть вернёмся к блоку присваивания s суммы p и t. Если же условие выполняется – выведем на экран значения p и t. На этом работа программы будет завершена.

Блок-схема алгоритма

Напишем программу по составленной блок-схеме. Назовём её Фибоначчи. В разделе описания переменных запишем четыре переменные: npt и s. Так как все члены ряда Фибоначчи – целые числа, а n целое по условию – все переменные будут принадлежать к целочисленному типу integer.

Запишем логические скобки. В начале запишем оператор writeln, который будет выводить на экран сообщение о том, что это программа, вычисляющая члены ряда Фиббоначи ближайшие к n. Далее запишем оператор write с запросом на ввод n. Следующим оператор readln, считывающий значение n. Теперь запишем операторы присваивания, переменным p и t значения 1. Дальше запишем оператор Цикла с постусловием repeat. Сразу же на следующей строке запишем служебное слово until с условием завершения работы цикла: t>=n. Запишем тело цикла. Оно будет начинаться c присваивания s:=p+t. Дальше будут следовать операторы присваивания p – значения t и t – значения s. После цикла будет следовать оператор write, выводящий на экран сообщение о том, что искомые члены ряда Фибоначчи равны p и t.

program fibonacci;

var

 n, p, t, s: integer;

begin

 writeln (‘Программа вычисления членов ряда Фибоначчи, ближайших к n.’);

write (‘n=’);

readln (n);

p:=1;

t:=1;

repeat

  s:=p+t;

p:=t;

t:=s;

until t >= n;

write (‘Искомые члены ряда Фибоначчи равны ‘, p, ‘ и ‘, t)

end.

Исходный код программы

Запустим программу на выполнение. Введём число 100.

Искомые члены ряда действительно равны 89 и 144. Программа работает правильно. Задача решена.

Важно запомнить:

·      Цикл с заданным условием окончания работы (с постусловием) организован таким образом, что сначала выполняется тело цикла, а затем проверяется его условие. Он выполняется, пока не выполняется его условие.