В PostScript предусмотрено два других способа управления итерациями. В одном из них оператор loop выталкивает из стека верхний элемент в качестве процедуры и затем неоднократно выполняет ее. Для предотвращения бесконечной итерации должен быть способ выхода из нее. Команда exit выводит процесс за пределы самого внутреннего активного цикла, никак не влияя на состояние стека. Операторы loop совместно с exit обычно используются тогда, когда число итераций, которое необходимо
1030
Приложение Г. Введение в PostScript*
выполнить, не может быть подсчитано заранее. Процесс итерации заканчивается, когда какое-нибудь
условие вызывает выполнение оператора exi t.
Пример
Допустим, мы хотим нарисовать на странице последовательность прямоугольников со случайным расстоянием между ними, как показано на рис. Г.22. После того как каждая полоска нарисована, к координате х добавляется случайная величина. Этот процесс продолжается неизвестное число раз - до тех пор, пока координата х не достигнет правого края страницы.
Ниже приведен фрагмент кода, рисующий такой ряд полосок, причем для выхода из цикла используется оператор exi t:
/xpos 10 def % initial x position % начальная позиция x /drawBar
{ 0 90 rlineto % assumes CP is at lower left corner предполагается, что CP в нижнем левом углу 13 0 rlineto О -90 rlineto
closepath fill} def % the main loop to draw the row of bars
% главный цикл для рисования ряда полосок
} /xpos xpos 16 add % make increment at least 16
% задаем шаг не менее 16
rand 30 mod add def % plus a random amount; set xpos
% добавляем случайную величину и устанавливаем xpos
xpos 600 gt {exit} if X escape if xpos > 600
% выходим, если xpos > 600
xpos 500 moveto drawBar % draw next bar
% рисуем следующую полоску
}loop
showpage
i4J jj Jfl, JUL t jyiJJtttJt I
.................................................................................................................шш......r.i
Рис. Г.22. Случайная строка из полосок Третий путь контроля числа повторений состоит в использовании цикла for. Когда число итераций известно заранее, цикл for предоставляет некоторый дополнительный контроль над итерациями. Оператор for поддерживает «переменную-счетчик», контролирующую итерации. Эта переменная не имеет настоящего имени; как мы увидим, она просто проталкивается в стек при каждой итерации данного цикла. Для удобства здесь мы будем называть ее CV (counting variable). Для работы с циклом for в стеке предполагается наличие четырех параметров: