Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Глава 6. Циклические программы



Оператор переходаGOTO. Цикл. Метки

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

Write ('Это ');
Write ('тело ');
Write ('цикла');
Write (' ')

в результате чего на мониторе мы бы увидели:

Это тело цикла Это тело цикла Это тело цикла Это тело цикла....

Большинство языков программирования (в том числе и Паскаль) устроены так, что операторы выполняются в том порядке, в котором они записаны. Это значит, что после оператора Write ('Это ') обязательно выполнится оператор Write ('тело '), а после него - Write ('цикла'), а после него - Write (' '). Все это хорошо. Но нам нужно, чтобы после выполнения оператора Write (' ') Паскаль нарушал этот свой принцип последовательного выполнения операторов и выполнял бы оператор Write ('Это '). Если мы этого добьемся, то дальше все пойдет само собой, так как после Write ('Это ') Паскаль автоматически выполнит Write ('тело ') и так далее до бесконечности.

Если бы операторы Паскаля можно было писать по-русски, то для достижения нашей цели было бы естественно воспользоваться такой конструкцией:

метка m1: Write ('Это ');
Write ('тело ');
Write ('цикла');
Write (' ');
иди к оператору, помеченному меткой m1

Здесь мы видим новый для нас " оператор" ИДИ, который выполняется после Write (' ') и единственная работа которого заключается в том, чтобы заставить компьютер перескочить к выполнению оператора Write ('Это '), помеченного меткой m1.

А вот как этот фрагмент выглядит реально на Паскале:

m1: Write ('Это ');
Write ('тело ');
Write ('цикла');
Write (' ');
GOTO m1

Здесь GOTO- оператор перехода, читается " 'гоуту", переводится " иди к", m1 - метка.

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

Мы пока знаем, что переменная, встречающаяся в программе, должна быть описана выше BEGIN после слова VAR. Метки, встречающиеся в программе, тоже должны быть описаны выше BEGIN после слова LABEL (читается " лэйбл", переводится " метка" ).

Вот наша программа полностью:

LABEL m1;
BEGIN
m1: Write ('Это ');
Write ('тело ');
Write ('цикла');
Write (' ');
goto m1
END.

Если вы уже запустили эту программу, то через некоторое время перед вами должен встать жизненно важный вопрос – как же ее остановить? Для этого достаточно прочесть параграф «Выполнение программы» из части IV. Вот вкратце, что вам нужно оттуда знать:

Для прерывания работы программы (в том числе и зациклившейся) существует комбинация клавиш Ctrl-Break (имеется в виду, что, удерживая нажатой клавишу Ctrl, вы должны щелкнуть по клавише Break). На экран возвращается окно редактора. Строка программы, на которой она была прервана, выделяется полосой белого цвета. Если вы снова запустите программу, она продолжит работу с прерванного места. Чтобы начать сначала, уберите полосу с экрана клавишами Ctrl-F2.

Группа операторов, выполняющихся многократно, называется телом цикла. У нас это все операторы, начиная с Write ('Это ') и кончая GOTO m1.

Пример программы:

LABEL 8;
VAR a, k: Integer;
BEGIN
k: =6;

a: =100;

goto 8;

a: =a+k;

k: =2*k;

WriteLn(a);

8: a: =a+1;

k: =k+10;

WriteLn(k, ' ', a);

END.

Эта программа напечатает 16 101. Операторы выполняются в такой последовательности:

k: =6;

a: =100;

goto 8;

a: =a+1;

k: =k+10;

WriteLn(k, ' ', a);

А операторы a: =a+k; k: =2*k; WriteLn(a) выполнены не будут вообще, несмотря на то, что написаны.

Задание 30: Определить без компьютера, что будет печатать программа:

LABEL m1, met5;
VAR n, k: Integer;
BEGIN
n: =10;

k: =0;

WriteLn('Считаем зайцев' );

met5: Write(n);

n: =n+k;

goto m1;

n: =n+1;

m1: Write(' зайцев ');

ReadLn;

k: =k+1;

goto met5;

WriteLn('Посчитали зайцев')

END.

 

А теперь, уважаемый читатель, нам с вами пришла пора снова отвлечься от программирования и расширить свои знания о работе на компьютере. Сейчас вам необходимо проделать то, что сказано в части IV в параграфе «Работа с несколькими окнами» и пункте «Работа с окнами пользователя и отладчика» параграфа «Исправление ошибок. Отладка программы».

 

 

Задания 31-33:

Написать программы для выполнения следующих заданий:

31) Бесконечно печатать букву А: ААААААААААА.....

32) Бесконечно печатать 1000 999 998 997 996......

33) Бесконечно печатать 100 50 25 12.5.... с 8 десятичными знаками.

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

Выход из цикла с помощью if

Интересно рассмотреть применение оператора goto внутри операторов if или case.

Задача: При помощи цикла напечатать на экране:

Начало счета 3 5 7 9 Конец счета

 

Вот три варианта программы. Первый – самый простой, а второй и третий нам понадобятся в дальнейшем.

 

1 ВАРИАНТ 2 ВАРИАНТ
LABELm; VAR f: Integer; BEGIN Write('Начало счета '); f: =3; m: Write(f, ' '); f: =f+2; if f< =9 then goto m; Write(' Конец счета') END. LABELm1, m2; VAR f: Integer; BEGIN Write('Начало счета '); f: =3; m1: Write(f, ' '); f: =f+2; if f> 9 then goto m2 else goto m1; m2: Write(' Конец счета') END.
   

 

Вот в каком порядке выполняются операторы программы первого варианта:

Write('Начало счета ') f: =3 Write(f, ' ') {печатается 3} f: =f+2 {f становится равным 5} if f< =9 goto m Write(f, ' ') {печ. 5} f: =f+2 {f = 7} if f< =9 goto m Write(f, ' ') {печ. 7} f: =f+2 {f = 9} if f< =9 goto m Write(f, ' ') {печ. 9} f: =f+2 {f = 11} if f< =9 Write(' Конец счета')

Здесь оператор goto выполняется три раза. На четвертый раз условие f< =9 оказывается ложным и поэтому выполняется не goto, а следующий за if оператор Write(' Конец счета'), то есть программа выходит из цикла и завершает свою работу.

3 ВАРИАНТ
LABELm1, m2, m3; VAR f: Integer; BEGIN Write('Начало счета '); f: =3; m1: if f< =9 then goto m3 else goto m2; m3: Write(f, ' '); f: =f+2; goto m1; m2: Write(' Конец счета') END.

Задания 34-36:

34) Напечатать 1 2 3 4... 99 100 99... 3 2 1.

35) " Таблицы Брадиса" - вычислить и напечатать с 6 десятичными знаками квадраты чисел 0.000 0.001 0.002 0.003... 0.999 1.000.

36) Для х=2700, 900, 300, 100... и т.д. вычислять и печатать y=x/4 + 20 и z=2y+0.23 до тех пор, пока yz не станет меньше 1/х.

Совет: Теперь, когда вы владеете отладочным режимом, смело применяйте его всякий раз, когда ваша программа не хочет делать то, что нужно. Зачем ломать голову над непослушной программой? – Берегите серое вещество, жмите F7!

Оператор цикла repeat

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

В Паскале - три оператора цикла: repeat, while и for. Первым изучим оператор repeat.

Конструкция repeat..... untila+2> 3*b читается " ри'пит.....ан'тил...", а переводится " повторяй......до тех пор, пока a+2 не станет больше 3*b".

Составим с использованием оператора repeat программу решения задачи о печати чисел 3 5 7 9 из предыдущего параграфа. Для того, чтобы точно определить работу оператора repeat, приведем ее параллельно со вторым вариантом программы решения этой задачи из того же параграфа:

 

2 ВАРИАНТ ВАРИАНТ С REPEAT
LABEL m1, m2; VAR f: Integer; BEGIN Write('Начало счета '); f: =3; m1: Write(f, ' '); f: =f+2; if f> 9 then goto m2 else goto m1; m2: Write(' Конец счета') END. VAR f: Integer; BEGIN Write('Начало счета '); f: =3; repeat Write(f, ' '); f: =f+2; until f> 9; Write(' Конец счета') END.

Порядок работы обеих программ совершенно одинаков, так что можно считать слово repeat заменой метки m1, а конструкцию until f> 9 считать заменой оператора if f> 9 then goto m2 else goto m1.

Синтаксис оператора repeat:

Repeat оператор; оператор;...; оператор until условие

Вкратце работу оператора repeat можно описать так: Повторяй выполнение операторов, стоящих между словами repeat и until, до тех пор, пока не станет истинным условие.

Более подробно работа оператора repeat описывается так:

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

Задача: Компьютер предлагает человеку ввести слово, после чего распечатывает это слово, снабдив его восклицательным знаком. Затем снова предлагает ввести слово и так до тех пор, пока человек не введет слово " Хватит". Распечатав его с восклицательным знаком, компьютер отвечает " Хватит так хватит" и заканчивает работу.

Придумаем строковую переменную, в которую человек будет с клавиатуры вводить слово. Назовем ее Slovo.

VAR Slovo: String;
BEGIN
repeat
WriteLn('Введите слово');
ReadLn(Slovo);
WriteLn(Slovo, '! ')
until Slovo='Хватит';
WriteLn('Хватит так хватит')
END.

Задание 37: Усложним эту задачу. Пусть компьютер перед распечаткой каждого слова ставит его порядковый номер.

Задание 38-39: Выполнить с применением оператора repeat последние два задания из предыдущего параграфа.

Задание 40: Если камень бросить горизонтально со 100-метровой башни со скоростью v=20м/с, то его расстояние от башни по горизонтали (s) будет выражаться формулой s=vt, где t – время полета камня в секундах. Высота над землей h будет выражаться формулой h=100 – 9.81t2/2. Вычислять и печатать t, s и h для t=0, 0.2, 0.4, 0.6 и так далее до тех пор, пока камень не упадет на землю.

Оператор цикла while

Синтаксис оператора while:

WHILE условие DO оператор

Слово while читается " вайл", слово do - " ду", вся конструкция переводится так - Пока условие истинно, делай оператор. Например, while a> b do b: =b+1.

Работает оператор while так:

Сначала компьютер проверяет истинность условия, стоящего после слова while. Если условие истинно, то выполняется оператор, стоящий после do. Затем снова проверяется истинность условия и в случае истинности снова выполняется этот оператор. И т.д. Если условие ложно, то оператор while прекращает свою работу и компьютер переходит к выполнению следующего оператора.

Оператор, стоящий после while, вполне может быть составным, поэтому тело цикла у оператора while, так же как и у оператора repeat, может состоять из многих операторов.

Решим при помощи while ту же задачу о печати чисел 3 5 7 9, что в предыдущем параграфе решили с помощью repeat. Для того, чтобы точно определить работу оператора while, приведем программу ее решения параллельно с третьим вариантом программы из 6.2:

3 ВАРИАНТ ВАРИАНТ С WHILE
LABELm1, m2, m3; VAR f: Integer; BEGIN Write('Начало счета '); f: =3; m1: if f< =9 then goto m3 else goto m2; m3: Write(f, ' '); f: =f+2; goto m1; m2: Write(' Конец счета') END. VAR f: Integer; BEGIN Write('Начало счета '); f: =3; while f< =9 do begin Write(f, ' '); f: =f+2; end; Write(' Конец счета') END.

Как видите, здесь после do стоит составной оператор begin Write(f, ' '); f: =f+2; end. Последовательность исполнения операторов и проверки условий в обеих программах совершенно аналогичны.

 

Типичная ошибка начинающих – небрежное обращение со знаками сравнения. Многие не видят большой разницы в том, как записать – while f< =9 или while f< 9, а затем, «недополучив» результат, удивляются, почему. И здесь лучшим средством для понимания является отладочный режим. Попробуйте ошибочный вариант последней программы (с while f< 9) выполнить в пошаговом режиме с использованием окон пользователя и отладчика. Для этого введите в окно отладчика две вещи: переменную f и выражение f< 9 (оно может иметь только два значения: true - истина и false - ложь, другими словами – «условие выполнено» и «условие не выполнено»).

 

Задание 41: Вычислять с использованием while квадратные корни из чисел 900, 893, 886, 879 и т.д. до тех пор, пока это можно делать.


Поделиться:



Последнее изменение этой страницы: 2017-03-17; Просмотров: 438; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.027 с.)
Главная | Случайная страница | Обратная связь