Циклические алгоритмы. Цикл с предусловием - pismo.netnado.ru o_O
Главная
Поиск по ключевым словам:
страница 1
Похожие работы
Циклические алгоритмы. Цикл с предусловием - страница №1/1

Циклы

Занятие I

Тема: Циклические алгоритмы. Цикл с предусловием.

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



Определение. Цикл – это последовательность операторов, которая может выполняться более одного раза.

Определение. Циклический алгоритм – это алгоритм, содержащий один или несколько циклов.

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

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

S=x1+x2+x3+...+xn

Допустимые значения переменной N должны удовлетворять условию n>0, так как количество слагаемых не может быть числом отрицательным.

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

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

• цикл с предусловием;

• цикл с постусловием;

• цикл со счетчиком.

Познакомимся с первым из них – оператором цикла с предусловием while.

Циклы с предусловием используются тогда, когда выполнение цикла связано с некоторым логическим условием. Оператор цикла с предусловием имеет две части: условие выполнения цикла и тело цикла.

При выполнении оператора while определенная группа операторов выполняется до тех пор, пока определенное в операторе while булево условие истинно. Если условие сразу ложно, то оператор не выполнится ни разу.

Общая форма записи следующая



while <булево выражение> do

begin

группа операторов



end;

На русском языке это звучит примерно так:



пока выполняется это условие делай

от начала

группа операторов



до конца;

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

При использовании цикла с предусловием надо помнить следующее:

1) значение условия выполнения цикла должно быть определено до начала цикла;

2) если значение условия истинно, то выполняется тело цикла, после чего повторяется проверка условия. Если условие ложно, то происходит выход из цикла;

3) хотя бы один из операторов, входящих в тело цикла, должен влиять на значение условия выполнения цикла, иначе цикл будет повторяться бесконечное число раз.

Вернемся к нашей задаче вычисления суммы чисел. При вычислении суммы используем следующий прием: вначале, когда еще не задано ни одно слагаемое, сумму полагают равной нулю (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 раз. Но чаще всего этот вид цикла используется тогда, когда количество повторений заранее не известно и зависит от выполнения какого-либо условия. Рассмотрим еще один пример.

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

Например, рассмотрите следующие циклические алгоритмы

а) Пока не сдал выпускные экзамены делай

начало

готовь уроки;



посещай школу;

конец;


б) Пока есть желание, возможность и здоровье делай

посещай занятия спортом



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

а) “Репка”. “Дед тянет-потянет, вытянуть не может. Позвал бабку. Бабка за дедку , дедка за репку, тянут потянут, вытянуть не могут. Позвала бабка внучку... И вытянули репку”.

б) “Курочка ряба”. “Снесла курочка яичко. Дед бил, бил, не разбил. Баба била, била, не разбила. Мышка бежала, хвостиком задела, яичко упало и разбилось”.

в) “Колобок”. “... Катится колобок по лесу. От зайца ушел, от медведя ушел, от волка ушел. Встретил лису, она его и съела”.

г) “Волк и лиса”. “... Сидит волк у проруби, хвост в воду опустил и приговаривает: “Ловись, ловись, рыбка, большая и маленькая”. Пришла за водой баба. Прогнала волка.

д) “Горшочек каши”. “... Варит горшок кашу, варит. Каша из дома на улицу потекла. Не знает мать девочки, что надо горшочку сказать. Пришла девочка, сказала: “Горшочек, не вари”. Перестал горшок кашу варить”.



Цикл с предусловием.

Продолжим изучение цикла с предусловием на примере решения следующей задачи.



Задача. Найти сумму чисел в непустой последовательности.

Рассмотрим алгоритм решения. Пусть нам дана такая последовательность чисел:

3, -4, 0, 5, 19, -20, 6, 2

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

1 2 3 4 5 6 7 8

3, -4, 0, 5, 19, -20, 6, 2

Получилось, что всего у нас чисел восемь, на первом месте стоит число 3, на втором - число (-4), на третьем - число 0 и т.д. Тогда переменная цикла i будет пробегать числа от 1 до 8, становясь на каждом шаге больше на 1 и запрашивая каждый раз очередное число. Поэтому общая схема цикла будет выглядеть так:

i:=1;


while i<=N do

begin


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

readln (x);

. . .

i:=i+1;


end;

Здесь N - количество чисел последовательности (в нашем случае 8), х - член последовательности, i - порядковый номер очередного члена последовательности. Просмотрим, как будет работать этот цикл.

1 шаг

i:=1;


while i<=N do {Проверяется условие 1<=8? Да. Значит выполняем тело цикла}

begin


write (‘Введите ‘,i,’-ое число’);{Вывод на экран “Введите 1-ое число”}

readln (x); {Считываем число 3 в переменную х}

. . .

i:=i+1; {Переходим к следующему по порядку числу: i=2}



end;

2 шаг


i:=1;

while i<=N do {Проверяется условие 2<=8? Да. Значит выполняем тело цикла}

begin

write (‘Введите ‘,i,’-ое число’);{Вывод на экран “Введите 2-ое число”}



readln (x); {Считываем число (-4) в переменную х}

. . .


i:=i+1; {Переходим к следующему по порядку числу: i=3}

end;


3 шаг

i:=1;


while i<=N do {Проверяется условие 3<=8? Да. Значит выполняем тело цикла}

begin


write (‘Введите ‘,i,’-ое число’);{Вывод на экран “Введите 3-ое число”}

readln (x); {Считываем число 0 в переменную х}

. . .

i:=i+1; {Переходим к следующему по порядку числу: i=4}



end;

и т. д.


8 шаг

i:=1;


while i<=N do {Проверяется условие 8<=8? Да. Значит выполняем тело цикла}

begin


write (‘Введите ‘,i,’-ое число’);{Вывод на экран “Введите 8-ое число”}

readln (x); {Считываем число 2 в переменную х}

. . .

i:=i+1; {Переходим к следующему по порядку числу: i=9}



end;

9 шаг


i:=1;

while i<=N do {Проверяется условие 9<=8? Нет. Значит цикл закончил свою работу и компьютер переходит к обработке следующего за end оператора}

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

Summa:=Summa+x;

Если Вам не совсем понятно, что происходит при выполнении этого оператора, Вам нужно вспомнить, как происходит присваивание значение переменной: сначала вычисляется значение выражения в правой части (в нашем случае Summa+x, т.е, значение переменной Summa увеличиваем на х), а затем присваиваем это значение переменной с именем, записанным в левой части (Summa). Таким образом, в переменной Summa собирается сумма всех считанных чисел.

Задание. Напишите полный текст программы, находящей сумму N чисел последовательности. Дополните программу нахождением среднего арифметического этих чисел.

Примечание. Средним арифметическим чисел называется сумма этих чисел, деленная на их количество.

Задачи для самостоятельного решения


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

2. Вводятся 15 чисел. Определить, сколько среди целых чисел.

3. Вывести все чётные числа начиная с числа N и до числа M. Числа N и M задает пользователь.

4. Составить программу, проверяющую, является ли последовательность из 10 целых чисел, вводимых с клавиатуры, возрастающей.

5. Составить программу, печатающую все делители целого числа в порядке возрастания.

6. Составить программу нахождения суммы чётных чисел, находящихся в промежутке от 26 до 88.

7. Найти наибольший общий делитель двух натуральных чисел a и b.

8. Спортсмен в первый день пробежал 10 км. Каждый следующий день он увеличивал норму на 10% от нормы предыдущего дня.

а) Определить через сколько дней спортсмен пробежит суммарный путь более 100 км.

б) Определить через сколько дней спортсмен будет пробегать более 20 км.

в) Какой путь пробежит спортсмен на 7-й день.

9. Вводятся 14 чисел. Определить, сколько среди них положительных (включая 0) и сколько отрицательных. (Числа вводятся в одну переменную в цикле)

10. Запросите 16 чисел и выведите на экран для каждого, делится ли оно нацело на 11. Спросите у пользователя, сколько нужно проанализировать чисел, а затем запросите эти числа и сделайте для каждого вывод, является ли оно четным или отрицательным.

12. Найдите сумму следующей последовательности

а1234-...+аn, где n - количество элементов, задаваемых пользователем.

13. Составить программу, печатающую все делители целого числа в порядке убывания.

14. Вывести на экран числа, кратные К из промежутка [А,В]. Числа А, В, К задает пользователь.

15. Запросите у пользователя положительное число А и найдите сумму всех натуральных чисел из промежутка [1, А].


Занятие II

Тема: Цикл с предусловием в графике.

Задача. Построить множество концентрических окружностей (с общим центром), удовлетворяющих следующим условиям:

а) радиус следующей окружности на m меньше предыдущей;

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

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

Program Krugi;

Uses


Crt, Graph;

Var


i,

m,

R,



a,

DV,


DM : integer;

Begin


ClrScr;

Randomize;

write (‘Введите шаг изменения радиуса окружностей ‘);

readln (m);

write (‘Введите радиус большей окружности ‘);

readln (R);

write (‘Введите радиус меньшей окружности ‘);

readln (а);

write (‘Введите координаты центра ‘);

readln (X, Y);

DV:=detect;

InitGraph (DV, DM, ‘..\BGI’);

SetBkColor (7);

while R>=a do

begin

SetColor (Random(15));



Circle (X, Y, R);

R:=R-m;


end;

readln;


CloseGraph;

End.


Примечание. Здесь применена процедура Randomise, которая инициализирует генератор случайных чисел. Значения же случайных чисел можно получить с помощью функции Random (Х), где Х - параметр, указывающий диапазон значений случайного числа. Оно изменяется в пределах [0,Х[. Результат в этом случае будет типа Word. Если параметр Х не задан, то результат буде типа real в пределах [0.0,1.0[.

Задачи для самостоятельного решения


1. Составить программу, перемещающую отрезок заданной длины слева направо. Имитация движения осуществляется закраской цветом фона линии на предыдущем шаге и построением ее по новой координате Х на следующем шаге.

2. Составить программу, перемещающую отрезок заданной длины сверху вниз.

3. Составить программу, перемещающую отрезок заданной длины из левого верхнего угла в правый нижний, постепенно его увеличивая.

4. Нарисовать веер, состоящий из секторов круга, разукрашенных разным цветом.

5. Нарисовать окружность, меняющую цвет заданное число раз.

6. Изобразить движущуюся окружность заданного радиуса и цвета.

7. Изобразить движение выбранной Вами фигуры.

8. Изобразить движение грузовика.

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

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

11. Составьте программу “Растущая ель”. Рост ели имитируется добавлением к нижнему основанию треугольника (кроне ели) линии на одну точку шире основания как слева, так и справа. К основанию ствола добавляется прямая линия. Программа прекращает работу при увеличении высоты дерева вдвое.

12. Составьте программу “Рост лиственного дерева”. Рост кроны изображается добавлением окружностей.

13. Нарисуйте действующую модель часов с кукушкой. Часы должны тикать, кукушка куковать.

14. Нарисуйте движение маятника.

15. Нарисуйте движение фигуры, используя уже имеющийся файл с программой из темы “Операторы графики”.

Занятие III

Тема. Контрольная работа

1. Запишите конструкцию цикла с предусловием. В каких случаях применяется цикл с предусловием?

2. Запишите правильную структуру последовательности операторов:

a:=1; b:=1;

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

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

3. Запишите правильную структуру последовательности операторов. Какими будут значения переменных а и b после выполнения операторов:

a:=1; b:=1;

while a<=8 do а:=a+1; b:=b+1

4. Запишите правильную структуру последовательности операторов. Определите значение переменной s после их выполнения.

а) s:=0; i:=0; while i<5 do Inc(i);s:=s+100 Div i;

b) s:=0; i:=0; while i>1 do begin s:=s+100 Div i; Dec(i) End;

5. Дана последовательность операторов, вычисляющих факториал f числа n, которая содержит пять ошибок. Найдите эти ошибки, предварительно записав операторы в правильном виде.

k:=1; f:=0;

while k

k:=k+1,


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

т.е. n!=1*2*3*...*(n-2)*(n-1)*n

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

p:=n;


while p>=0 do

begin


a:=a+p Mod 10;

p:=p Div 10

end;

7. Ниже представлен фрагмент программы вычисления количества цифр в заданном натуральном числе. Найдите и исправьте в нем ошибки.



8. Каким условиям должны удовлетворять значения переменной k, чтобы следующие циклы были бесконечны:

while c<0 do c:=c+k;

while k<>0 do k:=1+k;

while k<>0 do k:=k-2;

Подготовьтесь объяснить учителю их решения.

Занятие IV

Тема: Цикл с постусловием repeat.

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

Иногда при решении задач возникает необходимость выполнить тело цикла хотя бы один раз, а потом исследовать условие повторять ли его еще раз. Эту задачу выполнит другой вид цикла Repeat.

repeat повторяй

операторы операторы



until <условие>; до тех пор, пока условие не будет верным

Есть небольшое отличие в организации цикла repeat по сравнению с while: для выполнения в цикле repeat нескольких операторов не следует помещать эти операторы в операторные скобки begin ... end. Зарезервированные слова repeat и until действуют как операторные скобки.

Конструкция repeat ... until работает аналогично циклу while. Различие заключается в том, что цикл while проверяет условие до выполнения действий, в то время как repeat проверяет условие после выполнения действий. это гарантирует хотя бы одно выполнение действий до завершения цикла.

Например,

a) repeat b) repeat

read (Number); i := i+1;

Sum := Sum+Number; writeln (Sqr(i))

until Number=-1 until Number=-1



Задача. Определить, является ли введенное число простым.

Алгоритм решения этой задачи будет следующий. При помощи операции mod проводим проверку всех целых чисел от 2 до введенного числа Number . Мы проверяем является ли очередное проверяемое число делителем нашего числа (значит, остаток от деления введенного числа на проверяемое число равен нулю). Если такой делитель найден, значит, цикл досрочно завершает свою работу на некотором i-том шаге. Если делитель не найден, значит цикл проверил все числа и значение переменной цикла i будет равно конечному значению, т.е. Number. Поэтому, после записи цикла следует анализ значения переменной i и выводится соответствующее сообщение.



Примечание. Напомним, что простым называется число, которое не имеет делителей кроме 1 и самого себя.

Цикл не может продолжаться бесконечно, так как любое число всегда делится само на себя.

Program Prostoe;

Uses


Crt;

Var


i, {возможный делитель}

Number : integer; {исследуемое число}

Begin

ClrScr;


writeln (‘Какое число должно быть проверено? ‘);

read (Number);

i := 1;

repeat


i := i+1;

until Number mod i = 0;

if Number=i

then


writeln (Number,’ является простым‘)

else


writeln (Number,’ делится на ‘,i);

readln;


End.

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



Задание. Выберите две задачи, решенных Вами с помощью цикла с предусловием, и решите их с помощью цикла с постусловием.

Задачи для самостоятельного решения


1. Составьте программу для определения N!-M!

N! = 1*2*3*4*.........*n

2. Запросить имя пользователя и напечатать "Привет, Вася!" 10 раз. (если Вася – имя пользователя)

3. Программа должна вычислять произведение двух чисел и спрашивать завершать программу или нет, если нет то продолжать запрашивать данные вычислять произведение и печатать его.

4. Вывести на печать все трёхзначные натуральные числа, сумма цифр которых равна заданному числу N. (Операции div и mod не использовать.)

5. Составить программу, печатающую все простые числа, не превосходящие данного числа.

6. Население города увеличивается на 3% каждый год. В 1983 году население города составляло 65000. Напишите программу, которая выведет на экран предсказываемую численность населения города в каждом году вплоть до 1999г.

7. Найдите все натуральные числа от 1 до 1000, кратные 3.

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

9. Составить программу запроса пароля пока не будет введен пароль верно. В программе предусмотреть счетчик неправильных вводов пароля.

10. Произведение N первых нечетных чисел равно р. Сколько сомножителей взято?

11. Числа Фибоначчи (fn) определяются формулами:

f0=f1=1; fn=fn-1+fn-2 при n=2,3,...

Cоставить программу:

а) определения f - 40-е число Фибоначчи;

б) поиска f - первого числа Фибоначчи, большего m (m>1);

в) вычисления S - суммы всех чисел Фибоначчи, которые не превосходят 1000.

12. Самостоятельно придумать и решить задачу на применение цикла с постусловием.



Занятие V


Тема: Работа с клавиатурой. Стандартные процедуры read и readLn. Стандартные функции readKey и KeyPressed; их применение в циклах.

Это занятие мы посвятим вопросам программированию обменов с клавиатурой компьютера. Турбо Паскаль содержит несколько простых и ясных средств, которые позволяют организовать эффективное управление программы посредством клавиатуры.

Самая простая и часто применяемая техника организации приема информации основывается на использовании уже знакомых Bам процедур read и readln. Расширим знания о них. Эти процедуры работают со стандартным входным файлом, который отождествлен с “консолью”, т. е. с клавиатурой и экраном дисплея. На практике это означает, что информация, введенная с клавиатуры, помимо обработки процедурами, будет отображаться на экране.

Удобством указанных процедур является автоматическое преобразование ими вводимой цепочки символов в значение заданного типа. Так, если в разделе описания переменных имеется описание вида

Var

Chislo : integer;



то выполнение оператора readln (Chislo) будет происходить следующим образом. Программа будет приостановлена в ожидании ввода с клавиатуры символов, изображающих целое число. После ввода этих изображений они будут автоматически преобразованы в соответствующие двоичные значения и присвоены переменной Chislo. Аналогично организован прием значений действительного, символьного и строкового типа. Если read(readln) не может выполнить преобразования, то генерируется ошибка № 106 – Invalid numeric format (Неверный формат числовых данных) и выполнение программы прекращается. Это является стандартной реакцией, которую выполняет программа, взявшая на себя обработку ошибок. Мы вернемся еще к обработке ошибок, вызванных некорректным вводом, в теме “Процедуры и функции”, где научимся правильно составлять и использовать вспомогательные подпрограммы. А пока приведем пример применения этих процедур ввода при организации циклов.

Program Useread;

Var

X, Y : Byte;



Stop : String;

Begin


TextBackGround;

Randomize;

repeat

X:=Random (76);



Y:=Random (23);

GoToXY (X, Y);

TextColor (Random(15));

write(‘***’);

X:=1;

Y:=24;


write (‘Для остановки программы наберите “Стоп“‘);

write (‘Для продолжения – любую клавишу ‘);

readln(Stop);

until (Stop=‘Стоп‘) or (Stop =‘стоп‘);

readln;

End.


Примечание. Здесь использованы следующие процедуры:

GoToXY (X, Y:Byte) - перемещает курсор к элементу экрана с заданными координатами, учитывая, что размер экрана в текстовом режиме 25 строк по 80 символов.

TextBackGround (Color : Byte) – задает цвет фона.

TextColor (Color : Byte) – задает цвет символов.

Однако, несмотря на простоту и удобство, стандартные процедуры read и readln не обеспечивают всеж потребностей, возникающих при работе с клавиатурой. Их важнейший недостаток в том, что вместе с приемом символов они выполняют их отображение на экран (так называемое “эхо на монитор”). В большинстве случаев это либо не нужно, либо недопустимо. Например, если программа реализует некоторый оконный интерфейс, то вывод вводимых символов испортит изображение. Кроме того, они рассчитаны только на ввод относительно небольшого подмножества символов (буквы, цифры, знаки препинания) и частичного использования специальных клавиш (например, Backspace для отмены только что введенного символа). Эти процедуры не могут распознать нажатие функциональных или редактирующих клавиш и их сочетаний с управляющими клавишами Ctrl, Alt, Shift. В силу указанных причин процедуры read и readln редко используются в серьезных программах.

Стандартная функция readKey


Более универсальным средством взаимодействия с клавиатурой является стандартная функция readKey из системного модуля Crt. Функция вызывается без параметров, возвращает значение символьного типа и работает следующим образом. Организуется задержка выполнения с ожиданием нажатия клавиши. После того, как нажатие произведено, функция завершает работу, возвращая код нажатой клавиши. Полученное значение можно использовать далее в программе. Тривиальный пример работы с функцией readKey, не требующий комментариев, может выглядеть так:

Program UsereadKey;

Uses

Crt;


Var

Sym : Char;

Begin

ClrScr;


while true do

begin


write (‘Введите букву - ‘);

Sym := readKey;

writeln (‘Вы ввели букву - ‘, Sym);

if Sym = ‘q’

then

Exit


end

End.


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

Функция readKey не отображает введенный символ на экран, благодаря чему она широко используется для организации управления в различных диалоговых программах. В дополнение к этому readKey позволяет отслеживать нажатие более широкого множества клавиш, опознавая функциональные и редактирующие клавиши и их сочетания с управляющими клавишами Ctrl, Alt, Shift.

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

В основной набор входят клавиши букв, цифр, разделителей и знаков препинания, их комбинации с клавишей Shift (или, что то же самое, при включенном переключателе CapsLock), а также клавиши Tab, BackSpace, Enter и Esc. Если нажата одна из перечисленных клавиш, то readKey возвратит обычный ASCII-код соответствующего символа.

В расширенном наборе содержатся некоторые (не все) клавиши из основного набора в комбинации с клавишами Ctrl и Alt, а также функциональные и редактирующие клавиши. Если нажимается одна из клавиш расширенного набора, то функция readKey возвращает символ с кодом 0 (его представление в программе – chr(0) или #0). В этом случае повторное обращение к readKey вернет код клавиши из расширенного набора.

Коды клавиш из основного и расширенного наборов в виде, удобном для включения в Турбо Паскаль-программы, приведены в приложении.

Схема использования функции readKey для общего случая может выглядеть так:

Program UsereadKey2;

Uses

Crt;


Var

Sym : Char;

Begin

ClrScr;


while true do

begin


write (‘Нажмите клавишу‘);

Sym := readKey;



if Sym <> #0

then


begin {основной набор}

case Sym of

#8 : writeln (‘Вы нажали BackSpace‘);

#9 : writeln (‘Вы нажали Tab‘);

#13 : writeln (‘Вы нажали Enter‘);

#27 : writeln (‘Вы нажали Esc‘);

else

writeln (‘Вы ввели символ ‘,Sym);



end;

if Sym = #27

Then

Exit


end

else

begin {расширенный набор}



Sym := readKey;{повт. чтение: берем расширенный код}

writeln (‘Вы нажали клавишу с кодом ‘, Ord (Sym)));

end

end


End.

Большинство прикладных диалоговых программ использует описанную технику взаимодействия с клавиатурой. Однако встречаются случаи, когда возможностей функции readKey оказывается недостаточно. На самом деле функция readKey воспринимает нажатия не всех клавиш: достаточно попробовать, запустив вышеприведенную программу, нажать клавиши F11, F12, ввести комбинацию Alt+Esc и т.д. Тому, кто желает более детально изучить работу этой функции, предлагаем самостоятельно найти в книгах по Турбо Паскалю этот материал. А мы ограничимся вышесказанным.


Стандартная функция KeyPressed


Второй базовой функцией взаимодействия с клавиатурой является функция KeyPressed. В отличие от readKey, она предназначена не для приема кода нажатой клавиши, а для простой проверки, была ли нажата какая-либо клавиша. Эта функция вызывается без параметров и возвращает значение булевого типа: True, если было нажатие, и False в противном случае.

Важно понять, что KeyPressed не производит никаких действий с кодом нажатой клавиши, но код может быть далее прочитан функцией readKey, например,

. . .

if KeyPressed



then

S := readKey;

. . .

Cоотношение этих функций станет более понятным, если рассмотреть их внутреннюю организацию несколько подробнее. В системной области DOS имеется небольшой буфер, в который операционная система помещает коды нажатых клавиш. буфер организован в виде очереди, причем помещение кодов производится в ее хвост, а считывание из головы. Таким образом, каждое обращение к функции readKey извлекает из головы очереди один содержащийся там код. Если буфер пуст, то организуется задержка выполнения до тех пор, пока в нем не появится код ( появление кода соответствует нажатию клавиши). Если же к моменту вызова readKey нажатие уже произошло, то есть буфер содержит хотя бы один код, то никакой задержки не будет. Буфер очень невелик и рассчитан на хранение максимум 15 кодов, что соответствует 15 нажатиям. Кстати говоря, иногда встречается такая ситуация, когда та или иная программа “не успевает” выбирать коды клавиш из буфера (то есть нажатия производятся чаще). Ситуация переполнения буфера индицируется звуковым сигналом, после чего коды вновь нажимаемых клавиш будут пропадать.



Функция KeyPressed не извлекает код из буфера, а только проверяет , пуста ли очередь, и возвращает соответствующее булево значение. Более подробно рассмотрение системных аспектов работы с клавиатурой смотрите в соответствующей литературе.

Используя полученные знания решите выбранные с учителем задачи из нижеприведенного перечня.

1. Составьте программу движения круга вверх, вниз, влево, вправо в зависимости от нажатия клавиш управления курсором.

2. Составьте программу движения заданного слова сверху вниз и обратно, для остановки движения запрограммируйте нажатие какой-либо клавиши.

3. Составьте программу движения человечка, для остановки движения запрограммируйте нажатие какой-либо клавиши..

4. Составьте программу движения маятника, для остановки движения запрограммируйте нажатие какой-либо клавиши.

5. Составьте программу движения бегущей строки.

6. Составьте программу вывода слова на экран и поочередное мерцание его букв.

7. Составьте программу падания букв из введенного слова.

8. Составьте программу случайного вывода звездочек разного цвета на экран, для вывода запрограммируйте нажатие какой-либо клавиши.

9. Составьте программу рисования надувающихся пузырей и их лопания по достижению заданного радиуса.

10. Составить программу для вывода на экран бегущей надписи, например: "Для остановки нажми Ctrl+Stop".

11. Самостоятельно придумайте и решите задачу с применением знаний этого занятия.



Занятие VI

Тема: Цикл со счетчиком.

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

Можно, конечно, циклы со счетчиком моделировать при помощи операторов while и Repeat, но структура цикла со счетчиком проще.

Общая форма записи цикла со счетчиком

for i := A to B do for i := A downto B do

begin begin

. . . . . .

end; end;

Здесь переменная i - управляющая переменная или переменная цикла,

А - начальное значение переменной цикла,

В - конечное значение переменной цикла.

При переходе к обработке оператора цикла for управляющей переменной присваивается заданное начальное значение. Затем в цикле выполняется исполнительный оператор (или составной оператор). каждый раз при выполнении исполнительного оператора управляющая переменная увеличивается на 1 (для for...to) или уменьшается на 1 (для for...downto). Цикл завершается при достижении управляющей переменной своего конечного значения.

Например,

1) for i := 1 to ListSize do

begin

readln (Number):



S := S +Number;

end;


2) for Dlina := 15 downto 1 do

writeln (Sqr(Dlina));

3) for x := 1 to 10 do

for y := 1 to 10 do

writeln (x,’*’,y,’=‘,x*y);

4) for Range := Number+1 to Multi*3 do

writeln (Sqrt(Range));

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

for i := 1 to 10 do

begin


. . .

i := i-1;

. . .

end;


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

Внимание! Следует помнить, что управляющая переменная не может быть типа real.

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

for j := 1 to 0 do

writeln (j);

Однако цикл, представленный в такой форме, распечатает целые числа от единицы до десяти:

for j := 1 to 10 do

writeln (j);

Как можно догадаться, следующий цикл выполняет счет в обратном порядке

for j := 10 downto 1 do

writeln (j);

Часто исполнительная часть одного из циклов For является новым оператором цикла For. Структуры такого рода называются вложенными циклами. При завершении внутреннего цикла управляющая переменная внешнего цикла увеличивается. Повторение этих действий будет продолжаться до вавершения внешнего цикла. Приведенный ниже вложенный цикл печатает пары чисел, начиная от (1,1), (1,2),... и кончая (10,10):

for х:= 1 to 10 do

for у:= 1 to 10 do

writeln (‘(‘,х,’,’,y,’), ’);



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

Занятие VII-VIII


Тема: Самостоятельное решение задач.

Выберите с учителем задачи для решения из предложенного ниже списка.

1. Найдите количество точек с целочисленными координатами попадающих в круг радиуса R.

2. Составить программу, которая распечатывает на экране таблицу умножения.

3. Найдите все трёхзначные числа, равные сумме кубов своих цифр. Учтите, что abc=100a+10b+c

4. Составить программу вывода всех трёхзначных чисел, сумма цифр которых равна данному целому числу. Программа должна печатать именно числа, а не набор цифр.

5. Имитировать на экране работу электронных часов.

6. Напишите программу отгадывания буквы.

7. Задано n троек чисел a,b,c. Определить, сколько из предложенных троек можно использовать для построения треугольника, если a,b,c - длины его сторон. (Известно, что .)

8. Найти сумму целых положительных чисел, больших 20, меньших 100 и кратных 3.

9. Укажите все целые числа, которые увеличатся на 20%, если их цифры записать в обратном порядке.

10.Составьте программу взвешивания продавцом 2,5 кг муки.

11. Составить программу, в которой среди двухзначных чисел печатаются те числа, которые равны сумме своих цифр.

12. Замените буквы цифрами так, чтобы равенство ФАКТ+ФАКТ=НАУКА стало верным. Одинаковым буквам должны соответствовать одинаковые цифры, разным - разные.

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

14. В бригаде, работающей на уборке сена, имеется N косилок. Первая из них работала m ч., а каждай следующая на 10 мин. больше, чем предыдущая. Сколько часов проработала вся бригада?

15. В компьютер вводятся по очереди данные о росте N учащихся класса. Определить средний рост учащихся класса.

16. Составьте программу вычисления степени числа а с натуральным показателем n.

17. Каждая бактерия делится на две в течение одной минуты. В начальный момент имеется одна бактерия. Составьте программу, которая рассчитает количество бактерий на заданное Вами целое значение момента времени.

18. Дана последовательность из N целых чисел. Определить произведение максимального и минимального элементов этой последовательности.

19. Для двух последовательностей из N и M элементов соответственно найти произведение максимального элемента первой последовательности и минимального элемента второй последовательности.

20. Дано целое n>0 и последовательность из n действительных чисел, среди которых есть хотя бы одно отрицательное число. Найти величину наибольшего из отрицательных чисел этой последовательности.



Проверьте себя, ответив на вопросы:

1. Что называется циклом? Приведите пример.

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

3. Какие виды циклов Вы знаете? Почему они имеют такие названия?

4. В теле какого цикла не нужно ставить операторные скобки, даже если выполняется составной оператор?

5. Каким должно быть условие, чтобы тело цикла while ни разу не выполнилось? Почему?

6. Каким должно быть условие, чтобы тело цикла repeat выполнилось один раз? Почему?

7. Каким должно быть условие, чтобы тело цикла for ни разу не выполнилось? Почему?

8. Чему равен шаг изменения параметра цикла в операторе for?

9. Укажите отличительные особенности каждой из конструкций циклов.

10. Будет ли выполняться циклическая часть программы, если логическое выражение в конструкции REPEAT истинно с самого начала?

11. Что такое стоп-код? Когда его применяют?

12. Какие условия предъявляются к переменной цикла?

13. Какого типа должна быть переменная цикла?

14. Может ли переменная цикла использоваться в вычислениях?

15. Что называется шагом? Что означает выражение “шаг равен пяти”?

16. Что происходит на каждом шаге выполнения тела цикла при выполнении оператора Summa:=Summa+Chislo?

17. Какой цикл Вы применяете чаще? Каковы его достоинства и недостатки?

18. Функция ReadKey и ее применение в программах.

19. Функция KeyPressed и ее применение в программах.

20. Какие клавиши входят в основной набор?

21. Какие клавиши входят в расширенный набор? Как обратится к этим клавишам в программе?



22. Что обозначает слово downto в операторе цикла for?