ВЫХОД ИЗ ЦИКЛА (LEAVE) И ВЕТВЛЕНИЕ (BRANCH)
Существует способ написания цикла со счетчиком, при котором выполнение цикла может закончиться раньше, чем будет достигнуто заданное значение границы. Для этого нужно с помощью слова LEAVE запрограммировать внутри цикла DO изменение условия с «истины» на «ложь». LEAVE заставляет цикл немедленно завершиться1.
Перепишем наше прежнее определение слова СЛОЖНЫЕ-ПРОЦЕНТЫ. Теперь мы не будем запускать цикл ровно 20 раз, а организуем завершение этого цикла либо после его 20-го выполнения, либо после удвоения денежной суммы — в зависимости от того, какое из событий произойдет раньше.
Добавим следующую фразу: 2000 > IF LEAVE THEN
как в следующем тексте:: УДВОЕНО ( вклад процент — ) SWAP 21 1 DО CR ." Год " I 2 .R 3 SPACES 2DUP R% + DUP ." Сумма " . DUP 2000 > IF CR ." Более чем удвоено через" I . ." лет " LEAVE THEN LOOP 2DROP ;
1 Для пользователей систем, разработанных до принятия Стандарта-83. Ранее слово LEAVE вызывало завершение цикла при выполнении очередного слова LOOP или +LOOP.
В результате получим: 1000 6 УДВОЕНО
Год 1 Сумма 1060 Год 2 Сумма 1124 Год 3 Сумма 1191 Год 4 Сумма 1262 Год 5 Сумма 1338 Год 6 Сумма 1418 Год 7 Сумма 1503 Год 8 Сумма 1593 Год 9 Сумма 1689 Год 10 Сумма 1790 Год 11 Сумма 1897 Год 12 Сумма 2011
Более чем удвоено через 12 лет
В одном из упражнений в конце главы вам предлагается переработать слово УДВОЕНО таким образом, чтобы оно выбирало из стека в виде аргументов норму процента и начальную сумму и выполняло бы вычисления до получения удвоенной начальной суммы, после чего слово LEAVE завершало бы эти вычисления.
Слово LEAVE ведет себя, как и положено при использовании его во вложенных операторах цикла DO: оно просто «покидает» цикл, в котором находится. В одном цикле может употребляться несколько слов LEAVE. Цикл завершается при встрече первого из них.
Согласно Стандарту-83, любой код, размещенный после сочетания IF LEAVE THEN, не будет исполнен на последнем шаге.
Как правило, лучше применять это сочетание в качестве последнего выражения перед LOOP.
Еще одно предупреждение: как и все условные операторы, слово LEAVE должно находиться в том же определении, что и условия, по которым оно покидает цикл (DO и LOOP). Запомните, что нельзя помещать LEAVE в определении слова, вызываемого из цикла. Приведем пример неправильного использования слова LEAVE:: ВЫБОР ВАРИАНТ1 IF ВАРИАНТ2 LEAVE THEN ; : НЕПРАВИЛЬНЫЙ-ЦИКЛ 1000 0 DO ВЫЧИСЛЕНИЯ ВЫБОР LOOP ;
Здесь LEAVE используется вне цикла. Эти определения будут скомпилированы, но при выполнении приведут к непредсказуемому результату (возможно, даже к разрушению системы).
Два полезных приема. PAGE и QUIT. Для того чтобы придать более аккуратный вид данным, выводимым циклически (таким как таблицы и геометрические фигуры), перед выводом информации вам, возможно, придется очистить экран с помощью слова PAGE (СТРАНИЦА). Вы можете использовать слово PAGE непосредственно всякий раз, когда нужно очистить экран
PAGE ПРЯМОУГОЛЬНИК
При этом экран будет очищаться перед выводом прямоугольника, который вы определили ранее. А можно поместить слово PAGE один раз в начало определения:: ПРЯМОУГОЛЬНИК РAGЕ 256 0 DO I 16 MOD 0= IF CR THEN ." *" LOOP ;
Если вы не хотите, чтобы по завершении вычисления на экране появилось приглашение ok, примените слово QUIT (ВЫЙТИ). Вы можете использовать QUIT непосредственно:
ПРЯМОУГОЛЬНИК QUIT
а можете сделать его последним словом определения (перед точкой с запятой).
Ниже дается перечень слов Форта, приводимых в настоящей главе. DO ... LOOP DO: ( граница Организация цикла со счетчиком по задан- индекс -- ) ному диапазону индексов. LOOP: ( -- )
DO ... +LOOP DO: ( граница Аналогично DO ... LOOP . Только к ин- индекс — ) дексу на каждом шаге добавляется значение +LOOP: ( n -- ) n (а не как всегда единица ).
LEAVE ( -- ) Немедленное завершение выполнения цикла LOOP или +LOOP. (Используетея только внутри цикла.)
BEGIN ... UNTIL: ( ? -- ) Организация цикла с условием, который за- UNTIL вершается, когда ? принимает значение истина.
BEGIN ххх WHILE: ( ? -- ) Организация цикла с условием, причем ххх WHILE ууу выполняется всегда, а ууу—только REPEAT если ? истинно.
.R ( u ширина- Вывод числа одинарной точности без зна- поля -- ) кa. Число выровнено справа по границе поля.
PAGE ( -- ) Чистка экрана дисплея и установка курсора в верхний левый угол.
QUIT ( -- ) Завершение выполнения текущей задачи и возврат управления на терминал.