ZX-Ревю 1992 №7-8 1991 г.

Beta Basic - команды: LIST, LOCAL, LOOP, MERGE, MOVE, ON, ON ERROR, OVER 2, PLOT, POP, PROC, READ LINE, REF, RENUM, ROLL.


BETA BASIC

Начало см. стр. 3, 47, 91

34. LIST FORMAT число.

Эта команда использует сразу два ключевых слова БЕЙСИКа и предназначена для того, чтобы управлять форматом листинга Вашей программы, т.е. с ее помощью можно получить распечатку программы в удобном для восприятия виде.

Команда имеет несколько режимов, которые задаются параметром. Начальное состояние после загрузки Бета-Бейсика - LIST FORMAT 0.

LIST FORMAT 0.

Эта команда дает распечатку, похожую на ту, которую мы получаем в стандартном БЕЙСИКе, но есть незначительное отличие, заключающееся в том, что если строка программы длиннее, чем строка экрана, то перенос ее на вторую экранную строку выполняется со сдвигом. Таким образом, левые пять столбцов экрана содержат только номера программных строк и текст становится более разборчивым и удобочитаемым.

LIST FORMAT 1.

Распечатка по этой команде делается таким образом, что каждый оператор печатается с новой строки. Более того, некоторые из операторов (см. ниже) печатаются со смещением вправо на одну позицию, что позволяет распечатывать программу "лесенкой", так как это принято в языках, поддерживающих структурное программирование, например "ПАСКАЛЬ", "СИ" и др.

LIST FORMAT 2.

Действие то же, что и для LIST FORMAT 1, но автоматическое смешение для некоторых операторов выполняется не на одну, а на две позиции вправо.

LIST FORMAT 3.

Действие то же, что и для LIST FORMAT 0, но печать программы выполняется без номеров строк.

LIST FORMAT4.

Действие то же, что и для LIST FORMAT 1, но печать программы выполняется без номеров строк.

LIST FORMAT 5.

Действие то же, что и для LIST FORMAT 2, но без номеров строк.

Для глаза приятнее воспринимать смещение "лесенкой" на две позиции, но поскольку у нас невелика ширина экранной строки - всего 32 символа, то ее может оказаться недостаточным и поэтому введены режимы 1 и 4.

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

DEF PROC, DO, FOR - сдвигают все последующие операторы вправо на один или на два символа до тех пор, пока не встретятся соответствующие им END PROC, LOOP или NEXT.

Операторы IF, ON ERROR и ON сдвигают все прочие операторы своей программной строки вправо.

Операторы ELSE и EXIT IF отменяют сдвиг текущего оператора на одну или две позиции.

Если Вам захочется, чтобы оператор после ELSE или THEN печатался с новой строки, то Вы можете после них поставить двоеточие.

Пример действия команд LIST FORMAT 0 и LIST FORMAT 2 показан ниже.

100 DEF PROC primer

110 FOR n=1 TO 10: PRINT "primer": NEXT n

120 DO: PRINT a$: INPUT b$

130 PRINT "abc": LOOP

140 IF x=1 THEN: PRINT "yes": PAUSE 50: ELSE: PRINT "no

150 END PROC

100 DEF PROC primer 110 FOR n=1 TO 10

PRINT "primer" NEXT n 120 DO

PRINT a$ INPUT b$ 130 PRINT "abc"

LOOP

140 IF x=1 THEN

PRINT "yes" PAUSE 50

ELSE

PRINT "no" 150 END PROC

Если Вы очень привыкли к стандартному БЕЙСИКУ, то первое впечатление будет, что второй листинг выглядит несколько странно, но немного практики и вы почувствуете, насколько он удобнее.

35. LIST PROC имя процедуры.

Команда позволяет распечатать не всю программу, а только процедуру, которую Вы задали именем, например LIST PROC box.

На практике эта команда очень часто используется в длинных программах. Тогда Вам не надо помнить, в каком месте программы расположена Ваша процедура.

Может быть, Вам захочется хранить имя процедуры в строковой переменной. Команда LIST PROC не сможет тогда ее обработать напрямую и требуется обходной прием: 10 INPUT a$: KEYIN "LIST PROC"+a$

Две системные переменные содержат номера первой и последней строк процедуры, заданной в LIST PROC. Их адреса 23635 и 57358, соответственно. Работа с ними иногда может быть очень полезной и ее удобно выполнять, используя функцию DPEEK.

36. LIST REF.

REF - ключевое слово на клавише "SHIFT"+"7".

См. также REF.

LIST REF - дает список номеров помеченных строк. Меткой может быть имя переменной, число или набор символов. LIST REF тесно связана с командой REF и описана более подробно в соответствующем разделе, который желательно предварительно прочитать.

Если в некоей программной строке метка существует не один раз, то при печати списка этот номер строки появится многократно

Например:

10 FOR n=1 TO 10: PRINT n 20 NEXT n

Для такой программы команда LIST REF n даст следующий список:

10

10

20

Чтобы направить список на принтер, Вы можете использовать команду LLIST REF или:

LIST #(номер потока) REF метка

37. LOCAL переменная <,переменная><,переменная>...

Клавиша: "SHIFT" + "3"

См. также главу 3 "Процедуры" и раздел "DEF PROC".

Команда LOCAL позволяет создавать специальные переменные, которые существуют только внутри заданных процедур. (Параметры процедур автоматически имеют статус локальных и потому не нуждаются в объявлении их оператором LOCAL.) Использование команды LOCAL для создания локальных переменных в процедурах имеет то преимущество, что исключает образование помех, вызванных тем, что процедура может изменить содержимое какой либо переменной, относящейся к главной программе. Благодаря этой команде процедура может иметь переменные x и a$ и изменять их как угодно, не изменяя переменные x и a$ в главной программе.

Команда LOCAL может быть использована только в теле объявленной процедуры, иначе система выдаст сообщение об ошибке "Missing DEF PROC". Самое удобное для нее место - после объявления процедуры, сразу за DEF PROC. Тогда при чтении распечатки сразу становится ясно, какие переменные в процедуре используются. По желанию Вы можете иметь в процедуре несколько команд LOCAL.

Если переменные, объявленные как LOCAL, до этого объявления в программе уже существовали, то они "прячутся". На самом деле они, конечно существуют в области программных переменных и команда CLEAR их не уничтожит, но с точки зрения процедуры их как бы нет. В процедуре теперь эти имена могут использоваться снова. В конце работы процедуры все переменные, объявленные как LOCAL, будут уничтожены и исходные значения (если они были спрятаны) будут восстановлены. Вот простой пример. 10 LET n=1

20 test: REM чтобы выйти из курсора "К" воспользуйтесь ведущим пробелом. 30 PRINT n 40 STOP

100 DEF PROC test 110 LOCAL n 120 LET n=999 130 PRINT n 140 END PROC

Запустите этот пример и убедитесь, что n в процедуре равно 999, а вне ее n равно 1. Если вы опустите строку 120, то n не будет существовать внутри процедур, а если Вы опустите строку 10, то n не будет существовать в главной программе.

Если наша процедура test будет внутри себя вызывать некую субпроцедуру (например из строки 125), то для нее переменная n со значением 999 будет глобальной, для этой субпроцедуры процедура test является как бы главной программой.

Все переменные, доступные в процедуре являются глобальными по отношению к процедурам, вызываемым из нее. Чтобы "спрятать" эти переменные в нижележащих процедурах. Вы можете и в них использовать оператор LOCAL или использовать их в списке параметров.

В отличие от многих прочих диалектов БЕЙСИКа, БЕТА-БЕЙСИК поддерживает локальные массивы. Если, к примеру, в главной программе Вы используете а$, то в процедуре командой LOCAL а$ все строковые массивы а$ или переменные а$ будут локальными и не повлияют на переменные главной программы. Если Вы хотите числовой массив сделать локальным, то после его имени надо использовать круглые скобки. Например, LOCAL b(). Это "спрячет" любой существующий массив b(). После этого Вы можете в процедуре создать свой новый локальный массив b() того размера, который Вам нужен.

38. LOOP

или LOOP WHILE условие

или LOOP UNTIL условие

клавиша: L

См. также DO, EXIT IF.

LOOP - это нижняя граница цикла DO-LOOP (см. DO). Команда LOOP, заданная сама

по себе вызывает возвращение исполнения программы к соответствующему оператору DO.

LOOP может употребляться вместе с кодификаторами WHILE и UNTIL, которые обеспечивают возврат в начало цикла по условию.

LOOP WHILE условие - обеспечивает возврат назад, к вершине цикла только в том случае, если <условие> справедливо, в противном случае выполняются операторы и строки, стоящие за LOOP.

LOOP UNTIL условие имеет противоположное действие. Если указанное <условие> справедливо, возврат к вершине цикла не выполняется, а выполняется, когда оно ложно.

Если Вы используете в программе оператор LOOP без соответствующего DO, то получите сообщение об ошибке: T,"LOOP without DO".

39. MERGE

См. также DEFAULT = устройство. Эта команда имеет дополнительную возможность, которую использовать смогут только немногие владельцы микродрайва. Она позволяет загружать без автозапуска те программы, которые выполнены автостартующими. С ленты это можно делать и так.

40. MOVE

Эта команда тоже развивает возможности владельцев микродрайва. Она теперь позволяет перемещать не только блоки данных, но и программы, машинный код и массивы.

Чтобы перенести файл "test" с драйва 1 на драйв 2, делайте так: MOVE "m"; 1; "test" TO "m"; 2; "test"

Команда сработает, независимо от физической природы файла. Хоть MOVE и выглядит удобной командой, на практике большие файлы быстрее перемещаются через SAVE/LOAD.

41. ON

Клавиша: О

БЕТА-БЕЙСИК обеспечивает две различные формы оператора ON.

Вы можете задать после ON список число или выражение, которое определит, к какой строке будет выполняться переход по оператору GO TO или GO SUB.

Это довольно традиционный оператор для различных диалектов БЕЙСИКа, хотя и довольно архаичный в эпоху широкого применения процедур.

Вторая форма позволяет не только избрать строку, но и оператор.

Пример. Первая форма. GO TO ON число, номер строки, номер строки, номер строки...

или

GO SUB ON число, номер строки, номер строки, номер строки...

(Более стандартной выглядела бы форма ON число GO TO строка..., но клавиатурная система "Спектрума" делает ее усложненной).

Обычно при программировании на "Спектруме" такой многопозиционный переключатель организуют так: 10 INPUT choice:

GO TO choice*100+100

Но с использованием ON это можно делать более гибко, т.к. номера строк перехода не должны быть числами одного заданного ряда. 10 INPUT choice:

GO TO ON choice: 90,135,60,40 20 PRINT "Enter 1 to 4": GO TO 10

В этом примере будет выполнен переход к строке 90, если choice равно 1, к строке 135, если choice равно 2, к строке 60, если choice равно 3 и т.д. Если choice не входит в диапазон от 1 до 4, то никакого перехода не делается, а выполняется следующей оператор или программная строка, а она предоставляет пользователю возможность повторить свой выбор. В этом примере вы можете заменить INPUT на GET и тогда получите элегантную технику для написания программ, управляемых от меню.

Вторая форма.

ON число: оператор: оператор:...

Эта форма позволяет исполнить тот или иной оператор из списка, в зависимости от того, какое значение принимает параметр <число>.

Из списка операторов исполняется только указанный, после чего программа переходит к исполнению следующей строки. Если параметр <число> больше, чем количество операторов в строке, то сразу выполняется переход к следующей строке. Ниже приведен пример использования этой команды в ответ на ввод от пользователя числа 1,2 или 4. Если он введет число 3, то никакой реакции не произойдет и программа продолжится в естественном порядке. Это обеспечено тем, что третий оператор в строке 20 - пустой.

10 INPUT x

20 ON x: PRINT "one": PRINT "two":: PRINT "four"

30 GO TO 10

Совсем необязательно, чтобы операторы в строке ON были одного типа. Ниже показан пример использования "смешанных" конструкций, содержащих и вызов процедуры и GO SUB и PRINT.

10 DO

20 GET number ON number

GO SUB 100 sound GO SUB 200 PRINT "bye"

30 LOOP

Использование ON со списком процедур - наиболее современная, рациональная и удобочитаемая форма.

42. ON ERROR номер строки

или

ON ERROR: оператор: оператор:...

Клавиша: N.

Для оператора ON ERROR возможны две формы записи. Первая форма задает номер строки, к которой происходит переход, если происходит прерывание работы по ошибке. Остальные операторы в строке ON ERROR в этом случае не имеют к нему специального отношения.

Во второй форме после ошибки начинается выполнение операторов, содержащихся в данной строке.

За ошибку считается любая ошибка из числа перечисленных в инструкции к "Спектруму" или из числа приведенных в приложении к инструкции по работе с языком "БЕТА-БЕЙСИК 3.0", т.е. все сообщения Бейсика, кроме сообщений:

0: "OK"

9: "STOP statement"

Этот режим можно отключить оператором ON ERROR 0, но он также отключается автоматически при работе процедуры обработки ошибки и вновь включается после возврата в главную программу. (Ей приходится отключаться, иначе был бы конфуз, когда при обработке собственной ошибки она вызывала бы саму себя и вновь сталкивалась с той же ошибкой.)

Этой процедуре доступны три специальные переменные, которые могут быть очень и очень полезны: LINO, STAT и ERROR. Все это не ключевые слова и набираются по буквам.

LINO и STAT - номер строки, в которой произошла ошибка и номер оператора в строке.

ERROR - номер кода ошибки, когда мы закончим печать инструкции мы дадим коды всех ошибок.

Вы можете пользоваться этими переменными в своих целях, но делать это надо до того, как будет активизирована процедура ON ERROR, потому как при ее активизации, как и при активизации режима TRACE (см. ниже), эти переменные могут быть перезатерты.

Не рекомендуем Вам все возможные ошибки обрабатывать через ON ERROR. Желательно все, за исключением одного-двух сообщений обрабатывать естественным путем, иначе при отладке программы может быть трудно разобраться с тем, что в ней происходит. Во всяком случае Вы ведь не предполагаете, что Ваши программы будут изобиловать многочисленными ошибками. В нижеприведенном примере программа печатает точки на экране, а процедура обработки ошибок отсекает те, которые выходят за его пределы.

Первая форма выглядит так 100 ON ERROR 5000 110 FOR n=1 TO 10:

INPUT "x coord "; x; "у coord "; у 120 PLOT x,y: NEXT n

4990 STOP

5000 IF error=11 AND lino=120 THEN RETURN: ELSE POP: CONTINUE

Обратите внимание: Оператор STOP стоит в программе для того, чтобы предотвратить случайное исполнение процедуры обработки ошибки. Значения LINO и ERROR проверяются потому, что сообщение "Integer out of range" является широко распространенным и появляется во многих случаях. Возврат из процедуры обработки ошибки выполняется к оператору, следующему за тем, который вызвал ошибку, поэтому возврат выполняется к оператору NEXT n. Если номер строки или код ошибки были не те, то выполняется оператор CONTINUE. В результате этого подозрительный оператор выполняется еще раз (кроме случая "BREAK into program") и, поскольку CONTINUE не задействовал ON ERROR, то теперь обработка ошибки пойдет стандартным путем. Оператор POP очищает стек от адреса возврата в главную программу. Если этого не сделать, то нормальная работа стека будет нарушена.

Вторая форма выглядит так: 100 ON ERROR

IF error=11 AND lino=120

THEN RETURN ELSE

POP

CONTINUE

Есть одна "ошибка", которую необходимо обрабатывать путем, отличным от прочих. Это "BREAK into program". Поскольку ON ERROR отключается, когда выполняется переход GO SUB к процедуре обработки ошибки, то обычное действие BREAK будет состоять в том, что Ваша процедура остановится после исполнения первого же оператора, поскольку Вы еще не успели отпустить клавишу BREAK. Поэтому, если Вы хотите, чтобы по нажатию BREAK были предприняты какие-то действия и ваша процедура обработки ошибок работала бы, то вам необходимо ввести паузу в первом операторе процедуры обработки ошибки, достаточную для того, чтобы пользователь освободил клавишу BREAK. Для этой цели неплохо может служить оператор ВЕЕР. Если вы не хотите, чтобы генерируемый звук был слышен, используйте те частоты, которые не слышны для человеческого уха. Например: 100 ON ERROR 5000 110 PRINT "round and ";: PAUSE 10: GO TO 110

4990 STOP

5000 IF error = 21

THEN BEEP 1.69:

BORDER RND*7: RETURN: ELSE POP CONTINUE

43. OVER 2.

См. также GET, PLOT.

Кроме 0 и 1 OVER теперь может работать с параметром 2. OVER 2 имеет то действие, что те символы или рисунки, которые печатаются командой PLOT <строковая переменная>, добавляются к тому, что уже есть на экране, а не затирает имеющееся изображение и не инвертируют общие точки. Пиксел приобретает цвет INK, если он был INK или он становится INK от нового рисунка. Таким образом, OVER 2 аналогичен слиянию изображений по логике OR, в то время как OVER 1 работает по логике XOR. (Различие в их логике будет описано в разделе "функции").

44. PLOT X,Y <;строка>

См. также: GET, OVER 2, CSIZE, управляющие коды.

Как видите, Бета-БЕЙСИК допускает выполнение PLOT не только для точек, но и для символьных строк. Это могут быть обычные символьные строки или экранные блоки, снятые с экрана с помощью GET и сохраненные в памяти, как строковые переменные.

Координаты, выступающие параметрами оператора PLOT имеют отношение к левому верхнему углу той символьной последовательности, которая помещается на экран. Могут использоваться и все обычные прочие квалификаторы оператора PLOT, такие, как INVERSE, OVER, INK и т.п. Если печатаемая строковая последовательность выходит за пределы правого нижнего угла экрана, то она появляется в левом верхнем углу. Если какая-то часть помещаемого на экран символа выходит за его пределы, выдается сообщение об ошибке "Integer out of range". В то же время, нижние 7 пикселов изображаемых символов могут выходить за нижнюю границу и в этом случае они изображаются в системном окне экрана.

Координаты позиции PLOT, которые используются в качестве стартовых для работы оператора DRAW, не нарушаются при использовании команды PLOT со строковой переменной.

Изменяя координаты позиции PLOT для символа, Вы можете добиться гораздо более плавного эффекта мультипликации, чем это возможно в обычном БЕЙСИКе при использовании оператора PRINT AT.

100 FOR x=16 TO 224: PLOT x,x/2; "<>": NEXT x

Попробуйте ввести в цикл параметр STEP 2 или 3 или более. Скорость будет выше, а эффект не совсем тот. Поскольку рисунок "<>" имеет вокруг себя поле цвета PAPER шириной по крайней мере в один пиксел, то при движении по экрану он будет сам себя стирать, если перемещение делать на один пиксел за шаг. Некоторые буквы, например "Т" имеют включенные пикселы цвета INK, подходящие к самой кромке знакоместа, поэтому существуют такие направления движения символа, при котором он не стирается, а оставляет след на экране. Если Вы сами конструируете себе символьный набор, то не помешает делать его так, чтобы со всех сторон символа оставалось поле шириной в один пиксел.

Вы можете увеличивать или уменьшать размеры помещенных на экран символов, графики, блоков и т.п. с использованием команды CSIZE (см. соответствующий раздел). Команда CSIZE должна непосредственно следовать за PLOT. Например: PLOT CSIZE 32;INK 2: 100,88;"HI!"

В печатаемую символьную строку Вы можете включить управляющие коды CHR$ 8 -CHR$ 11. Тогда Вы сможете получать гораздо более сложные геометрические построения.

Возможность помещать строки на экран командой PLOT очень полезна для печати графиков и диаграмм. Во-первых, здесь возможна более высокая точность, а во-вторых можно пользоваться той же координатной системой, которой пользуются графические функции, например DRAW, CIRCLE.

45. POKE адрес, строка

БЕТА-БЕЙСИК дает возможность не только выполнять POKE для чисел, но и для символьных строк, что в совокупности с функцией MEMORY$ дает возможность скоростных манипуляций с большими массивами памяти. Надо, правда, отметить, что если нерасчетливый POKE какого-либо числа может вывести из строя программу, то для строк это становится еще более критичным. Рассмотрим пример: 10 LET screen=16364 20 POKE screen, STRING$ (6114, "U")

О функции STRING$ мы будем говорить позже, в разделе "Функции". Здесь мы заполняем экранную память кодом буквы "U", но воспринимается это не как код, а как двоичное число 01010101, что изображает на экране полосы.

Следующий пример демонстрирует копирование начальной области ПЗУ в файл экранных атрибутов. 10 LET attr = 22528 20 POKE attr, MEMORY$()(1 TO 704)

Теперь давайте нарисуем на экране что-нибудь простое, сохраним изображение в строковой переменной и затем восстановим его на экране, используя POKE. 10 CIRCLE 128,88,70 20 FILL 128,88

30 LET a$ = MEMORY$() (16384 TO 23295): REM весь экран 40 CLS: PRINT "нажмите любую клавишу": PAUSE 0 50 POKE 16384,a$

В памяти компьютера могут одновременно храниться несколько таких картинок, вы можете оперативно менять их местами и по одной выбрасывать на экран. Если Вам надо больше картинок, вы можете одну треть экрана считывать в строковую переменную. Если вас интересует не только черно-белая информация, но и атрибуты цвета, то и треть файла атрибутов Вы тоже можете сбрасывать в такую же переменную.

Для хранения черно-белой информации экранных сегментов вы может пользоваться следующими командами: Верх:

LET a$=MEMORY$()(16384 TO 18431)

Середина: LET a$=MEMORY$()(18432 TO 20479) Низ:

LET a$=MEMORY$()(20480 TO 22527)

У компьютера достаточно памяти даже для того, чтобы исполнить реальный мультфильм путем использования команды POKE в сегмент экрана. Чтобы хранить данные в памяти, можно использовать массив DIM a$(10,2048).

Конечно, потенциальных возможностей у манипуляций с большими объемами памяти гораздо больше, чем просто обслуживание экранной памяти. Вы можете, например очистить большой объем верхней памяти и сохранить там целую программу, а потом вызывать ее опять. Так можно обеспечить одновременное присутствие в памяти компьютера сразу нескольких программ. CLEAR 33900

10 POKE 34000, MEMORY$() (22552 TO 33800) 20 REM остальные строки этой программы.

Теперь Вы можете сделать NEW и удалить Вашу программу, но ее копия останется в верхней памяти выше границы RAMTOP, установленной оператором CLEAR. Можно опять вызвать эту программу в работу: POKE 33552, MEMORY$() (34000 TO 44248)

Эту вызывающую команду можно "подвесить" на клавишу, определяемую пользователем и, поскольку такие определения тоже хранятся выше уровня RAMTOP, то оно будет защищено от разрушения командой CLEAR. DEF KEY "j": POKE 23552, MEMORY$() (34000 TO 44248)

В тот момент, как программа будет восстановлена, она продолжит работу с того места, в котором она была "спрятана", т.к. вместе с программой отгружались и восстанавливались все ее системные переменные.

Итак, как видите, БЕТА-БЕЙСИК дает Вам несложный механизм организации виртуального диска (RAM-диска) для работы сразу с несколькими программами.

И еще одна идея для использования POKE, заключающаяся в возможности сохранения машинного кода вместе с БЕЙСИК-программой. Присвойте этому блоку кодов имя символьной переменной и выгрузите БЕЙСИК на ленту таким образом, чтобы при последующей загрузке POKE, находящийся в строке автостарта, автоматически перебрасывал этот код на нужное место памяти и дальше запускайте его. Это делается значительно быстрее, чем раздельная загрузка БЕЙСИК-программы и блока машинных кодов. Для того, чтобы освободить место под блок машинного кода и не потерять при этом БЕЙСИК-переменные, воспользуйтесь командой CLEAR.

46. POP <числовая переменная>

Клавиша: Q

Команда POP удаляет последний адрес со стека, обеспечивавшего правильную работу команд GO SUB, DO-LOOP, PROC. Если при этом Вы используете параметр <числовая переменная>, то номер строки, к которой должен был бы быть исполнен переход, если бы вы не сняли его со стека, запоминается в этой переменной.

Команда POP может позволить Вам завершать работу в подпрограммах, процедурах и циклах не естественным путем и при этом закупорки стека не произойдет, если выходя в неположенном месте, например из цикла, Вы снимете адрес естественного возврата со стека. Команда POP без параметра просто удалит этот адрес со стека, а если Вы используете ее с параметром, например с переменной loc, то этот адрес еще останется в вашей переменной и, может быть, он Вам впоследствии для чего-нибудь пригодится. Может быть, по ходу программы Вы примете решение о том, что POP был сделан неправильно и надо все-таки перейти туда, куда должна была возвращать Ваша процедура. В этом случае знание 1ос позволит Вам сделать GO TO 1ос+1, хотя надо отметить, что это все же не вполне то же самое, что и естественный RETURN. Дело в том, что адрес, откуда Вы прошли в подпрограмму, запомнен на стеке и после RETURN Вы возвращаетесь туда, откуда уходили. Возвращаетесь либо на следующую строку, либо на следующий оператор в той же строке, если он есть. Переход же по GO TO loc+1 не может вернуть Вас к следующему оператору, а только к следующей строке.

Пример: 100 GO SUB 500 110 STOP 500 POP loc

510 PRINT "Подпрограмма вызывалась из строки "; loc 520 GO TO loc

Если Вы в строке 520 поставите

520 RETURN

то получите сообщение "RETURN without GOSUB", поскольку к этому моменту на стеке уже не будет никакого адреса, ведь он был снят командой POP.

Вызов команды POP, когда на стеке нет данных, дает сообщение об ошибке V, "No POP data".

47. PROC имя <параметр><,параметр><,параметр>...

Клавиша: 2

См. также Главу 3 "Процедуры", а также раздел DEF PROC.

Для того, чтобы вызвать процедуру, в версии 3.0 нет необходимости давать ключевое слово PROC и оно сохранено главным образом для того, чтобы обеспечить совместимость с предыдущими версиями БЕТА-БЕЙСИКа. Вы можете обращаться к процедуре по ее имени без этого ключевого слова, для чего имя вводятся после отключения K-режима вводом

ведущих пробелов или вызовом режима KEYWORDS 4.

С другой стороны, слово PROC используется, например, в команде LIST PROC (см.).

48. READ LINE строковая переменная <,строковая переменная>...

См. также Главу 3 "Процедуры".

Команда состоит из двух ключевых слов и позволяет работать без кавычек со списком данных, которые обычно должны иметь кавычки. Например: 100 DATA dog, rat, fish, frog, z$,12,"?*+" 110 READ LINE a$ 120 PRINT a$: GO TO 110

Оператор DATA ограничивает типы данных, которые можно хранить таким способом, поскольку допустимы только полноценные выражения. В строке 100 "cat" может быть числовой переменной, но "?*+" требует наличия кавычек. Оба типа можно было бы объединить, добавив:

115 IF a$(1)=CHR$ 34 THEN LET a$=VAL$ a$

READ LIKE позволяет сделать строки DATA более удобными для чтения, хотя главное назначение этой команды - сделать возможным ввод строковых данных без кавычек.

49. REF метка

Клавиша: SHIFT + "7"

Эта команда позволяет выполнить в программе поиск заданной "метки", которая может быть числом, именем переменной или набором символов.

Когда указанная метка найдена, строка, содержащая ее, появляется в системном окне компьютера (в строках редактирования). При этом курсор стоит непосредственно за меткой. Если Вы не хотите вносить изменений в найденную строку. Просто нажмите ENTER. Чтобы найти другие строки, содержащие такую же метку, нажмите ENTER еще раз и так далее, когда поиск будет закончен полностью, появится сообщение "O.K. "

Если вместо нажатия ENTER вы введете какую-либо команду, то компьютер решит, что Вы закончили поиск и теперь, чтобы опять продолжить поиск. Вам надо снова задавать команду REF.

Примеры: (символы, не являющиеся буквой, цифрой и знаком $ показаны, как _.)

REF a$ ищется a$

REF count ищется _count_

REF "count" ищется count

REF 1 ищется 1 (число)

REF "1" ищется 1 (символ)

REF 12*4 ищется 12 (число) * 4 (число)

REF (a$) ищется значение a$, так, например, если а$ = "fish", то ищется "fish", а не

а$.

REF х ищется значение х, например, если x=10, то ищется 10(числовая форма).

Не играет никакой роли регистр встреченных символов - прописные буквы или строчные.

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

count account counts

При поиске чисел поиск идет не по их символьному представлению на экране, a по их числовой интегральной (пятибайтной) форме, которая стоит за всяким числом, появляющимся в любой БЕЙСИК строке. Это тоже позволяет избежать конфузов. Таким образом, внутренние вложения в переменные и числа не мешают правильной работе.

Если же Вы ищете набор символов, заключите его в скобки и он будет найден, даже если является вложением в большую строку.

Если Вы используете строковую переменную при поиске, то ее надо заключить в скобки, чтобы БЕТА-БЕЙСИК мог отличить случай поиска по имени от поиска по значению.

50. REF имя переменной.

Клавиша: SHIFT + "/"

Мы рекомендуем Вам предварительно прочитать главу 3 "Процедуры", прежде чем двигаться дальше.

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

Это означает, что во время исполнения процедуры соответствующие переменные могут быть временно переименованы в имя, стоящее после REF. Это обеспечивает передачу параметров не только из вышележащей процедуры в нижележащую, но и наоборот снизу вверх. Пассивы всегда должны передаваться, как ссылки. В нижележащем примере REF a$ относится к символьной строке или массиву, а REF b() - относится к числовому массиву. 100 DEF PROC crunch REF a$, REF b(), REF OUTPUT

51. RENUM <*><начало TO конец> LINE <новое начало> STEP <шаг>.

Клавиша: 7

RENUM обеспечивает очень мощные возможности по перенумерованию блоков программных строк, их перемещению и их копированию.

Просто команда RENUM без параметров перенумерует все строки программы так, что номером первой строки будет 10, а далее все строки будут идти с шагом по 10. Но можно и задать перенумерацию не всей программы, а только заданного блока строк.

RENUM 130 TO 220 - перенумерует все строки из этого диапазона.

RENUM 130 TO - перенумерует все строки, начиная со строки 130 и до конца программы.

RENUM TO 100 - перенумерует строки, начиная с первой программной строки и до строки 120 включительно, за исключением нулевой строки.

Перенумерованный блок будет перемещен в программе на заказанное место, если в памяти для него место имеется, в противном случае может быть выдано сообщение об ошибке: G, "No room for line" ("Для строки нет места").

Команда RENUM* отличается тем, что она выполняет не перемещение строк, а их копирование, т.е. создается новый блок с заданной нумерацией строк, но старый при этом не уничтожается.

Вы можете задать в качестве первой строки не десятую, а любую другую, указав параметр LINE (это ключевое слово). Если Вас не устраивает стандартный шаг нумерации строк в БЕЙСИКе через десять, задайте свой в качестве параметра STEP (ключевое слово). И LINE и STEP могут быть даны или опущены по желанию, но если Вы их даете, то порядок их следования должен быть только таким, как указано в описании команды и не наоборот.

Некоторые примеры: RENUM

RENUM LINE 100 STEP 20

RENUM 100 LINE 300 (перенумеровывается только одна строка)

RENUM 1540 TO LINE 2000

RENUM 100 TO 176 LINE 230 STEP 5

RENUM * 10 TO 100 LINE 500 -копирование блока строк.

При перенумерации программных строк все ссылки на строки по их номеру тоже перерабатываются, включая GO TO, GO SUB, RESTORE, RUN, ON, ON ERROR, TRACE, LIST, LLIST, LIKE.

Операторы DELETE и CLOCK - не перерабатываются, Вам придется заняться этим вручную.

RENUM не может также самостоятельно переработать вычисляемые ссылки на номера строк, такие как GO TO ln*100.

После завершения перенумерации все указания на такие подозрительные места будут распечатаны на экране, чтобы Вы могли с ними разобраться, например:

Failed at 100:2

Failed at 230:4

Все GO TO, GO SUB и т.п., содержащие после себя такие вычисляемые адреса перехода, будут распечатаны, даже если Вы и перенумеровываете лишь малый блок и в ней нет таких операторов, потому что они могут быть в других местах программы и указывать именно на тот блок, который Вы и перенумеровали.

Если Вы желаете направить распечатку таких сложных строк на принтер, воспользуйтесь: OPEN #2, "P": RENUM: OPEN #2, "S"

Примечание: во время работы команда RENUM образует временный буфер в экранной области компьютера, что сопровождается неожиданными помехами на экране. Не обращайте на них внимание, по окончании работы экран будет восстановлен.

52. ROLL код направления <, число><; х, y; ширина, длина >

Клавиша: R

См. также SCROLL

Команда ROLL перемещает изображение, имеющееся на экране или в заданном окне вверх, вниз, влево или вправо. Все, что выходит за пределы окна, тут же появляется с противоположной стороны. Одним словом, команда, в отличие от команды SCROLL, не разрушает содержимое экрана, а только перемещает его.

Как видите, команда ROLL имеет довольно сложный синтаксис, хотя большая часть сопровождающих параметров служит только для того, чтобы задать окно, внутри которого действует ROLL. Если Вы, например, хотите сдвинуть на один пиксел содержимое текущего окна, а таковым обычно является весь экран, если вы не задали иначе, то команда имеет такой простой вид:

10 ROLL код направления

Если вам надо сдвинуть только черно-белую графику без цветовых атрибутов, то в качестве кода направления нужно задать 5,6,7 или 8 (соответственно это означает влево, вниз, вверх, вправо).

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

Нарисуйте (DRAW, CIRCLE) какое-либо несложное, но крупное изображение или просто дайте команду LIST и экран будет заполнен, а затем попробуйте следующие строки:

100 FOR d=5 TO 6: FOR p= 1 TO 100

110 ROLL d

120 NEXT p: NEXT d: STOP

Можно делать смещение и по диагонали. В этом случае в цикле выполняется последовательность движений вверх, вправо или т. п. Если хотите, чтобы движение шло более быстро (но менее плавно), попробуйте:

110 ROLL d, 4

Этот параметр указывает на сколько пикселов за один раз должно производиться смещение. Он не должен быть более, чем 256 при горизонтальном движении и чем 177 - при вертикальном. Если параметр не указав, по умолчанию принимается единица. Очевидно, что чем больше это число, тем более значительно будет передвинуто изображение. При вертикальной движении скорость обычно пропорциональна количеству пикселов, передвигаемых за раз. При горизонтальной движении наилучший результат дает шаг в 4 или в 8 пикселов, т. к. в этом случае используются более скоростные команды машинного кода процессора Z-80.

Если Вы хотите передвигать не только чёрно-белую информацию, но и цветовые атрибуты, добавьте к коду направления число 4, а если хотите передвигать только атрибуты, наоборот отнимите 4.

Код Направление Действие

1 Влево Атрибуты

2 Вниз Атрибуты

3 Вверх Атрибуты

4 Вправо Атрибуты

5

Влево

Графика

6

Вниз

Графика

7

Вверх

Графика

8

Вправо

Графика

9

Влево

Граф. + Атр.

10

Вниз

Граф. + Атр

11

Вверх

Граф. + Атр.

12

Вправо

Граф. + Атр

Атрибуты можно сдвигать только на 8 пикселов за один шаг и параметр, определяющий шаг смешения здесь игнорируется.

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

10 PRINT AT 10, 10: PAPER 2; "DEMO" 20 ROLL 9: PAUSE 10: GO TO 20

Вы увидите, что рассогласование движения атрибутов и графики достигает 4-х пикселов. Теперь попробуйте такой вариант: 10 PRINT AT 10, 10; INK 2; " DEMO "

Дополнительные пробелы, охватывающие слово "DEMO", обеспечивают то, что оно всегда прикрыто 6-символьной полосой красного цвета. Аналогичный метод работает и для других геометрических форм. Нижеприведенный пример создает цветные круги, каждый из которых окружен защитным кольцом с соответствующей установкой атрибутов. 10 LET y=88, r=15 20 FOR n=1 TO 4 30 LET x=n*48+8 40 CIRCLE x,y,r 50 FILL INK n; x, y

60 CIRCLE INK n; INVERSE 1: OVER 1; x, y, r+5 70 NEXT n 80 ROLL 9 90 GO TO 80

Если перемещению подлежит не весь экран, а только его часть (окно), то его Вы можете задать, указав координаты x и y левого верхнего угла, ширину и высоту. При этом здесь применяются разные координатные системы. Параметры X, Y и высота окна задаются в пикселах, а ширина окна - в знакоместах. Ее конечно тоже можно было бы задавать в пикселах, но тогда команда получается медленноработающей. Итак, параметр ширины может быть от 1 до 32, а параметр высоты - от 1 до 176.

Что же касается атрибутов, то они перемещаются только с точностью до знакомест, поэтому работая в цвете необходимо четко планировать свои действия.

Вы можете предварительно задать окно командой WINDOW и тогда команда ROLL будет работать с данным окном без необходимости указывать его параметры.

ROLL может эффективно применяться при создании аркадных игр для обеспечения плавных движений героя или ландшафта. Интересный головокружительный эффект может иметь создание сразу нескольких пересекающихся окон, двигающихся в разных направлениях.

100 LIST: LIST: LIST

110 LET pixels=4

120 ROLL 5, pixels; 0,175;32,88

13O ROLL 6, pixels; 0,175;16,176

140 ROLL 8, pixels; 0,87;32,88

150 ROLL 7, pixels; 128,175;16,176

160 GO TO 120

Поэкспериментируйте с этой программой. Попробуйте задать pixels=1. Попробуйте изменить строку 100 на следующую:

100 KEYWORDS 0: PRINT STRING$(704 , " END PROC "): KEYWORDS 1

Слова END PROC набирайте не по буквам, а клавишей 3 в графическом режиме. И, наконец, последний пример:

200 FOR n=1 TO 7: LIST: NEXT n

210 FOR m=1 TO 175:

ROLL 5;0,175;32,m NEXT m

(Продолжение в следующем выпуске)

Михайленко B.C.




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Проба пера - Девять жизней Клэр.
Info - Анкета ZX-CLUB.
Информация - помощь.
Система - о командах "Принудительное прерывание" мелкосхемы контроллера флоппи-дисков КР1818ВГ93.
AyHits - Max и музыка :)

В этот день...   23 апреля