Начальный курс программирования на языке Форт

ВЛОЖЕННЫЕ ЦИКЛЫ


Ранее мы определили слово с именем ПРОИЗВЕДЕНИЯ, в котором содержался цикл DO. При желании можно было бы поместить слово ПРОИЗВЕДЕНИЯ внутрь другого цикла DO, например: : ТАБЛИЦА CR 11 1 DO I ПРОИЗВЕДЕНИЯ LOOP ;

В результате мы получили бы таблицу умножения в таком виде: 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 и т.д. 10 20 30 40 50 60 70 80 90 100

так как I во внешнем цикле обеспечивает аргумент для слова ПРОИЗВЕДЕНИЯ.

Циклы тоже можно вкладывать один в другой только в пределах одного определения: : ТАБЛИЦА CR 11 1 DO 11 1 DO I J * 4 .R LOOP CR LOOP ;

Обращаем ваше внимание на тот случай, когда во внутреннем цикле находится фрагмент I J *

Если I копирует индекс того цикла, внутри которого само расположено, то слово J копирует индекс следующего внешнего цикла. Поэтому выражение I J * приведет к перемножению двух индексов. Таким образом мы создаем значения нашей таблицы.

Что можно сказать теперь о выражении 4 .R

Это всего лишь видоизмененный оператор, который используется для печати чисел в табличной форме с выравниванием их по вертикали. Цифра 4 определяет заданное число позиций в столбце. Новую таблицу можно теперь распечатать так: 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 и. д.

Под каждое число выделено четыре позиции независимо от того, сколько цифр содержится в данном числе. Слово .R означает «вывод числа, выравненного вправо».

+LOOP

Если вы хотите, чтобы значение индекса на каждом шаге выполнения цикла изменялось не на единицу, а на некоторую другую величину, то вместо LOOP можно использовать слово +LOOP. Для этого слова в стеке должно находиться число, значение которого является приращением индекса на каждом шаге. Например, в определении : ЧЕРЕЗ-ПЯТЬ 50 0 DO I . 5 +LOOP ;

индекс всякий раз будет увеличиваться на пять, что приведет к следующему результату:ЧЕРЕЗ-ПЯТЬ 0 5 10 15 20 25 3В 35 40 45 ок

(Представляете, о каких гигантских шагах идет речь.)

Отрицательное приращение заставляет цикл выполняться в обратном направлении, например:: СНИЖЕНИЕ -10 0 DO I . -1 +LOQP ;


дает такой результат: СНИЖЕНИЕ 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 ок

Слово +LOOP начнет с нуля и с шагом, равным -1, «пойдет» к финишной черте, пока не пересечет ее. Заметьте, что в этом направлении мы выполняем цикл фактически 11 раз, поскольку финишная черта всегда лежит между значением границы и ее значением  -1 независимо от того, в какую сторону перемещается +LOOP. Завершение же цикла вызывает переход финишной черты.



Приращение может быть получено каким угодно образом, но на каждом шаге выполнения оно должно находиться в стеке. Рассмотрим пример: : ПРИРАЩЕНИЕ ( приращение граница индекс -- ) DO I . DUP +LOOP DROP ;

Внутри этого определения непосредственно нет приращения. Оно будет взято из стека при выполнении слова ПРИРАЩЕНИЕ наряду с границей и индексом. Посмотрите, что происходит в данном случае: 1 5 0 ПРИРАЩЕНИЕ 0 1 2 3 4 ок 2 5 0 ПРИРАЩЕНИЕ 0 2 4 ок -3 -10 10 ПРИРАЩЕНИЕ 10 7 4 1 -2 -5 -8 ок

Наш следующий пример демонстрирует изменение приращения на каждом шаге выполнения цикла: : УДВАИВАНИЕ CR 32767 1 DO I . I +LODP ;

Здесь индекс непосредственно используется в качестве приращения. Начиная с единицы он всякий раз удваивается, как это показано ниже: УДВАИВАНИЕ

1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 ок


Если бы в этом примере аргумент для +LOOP принял хотя бы один раз значение 0, то мы никогда не вышли бы из цикла — получился бы так называемый бесконечный цикл1.



1 Для специалистов. Некоторые Форт-системы, созданные до принятия Стан-дарта-83, включают /LOOP, которое, как и +LOOP, выбирает из стека приращение, но оно должно быть положительным. Это может привести к тому, что индекс превысит значение 32767, скажем, при индексации по адресам или номерам блоков, так как указанные числа принимают только положительные значения в отличие от тех ситуаций, когда выполняются операции над числами со знаком. Слово 4- LOOP, удовлетворяющее Стандарту-83, снимает данную проблему.


Содержание раздела