59. Анализ работы программ, содержащих циклы

Программирование циклических алгоритмов

Ключевые слова:

  • while (цикл-ПОКА)

  • repeat (цикл-ДО)

  • for (цикл с параметром)

Программирование циклов с заданным условием продолжения работы

Цикл с заданным условием продолжения работы (цикл-ПОКА) программируется в языке Паскаль с помощью оператора while. Общий вид оператора:

while <условие> do <оператор>

Здесь:

<условие> — логическое выражение; пока оно истинно, выполняется тело цикла;
<оператор> — простой или составной оператор, с помощью которого записано тело цикла.

Запишем на языке Паскаль рассмотренный в п. 2.4.3 (пример 14) алгоритм получения частного q и остатка r от деления натурального числа х на натуральное число у без использования операции деления.

program n_14;
var х, у, q, г: integer;
begin
writeln ('Частное и остаток');
write ('Введите делимое х>>');
readln (х);
write ('Введите делитель у>>');
read (у) ;
r :=х;
q:=0;
while r>=x do
begin
r:=r-y;
q:=q+1
end;
writeln ('Частное q=', q) ;
writeln ('Остаток r=', r)
end.

Каким будет результат выполнения программы при х = -10 и у = 3? Как вы можете объяснить этот результат?

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

Цикл с заданным условием окончания работы (цикл-ДО) программируется в языке Паскаль с помощью оператора repeat.

Общий вид оператора:

repeat <оператор1; оператор2; ...; > until <условие>

Здесь:

<оператор1>; <оператор2>; ... — операторы, образующие тело цикла;
<условие> — логическое выражение; если оно ложно, то выполняется тело цикла.

Запишем на языке Паскаль рассмотренный в п. 2.4.3 (пример 17) алгоритм решения задачи о графике тренировок спортсмена.

program n_15;
var i: integer; х: real;
begin
writeln (Трафик тренировок');
i: =1;
x: =10;
repeat
i: =i + 1;
x:=x+0.1*x;
until x>=25;
writeln ('Начиная c ', i, '-го дня спортсмен
будет пробегать 25 км')
end.

Программирование циклов с заданным числом повторений

Цикл с заданным числом повторений (цикл-ДЛЯ) программируется в языке Паскаль с помощью оператора for. Его общий вид:

for <параметр>:=<начальное_значение> to <конечное_значение> do <оператор>

Здесь:

<параметр> — переменная целого типа;
<начальное_значение> и <конечное_значение> — выражения того же типа, что и параметр, вычисляемые перед началом цикла;
<оператор> — простой или составной оператор — тело цикла.

При выполнении этого оператора после каждого выполнения тела цикла происходит увеличение на единицу параметра цикла; условием выхода из цикла является превышение параметром конечного значения.

Запишем на языке Паскаль рассмотренный в п. 2.4.3 (пример 19) алгоритм вычисления степени с натуральным показателем n для любого вещественного числа а.

program n_16;
var i, n: integer; a, y: real;
begin
writeln ('Возведение в степень');
write ('Введите основание а>>');
readln (а);
write ('Введите показатель n>>');
readln (n);
у:=1;
for i:=1 to n do y:=y*a;
writeln ('y=', y)
end.

Различные варианты программирования циклического алгоритма

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

Пример. Напишем программу, в которой осуществляется ввод целых чисел (ввод осуществляется до тех пор, пока не будет введён ноль) и подсчёт количества введённых положительных и отрицательных чисел.

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

program n_17;
var n, k1, k2: integer;
begin
k1:=0;
k2:=0;
repeat
write ('Введите целое число>>');
readln (n);
if n>0 then k1:=k1+1;
if n<0 then k2:=k2+1;
until n=0;
writeln ('Введено:');
writeln ('положительных чисел - ', k1) ;
writeln ('отрицательных чисел - ', k2)
end.

Имеющееся условие окончания работы можно достаточно просто преобразовать в условие продолжения работы — работа продолжается, пока n ≠ 0. И мы можем воспользоваться оператором while:

program n_18;
var n, k1, k2: integer;
begin
k1:=0;
k2:=0;
while n<>0 do
begin
writeln ('Введите целое число>>') ;
read (n);
if n>0 then k1:=k1+1;
if n<0 then k2:=k2+1;
end;
writeln ('Введено:');
writeln ('положительных - ', k1);
writeln ('отрицательных - ', k2)
end.

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

Вопросы и задания:

1. Ознакомьтесь с материалами презентации к параграфу, содержащейся в электронном приложении к учебнику. Используйте эти материалы при подготовке ответов на вопросы и выполнении заданий.

2. Дана последовательность операторов:

а:=1;
b: =2 ;
while a+b<8 do
begin
а: =а+1 ;
b: =b+2;
end;
s: =а+b

Сколько раз будет повторен цикл и какими будут значения переменных a, b, s после исполнения этой последовательности операторов?

3. Требовалось написать программу вычисления факториала числа n (факториал числа n есть произведение всех целых чисел от 1 до n). Программист торопился и написал программу неправильно. Ниже приведён фрагмент его программы, в котором содержатся пять ошибок:

k: =1;
f :=0;
while k<n do
f:=f*k;
k:=k+1

Найдите ошибки. Допишите необходимые операторы и выполните программу на компьютере.

4. Проанализируйте следующий цикл:

while a<b do
с:=а=b;

В чём его особенность?

5. Запишите на языке Паскаль программы решения задач № 25-29 из § 2.4. Используйте оператор while.

6. Дана последовательность операторов:

а: =1;
b: =1;
repeat
а:=а+1;
b:=b*2;
until b>8;
s:=а+b

Сколько раз будет повторён цикл и какими будут значения переменных а, Ь, s после исполнения этой последовательности операторов?

7. Напишите программу, в которой осуществляется ввод целых чисел (ввод осуществляется до тех пор, пока не будет введён ноль) и подсчёт суммы и среднего арифметического введённых положительных чисел. Используйте оператор repeat.

8. Напишите программу, в которой осуществляется ввод целых чисел (ввод осуществляется до тех пор, пока не будет введён ноль) и определение максимального (наибольшего) из введённых чисел. Используйте оператор repeat.

9. Напишите программу вычисления наибольшего общего делителя двух целых чисел:

а) используйте оператор repeat;
б) используйте оператор
while.

Цикл с заданным условием продолжения работы ( цикл –ПОКА-while)

Цикл с заданным условием продолжения работы (цикл –ПОКА) программируется в языке Паскаль с помощью оператора while.

Общий вид оператора:

Вайл (условие) ду (оператор)

<условие> - логическое выражение; пока оно истинно, выполняется тело цикла;

<оператор> - простой или составной оператор, с помощью которого записано тело цикла.

Пример

Требуется вычислить наибольший общий делитель двух натуральных чисел А и В.

Для решения воспользуемся алгоритмом Евклида: будем уменьшать каждый раз большее из чисел на величину меньшего до тех пор, пока оба числа не станут равны.

program P_1;

var a, b: integer;

begin

write ('введите два натуральных числа');

readln (a, b);

while a<>b do {Пока а не равно b}

if a>b then a:=a-b {Если а больше бэ, тогда а присвоить значение разности а минус бэ}

else b:=b-a; {Иначе бэ присвоить значение разности бэ минус а}

writeln ('НОД=',a);

readln

end.

Проверим.

Мы ввели числа 12 и 15

12 равно 15? Нет, тогда проверяем условие а больше бэ? Нет, значит присваиваем переменной бэ разность чисел 15 и 12, т.е число 3.

Возвращаемся к циклу 12 равно 3? Нет, тогда проверяем условие а больше бэ? Да, тогда присваиваем переменной а значение разности 12 и 3, равное 9.

Возвращаемся к циклу 9 равно 3? Нет, тогда проверяем условие 9 больше 3? Да, тогда присваиваем переменной а, разность 9 и 3, т.е. 6.

Возвращаемся к циклу 6 равно 3? Нет, тогда проверяем условие 6 больше 3. Да, тогда присваиваем переменной а значение разности 6-3, равное 3.

Возвращаемся к циклу 3= 3? Да, выводим на печать а. Цикл завершился.

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

Цикл –ДО программируется в языке Паскаль с помощью оператора repeat.

Общий вид оператора:

репит (оператор1; оператор2; …;) антил (условие)

< оператор1; оператор2;…; > - операторы, образующие тело цикла;

< условие > - логическое выражение; если оно ложно, то выполняется тело цикла.

Пример

Напишем программу, которая будет считывать строку от пользователя до тех пор, пока в строке не встретится точка или количество символом в строке не превысит 20.

program P_2;

var c:char; i:integer; str:string;

begin

i:=0; str:='';

writeln ('Введите текст');

repeat

inc(i);

read(c);

str:=str+c;

until (c = '.') or (i>20);

writeln(str);

end.

Проверим.

Мы ввели строчку: «Служить бы рад, прислуживаться – тошно.

Программа, не встретив точки, оставила только первые 20 символов.

Программа циклов с заданным числом повторений.

Цикл – ДЛЯ программируется на языке Паскаль с помощью оператора for.

Общий вид оператора:

фор (параметр):= (начальное_значение) ту (конечное_значение) ду (оператор)

<параметр> - переменная целого типа;

<начальное_значение> и < конечное_значение > - выражение того же типа, что и параметр, вычисляемые перед началом цикла;

<оператор> - простой или составной оператор – тело цикла.

При выполнении этого оператора после каждого выполнения тела цикла происходит увеличение на единицу параметра цикла; условием выхода из цикла является превышение параметром конечного значения.

Пример

Напишем программу вычисления степени с натуральным показателем n для любого вещественного числа а.

program P_3;

var i, n:integer; a, y: real;

begin

writeln ('Возведение в степень');

write (‘Введите основание а ‘);

readln (a);

write (‘Введите показатель n ’);

readln (n);

y:=1;

for i:=1 to n do y:=y*a;

writeln(‘y= ‘, y)

end.

Проверим.

Возведем число 5 в степень 3. Программа показывает, что это число 125. Проверим. 5*5*5= 125. Все верно.

ЗАДАНИЯ ДЛЯ ЗАКРЕПЛЕНИЯ:

Сначала проверим ваши теоретические знания.

Возьмем для примера задачу: найти сумму некоторого количества чисел, задаваемых пользователем. Исходными данными в этом случае являются переменная N - количество чисел и сами эти числа. Значение очередного числа обозначим переменной Х. Результатом работы алгоритма станет сумма этих чисел, которую обозначим переменной S. Допустимые значения переменной N должны удовлетворять условию n>0, так как количество слагаемых не может быть числом отрицательным.

Как же мы должны решать эту задачу? Сначала нужно запросить, сколько чисел нужно будет сложить и считать это число в переменную N. Затем нужно так организовать операторы, чтобы программа запрашивала очередное число и каждый раз складывала его с предыдущими; и повторяла эту группу операторов N раз.

При вычислении суммы используем следующий прием: вначале, когда еще не задано ни одно слагаемое, сумму полагают равной нулю (S:=0), а затем, получая очередное слагаемое, прибавляют его к сумме (S:=S+x) (см. программу ниже). Очень важное значение в операторе цикла имеет так называемая переменная цикла. В нашей программе она называется i. С ее помощью мы обращаемся к пользователю за очередным числом (write (‘Введите ‘,i,’-ое число ’)) и считаем количество уже введенных чисел (i:=i+1), чтобы не запросить лишнее. Одновременно переменная цикла участвует в булевом выражении (i<=N).

Рассмотрите внимательно программу, решающую нашу задачу.

Program Summa;

Uses Crt;

Var i, N : integer; x, S : real;

Begin

ClrScr;

write (‘Сколько чисел для сложения? ‘);

readln (N);

S:=0;

i:=1;

while i<=N do

begin

write (‘Введите ‘,i,’-е число ’);

readln (x);

S:=S+x;

i:=i+1;

end;

write (‘Сумма введенных чисел равна ‘,s:5:2);

readln;

End.

Хотелось бы, чтобы Вы смогли представить работу этой программы. Давайте попробуем вместе.

Пусть нам требуется сложить следующие числа: 5, 7, -4, 0, 8, 20. Посчитаем, сколько их всего – шесть. Это число мы введем, когда программа задаст вопрос: Сколько чисел для сложения? Теперь наша программа запросит ввести 1-ое число, т. к. на первом шаге переменная i равна 1. Мы введем число 5. Программа считает его в переменную х. Теперь число 5 сложим с числом 0 и результат присвоим переменной S (оператор S:=S+x). В этот момент S становится равной 5. Чтобы перейти к следующему числу, увеличим значение переменной i на 1 (оператор i:=i+1). Выполнение операторов тела цикла закончено. Теперь программа переходит опять к анализу условия вхождения в цикл (i<=N). Переменная цикла i=2, переменная N=6, поэтому значение логического условия 2<=6 равно True. Значит снова выполняется тело цикла:

while i<=N do {2<=6}

begin

write (‘Введите ‘,i,’-ое число ’); {Введите 2-е число}

readln (x); {Считали число 7}

S:=S+x; {S:=5+7}

i:=i+1; {i:=2+1}

end;

Итак, мы сложили два числа и переходим опять к проверке условия. Ответим на вопрос: 3<=6? Да. Поэтому снова начинаю работать операторы тела цикла и мы переходим к третьему числу:

while i<=N do {3<=6}

begin

write (‘Введите ‘,i,’-ое число ’); {Введите 3-е число}

readln (x); {Считали число -4}

S:=S+x; {S:=12 + (-4)}

i:=i+1; {i:=3+1}

end;

Аналогично, мы сложим и остальные числа. Но когда же операторы цикла выполнятся последний раз и остановится работа цикла? Когда сложим последнее число. Проверим это.

while i<=N do {6<=6}

begin

write (‘Введите ‘,i,’-ое число ’); {Введите 6-е число}

readln (x); {Считали число 20}

S:=S+x; {S:=16+20}

i:=i+1; {i:=6+1}

end;

Проверяется опять условие 7<=6. Значение этого условия равно False, а значит тело цикла выполняться не будет. Цикл закончил свою работу. А мы получили результат: посчитали сумму всех шести чисел S=32.

Теперь проверим знания на примере составления программы нахождения факториала числа.

Текст задачи:

Написать программу вычисления факториала числа n (факториал числа n есть произведение всех целых чисел от 1 до n). Ниже приведён пример программы для расчёта факториала, но некоторые фрагменты пропущены. Попробуйте восстановить программу.

Примеры задач: Оператор цикла с предусловием

Задача 1. Дано натуральное число n. Посчитать количество цифр в числе.

{Подсчет количества цифр начнем с последней цифры числа. Увеличим счетчик цифр на единицу. Число уменьшим в 10 раз (тем самым мы избавляемся от последней цифры числа). Далее с получившимся числом проделаем ту же последовательность действий и т. д., пока число не станет равным нулю. Примечание: в теле цикла обязательно должен быть оператор, влияющий на соблюдение условия, в противном случае произойдет зацикливание.}

program prim1;

uses crt;

var m, n: longint;

k: integer; {счетчик цифр}

begin

clrscr;

{Вводим целое число.}

writeln('Введите N='); readln(n);

{Запоминаем его и счетчику цифр присваиваем начальное значение.}

m:=n;k:=0;

{Пока m<>0 делать цикл.}

while m <>0 do

begin

{"Уменьшаем" число на последнюю цифру, т. е. в 10 раз.}

k:=k+1; m:= m div 10; {Inc(k) }

end;

{Вывод количества цифр.}

writeln('B числе ',n,'- ',k, ' цифр!');

readln;

end.

Задача 2. Вычислить наибольший общий делитель двух натуральных чисел А и В.

program E6;

var a, b: integer;

begin

write ('введите два натуральных числа');

readln (a, b);

while a<>b do

if a>b then a: = a - b

else b: = b - a;

write ('НОД = ', a);

readln;

end.

Задача 3. Составление таблицы значений функции у = sin х отрезке [0;3.14] с шагом 0,1.

program E10;

var х, у: real;

begin

х: = 0;

writeln ('x' : 10,'sinx' : 10);

while x < = 3.14 do

begin

y: = sin(x);

writeln (x : 10,' ' ,y : 7 : 5);

x: = x + 0.1

end;

readln

end.

Задача 4. Приближенное вычисление суммы бесконечно убывающего ряда 1+x/1!+x2/2!+x3/3!+ ...

Program Summer2;

var

Eps:real; { Заданное число "эпсилон" }

X: real; { Основание степени в числителе дроби }

S: real; { В этой переменной будем накапливать сумму }

Y; real; { Для хранения очередного слагаемого }

i: integer; { Счетчик числа шагов }

begin

write('Введите X и Epsilon:');

readln(X, Eps);

Y:=l; { Первое слагаемое }

S:=Y; { Положим в сумматор первое слагаемое }

i:=0; { Обнулим счетчик шагов }

while abs(Y)>=Eps do { Пока добавленное слагаемое не меньше "эпсилон", считаем сумму. Если "эпсилон" сразу не меньше 1, цикл не выполнится ни разу! }

begin { Началось тело цикла }

i:=i+l; { Вычислили номер текущего шага }

Y:=Y*X/i; { Посчитали новое слагаемое }

S:=S+Y { Увеличили сумму на текущее слагаемое }

end; { Тело цикла завершилось. После этой строки компьютер перейдет на оператор while для сравнения переменной "эпсилон" с только что добавленным слагаемым }

{ Теперь выведем результат на экран }

Writeln('Сумма чисел=', S:6:4);

readln

end.

Задача 5. Возведение числа а, введенного с клавиатуры, в степень n

Program Stp:

var P: real: { Переменная, которая хранит результат очередного шага }

N: integer; { Показатель степени }

i: integer; { Счетчик числа шагов }

A: real; { Основание степени }

begin

write('Введите основание степени:');

readln(A);

write('Введите показатель степени:');

readln(N);

i:=0; { 0-й шаг }

Р:=1; { 20=1 }

while i< abs(N) do { Показатель может быть отрицательным, поэтому используем для анализа его абсолютную величину. Если показатель N=0, то в тело цикла не попадаем ни разу, так как 0-й шаг уже сделан }

begin

i:=i+l; { Увеличиваем i на 1,то есть i теперь равно номеру текущего шага }

Р:=Р*А { Получаем результат i- го шага, то есть A^i }

end;

{ В переменной Р на данный момент получен результат для положительного N }

if N < 0 then { Если показатель N - отрицательный, то результат должен иметь обратную величину }

Р:=1/Р;

writeln('Результат=',Р;6:3);

readln