KEYWORDS 4.
В этом режиме нет курсора "К", т.е. все ключевые слова вводятся
только по буквам. Форсировать появление курсора "К", тем не менее,
все же возможно. Это делается нажатием клавиш SYMBOL SHTFT и ENTER.
Этот режим, возможно, предпочтут те, кому может потребоваться
совместимость с другими моделями персональных компьютеров.
d) Распознавание ключевых слов.
Есть небольшое ограничение в режимах 3 и 4, которое заключает-
ся в том', что Вы не можете использовать имена переменных и процедур,
совпадающие по написанию с ключевыми словами, поскольку при
запоминании программной строки в памяти компьютера может произойти
ИХ замена на токен ключевого слова. Тем не менее, ключевое слово
может быть частью имени переменной или процедуры без проблем.
Ключевые слова в этих режимах распознаются как набранные про-
писными, так и строчными буквами. Мы Вам рекомендуем использовать
строчные буквы, тогда после конверсии этих ключевых слов в токены,
Вы сможете наглядно увидеть, какие ключевые слова были преобразованы
и> возможно, найдете синтаксическую ошибку.
Символы, стоящие непосредственно перед ключевым словом или за
ним не могут быть буквами или символами подчеркивания .
Printa - не будет конвертировано в PRINT а, т.к. компьютер
предположит, что это имя переменной или процедуры.
Print а - будет преобразовано в PRINT а. Ниже приведены нес-
колько примеров возможных строк и показано их возможное преобразо-
вание в результате "токенизации".
print 10 ......... PRINT 10
gotolO ......... GO ТО 10
go to x .......... GO TO x
gotox ............ gotox
defproc pink ..... DEF PROC pink
mat_print ........ matprint
print fork, total ........ PRINT fork,total
alter to ink3,paper1 ........ ALTER TO INK 3, PAPER 1
print Strings(10,"plot") ........ PRINT STRINGS(10,"plot")
Пример с GO TO показывает, что внутренние пробелы в этот опера-
тор можно и не включать. Точно так же и "gosub", "onerror",
defproc" будут распознаны, как полноценные ключевые слова.
Слово "ink", входящее как составная часть в "pink" и "print",
входящее в "mat_print" распознаны не будут, т.к. перед ключевым
словом не должно быть буквы или знака "_".
LET переменная = число <, переменная = число...
Маленькое усовершенствование старой команды LET позволяет вы-
полнять серию присвоений, разделяя их запятыми. Это сокращает объем
занятой памяти (по одному байту на каждый опущенный LET), делает
ввод более удобным и листинг более читаемым. Так, запись
10 LET x=l,y=2,z=3,a$="y",b$="n" заменяет
10 LET х=1: LET у=2: LET z = 3: LET a$="y": LET b$="n"
LIST <номер строки> TO <номер строки>
или
LLIST сномер строки> ТО <номер строки>
Вы видите'по синтаксису, что здесь есть небольшое добавление к
стандартному БЕЙСИКу. Вы можете выводить на экран или принтер за-
данный Вами блок программы. Если первый номер строки не указан, то
по умолчанию принимается строка, следующая за нулевой. Если второй
номер строки не указан, предполагается по умолчанию последняя строка
программы. Если оба параметра опущены, Вы получаете эквивалент
обычной команде LIST.
LIST 20 ТО 100
LIST ТО 200
LLIST 100 ТО 180
Если строка с первым номером существует, то при листинге она
будет изображена с курсором ">", т.е. она готова к вызову на ре-
дактирование .
Если оба номера совпадают, то будет изображена только одна
строка.
LIST DATA ИЛИ LIST VAL ИЛИ LIST VAL$
Эти разновидности команды LIST позволяют распечатать сводку пе-
ременных :
LIST DATA - все переменные
LIST VAL - числовые переменные
LIST VAL$ - строковые переменные.
"Спектрум" имеет 6 типов переменных. Команда LIST VAL рас-
печатывает из них 4 типа в следующем порядке:
1. Числовые массивы.
2. Переменные циклов FOR-NEXT.
3. Переменные с односимвольными именами.
4. Переменные с многосимвольными именами.
Команда LIST VAL$ распечатает остальные два типа переменных:
5. Символьные массивы.
6. Обычные символьные переменные.
Команда LIST DATA распечатает все 6 типов переменных.
Переменные каждого типа распечатываются в алфавитном порядке
(для переменных с многосимвольным именем в расчет принимается толь-
ко первая буква). Пример того, что может дать LIST DATA приведен
ниже:
d( 10,4)
k(3,3,4)
n STEP 1 500 LN 200
g 3.5
j 100
s 23 . 1
applen 1
number 9999
xos 0
xrg 256
yos 0
yrg 176
t$(100,10)
a$ LEN 5 "Hello"
b$ LEN 40 " Too long to..."
e$ LEN 5 "Bang!"
Для массивов изображается только их размерность, но не содер-
жание. Переменные циклов FOR-NEXT можно отличить от прочих благода-
ря присутствию параметра STEP и параметра LN (looping number - номер
строки, из которой производится возврат в голову цикла). Для
длинных строковых переменных изображаются только первые 15 символов.
Здесь DEF KEY располагается на клавише SHIFT + 1.
См. также DEF KEY.
Эта команда позволит распечатать список клавиш, определенных
пользователем. Сначала распечатывается клавиша, а затем символьная
строка или оператор, которые за ней закреплены. Если в назначении
клавиши последним символом является двоеточие, то полагается, что
при нажатии этой клавиши, то, что за ней закреплено, сопро-
вождается последующим ENTER, т.е. сразу после нажатия содержимое
появляется в нижней части экрана в системном окне.
Эта команда использует сразу два ключевых слова БЕЙСИКа и
предназначена для того, чтобы управлять форматом листинга Вашей
программы, т.е. с ее помощью можно получить распечатку программы в
удобном для восприятия виде.
Команда имеет несколько режимов, которые задаются параметром.
Начальное состояние после загрузки БЕТА-БЕЙСИКа - LIST FORMAT 0.
LIST FORMAT 0.
Эта команда дает распечатку, похожую на ту, которую мы получаем
в стандартном БЕЙСИКе, но есть незначительное отличие, заключающееся
в том, что если строка программы длиннее, чем строка экрана, то
перенос ее на вторую экранную строку выполняется со сдвигом. Таким
образом, левые пять столбцов экрана содержат только номера
программных строк и текст становится более разборчивым и
удобочитаемым.
LIST FORMAT 1.
Распечатка по этой команде делается таким образом, что каждый
оператор печатается с новой строки. Более того, некоторые из опе-
раторов (см. ниже) печатаются со смещением вправо на одну позицию,
что позволяет распечатывать программу "лесенкой", так как это
принято в языках, поддерживающих структурное программирование, на-
LIST DEF KEY
LIST FORMAT ЧИСЛО
припер "ПАСКАЛЬ", "СИ" и др.
LIST FORMAT 2.
Действие то же, что и для LIST FORMAT 1, но автоматическое сме-
щение для некоторых операторов выполняется не на одну, а на две
позиции вправо.
LIST FORMAT 3.
Действие то же, что и для LIST FORMAT 0, но печать программы
выполняется без номеров строк.
LIST FORMAT 4.
Действие то же, что и для LIST FORMAT 1, но печать программы
выполняется без номеров строк.
LIST FORMAT 5.
Действие то же, что и для LIST FORMAT 2, но без номеров строк.
Для глаза приятнее воспринимать смещение "лесенкой" на две
позиции, но поскольку у нас невелика ширина экранной строки - всего
32 символа, то ее может оказаться недостаточным и поэтому введены
режимы 1 и 4.
Появление в тексте программы следующих операторов вызывают
автоматический сдвиг листинга:
DEF PROC, DO, FOR - сдвигают все последующие операторы вправо
на один или на два символа до тех пор, пока не встретятся соответ-
ствующие ИМ END PROC, LOOP или NEXT.
Операторы IF, ON ERRROR и ON сдвигают все прочие операторы
своей программной строки вправо.
Операторы ELSE и EXIT IF отменяют сдвиг текущего оператора
на одну или две позиции.
Если Вам захочется, чтобы оператор после ELSE или THEN печа-
тался с новой строки, то Вы можете после них поставить двоеточие.
Пример действия команд LIST FORMAT 0 и LIST FORMAT 2 показан ниже.
100 DEF PROC primer
110 FOR n=l TO 10: PRINT "primer
": NEXT n
120 DO: PRINT a$: INPUT b$
130 PRINT "abc": LOOP
140 IF x=l THEN: PRINT "yes": PA
USE 50: ELSE: PRINT "no"
150 END PROC
100 DEF PROC primer
110 FOR n=l TO 10
PRINT "primer'
NEXT П
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
Если Вы очень привыкли к стандартному БЕЙСИКу, то первое впе-
чатление будет, что второй листинг выглядит несколько странно, но
немного практики и Вы почувствуете, насколько он удобнее.
LIST PROC имя процедуры.
Команда позволяет распечатать не всю программу, а только проце-
ДУРУ* которую Вы задали именем, например LIST PROC box.
На практике эта команда очень часто используется в длинных про-
граммах. Тогда Вам не надо помнить, в каком месте программы
расположена Ваша процедура.
Может быть, Вам захочется хранить имя процедуры в строковой
переменной. Команда LIST PROC не сможет тогда ее обработать напря-
мую и требуется обходной прием:
10 INPUT а$: KEYIN "LIST PROC"+a$
Две системные переменные содержат номера первой и последней
строк процедуры, заданной в LIST PROC. Их адреса 23625 и 57358,
соответственно. Работа с ними иногда может быть очень полезной и ее
удобно выполнять, используя функцию DPEEK.
LIST REF.
REF - ключевое слово на клавише "SHIFT"+"7".
См. также REF.
LIST REF - дает список номеров помеченных строк. Меткой может
быть имя переменной, число или набор символов. LIST REF тесно
связана с командой REF и описана более подробно в соответствующем
разделе, который желательно предварительно прочитать.
Если в некоей программной строке метка существует не один раз,
то при печати списка этот номер строки появится многократно
Например:
10 FOR П=1 ТО 10: PRINT п
20 NEXT п
Для такой программы команда LIST REF п даст следующий
список: 10
10
20
Чтобы направить список на принтер, Вы можете использовать
команду LLIST REF или:
LIST #(номер потока) REF метка
LOCAL переменная <, переменнаях, переменная>. . .
Клавиша: "SHIFT" + "з"
См. также Главу 3 "Процедуры" и раздел "DEF PROC".
Команда LOCAL позволяет создавать специальные переменные, ко-
торые существуют только внутри заданных процедур. (Параметры про-
цедур автоматически имеют статус локальных и потому не нуждаются в
объявлении их оператором LOCAL.) Использование команды LOCAL для
создания локальных переменных в процедурах имеет то преимущество,
что исключает образование помех, вызванных тем, что процедура мо-
жет изменить содержимое какой-либо переменной, относящейся к главной
программе. Благодаря этой команде процедура может иметь переменные х
и а$ и изменять их как угодно, не изменяя переменные х и а$ в
главной программе.
Команда LOCAL может быть использована только в теле объяв-
ленной процедуры, иначе система выдаст сообщение об ошибке "Mis-
sing DEF PROC". Самое удобное для нее место - после объявления про-
цедуры, сразу за DEF PROC. Тогда при чтении распечатки сразу ста-
новится ясно, какие переменные в процедуре используются. По жела-
нию Вы можете иметь в процедуре несколько команд LOCAL.
Если переменные, объявленные как LOCAL, до этого объявления в
программе уже существовали, то они "прячутся". На самом деле они,
конечно существуют в области программных переменных и команда CLEAR
их не уничтожит, но с точки зрения процедуры их как бы нет. В
процедуре теперь эти имена могут использоваться снова. В конце ра-
боты процедуры все переменные, объявленные как LOCAL, будут
уничтожены и исходные значения (если они были спрятаны) будут
восстановлены. Вот простой пример.
10 LET п=1
20 test: REM чтобы выйти из курсора "К" воспользуйтесь
ведущим пробелом.
30 PRINT п
40 STOP
100 DEF PROC test
110 LOCAL n
120 LET n=999
130 PRINT n
140 END PROC
Запустите этот пример и убедитесь, что п в процедуре равно 999,
а вне ее п равно 1. Если Вы опустите строку 12 0, то п не будет
существовать внутри процедур, а если Вы опустите строку 10, то п не
будет существовать в главной программе.
Если наша процедура test будет внутри себя вызывать некую суб-
процедуру (например из строки 125), то для нее переменная п со
значением 999 будет глобальной. Для этой субпроцедуры процедура
test является как бы главной программой.
Все переменные, доступные в процедуре являются глобальными по
отношению к процедурам, вызываемым из нее. Чтобы "спрятать" эти
переменные в нижележащих процедурах, Вы можете и в них использо-
вать оператор LOCAL или использовать их в списке параметров.
В отличие от многих прочих диалектов БЕЙСИКа, БЕТА-БЕЙСИК
поддерживает локальные массивы. Если, к примеру, в главной
программе Вы используете а$, то в процедуре командой LOCAL а$ все
строковые массивы а$ или переменные а$ будут локальными и не
повлияют на переменные главной программы. Если Вы хотите числовой
массив сделать локальным, то после его имени надо использовать
круглые скобки. Например, LOCAL b(). Это "спрячет" любой
существующий массив Ь(). После этого Вы можете в процедуре создать
свой новый локальный массив Ь() того размера, который Вам нужен.
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
withiut DO".
MERGE
См. также DEFAULT = устройство
Эта команда имеет дополнительную возможность, которую исполь-
зовать смогут только немногие владельцы микродрайва. Она позволяет
загружать без автозапуска те программы, которые выполнены ав~
тостартующими. С ленты это можно делать и так.
MOVE
Эта команда тоже развивает возможности владельцев микродрай-
ва. Она теперь позволяет перемещать не только блоки данных, но и
программы, машинный код и массивы.
Чтобы перенести файл "test" с драйва 1 на драйв 2, делайте так:
MOVE "m";1;"test" ТО "m";2;"test" Команда сработает, независимо от
физической природы файла. Хоть MOVE и выглядит удобной командой, на
практике большие файлы быстрее перемещаются через SAVE/LOAD.
ON
Клавиша: О
БЕТА-БЕЙСИК обеспечивает две различные формы оператора ON.
Вы можете задать после ON список число или выражение, которое
определит, к какой строке будет выполняться переход по оператору GO
ТО или Gt) SUB.
Это довольно традиционный оператор для различных диалектов
БЕЙСИКа, хотя и довольно архаичный в эпоху широкого применения
процедур.
Вторая форма позволяет не только избрать строку, но и опера-
тор.
Пример.
Первая форма.
GO ТО ON число, номер строки, номер строки, номер строки...
или
GO SUB ON число, номер строки, номер строки, номер строки...
(Более стандартной выглядела бы форма ON число GO ТО строка,.,
но клавиатурная система "Спектрума" делает ее усложненной).
Обычно при программировании на "Спектруме" такой многопозицион-
ный переключатель организуют так:
10 INPl/T choice: GO ТО choice*100 + 100
Но с использованием ON это можно делать более гибко, т.к.
номера строк перехода не должны быть числами одного заданного ряда.
10 INPUT choice: GO ТО 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 х
20 ON х: PRINT "one":
PRINT "two"::
PRINT "four"
30 GO TO 10
Совсем необязательно, чтобы операторы в строке ON были одного
типа. Ниже показан пример использования "смешанных" конструкций,
содержащих и вызов процедуры и GO SUB и PRINT.
10 DO
2 0 GET number
ON number
GO SUB 100
sound
GO SUB 200
PRINT "bye"
3 0 LOOP
Использование ON со списком процедур - наиболее современная,
рациональная и удобочитаемая форма.
ON ERROR номер строки или ON ERROR: оператор: оператор:...
Клавиша: N.
Для оператора ON ERROR возможны две формы записи. Первая форма
задает номер строки, к которой происходит переход, если происходит
прерывание работы по ошибке. Остальные операторы в строке ON ERROR
в этом случае не имеют к нему специального отношения.
Во второй форме после ошибки начинается выполнение операторов,
содержащихся в данной строке.
За ошибку считается любая ошибка из числа перечисленных в
инструкции к "Спектруму" или из числа приведенных в приложении к
инструкции по работе с языком "БЕТА-БЕЙСИК 3.0", т.е. все сооб-
щения БЕЙСИКа, кроме сообщений: 0: "ОК"
9: "STOP statement"
Этот режим можно отключить оператором ON ERROR 0, но он так-
же отключается автоматически при работе процедуры обработки ошибки и
вновь включается после возврата в главную программу. (Ей прихо-
дится отключаться, иначе был бы конфуз, когда при обработке соб-
ственной ошибки она вызывала бы саму себя и вновь сталкивалась с той
же ошибкой.)
Этой процедуре доступны три специальные переменные, которые
могут быть очень и очень полезны: LINO, STAT и ERROR. Все это не
ключевые слова и набираются по буквам.
LINO и STAT - номер строки, в которой произошла ошибка и номер
оператора в строке.
ERROR - номер кода ошибки. Когда мы закончим печать инструкции
мы дадим коды всех ошибок.
Вы можете пользоваться этими переменными в своих целях, но де-
лать это надо до того, как будет активизирована процедура ON ER-
ROR, потому как при ее активизации, как и при активизации режима
TRACE (см. ниже), эти переменные могут быть перезатерты.
Не рекомендуем Вам все возможные ошибки обрабатывать через ON
ERROR. Желательно все, за исключением одного-двух сообщений об-
рабатывать естественным путем, иначе при отладке программы может
быть трудно разобраться с тем, что в ней происходит. Во всяком
случае Вы ведь не предполагаете, что Ваши программы будут изобило-
вать многочисленными ошибками. В нижеприведенном примере программа
печатает точки на экране, а процедура обработки ошибок отсекает те,
которые выходят за его пределы.
Первая форма выглядит так:
100 ON ERROR 5000
110 FOR n=1 TO 10: INPUT "x coord ";x;"y coord ";y
120 PLOT X,y: NEXT n
4990 STOP
5000 IF error=ll AND lino=120 THEN RETURN: ELSE POP :
CONTINUE
Обратите внимание:
Оператор STOP стоит в программе для того, чтобы предотвратить
случайное исполнение процедуры обработки ошибки. Значения LINO и
ERROR проверяются потому, что сообщение "Integer out of range"
является широко распространенным и появляется во многих случаях.
Возврат из процедуры обработки ошибки выполняется к оператору,
следующему за тем, который вызвал ошибку, поэтому возврат вы-
полняется к оператору NEXT п. Если номер строки или код ошибки были
не те, то выполняется оператор CONTINUE. В результате этого
подозрительный оператор выполняется еще раз (кроме случая "BREAK
into program") и, поскольку CONTINUE не задействовал ON ERROR, то
теперь обработка ошибки пойдет стандартным путем. Оператор POP
очищает стек от адреса возврата в главную программу. Если этого не
сделать, то нормальная работа стека будет нарушена.
Вторая Форма выглядит так:
100 ON ERROR
IF error=l1 AND lino=120
THEN RETURN
ELSE
POP
CONTINUE
Есть одна "ошибка", которую необходимо обрабатывать путем,
отличным от прочих. Это "BREAK into programm". Поскольку 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
OVER 2.
См. также GET, PLOT.
Кроме 0 и 1 OVER теперь может работать с параметром 2. OVER 2
имеет то действие, что те символы или рисунки, которые печатаются
командой PLOT <строковая переменная>, добавляются к тому, что уже
есть на экране, а не затирает имеющееся изображение и не инвер-
тируют общие точки. Пиксел приобретает цвет INK, если он был INK
или он становится INK от нового рисунка. Таким образом, OVER 2
аналогичен слиянию изображений по логике OR, в то время, как OVER 1
работает по логике XOR. (Различие в их логике будет описано в
разделе "Функции").
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 х=16 ТО 224: PLOT х,х/2; "о": NEXT х
Попробуйте ввести в цикл параметр STEP 2 или 3 или более.
Скорость будет выше, а эффект не совсем тот. Поскольку рисунок "о"
имеет вокруг себя поле цвета PAPER шириной по крайней мере в один
пиксел, то при движении по экрану он будет сам себя стирать, если
перемещение делать на один пиксел за шаг. Некоторые буквы, например
"Т" имеют включенные пикселы цвета INK, подходящие к самой кромке
знакоместа, поэтому существуют такие направления движения символа,
при котором он не стирается, а оставляет след на экране. Если Вы
сами конструируете себе символьный набор, то не помешает делать его
так, чтобы со всех сторон символа оставалось поле шириной в один
пиксел.
Вы можете увеличивать или уменьшать размеры помещенных на экран
символов, графики, блоков и т.п. с использованием команды CSIZE (см.
соответствующий раздел). Команда CSIZE должна непосредственно
следовать за PLOT. Например:
PLOT CSIZE 32;INK 2;100,88;"HI!"
В печатаемую символьную строку Вы можете включить управляющие
коды CHR$ 8 - CHR$ 11. Тогда Вы сможете получать гораздо более
сложные геометрические построения.
Возможность помещать строки на экран командой PLOT очень
полезна для печати графиков и диаграмм. Во-первых, здесь возможна
более высокая точность, а во-вторых можно пользоваться той же
координатной системой, которой пользуются графические функции,
например DRAW, CIRCLE.
РОКЕ адрес,строка
БЕТА-БЕЙСИК дает возможность не только выполнять РОКЕ для чи-
сел, но и для символьных строк, что в совокупности с функцией
MEMORY$ дает возможность скоростных манипуляций с большими масси-
вами памяти. Надо, правда, отметить, что если нарасчетливый РОКЕ
какого-либо числа может вывести из строя программу, то для строк это
становится еще более критичным. Рассмотрим пример:
10 LET screen=16384
20 POKE screen, STRINGS(6144,"U")
О функции STRINGS мы будем говорить позже, в разделе "Функ-
ции" . Здесь мы заполняем экранную память кодом буквы "U", но вос-
принимается это не как код, а как двоичное число 01010101, что изо-
бражает на экране полосы.
Следующий пример демонстрирует копирование начальной области
ПЗУ в файл экранных атрибутов.
10 LET attr = 22528
20 POKE attr, MEM0RY$()(1 TO 704)
Теперь давайте нарисуем на экране что-нибудь простое, сохраним
изображение в строковой переменной и затем восстановим его на
экране, используя РОКЕ.
10 CIRCLE 128,88,70
20 FILL 128,88
30 LET а$ = MEMORY$()(16384 ТО 23295): REM весь экран
40 CLS: PRINT "нажмите любую клавишу": PAUSE 0
50 РОКЕ 16384,а$
В памяти компьютера могут одновременно храниться несколько
таких картинок. Вы можете оперативно менять их местами и по одной
выбрасывать на экран. Если Вам надо больше картинок, Вы можете одну
треть экрана считывать в строковую переменную. Если Вас интересует
не только черно-белая информация, но и атрибут» цвета, то и треть
файла атрибутов Вы тоже можете сбрасывать в такую же переменную.
Для хранения черно-белой информации экранных сегментов Вы может
пользоваться следующими командами:
Верх: LET a$=MEM0RY$()(16384 ТО 18431)
Середина: LET a$=MEM0RY$()(18432 ТО 20479)
Низ: LET a$=MEM0RY$()(20480 ТО 22527)
У компьютера достаточно памяти даже для того, чтобы исполнить
реальный мультфильм путем использования команды РОКЕ в сегмент
экрана. Чтобы хранить данные в памяти, можно использовать массив
DIM а$(10,2048).
Конечно, потенциальных возможностей у манипуляций с большими
объемами памяти гораздо больше, чем просто обслуживание экранной
памяти. Вы можете, например очистить большой объем верхней памяти и
сохранить там целую программу, а потом вызывать ее опять. Так можно
обеспечить одновременное присутствие в памяти компьютера сразу
нескольких программ.
CLEAR 33900
10 РОКЕ 34000, MEM0RY$()(22552 ТО 33800)
20 REM остальные строки этой программы.
Теперь Вы можете сделать NEW и удалить Вашу программу, но ее
копия останется в верхней памяти выше границы RAMTOP, установлен-
ной оператором CLEAR.
Можно опять вызвать эту программу в работу:
РОКЕ 23552, MEMORY$() (34000 ТО 44248)
Эту вызывающую команду можно "подвесить" на клавишу, определя-
емую пользователем и, поскольку такие определения тоже хранятся выше
уровня RAMTOP, то оно будет защищено от разрушения командой CLEAR.
DEF KEY "j": POKE 23552, MEMORY$() (34000 TO 44248)
В тот момент, как программа будет восстановлена, она продол-
жит работу с того места, в котором она была "спрятана", т.к. вместе
с программой отгружались и восстанавливались все ее системные
переменные.
Итак, как видите, БЕТА-БЕЙСИК дает Вам несложный механизм орга-
низации виртуального диска (RAM-диска) для работы сразу с нес-
колькими программами.
И еще одна идея для использования РОКЕ, заключающаяся в воз-
можности сохранения машинного кода вместе с БЕЙСИК-программой.
Присвойте этому блоку кодов имя символьной переменной и выгрузите
БЕЙСИК на ленту таким образом, чтобы при последующей загрузке РОКЕ,
находящийся в строке автостарта, автоматически перебрасывал этот код
на нужное место памяти и дальше запускайте его. Это делается
значительно быстрее, чем раздельная загрузка БЕЙСИК-программы и
блока машинных кодов. Для того, чтобы освободить место под блок
машинного кода и не потерять при этом БЕЙСИК-переменные, вос-
пользуйтесь командой CLEAR.
POP <числовая переменная>
Клавиша: Q
Команда POP удаляет последний адрес со стека, обеспечивающего
правильную работу команд GO SUB, DO-LOOP,PROC. Если при этом Вы
используете параметр <числовая переменная>, то номер строки, к
которой должен был бы быть исполнен переход, если бы Вы не сняли его
со стека, запоминается в этой переменной.
Команда POP может позволить Вам завершать работу в подпро-
граммах, процедурах и циклах не естественным путем и при этом за-
купорки стека не произойдет, если Выходя в неположенном месте, на-
пример из цикла, Вы снимете адрес естественного возврата со стека.
Команда POP без параметра просто удалит этот адрес со стека, а ес-
ли Вы используете ее с параметром, например с переменной 1ос, то
этот адрес еще останется в Вашей переменной и, может быть, он Вам
впоследствии для чего-нибудь пригодится. Может быть, по ходу
программы Вы примете решение о том, что POP был сделан неправильно и
надо все-таки перейти туда, куда должна была возвращать Ваша
процедура. В этом случае знание 1ос позволит Вам сделать GO ТО
1рс+1, хотя надо отметить, что это все же не вполне то же самое, что
и естественный RETURN. Дело в том, что адрес, откуда Вы прошли в
подпрограмму, запомнен на стеке и после RETURN Вы возвращаетесь
туда, откуда уходили. Возвращаетесь либо на следующую строку, либо
на следующий оператор в той же строке, если он есть. Переход же по
GO ТО 1ос+1 не может вернуть Вас к следующему оператору, а только к
следующей строке. Пример:
100 GO SUB 500
110 STOP
500 POP loc
510 PRINT "Подпрограмма вызывалась из строки ";1ос
520 GO TO loc+1
Если Вы в строке 520 поставите 520 RETURN то получите сообщение
"RETURN without GOSUB", поскольку к этому моменту на стеке уже не
будет никакого адреса, ведь он был снят командой POP.
Вызов команды POP, когда на стеке нет данных, дает сообщение
об ошибке V, "No POP data".
PROC имя <параметр><,параметр><,параметр>...
Клавиша: 2
См. также Главу 3 "Процедуры", а также раздел DEF PROC.
Для того, чтобы вызвать процедуру, в версии 3.0 нет необходи-
мости давать ключевое слово PROC и оно сохранено главным образом для
того, чтобы обеспечить совместимость с предыдущими версиями
БЕТА-БЕЙСИКа. Вы можете обращаться к процедуре по ее имени без этого
ключевого слова, для чего имя вводится после отключения К-режима
вводом ведущих пробелов или вызовом режима KEYWORDS 4.
С другой стороны, слово PROC используется, например, в команде
LIST PROC (см.).
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$(l)=CHR$ 34 THEN LET a$=VAL$ a$
READ LINE позволяет сделать строки DATA более удобными для
чтения, хотя главное назначение этой команды - сделать возможным
ввод строковых данных без кавычек.
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 (а$) ищется значение а$, так, например, если а$ = "fish", то
ищется "fish", а не а$.
REF х ищется значение х, например, если х=10, то ищется 10
(числовая форма).
Не играет никакой роли регистр встреченных символов - прописные
буквы или строчные.
При поиске переменных необходимое условие, что имя должно на-
чинаться и заканчиваться символами, отличными от буквы или цифры.
Это позволяет отличать разные переменные, имеющие общие символы в
имени, например: count account counts
При поиске чисел поиск идет не по их символьному представлению
на экране, а по их числовой интегральной (пятибайтной) форме,
которая стоит за всяким числом, появляющимся в любой БЕЙСИК-стро-
ке. Это тоже позволяет избежать конфузов. Таким образом, внут-
ренние вложения в переменные и числа не мешают правильной работе.
Если же Вы ищете набор символов, заключите его в скобки и он
будет найден, даже если является вложением в большую строку.
Если Вы используете строковую переменную при поиске, то ее надо
заключить в скобки, чтобы БЕТА-БЕЙСИК мог отличить случай поиска по
имени от поиска по значению.
REF имя переменной.
Клавиша: SHIFT + "7"
Мы рекомендуем Вам предварительно прочитать главу 3 "Проце-
дуры", прежде чем двигаться дальше.
Здесь ключевое слово REF используется для того, чтобы сооб-
щить процедуре о том, что такие-то и такие-то параметры этой про-
цедуры передаются в виде ссылки, а не по значению.
Это означает, что во время исполнения процедуры соответствую-
щие переменные могут быть временно переименованы в имя, стоящее
после REF. Это обеспечивает передачу параметров не только из
вышележащей процедуры в нижележащую, но и наоборот снизу вверх.
Массивы ВСЕГДА ДОЛЖНЫ передаваться, как ссылки. В нижележащем
примере REF а$ относится к символьной строке или массиву, a REF Ь()
- относится к числовому массиву.
100 DEF PROC crunch REF а$, REF b(), REF output
RENUM <*><начало TO конец> LINE <новое начало STEP <шаг>.
Клавиша: 7
RENUM обеспечивает очень мощные возможности по перенумерова-
нию блоков программных строк, их перемещению и их копированию.
Просто команда RENUM без параметров перенумерует все строки
программы так, что номером первой строки будет 10, а далее все
строки будут идти с шагом по 10. Но можно и задать перенумерацию не
всей программы, а только заданного блока строк.
RENUM 130 ТО 220 - перенумерует все строки из этого диапазона.
RENUM 130 ТО - перенумерует все строки, начиная со строки 130 и
до конца программы.
RENUM ТО 100 - перенумерует строки, начиная с первой программной
строки и до строки 120 включительно, за исключением нулевой строки.
Перенумерованный блок будет перемещен в программе на заказан-
ное место, если в памяти для него место имеется, в противном случае
может быть выдано сообщение об ошибке: G, "No room for line" ("Для
строки нет места").
Команда RENUM* отличается тем, что она выполняет не перемещение
строк, а их копирование, т.е. создается новый блок с заданной ну-
мерацией строк, но старый при этом не уничтожается.
Вы можете задать в качестве первой строки не десятую, а любую
другую, указав параметр LINE (это ключевое слово). Если Вас не ус-
траивает стандартный шаг нумерации строк в БЕЙСИКе через десять,
задайте свой в качестве параметра STEP (ключевое слово). И LINE и
STEP могут быть даны или опущены по желанию, но если Вы их даете, то
порядок их следования должен быть только таким, как указано в
описании команды и не наоборот. Некоторые примеры:
RENUM
RENUM LINE 100 STEP 20
RENUM 100 LINE 300 (перенумеровывается только одна строка)
RENUM 1540 ТО LINE 2000
RENUM 100 ТО 176 LINE 230 STEP 5
RENUM * 10 TO 100 LINE 500 - копирование блока строк.
При перенумерации программных строк все ссылки на строки по их
номеру тоже перерабатываются, включая GO ТО, GO SUB, RESTORE, RUN,
ON, ON ERROR, TRACE, LIST, LLIST, LINE.
Операторы DELETE и CLOCK - не перерабатываются, Вам придется
заняться этим вручную.
RENUM не может также самостоятельно переработать вычисляемые
ссылки на номера строк, такие как GO ТО 1п*100.
После завершения перенумерации все указания на такие подозри
тельные места будут распечатаны на экране, чтобы Вы могли с ними
разобраться, например: Failed at 100:2
Failed at 230:4
Все GO TO, GO SUB и т.п., содержащие после себя такие вычис-
ляемые адреса перехода, будут распечатаны, даже если Вы и пере-
нумеровываете лишь малый блок и в нем нет таких операторов, потому
что они могут быть в других местах программы и указывать именно на
тот блок, который Вы и перенумеровали.
Если Вы желаете направить распечатку таких сложных строк на
принтер, воспользуйтесь:
OPEN #2,"р": RENUM:
OPEN #2, "s"
Примечание: Во время работы команда RENUM образует временный
буфер в экранной области компьютера, что
сопровождается неожиданными помехами на экране. Не
обращайте на них внимание, по окончании работы
экран будет восстановлен.
ROLL код направления <,число> <;х,у;ширина, длина>
Клавиша: R
См. также SCROLL
Команда ROLL перемещает изображение, имеющееся на экране или в
заданном окне вверх, вниз, влево или вправо. Все, что выходит за
пределы окна, тут же появляется с противоположной стороны. Одним
словом, команда, в отличие от команды SCROLL, не разрушает со-
держимое экрана, а только перемещает его.
Как видите, команда ROLL имеет довольно сложный синтаксис, хотя
большая часть сопровождающих параметров служит только для того,
чтобы задать окно, внутри которого действует ROLL. Если Вы, на-
пример, хотите сдвинуть на один пиксел содержимое текущего окна, а
таковым обычно является весь экран, если Вы не задали иначе, то
команда имеет такой простой вид:
10 ROLL код направления
Если Вам надо сдвинуть только черно-белую графику без цветовых
атрибутов, то в качестве кода направления нужно задать 5,6,7 или 8
(соответственно это означает влево, вниз, вверх, вправо). Поскольку
команда ROLL вызывает смещение изображения на небольшую величину,
самый лучший способ ее применения - внутри циклов.
Нарисуйте (DRAW, CIRCLE) какое-либо несложное, но крупное
изображение или прдсто дайте команду LIST и экран будет заполнен, а
затем попробуйте следующие строки:
100 FOR d=5 ТО 8: FOR р=1 ТО 100
110 ROLL d
120 NEXT р: NEXT d: STOP
Можно делать смещение и по диагонали. В этом случае в цикле
выполняется последовательность движений вверх, вправо или т.п. Если
хотите, чтобы движение шло более быстро (но менее плавно),
попробуйте: 110 ROLL d,4
Этот параметр указывает на сколько пикселов за один раз дол-
жно производиться смещение. Он не должен быть более, чем 256 при
горизонтальном движении и чем 177 - при вертикальном. Если параметр
не указан, по умолчанию принимается единица. Очевидно, что чем
больше это число, тем более значительно будет передвинуто изо-
бражение. При вертикальном движении скорость обычно пропорцио-
нальна количеству пикселов, передвигаемых за раз. При горизон-
тальном движении наилучший результат дает шаг в 4 или в 8 пик-
селов, т.к. в этом случае используются более скоростные команды
машинного кода процессора Z-80.
Если Вы хотите передвигать не только черно-белую информацию, но
и цветовые атрибуты, добавьте к коду направления число 4, а если
хотите передвигать только атрибуты, наоборот отнимите 4.
Атрибуты можно сдвигать только
на 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 у=88, г=15
20 FOR п=1 ТО 4
30 LET х=п*48+8
Код |
Направление |
Действие |
1 |
Влево |
Атрибуты |
2 |
Вниз |
Атрибуты |
3 |
Вверх |
Атрибуты |
4 |
Вправо |
Атрибуты |
5 |
Влево |
Графика |
6 |
Вниз |
Графика |
7 |
Вверх |
Графика |
8 |
Вправо |
Графика |
9 |
Влево |
Граф. + Атр. |
10 |
Вниз |
Граф. + Атр. |
11 |
Вверх |
Граф. + Атр. |
12 |
Вправо |
Граф. + Атр. |
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 и высота окна задаются в
пикселах, а ширина окна - в знакоместах. Ее конечно тоже можно было
бы задавать в пикселах, но тогда команда получается медлен-
ноработающей. Итак, параметр ширины может быть от 1 до 32, а
параметр высоты - от 1 до 176.
Что же касается атрибутов, то они перемещаются только с точнос-
тью до знакомест, поэтому работая в цвете необходимо четко планиро-
вать свои действия.
Вы можете предварительно задать окно командой WINDOW и тогда
команда ROLL будет работать с данным окном без необходимости
указывать его параметры.
ROLL может эффективно применяться при создании аркадных игр для
обеспечения плавных движений героя или ландшафта. Интересный
головокружительный эффект может иметь создание сразу нескольких
пересекающихся окон, двигающихся в разных направлениях.
100 LIST: LIST: LIST
110 LET pixels=4
120 ROLL 5, pixels; 0,175;32,88
130 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=l, попробуйте изменить строку 100 на следующую:
100 KEYWORDS 0: PRINT STRINGS(704," END PROC "): KEYWORDS 1
Слова END PROC набирайте не по буквам, а клавишей 3 в графичес-
ком режиме. И, наконец, последний пример:
200 FOR п=1 ТО 7: LIST: NEXT n
210 FOR m=l TO 175: ROLL 5;0,175;32,m: NEXT m
SAVE «зтрока TO строка;> <устройство;> имя и
SAVE DATA <устройство;>имя
См. также DEFAULT <устройство>
В отличие от стандартного БЕЙСИКа, БЕТА-БЕЙСИК позволяет вы-
гружать не всю программу, а только ее часть, а также выгружать
отдельным блоком программные переменные. Параметр сстрока ТО
строка> указывает, начиная с какой строки производится выгрузка и по
какую. Если он не указан, то выгружается вся программа целиком.
В форме SAVE DATA этот оператор служит для выгрузки только
программных переменных. Если номер устройства, на которое должна
происходить выгрузка, не указан, то выгрузка производится на ленту
(если ранее оператором DEFAULT не было задано какое-либо иное уст-
ройство в качестве основного). Если же номер устройства задан, то
выгрузка производится на соответствующий микродрайв (если командой
DEFAULT в качестве устройства ввода/вывода не были назначены
локальная сеть или последовательный порт RS232). Примеры:
SAVE 10 ТО 200; "fragment" - часть программы, начиная с деся-
той строки по строку 200 включи-
SAVE 900 ТО;"box"
SAVE DATA "vars3"
SAVE 20 TO 70;2;"bit"
тельно выгружается на ленту под
именем "fragment".
- под именем "Ьох"выгружается часть
программы, начиная со строки 900 и
до конца.
- под именем "vars3" выгружаются все
программные переменные.
- под именем "bit" на микродрайв
номер 2 выгружается часть
программы, начиная со строки 20 по
70-ую.
ВНИМАНИЕ!
1. Если Вы захотите загрузить ранее выгруженную часть программы
или блок программных переменных, то имейте в виду, что после ко-
манды LOAD стирается имеющаяся в компьютере Бейсик-программа,
включая и нулевую строку. Блок программных переменных тоже трак-
туется как программа, не имеющая номеров строк.
Во избежание подобных коллизий Вам целесообразно подгружать ра-
нее отгруженные фрагменты с помощью команды MERGE.
2. Одно из важнейших назначений команды 'SAVE строка ТО строка'
состоит в том, чтобы Вы могли отгружать свои процедуры по-отдель-
ности и формировать из них на кассете библиотеки процедур для
последующего использования. Узнать начальные и конечные номера
строк для каждой процедуры можно с помощью ранее рассмотренной,
команды LIST PROC.
Может быть, Вы сочтете целесообразным перед выгрузкой процедуры
переместить ее в конец программы, поменяв в ней номера строк с
помощью команды RENUM и впоследствии использовать с помощью команды
MERGE.
3. Наиболее целесообразное применение оператора SAVE DATA -
для отгрузки состояния программы. Если Вы написали игровую програм-
му, имеющую большую продолжительность, то с помощью такой команды
сможете дать пользователю возможность отложить игру. Впоследствии
он сможет начать ее сначала или продолжить, загрузив отложенный блок
программных переменных.
SCROLL код направления <,число> <;х,у;ширина, длина>
Клавиша: S
См. также ROLL
Команда SCROLL имеет синтаксис очень похожий на синтаксис
команды ROLL (следует сначала прочитать раздел о команде ROLL).
Основное отличие состоит в том, что команда SCROLL может быть
использована без параметров, а команда ROLL - не может. В этом
случае SCROLL вызывает скроллинг экрана на одно знакоместо вверх.
Если за командой стоит код направления 5,6,7 или 8, то теку-
щее окно (а обычно это весь экран) будет передвинуто в заданном
направлении (направление смещение стандартно для "Спектрума"):
5 - влево 6 - вниз
7 - вверх 8 - вправо
Когда часть изображения выходит за пределы экрана, она без-
возвратно теряется. С противоположной стороны экрана вытягивается
чистое поле.
Команда может действовать не на весь экран, а только на задан-
ное окно. В этом случае следует задать параметры.
X,Y - координаты левого верхнего угла окна (задаются в пиксе-
лах). Система координат та же, что и для команд PLOT и DRAW.
Ширина - размер окна по горизонтали (задается в знакоместах).
Длина - размер окна по верти кали (задается в пикселах).
Обе команды и SCROLL и ROLL широко применяются при разработке
игровых программ, а также в различных графических приложениях.
Попробуйте поэкспериментировать с теми примерами, которые были
приведены для команды ROLL, заменив команду на SCROLL и посмотрите
на разницу их действия.
А вот пример небольшой программы, которая передвигает по экрану
символьную строку.
100 LET а$ = "HAPPY NEW YEAR"
110 FOR с = 1 TO LEN a$
120 PRINT AT 10,31; INK 7; A$(c)
130 FOR p=l TO 8
140 SCROLL 5; 0,95;32,8
150 NEXT p
160 NEXT с
170 FOR p=l TO 255
180 SCROLL 5; 0,95; 32,8
190 NEXT p
Обратите внимание на то, что в строке 120 устанавливается белый
цвет INK (предполагается, что исходно цвет PAPER тоже белый). В этом
случае символы, печатаемые в позиции 10,31 оказываются невидимыми и
только по мере смещения влево командой SCROLL проявляются на экране.
Печать символов по одному выполняет цикл по "с" (строки 110...160).
Смещение их влево на одно знакоместо выполняет первый цикл по "р"
(строки 130...150), а второй цикл по "р" (строки 170...190) выводит
текст за пределы экрана.
Эти же принципы могут быть использованы для изящной выдачи
текстов на экран, например при печати информационных сообщений.
200 |
DATA "Давным давно в |
далекой |
210 |
DATA "галактике жили |
были... |
300 |
FOR k= 1 ТО 2 READ а$ |
|
310 |
PRINT AT 21,0; INK 7; |
a$ |
320 |
FOR p=l TO 8: |
|
330 |
SCROLL 7 |
|
340 |
NEXT p |
|
350 |
NEXT k |
|
360 |
FOR p=l TO 176 |
|
370 |
SCROLL 1 |
|
380 |
NEXT p |
|
SORT или SORT INVERSE «зтроковый массив>/
<числовой массив>/
«зимвольная строка>
Клавиша: М
Команда SORT переорганизует символьные строки или символы или
числа в восходящем или в нисходящем порядке. Рассмотрим для начала
ее работу с символьными массивами на примере следующей программы,
которая генерирует 100 десятибуквенных символьных строк. (Вы можете
ускорить работу этой программы, если воспользуетесь вместо
стандартной функции БЕЙСИКа RND функцией БЕТА-БЕЙСИКа RNDM, о
которой речь пойдет ниже.
100 DIM а$ (100,10)
110 FOR s=l ТО 100
120 FOR р=1 TO 10
130 LET a$(s,p) = CHR$(RND*25+65)
140 NEXT p
150 NEXT s
160 GO TO 200
170 SORT a$
200 FOR s= 1 TO 100
210 PRINT a$(s)
220 NEXT s
Как только массив будет сгенерирован (а это займет опреде-
ленное время), программа распечатает его в том порядке, в каком он
получится.
Теперь дайте прямую команду GO ТО 170 (только не RUN, а то
массив будет утрачен) и Вы увидите, как тот же массив будет рас-
печатан в алфавитном порядке.
Сортировка 100 строк займет 0,2 секунды и это время очень
мало зависит от длины строк, но сильно зависит от их количества.
Сортировка массива длиной 200 строк займет примерно 0,7 сек., а для
массива в 400 строк - около трех секунд.
Строки сортируются в порядке возрастания кодов первых симво-
лов. Если Вы не знаете, какому символу какой код соответствует, то
распечатайте себе на память эту таблицу:
100 FOR i = 32 ТО 127
110 PRINT i, CHR$ i
120 NEXT i
Если в строке 170 SORT a$ заменить на SORT INVERSE a$, то
массив будет отсортирован и распечатан в обратном порядке.
Вы можете сортировать не весь массив, а только его часть, на-
пример :
SORT а$ (1 ТО 20) отсортирует только первые 20 элементов масси-
ва, а команда SORT а$(30 ТО) - отсортирует все элементы, начиная с
тридцатого и до конца. Можно поступить еще хитрее и отсортировать
массив не по первому символу, а например по второму и всем
последующим. SORT а$ () (2 ТО) В этом случае первый символ не будет
приниматься во внимание. Как видите, нам пришлось применять скобки
дважды.
Команда SORT позволит Вам создавать и эксплуатировать
простые, надежные и гибкие базы данных.
Когда мы говорим о базах данных, то массив, о котором шла речь,
будем считать ФАЙЛОМ, а его символьные строки - ЗАПИСЯМИ. В записи
можно выделить различные области для разной информации, назовем их
ПОЛЯМИ. Например, первые 20 символов записи отведем для имени
Вашего партнера. Это будет ПОЛЕ "ИМЯ". Следующие 20 символов
отведем для его адреса - ПОЛЕ "АДРЕС". И, наконец еще один символ
для записи возраста - ПОЛЕ "ВОЗРАСТ". Всего на запись уйдет 41
символ.
Встает вопрос, каким образом одним символом выразить двузнач-
ный возраст. Это возможно. Одного символа достаточно для выра-
жения возраста от 0 до 255, если сделать так:
LET а$ (s;41) = CHR$ п, где s - номер записи в Вашей базе,
п - возраст партнера.
Такая форма хранения чисел достаточно проста и экономит па-
мять. Но что делать, если нам понадобится хранить более сложную
информацию, например размер сберегательного счета. Вы можете
воспользоваться следующим приемом:
LET а$ (s,41 ТО 46) = STR$ b ,где b - содержимое расчетного
счета.
Это число будет храниться в виде строки, например: "100" или
"22375".
Правда, при этом возникает один недостаток, связанный с тем,
что числа будут выровнены по левому полю и сортировка сработает
неправильно. Посмотрите, если у Вас есть три записи "9м, "75м и
"500", то после сортировки они расположатся в порядке: 500
75
9
Причина в том, что левое поле при сортировке является
первичным.
Йервый выход из положения прост, но неудобен. Вам всегда
придется помнить об этой особенности и, вводя числа в свою базу,
добавлять необходимое число ведущих нулей: 000009
000075
000500
Более грамотный выход - следующий. Прежде, чем заносить данные
по полю "СЧЕТ" в массив, программа должна переформатировать их так,
чтобы они были выровнены не по левому полю, а так, чтобы их
десятичные знаки занимали одинаковые положения. Сотни - под сотнями,
десятки - под десятками, тысячи - под тысячами и т.п. Тогда наш
пример по результатам сортировки выглядел бы так: 9
75
500
Такое форматирование можно сделать с помощью функции Бета-
Бейсика USING$, о которой мы расскажем чуть ниже. Пример ее
использования выглядит так:
LET a$(s, 41 ТО 46) = USING$ ( "000.00м,b)
Теперь Вы можете сортировать свои записи по полям "ИМЯ", "АД-
РЕС", "СЧЕТ". Вы можете, например, отсортировать базу по именам, а
затем первые двадцать записей - по размеру счета и т.п. Вы можете
сортировать их как в восходящем, так и в нисходящем порядке.
Конечно, Вам следует принять меры предосторожности при запол-
нении базы, чтобы не нарушить ее структуру, т.е. внося имя парт-
нера следует его ВСЕГДА записывать с первой позиции и НИКОГДА не
продолжать за двадцатую, иначе нарушится поле "АДРЕС". Впрочем, все
меры предосторожности следует делать программно, проверяя вводимые с
помощью INPUT данные и тогда ошибки можно исключить.
Мы разобрались с символьными массивами, но команда SORT может
работать и со строковыми переменными:
INPUT s$: SORT s$: PRINT s$
Если Вы здесь по команде INPUT введете строку "Fred Bloggs", то
на печать получите " BFdegglors".
Это не выглядит очень полезным, но позволяет работать с чис-
ловыми данными в тех случаях, когда они представлены символьными
строками, а мы на наших страницах уже неоднократно упоминали о том,
что это весьма экономичный способ хранения чисел в памяти
компьютера.
Команда SORT может работать и с числовыми массивами, как с од-
номерными, так и с двумерными. Синтаксис ее применения тот же, что
и при работе с символьными массивами. Двумерные массивы мы можем
представлять для себя в виде таблиц, в которых первая размерность
это номер ряда, а вторая - номер столбца. Так, команда
SORT b (1 ТО 20) (2)
отсортирует первые двадцать рядов таблицы по второму столбцу. Обра-
тите внимание на то, что мы всегда должны использовать хотя бы одну
пару скобок при имени массива Ь() для того, чтобы компьютер отличал
массив от простой переменной Ь, даже и в тех случаях, когда внутри
скобок ничего не стоит.
SORT Ь()
Если используется и вторая пара скобок (для указания номера
столбца, по которому производится сортировка), в ней должно быть не
более одного числа, в отличие от сортировки символьных массивов.
Сортировка числовых массивов идет примерно в четыре раза мед-
ленне, чем сортировка строковых массивов. Это связано с необхо-
димостью иметь дело с интегральной (пятибайтной) формой записи чисел
в "Спектруме" (см. "Программирование в машинных кодах"; М:,
"ИНФОРКОМ", 1990, 1992).
В отличие от сортировки символьных массивов и строк, при
числовой сортировке первыми идут более высокие числа, а затем низ-
кие. Сделать порядок следования чисел возрастающим можно очевидно
командой SORT INVERSE.
SPLIT (не ключевое слово).
Фактически вместо этой команды вводится символ "о" .
Клавиша SYMBOL SHIFT + W (не в графическом режиме,а в обычном).
Фактически это не оператор языка, а дополнительная возмож-
ность редактирования программы. Если Вы редактируете очень длин-
ную строку (она находится в нижней части экрана) и хотите часть ее
ввести в программу, а с оставшейся частью продолжить работу, то
можете самым первым символом в любом операторе строки поставить
символ "о" и нажать ENTER. В этом случае начало строки до этого
символа перейдет в программу со своим номером строки, а оставшаяся
часть останется в области редактирования с тем же номером строки и
курсором справа от него, чтобы Вы могли первым делом изменить его
так, как Вам наДо. Например, в нижней части экрана у Вас было:
10 PRINT "hello": GO ТО 10: о PRINT "godbye"
Если Вы теперь нажмете ENTER, то в листинг программы пойдет:
10 PRINT "hello": GO ТО 10
а в нижней части останется:
10 (курсор) PRINT "goodbye"
Теперь Вы можете изменить номер строки и, соответственно, от-
править эту строку в ту часть программы, в какую хотите, но можете
передумать и "подшить" ее к десятой строке с помощью команды JOIN.
TRACE номер строки или TRACE: оператор: оператор:..
Клавиша: Т.
Эта команда относится к разряду отладочных. С ее помощью Вы
можете запускать БЕЙСИК-программу на выполнение с постоянной распе-
чаткой результатов заданной строки, заданного оператора или за-
данной переменной. При этом Вы можете изменять (замедлять) ско-
рость исполнения программы.
Существуют две формы оператора TRACE.
1. TRACE номер строки - вызывает переход GO SUB к этой строке
перед исполнением любого оператора в Вашей программе. Это не
относится к операторам самой этой строки, а то программы бы
зациклилась.
2. Вторая форма: TRACE оператор: оператор: ....
В этом случае перед исполнением любого оператора Вашей прог-
раммы исполняется последовательность операторов, стоящих после TRA-
CE.
И в том и в другом случае, при использовании оператора TRACE
Вам доступны две вспомогательные переменные - lino и stat.
LINO - это номер строки, которая сейчас будет выполняться.
STAT - номер оператора в этой строке, который сейчас будет
исполняться.
При исполнении трассирующей подпрограммы режим TRACE естест-
венно отключается и вновь будет включен по оператору RETURN, который
завершает эту подпрограмму. Содержимое подпрограммы можете
избрать любое, например:
9000 PRINT INVERSE 1; lino;":"; stat; RETURN
Введите эту подпрограмму в свою программу и введите команду
TRACE 9000 в ту точку программы, с которой хотите начать отладку.
Если Вы хотите воспользоваться второй формой оператора TRACE,
то можете не вводить строку 9000, а вставить в ту строку, с которой
хотите начать отладку, последовательность операторов:
TRACE: PRINT INVERSE 1; lino; ":"; stat: RETURN
Отключить режим трассирования, начиная с какой-то строки в
Вашей программе можно вставив туда оператор TRACE 0.
Приведенная выше TRACE-подпрограмма позволит получить на экране
номера строк и номера операторов, исполняемых Вашей программой в
любой момент. Для того, чтобы отличать их от тех данных, которые
программа должна выдавать на экран сама по себе, включен режим
инверсной печати INVERSE 1.
Если Вы хотите, чтобы не только номера исполняемых строк, но их
содержимое было постоянно перед глазами, Вы можете использовать
команды:
LIST lino ТО lino или LIST lino-l ТО lino
Если у Вас задан интервал между строк больше, чем 1, вторая
команда будет отличаться от первой тем, что при печати содержимого
строк не будет изображаться позиция курсора.
Команды RUN и CLER также отбивают режим трассирования, как и
TRACE 0.
Если Вы хотите замедлить исполнение программы, введите в
подпрограмму TRACE оператор PAUSE или сделайте это иным доступным
Вам способом, например через ВЕЕР.
Вы можете распечатать также и содержимое интересующих Вас пере-
менных, задав их печать в подпрограмме, но тогда постарайтесь, чтобы
эти переменные были объявлены как можно ранее в Вашей программе,
иначе можете получить сообщение "Variable not found".
Чтобы отличать ту печать, которую делает оператор TRACE от той,
которую ведет сама программа, Вам может быть захочется ис-
пользовать оператор PRINT AT (а это может пригодиться, если про-
грамма стррит некоторое графическое изображение и Вы не хотите его
нарушать посторонней печатью). Но в этом случае Вам придется
позаботиться о том, чтобы перед вызовом трассирующей подпрограммы
запоминались координаты текущей позиции печати, а после ее
исполнения они бы восстанавливались. Нижеприведенная подпрограмма
позволит это сделать:
9000 LET pos = DPEEK(23688)
9010 PRINT AT 0,0; lino;":"; stat;" ","a$= "; a$
9020 DPOKE 23688,pos: RETURN
Системная переменная SPOSN, расположенная в адресах 23688 и
23689 хранит информацию о текущих координатах позиции печати. Запо-
миная и восстанавливая ее через переменную pos, Вы добьетесь того,
чего хотели.
Поработав какое-то время с БЕТА-БЕЙСИКом, Вы сами для себя
выработаете наиболее удобную отладочную процедуру и тогда сможете
присвоить ее с помощью команды DEF KEY какой-либо клавише и
отгрузить вместе с самим БЕТА-БЕЙСИКом на ленту, чтобы впоследствии
вызывать одним нажатием тогда, когда надо.
UNTIL условие.
Клавиша: К.
Оператор позволяет исполнять циклы DO - LOOP до тех пор, пока
"условие" не станет справедливым. Подробности см. в описании
операторов DO - LOOP.
USING и USING$
Клавиша: U.
И USING и USING$ служат для того, чтобы задать формат, в ко-
тором Вы хотите распечатать числа. Оператор USING самостоятельно не
используется, а употребляется только в качестве квалификатора
оператора PRINT или LPRINT, в то время, как USING$ является функ-
цией, имеет самостоятельное значение в виде символьной строки.
Функция USING$ выдает символьную строку такой, какой она могла бы
быть напечатана при использовании оператора PRINT USING. Благодаря
этому появляется возможность использовать форматированные строки не
только с командой PRINT, но и с любой другой, например LET, которая
может работать со строками.
При использовании USING или USING$ желаемый формат задается в
виде форматной строки. Это символьная строка, в которой знаком "хэш"
(#) обозначены ведущие пробелы, символ "ноль" обозначает ведущие
нули и любой из них может служить для указания значащих цифр после
десятичной точки.
100 FOR п=1 ТО 20:
110 LET X=RND*100
120 PRINT X, USING "###.##";x
130 NEXT П
Вы получите на экране два столбца. Слева - неотформатиро-
ванная печать, а справа - отформатированная. Обратите внимание
насколько она выглядит аккуратнее. Попробуйте в строке 120 изменять
форматную строку и посмотрите, как будет меняться результат.
Обратите также внимание, что при форматировании чисел с помощью
USING происходит их округление до заданной в формате десятичной
цифры.
А вот еще несколько примеров того, как работает форматная
строка для числа 12.3456.
"##.#" 12.3
"###.#" _12.3
"####.##" _12.35
"000.00" 012.35
"00" 12
"$00.00" $12.35
"0.00" %. .3
Предпоследний пример демонстрирует возможность использования в
форматной строке произвольных символов, а не только знаков "#" и
"0".
Последний пример демонстрирует случай переполнения формата.
Нельзя одним знаком выразить двузначную целую часть - об этом
свидетельствует символ %, выводимый на печать, как индикатор ошибки.
Функция USINGS очень похожа на оператор USING. Разницу
продемонстрируем на примерах. Вместо PRINT USING а$; number можно
сделать PRINT USING$ (а$, number) или
LET b$ - USING$ (a$,number)
PRINT b$
VERIFY <строка TO строка;> <устройство;> имя
и
VERIFY DATA <устройство;> имя
Как и стандартная команда VERIFY, эта команда с параметрами
служит для проверки правильности выгруженного на ленту или микро-
драйв блока данных (программы или ее фрагмента).
Мы не будем останавливаться на синтаксисе команды - он в
точности соответствует синтаксису команд SAVE и SAVE DATA,
рассмотренных ранее.
WHILE условие.
Клавиша: J.
Оператор позволяет исполнять циклы DO - LOOP до тех пор, пока
"условие" справедливо. Подробности см. в описании операторов DO
LOOP.
WINDOW номер окна <,x,y,w,l>
Клавиша: 5.
См. также CLS, CSIZE.
Команда WINDOW позволяет Вам назначить часть экрана для выдачи
информации при печати или листании. Если окон несколько, то каждое
имеет текущую координату позиции печати, а также статусы OVER,
BRIGHT, FLSH, INK, PAPER и CSIZE.
В качестве номера окна Вы можете использовать любое число от 1
до 127, причем заданное Вами число не имеет никакого специального
значения - это просто опознавательный номер, присущий данному окну.
Все параметры, присвоенные каждому окну, хранятся выше адреса
RAMTOP (который, если надо, понижается). Это защищает данную
информацию от уничтожения командой NEW и позволяет выгрузить ее на
ленту вместе с кодом самого БЕТА-БЕЙСИКа.
Нулевое окно - это весь экран и именно оно является "текущим
окном" в момент первого запуска БЕТА-БЕЙСИКа. Это означает, что
исходный размер символов и установка цветов - стандартные. Чтобы
задать иное окно, Вы можете делать например так:
WINDOW 1,0,175,128,176
Заданное окно имеет координаты левого верхнего угла 0, 175.
Ширина окна - 128 пикселов (пол-экрана), а высота - 176 пикселов
(весь экран). Текущий установленный размер символов - стандартный
(8X8), а установка цветовых атрибутов соответствует нулевому окну,
хотя их можно и изменить.
Мы только что задали первое окно, но это еще не сделало его
текущим. Чтобы сделать это, надо дать команду WINDOW, указав при ней
только номер окна: WINDOW 1
Указанное окно стало текущим (если оно было задано). Если же
Вы забыли его предварительно задать, то получите сообщение об ошибке
устройства ввода/вывода - "Invalid I/O device". Единственное окно,
которое задается автоматически, без Вашего участия - нулевое окно.
После того, как первое окно стало текущим, весь вывод на пе-
чать по командам PRINT, LIST, PLOT, DRAW и т.п. будет произво-
диться только в пределах области данного окна, то есть, только на
левой половине экрана. Если хотите поэкспериментировать с окнами
другого размера, можете изменить определение первого окна или за-
дать любое другое. В любом случае все изменения, которые Вы произ-
ведете, будут видны на экране только после того, как Вы дадите
команду WINDOW п, даже если окно с номером п перед этим и так было
текущим. .Только после этой команды начинают действовать параметры
окна, установленные при его задании.
При выходе из окна, а точнее говоря при вызове другого окна,
сохраняются все параметры, соответствовавшие данному окну - CSIZE,
INK, PAPER и т.п., включая и координаты текущей позиции печати. Они
сохраняются в областях памяти выше уровня RAMTOP.
Когда Вы вновь войдете в это окно, вызвав его командой WINDOW
п, все эти параметры будут для него восстановлены. Таким образом,
Вы можете менять размер печатаемых символов CSIZE и цветовые
атрибуты переключением между окнами.
В нижеприведенном примере задаются два окна и поочередно в них
производится печать.
10 WINDOW 1,0,175,128,176
20 WINDOW 2,128,151,128,80
30 WINDOW 1: INK 1: PAPER 6
40 WINDOW 2: INK 7: PAPER 1: CSIZE 4,8
50 WINDOW 0
60 PRINT WINDOW 1;"one"; WINDOW 2; "two";: GO TO 60
Если Вам надо очистить какое-либо окно, Вы можете использовать
оператор CLS п, где п - номер окна, подлежащего очистке. В самом
начале программы целесообразно давать команду CLS 0, очищая весь
экран и подготавливая его к работе.
Если Вам надо удалить из памяти параметры задания какого-либо
окна, для этого служит оператор ERASE WINDOW n
XOS, XRG, YOS, YRG.
Это не ключевые слова, а своеобразные переменные, с помощью
которых можно изменять масштаб экрана и начало координатной сетки,
используемой операторами PLOT, DRAW, DRAW ТО, CIRCLE, GET и FILL.
XOS - смещение оси X от стандартной.
YOS - смещение оси Y от стандартной.
У этих переменных есть одна особенность. В отличие от прочих,
команды CLEAR и RUN их не уничтожают, а устанавливают в заранее
заданное фиксированное значение.
Попробуйте дать команду CLEAR, а затем сделать PRINT XOS или
PRINT xos и Вы получите "0", а не "Variable not found", как это было
бы для обычных переменных.
Оба смещения имеют нулевые значения, если Вы не зададите
иные с помощью команды LET.
LET xos=128, yos=88
Такое задание начала координат очень удобно для команды PLOT,
т.к. теперь координата X изменяется не от 0 до 255, а от -128 до 127
и, соответственно, координата Y изменяется от -88 до 87.
Команда CLS, как Вы знаете, не только очищает весь экран, но
еще и устанавливает текущую позицию печати в координаты 0,0. Если Вы
изменили начало координат с помощью XOS и YOS, то начальная позиция
печати будет устанавливаться после CLS в новое начало координат.
Переменные XRG и YRG определяют масштаб, в котором исполня-
ются команды PLOT, DRAW и пр. Исходное значение XRG = 256 (Вы
можете напечатать до 256 различных точек вдоль оси X), а для YRG
176. Изменив XRG и YRG, Вы меняете масштаб изображения.
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:
50 STOP
100 CLS: PLOT 0,0: DRAW 50,0
110 DRAW 0,50: DRAW -50,0
120 DRAW 0,-50: PAUSE 100
1*30 RETURN
По этой программе сначала рисуется нормальный квадрат, за-
тем он вытягивается по оси X, затем по осям X и Y и, наконец, только
по оси Y.
Нижеприведенная программа рисует график функции "синус", ис-
пользуя как смещение начала координат, так и изменение масштаба.
100 LET XRG = 2*PI: REM 360 град.
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
Обратите внимание на то, что величина ^начального смещения на-
чала координат также подвергается масштабированию в заданном диапа-
зоне .
При изображении дуг или окружностей есть одна особенность.
Так, последняя тока дуги будет напечатана в соответствии с новой
системой координат и с масштабом, но сама кривая - не подвергнется
изменениям. То же относится и к окружности. Центр ее будет помещен в
точку в соответствии с новой системой координат и с масштабом, но у
Вас нет средств промасштабировать радиус, так что если Вы захотите
подобным способом получить растянутую вдоль какой-либо оси
окружность, то у Вас ничего не получится.
Есть интересная возможность использования масштабирования.
Предположим, что Вы подготовили программу для того, чтобы получать
графическое изображение на полном экране. После этого Вам
захотелось разделить экран пополам (по вертикали) и в правой
половине экрана распечатывать листинг программы, а в левой по-
ловине - результат ее работы. Это сделать несложно, задав два окна.
Но теперь есть проблема в том, что раз графические команды у Вас
были рассчитаны на полный экран, то они не смогут работать нормально
в его одной половине. В этом случае при переключении на окно Вы
можете поменять и масштаб LET XRG = 128.