BETA BASIC
Мы продолжаем печать инструктивных материалов по работе с языком программирования BETA BASIC. Начало - см. стр. 134.
20. Команда: PROC
Структура: PROC имя
Клавиша: 2
См. также DEF PROC, END PROC.
PROC - это сокращение от слова процедура.
Процедуры похожи на GO SUB с именем, но имеют то преимущество, что Вам не надо беспокоиться о том, где в программе находится определение процедуры. Компьютер найдет ее где угодно, при условии, что DEF PROC - первое выражение в строке (это ограничение несколько увеличивает скорость вычислений).
Имя процедуры должно удовлетворять тем же условиям, что и имя переменной. Определение процедуры может иметь длину в сколько угодно строк - оно заканчивается оператором END PROC. Так же, как и DEF FN, DEF PROC игнорируется программой, если они не были вызваны через PROC. Программа в своих вычислениях просто перепрыгивает через них. Все переменные, используемые в основной программе, доступны и для процедуры, а все переменные, которые создает или изменяет процедура, доступны для главной программы.
10 FOR n=1 TO 20:PROC draw square: NEXT n 200 DEF PROC draw square: LET side-RND*20+20 210 PLOT RND*215,RND*135:DRAW side,0:DRAW 0,side 220 DRAW-side,0:DRAW 0,-side:END PROC 230 PRINT "Finished"
Идеальная "структурированная" программа должна содержать серию заданных процедур, каждая из которых выполняет определенную работу и может быть оттестирована независимо. Они вызываются в нужном порядке из основного тела программы, например:
100 PROC Set up board (установить игровое поле) 110 PROC Play game (играть в игру) 120 PROC Show Score (показать счет) 130 STOP
Если процедура не была задана, то использование PROC вызовет сообщение:
W: "Missing DEF FROC" (W: "Отсутствует DEF PROC")
Это же произойдет, если Вы используете END PROC, не задав DEF PROC. исключение составляет тот случай, когда в стеке есть доступный адрес возврата. END PROC не знает, что это не адрес PROC и "благополучно" возвратится к указанной строке. Если Вы забудете дать END PROC, то программа выдаст сообщение:
X: "No END PROC" ^"Отсутствует END PROC")
Программа будет пытаться "перепрыгнуть" через определение процедуры, но не найдет где она кончается.
21. Команда: RENUM
Структура: RENUM // ( начало TO конец) // //LINE новое начало// // STEP шаг//
Клавиша: 4
Просто RENUM используется для перенумерации всей программы таким образом, что номер первой строки равен 10 и интервал между строками также равен 10. Примеры.
RENUM (130 TO 220) - перенумерация указанного блока;
RENUM (130 TO) - перенумерация строк со 130 до конца программы;
RENUM (TO 100) - перенумерация всех строк программы, кроме нулевой, до строки 100 включительно.
Если блок нельзя перенумеровать так, чтобы после его перенумерации строки не "влезли" бы в строки остальной части программы, то Вы получите сообщение:
G: NO ROOM for line" (G: "нет места для строки")
В данном контексте оно имеет несколько иное значение, чем в обычном стандартной Бейсике.
Если Вам надо задать специфический номер первой строки, то используйте LINE. (Это ключевое слово, т.е. набирается не по буквам).
Шаг между строками задается с помощью STEP. Это тоже ключевое слово.
Примеры
RENUM
RENUM LINE 100 STEP 20
RENUM (1540 TO) LINE 2000
RENUM (100 TO 176) LINE 230 STEP 5
Вы понимаете, что после перенумерации могут "пострадать" операторы перехода GO TO или GO SUB. Поэтому БЕТА-БЕЙСИК при перенумерации выявляет такие строки и изменяет их. Вместе с тем, могут быть особые случаи, например когда Вы делаете вычисляемый GO TO.
Сначала программа делает поиск выражений, которые могут нуждаться в перенумерации, например GO TO L*100. Такое выражение может указывать на строку, которую Вы собираетесь перенумеровать. Этот случай может оказаться слишком сложным для обычной процедуры перенумерации, поэтому перенумерация прервется с сообщением:
Y: "TOO hard" (Y: "слишком сложно")
Это дает вам возможность переделать выражение, может быть с использованием оператора ON (см. выше). Можете также на первых порах просто изменить это выражение как-нибудь, чтобы удовлетворить RENUM временно. Например, спрячьте недостойное выражение в кавычки
PRINT "GO TO L*100"
или поставьте перед ним REM
REM GO TO L*100.
После того, как все недопустимые выражения будут спрятаны, дайте еще раз команду RENUM. Теперь будут изменены в программе все ссылки на перенумерованные строки, включая: GO TO, GO SUB, RESTORE, RUN, ON, ON ERROR, TRACE, LIST, LLIST, LINE, DELETE.
Функцию CLOCK это не касается. Ее надо переделать самому! (Это потому, что после CLOCK может быть не только номер строки, но и число, показывающее режим настройки будильника).
Примечание. RENUM организует промежуточную таблицу для хранения данных, которая размещается в экранной области памяти. Она чистится после окончании перенумерации, поэтому не пугайтесь, глядя на экран.
22. Команда: ROLL
Структура:ROLL направление; // X координата, Y координата; ширина, длина//
Клавиша: R
См. также SCROLL
ROLL смещает весь экран или заданное окно на один пиксел вверх, вниз, влево или вправо. Все, что выйдет за границы окна, появится из противоположной границы. Другими словами, команда не уничтожает на экране ничего, она просто переорганизует информацию (в отличие от SCROLL). Направление ROLL задается числом 5,6,7 или 8 после команды. Поскольку каждая команда ROLL выполняет незначительное смещение, то лучше всего ее использовать в цикле. Нарисуйте график (DRAW) или дайте LIST, затем попробуйте: 100 FOR d=5 TO 8: FOR p=1 TO 100 110 ROLL d: NEXT p: NEXT d: STOP
ROLL по диагонали может быть выполнен последовательной подачей ROLL вверх и ROLL вправо.
ROLL для окна экрана вводится подачей после кода направления еще четырех параметров: координат X и Y левого верхнего угла окна (в той же системе координат, что и для PLOT и DRAW), а также ширины окна (в символах) и его длины (в пикселах). Ширина может быть от 1 до 32, а длина от 1 до 176. ROLL может быть очень эффективной командой в играх для организации перемещения объектов или ландшафта. Чрезвычайно интересный, хотя и вызывающий легкое головокружение эффект может быть получен организацией нескольких взаимопересекающихся окон таким образом, что экран начинает двигаться и дергаться в разных направлениях.
Интересный эффект дают следующие программы:
100 LIST:LIST:LIST
110 ROLL 5;0,175;32,88 :ROLL 6;0,175;16,176 120 ROLL 8;0,87;32,88 :ROLL 7;128,175;16,176 130 GO TO 110
или
200 FOR N=1 TO 7:LIST:NEXT N
210 FOR L=1 TO 175:ROLL 5;0,175;32,L:NEXT L
23. Команда SCROLL
Структура: SCROLL // направление//;// X координата, Y координата; ширина, длина//
Клавиша: S
См. также ROLL
SCROLL по синтаксису очень похожа на ROLL. Основное отличие состоит в том, что SCROLL можно использоваться без параметров. В этом случае передвигается целиком весь экран вверх на один символ.
Если после SCROLL дать 5,6,7,8, то весь экран будет смещен на один пиксел в соответствующем направлении. Bсe, что выйдет за пределы экрана, пропадет совсем.
Новый экран, который "вытягивается" с противоположной стороны - чистый.
Можно передвигать информацию в части экрана - в окне. Для этого после команды должны стоять: код направления движения;
- координаты X и Y левого верхнего угла окна (в той же системе, что и для DRAW и
PLOT);
- ширина окна (в единицах символов);
- его длина (в пикселах). SCROLL так же, как и ROLL, широко применяются в играх для создания движущихся изображений. Опробуйте примеры, приведенные для ROLL с командой SCROLL и сравните результат.
А вот пример программы, которая печатает строку и прогоняет ее по экрану:
100 LET A$="A NICE LONG STRING.." (красивая длинная строка)
110 FOR C=1 TO LEN A$
120 PRINT AT 10,31; INK 7; A$(C)
130 FOR P=1 TO 8: SCROLL 5:0,95:32,8: NEXT P
140 NEXT C
150 FOR P = 1 TO 255: SCROLL 5;0,95;32,8: NEXT P
Текст будет печататься символ за символом в одном и том же месте экрана белым цветом INK. Цвет может быть и другим, но он должен совпадать с цветом PAPER. Буквы будут медленно "выплывать" из квадрата, в котором они "невидимы".
Внутренний цикл FOR-NEXT сдвигает символ на одну позицию влево прежде, чем напечатается второй символ.
Строка 150 перемещает текст по экрану.
Примечание:
Если Вам покажется неудобным смешивать координатные системы "PRINT AT" и PLOT, то Вы можете воспользоваться усовершенствованной командой PLOT Бета-Бейсика и заменять строку 120 на:
120 PLOT 248,95; A$ (C)
Этот же принцип может быть использован, чтобы сделать текст привлекательным:
200 DATA "LONG AGO,IN A DISTANT GALAXY"
210 DATA "LOTS MORE TEXT, LOTS MORE..."
300 FOR L=1 TO 2: READ A$
310 PRINT AT 21,0; INK 7; A$
320 FOR P=1 TO 8: SCROLL 7: NEXT P: NEXT L
330 FOR P=1 TO 176: SCROLL 7 : NEXT P
24.Команда: SORT
Структура:
SORT строковый массив или
SORT числовой массив или SORT строковая переменная Клавиша: M
Команда SORT организует строки, числа или буквы в восходящем или нисходящем порядке. Сначала обсудим ее применение со строковыми массивами. Вот программа, генерирующая 100 десятибуквенных случайных строк.
100 DIM A$(100,10) 110 FOR S=1 TO 100:FOR L=1 TO 10 120 LET A$ (S,L)=CHR$(RND*25+65) 130 NEXT L:NEXT S: GO TO 200 140 SORT A$
200 FOR S=1 TO 100:PRINT A$(S): NEXT S
После того, как массив будет сгенерирован, что займет некоторое время, он будет распечатан. Теперь дайте GO TO 140, и он будет отсортирован и вновь распечатан (RUN не давайте). На сортировку уйдет примерно 1/5 секунды. Оно может немного возрасти, если Вы будете использовать более длинные строки. Количество строк более критично. 200 займут 0,7 сек., а 400 - 3 секунды.
Строки сортируются в соответствии с кодами символов. Пробел предшествует "A", а "A", в свою очередь предшествует "а". Если бы в строке 140 было записано SORT INVERSE a$,
то порядок мог бы быть противоположным.
Попробуйте. Можно сортировать и отдельные блоки строк, например первые 20:
SORT A$(1 TO 20)
Команда SORT A$(30 то) выполнит сортировку от 30-ой строки и до конца. Можно выполнять сортировку и не по первому символу. Так, команда
SORT A$()(2 TO)
выполнит сортировку всего массива по второму и последующим символам. Команда SORT дает возможность создавать быстроработающие базы данных. В этом контексте назовем весь массив файлом, а каждую отдельную строку - записью. Области каждой строки могут быть использованы для различных типов информации - это поля. Вам для этого могут понадобиться относительно длинные строки. Файл имен, адресов и других данных, например возраста, может быть организован так, что например первые 20 символов в каждой записи (строке) будут содержать имя персоны, следующие 20 - адрес, а последние - возраст. Поскольку любой возраст укладывается в диапазон от 0 до 255, то можно использовать: LET A$ (S,41);CHR$ age, чтобы поместить возраст в запись. Такое хранение данных несложно и занимает мало памяти.
Предположим, что Вам надо хранить еще что-либо более сложное, например, банковский счет. Если Вы используете: LET A$(S,41 то 46)=STR$ balance,
то информация будет помещена в строку, но она будет выровнена по левому полю, т.е. если вам надо ввести "9", то число "9" запишется в позиции 41, также как и цифра "9" от числа 900. В результате по этому полю не может правильно работать сортировка.
Поэтому вам нужно аккуратно записывать все данные с тем, чтобы десятичные точки располагались в одну колонку, тогда у каждой строки единицы, десятки и сотни будут записаны в одних и тех же позициях. Для этого можно пользоваться форматирующей функцией FN U$:
LET A$(S,41 TO 46)=FN U$("000.000",balance)
Полное описание этой функции Вы найдете, когда прочитаете FN U$, USING, FN C$. Теперь Вы можете сортировать свои записи по возрасту, по счету в банке или в алфавитном порядке.
Обратите внимание на то, что поскольку код "1" меньше, чем код "2", то меньшие числа будут по результатам сортировки размещаться раньше. Можете пользоваться SORT INVERSE, чтобы большие числа шли раньше.
Сортировка работает также с обычными строками и с одномерными массивами. INPUT S$: SORT S:: PRINT S$
Если в INPUT Вы дадите "Fred Bloggs", то на печати получите "BF degglors". Это не
выглядит очень полезным, но это дает возможность работы с числовыми данными, которые наиболее экономично хранятся в качестве строковых переменных. Например; LET S$ (position)=CHR$(data)
Это может также применяться к обычным одномерным или двумерным числовым массивам, которые используют тот же синтаксис, что и строковые массивы. Двумерный числовой массив можно рассматривать как таблицу, в которой первая размерность - ряд, а вторая - столбец.
Сортировка чисел идет в четыре раза медленнее, чем строк, потому что SORT должна проверить два различных числовых формата, а также учесть возможность наличия как положительного, так и отрицательного числа.
25. Команда: TRACE
Структура: TRACE номер строки. Клавиша: T
Эта команда позволяет выполнять отладку Бейсик-программ. Она распечатывает текущую строку, текущее выражение в строке, а также избранные переменные, причем выполняет это с уменьшенной скоростью.
TRACE позволяет выполнять немедленный переход, до начала каких либо вычислений, к специальной подпрограмме. Эта подпрограмма может иметь две переменные (не ключевые слова) line и stat. line - это номер строки. stat - это номер выражения в строке.
Речь идет о строке, выполнение которой сейчас начнется. TRACE отключается во время работы своей подпрограммы, но снова включается после RETURN. Содержание этой подпрограммы - Ваше дело! Например:
9000 PRINT INVERSE 1 ;line; ":"; stat: RETURN
Включите эту процедуру в программу и вставьте инструкцию: TRACE 9000 TRACE вставляется с того места, с которого Вы хотите начать отладку. Если бы хотите отключить TRACE в каком-то месте программы, вставьте TRACE 0.
Использование TRACE дает печать выражений по мере их исполнения в формате, который используют системные сообщения. Чтобы отличить их от системных сообщений, воспользуйтесь оператором INVERSE. Трейсирование отключается после RUN, CLEAR и TRACE 0. Если Вы хотите замедлить процесс, вставьте PAUSE или другое средство по Вашему усмотрению. Переменные также могут выводиться на печать. Если Вам это нужно, то объявите их где-нибудь в начале программы, иначе может быть сообщение "Variable not found" ("переменная не найдена"). Чтобы не перепутать результаты печати от TRACE и результаты печати программы, мы Вам советуем использовать PRINT AT, но при этом надо запоминать место текущей печати. Иначе печать из главной программы все равно будет мешать. Это можно сделать например так: 9000 LET col=PEEK 23688:LET row = PEEK 23689 9010 PRINT AT 0,0; line; ":"; stat:" ","A$ =";A$;" " 9020 POKE 23688,col:POKE 23689,row:RETURN
По этой программе печатается номер исполняемой строки и переменная A$. Пробелы необходимы, чтобы исключить наложение печатаемых данных. Подпрограмма запоминает системные переменные, характеризующие позицию печати с тем, чтобы оно изменялось инструкцией PRINT AT только временно.
26. команда: UNTIL
Структура: UNTIL условие Клавиша: K См. DO и LOOP.
Задает условия выполнения циклов DO-LOOP.
27. Команда USING
Клавиша: U
Пример: PRIRT USING format строка,число.
См. также FN U$
Оператор USING, как и функция FN U$ (см. далее) задают спецификацию формата, в котором должны печататься числа. По желанию вместо USING можно использовать FN U$. Желаемый формат задается строковой переменной, в которой используются знаки # вместо ведущих пробелов, нули вместо предшествующих нулей и либо то, либо другое вместо цифр, стоящих после десятичной точки. 100 FOR n=1 TO 20:LET X=RND*100 110 PRINT X,USING"###,##";X:NEXT n
Обратите внимание, насколько аккуратнее получается печать отформатированных чисел, поэкспериментируйте с различными форматобразующими строками. Некоторые возможные форматирующие строки и результат их действия на число 12.3456 показаны ниже:
# #. # " 12.3
# # #. # " 12.3
# # # #. # #" 12.35 000.00" 012.35 00" 12 R00.00" R12.35 0.00 " %..3
Предпоследний пример показывает, что в форматирующей строке можно использовать не только # и 0, но и другие символы. В этом случае они напрямую передаются на печать.
Последний пример показывает печать знака %, который говорит о переполнении заказанного формата.
FN U$ применяется таким же образом, но: вместо PRINT USING A$; число надо: PRINT FN U$ ^$,число).
28. Команда WHILE
Структура: WHILE условие Клавиша: J
Позволяет вводить условие для завершения циклов DO-LOOP.
29. XOS,XRG,YOS,YRG
Эти четыре слова не являются ключевыми - это специальные переменные, которые позволяют изменять начало отсчета координат и масштаб координатной сетки, используемой командами PLOT, DRAW и CIRCLE.
XOS и YOS задают x-координату и y- координату начала системы отсчета, а XRG и YRG -масштаб по осям X и Y.
Эти переменные устанавливаются через CLEAR и RUN. очень часто изменение начала отсчета системы координат бывает более удобным, чем изменение выражений PLOT, например:
LET XOS = 126: LET YOS = 88
Эти команды сдвигают начало системы координат в центр экрана.
XRG нормально имеет значение 256 (т.е. Вы можете поместить до 256 точек на оси X). YRG нормально установлено в 176. 10 GO SUB 100: REM normal 20 LET XRG = 128: GO SUB 100 30 LET YRG = 88: GO SUB 100 40 LET XRG=256:GO SUB 100:STOP 100 CLS:PLOT 0,0:DRAW 50,10: DRAW 0,50 110 DRAW 50,0:DRAW 0,-50: PAUSE 100: RETURN
Сначала изображается нормальный квадрат, затем сжатый по оси X, далее сжатый по обеим осям и, наконец, он сжимается только по оси Y.
Нижеследующий пример показывает изображение графика функции синус. 100 LET XRG = 2*PI 110 LET YRG = 2.2 120 LET YOS = 1.1
130 FOR n=0 TO 2*PI STEP 2*PI/256 140 PLOT n,SIN n:NEXT n
Заметьте, что позиция начала координат тоже масштабируется.
При использовании функции CIRCLE величина радиуса не масштабируется, поэтому получить растянутую окружность таким способом не удается.
На этом мы пока прощаемся до следующего выпуска, в котором рассмотрим дополнительные функции Бета-Бейсика.