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. Все верно.
Свободное программное обеспечение: PascalABC
Презентация «Программирование циклических алгоритмов»
Презентация "Программирование циклов с заданным условием окончания работы"
ЗАДАНИЯ ДЛЯ ЗАКРЕПЛЕНИЯ:
Сначала проверим ваши теоретические знания.
Возьмем для примера задачу: найти сумму некоторого количества чисел, задаваемых пользователем. Исходными данными в этом случае являются переменная 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