Диалекты бейсика для ZX Spectrum 1992 г.

Beta Basic - Работа с массивами. Работа с клавиатурой.


РАБОТА С МАССИВАМИ_

SORT, INARRAYO, LENGTH(), COPY, JOIN, DELETE, CHAR$(), NUMBER()

SORT [INVERSE] < символьный масс ив {числовой массив|строка символов >

Этот оператор упорядочивает элементы числового или символьного массива. Числовой массив должен быть одномерным, символьный — либо одномерным, либо двухмерным (одномерный массив символьных строк). В одномерном символьном массиве оператор SORT расставляет символы (в массиве строк — строки) в алфавитном порядке, точнее, в порядке возрастания кодов. Числовой массив сортируется но значениям его элементов от большего к меньшему. Конструкция SORT INVERSE сортирует элементы в обратном порядке.

SORT позволяет почти мгновенно отыскать максимальное и минимальное значения в числовом массиве:

10 DIM А( 100)

20 FOR k=1 ТО 100: LET A(k)=10*RND: NEXT k

30 SORT A(): LET Max=A(1): LET Min=A(100)

40 PRINT "Min=";Min, "Max=";Max

Еще интереснее использовать этот оператор с символьными массивами. Здесь он открывает большие перспективы для создания справочных систем и баз данных.

В символьной строке оператор SORT сортирует символы; в массиве символьных строк переставляет строки, а порядок символов в пределах каждой строки не изменяет. То есгь последовательность строк в массиве становится подобной размещению слов в словаре.

Сферу влияния оператора SORT можно ограничить заданным диапазоном строк с помощью сечения массива, например:

SORT А$(1 ТО 40)

Сортировать массив можно не только по первым символам строк, но и по произвольному сечению, заданному во втором измерении. К примеру, строка

SORT А$(1 ТО 40)(2 ТО)

отсортирует первые 40 строк массива, игнорируя их первый символ.

INARRAY(<массив строк>,<строка-образец>)

По многим свойствам эта функция напоминает функцию INSTRING. Она возвращает номер элемента массива символьных строк, в котором обнаружено первое включение <строки-образца>. На элемент массива (строку), начиная с которой необходимо вести поиск, указывает первый аргумент функции, например:

INARRAY(A$(20),"A")

Эта функция начнет поиск символа А с 20-го элемента массива (то есть с 20-й строки).

COPY <массив 1> ТО <массив 2>

JOIN < массив 1> ТО < массив 2 >

Оба оператора добавляют к <массиву 2> элементы <массива 1>. Оператор COPY копирует указанные элементы, сохраняя их в исходном массиве, a JOIN переносит, не сохраняя оригинал («сшивает» два массива). Поддерживается работа с одно- и двухмерными числовыми и символьными массивами.

Допустимо копировать массивы сами в себя.

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

10 LET A$="QWERTYUIOP": LET B$="qwertyuiop" 20 COPY A$ TO B$ 30 PRINT "A$=";A$, "B$=";B$

Эта небольшая программка выведет на экран: A$=QWERTYUIOP B$=qwertyuiopQWERTYU!OP

После замены в строке 20 оператора COPY на JOIN выполнение программы прервется на 30-й строке сообщением Variable not found — оператор JOIN ликвидирует переменную А$ после переноса ее содержимого в переменную В$.

Заменим 20-ю строку на 20 COPY А$(4 ТО 6) ТО В$(3)

Результат станет таким:

A$=Q WERTYUIOP B$=qwRTYertyuiop

Применение оператора JOIN с такими же параметрами приведет к следующему:

A$=QWEUIOP B$=qwRTYertyuiop

Таким образом, сечение массива-источника (в нашем случае А$(4 ТО 6)) задает фрагмент, подлежащий переносу или копированию. Номер элемента, указанный в массиве-приемнике, (В$(3)) определяет место в нем, куда будет вставлен соответствующий фрагмент.

При работе с числовыми массивами также допустимо задавать их сечения, используя тот же синтаксис, что и с символьными массивами.

Операции копирования и переноса двухмерных массивов более сложны. Для их анализа Вы можете написать специальную программу. Мы же ограничимся приведением диаграмм, иллюстрирующих работу операторов COPY и JOIN с массивами разных размеров и размерностей (рис. 24). На диаграммах представлены

массивы А() и В() (они могут быть как числовыми, так и символьными), а также результаты выполнения оператора COPY А() ТО В() или JOIN А() ТО В().

но т i=i то з 120 on i

LET Н5Ш LET »=37«

if тм<т тнел

LET a:12S2, Ph0IW=235 ELSE

LET 1=19.03, Phon«:242

131 ПЕХТ i

Рис. 21. Фрагмент листинга программы Beta Basic.

еееее| еввееI

j

1 AAA AAA

ввв ввв

| АААА j АЛЛА

ВВВ I ,ВВВ I АЛА, AAA

ВВВВВ ВВВВВ АААоо АААоо

2)

:в 3) В

. IВВВВВ А) ВВВВВ

Г ввввв!

[ВВВВВ Аоооо I Аоооо IАоооо

АААА АААА

А и В — элементы соответствующих массивов;

о — нулевое значение в числовом массиве или пробел — в символьном.

Рис. 24. Работа COPY и JOIN с двухмерными массивами.

Из этих диаграмм становится ясно, что в случае, когда второе (либо единственное) измерение массива-приемника меньше второго (либо единственного) измерения массива-источника, массив-приемник играет роль «прокрустова ложа» — пристраиваемый фрагмент или весь массив будет усечен по второй размерности до границ своего нового пристанища (случаи 1 и 3).

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

Для всех вариантов применения оператора JOIN, если не было указано сечение массива-источника, последний будет удален из области переменных.

Синтаксис описываемых операторов допускает использование сечений только по первому измерению.

Как и случае одномерных массивов и символьных строк, двухмерные массивы можно копировать или переносить не только в конец массива-приемника, но и в любое другое его место.

DELETE <массив^символьная переменная)

Оператор удаляет из области переменных символьный или числовой массив либо, если задано сечение массива, его фрагмент. Он г1акже работает с символьными и числовыми переменными, удаляя их из области переменных. Действие оператора DELETE демонстрирует следующая программа:

10 DIM А(30,100)

20 DELETE А(11 ТО 20)

30 PRINT "A(";LENGTH(1 ,"A()");",";LENGTH(2,"A()");")"

Она напечатает: А(20,100), то есть оператор DELETE при указании сечения сокращает массив по первому измерению. В случае работы с символьными строками он позволяет вырезать из них заданные фрагменты. При этом оператор DELETE С$(М ТО N) равносилен строке LET С$=С$( ТО M)+C$(N ТО ).

Удаляя из программы переменные и массивы, отслужившие свой век, DELETE позволяет экономно расходовать память компьютера.

LENGTH!<измерение массива>,"<имя массива)")

Функция LENGTH определяет количество элементов одно- или двухмерного массива (как символьного, так и числового) по каждому его измерению. Номер измерения задается первым аргументом функции, который может принимать значения 1 или 2. Имя массива заключается в кавычки100:

10 DIM А(10,45)

20 PRINT LENGTH(1 ,"А()"), LENGTH(2,"A()")

В результате работы этого примера будут выведены два числа — 10 и 45.

Функция LENGTH позволяет работать с массивом, размеры которого в данной точке программы неизвестны, без опасения выйти за его пределы. Это может понадобиться в процедурах, где универсальный алгоритм рассчитан на работу с массивами, в общем случае имеющими разную длину. Например, программа сортировки элементов одномерного массива (см. стр. 273) может быть переписана так:

10 DIM 0(100)

20 FOR k=1 ТО 100

30 LET G(k)=10*RND

40 NEXT k

SO PROC Limits G(),Emax,Emin

60 PRINT "Min=";Emin, "Max=";Emax 1000 DEF PROC Limits REF F(), REF Max, REF Min 1010 LOCAL Lng,Q() 1020 LET Lng=LENGTH(1/'F()") 1030 DIM Q(1)

1040 COPY F() TO Q(): DELETE Q(1) 1070 SORT INVERSE Q() 1080 LET Min=Q(1): LET Max=Q(Lng) 1090 END PROC

В начале этой программы при помощи генератора случайных чисел формируется массив G() (причем размер массива может быть произвольным), и ссылка на него передается в процедуру Limits (строка 50). В ней вычисляется размер массива F() (процедура «знает» массив G() только под этим именем; строка 1020) и затем его содержимое копируется в массив Q() (строка 1040), объявленный ранее как локальный (строка 1010). Далее идет сортировка (строка 1070) и нахождение предельных значений (строка 1080) по старой схеме. По выходу из процедуры не определенные ранее переменные Emax и Emin будут иметь значения, которые получили в процедуре их alter ego — переменные Мах и Min.

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

CHAR$(< число >)

NUMBER (< двухсимвольная переменная >)

Как известно, под хранение любого числа в памяти ZX Spectrum отводится 5 байтов, в то время как для представления целого числа из интервала 0...65535 достаточно только двух. Поэтому целочисленные массивы преимущественно «хранят воздух» — на Vs они заполнены нулями. Бороться с такой непозволительной роскошью помогает функция CHARJ: она представляет числа из интервала 0...65535 двухбайтовыми строками, то есть равносильна следующему набору инструкций:

LET A=INT (N/256): LET B=N-A*256 LET D$=CHR$ A+CHR$ B

- где N — целое число из указанного диапазона.

Функция NUMBER() производит обратную операцию — переводит двухсимвольные строки в форму целых чисел. Аналогом функции является строка:

LET N=256*CODE D$(1)+CODE D$(2)

Ниже мы приводим пример, демонстрирующий экономию памяти, достигаемую с помощью этих функций:

10 DIM D$(500,2)

20 FOR К=1 ТО 500

ВО LET D$(K)=CHAR$(K): NEXT К

40 PRINT МЕМ()

50 DIM N(500)

60 FOR K=1 TO 500

70 LET N(K)=NUMBER(D$(K))

80 NEXT K: DELETE D$()

90 PRINT MEM()

В первом цикле программы с помощью функции CHAR$ из целых чисел от 1 до 500 формируется символьный массив (строки 10...30), после чего на экран выводится количество памяти в байтах, доступной для бейсик-программ (строка 40). Во втором цикле (строки 60...80) функция NUMBER переводит символьный массив в числовой. После удаления символьного массива снова печатается объем свободной памяти. Анализируя результат, можно сделать вывод, что для целочисленного массива размером лишь в 500 элементов преобразование его в двухбайтовое представление дает экономию в полтора килобайта.

РАБОТА С КЛАВИАТУРОЙ_

EDIT, GET

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

EDIT [LINE] < символьная переменная> | < числовая переменная >

По действию оператор EDIT близок к INPUT — он присваивает переменной, указанной следом за ним, соответственно символьное или числовое значение, введенное с клавиатуры. Но в отличие от INPUT, он не отнимает у переменной ее прежнего содержимого, а выводит его в строку служебного экрана для редактирования. Вот небольшой пример:

10 LET A$="QWERTY", B$="qwerty" 20 INPUT "A$="; LINE A$, 30 EDIT "B$="; LINE B$ 40 PRINT "A$=";A$,"B$=";B$

Если при выполнении, этой программки на запросы обоих операторов просто нажать клавишу Enter, то PRINT (строка 40) «покажет», что переменная А$ «опустошилась», а В$ сохранила ранее присвоенное ей значение. Поместив перед именем переменной точку с запятой, можно организовать редактирование и числовых переменных. Если стоящая в EDIT переменная не была к этому моменту определена, то оператор EDIT будет работать как обычный INPUT. В списке из нескольких переменных для всех из них, кроме первой, EDIT тоже работает как INPUT.

Недопустимо подсовывать оператору EDIT «пустую строку» — это может привести к сбросу или зависанию компьютера. Поэтому перед применением EDIT в программе (если нет уверенности) рекомендуется делать проверку неременной на «пустоту»:

IF А$="" THEN INPUT А$: ELSE EDIT А$

GET < символьная переменная {числовая переменная >

Оператор GET производит опрос клавиатуры и присваивает переменной символьное или числовое (в зависимости от того, какая переменна» используется в качестве параметра) значение, соответствующее нажатой клавише, одной или в комбинации с функциональными клавишами CS и SS На нажатие самих функциональных клавиш GET не реагирует. В отличие от функции стандартного Бейсика INKEY$, оператор GET задерживает выполнение программы и ждет, пока не будет нажата клавиша. Он в некоторой степени аналогичен комбинации

PAUSE 0: LET A$=INKEY$

Кроме того, оператор GET позволяет менять режимы курсора во время ожидания нажатия клавиши: он не реагирует на нажатие комбинаций клавиш, задающих тот или иной тип курсора. Используя это свойство, можно считывать символы, возвращаемые клавиатурой не только в режимах курсора [L] или [С], как при работе с функцией INKEY$, но и в режимах [Е] и [GJ.

Оператор GET с числовой переменной в качестве параметра при нажатии цифровых клавиш в режимах курсора [LJ и [С] присваивает ей, соответственно, значения от 0 до 9. При нажатии клавиши А переменной присваивается значение 10, В — 11 и т. д. по алфавиту.

Рассмотрим небольшой пример:

10 PRINT OVER 1 ;"_";CHR$ 8;: GET A$

30 PRINT OVER 1 ;"_";CHR$ 8;: 40 PRINT A$;

50 GO TO 10

Для такой крохотной программки результат неожиданный и впечатляющий: теперь можно свободно перемещать курсор по экрану и вводить символы и ключевые слова в люОом его месте. Чтобы избежать сообщения invalid colour при попытке удалить символ клавишами CS/0, находясь в режиме курсора [Е]*, целесообразно заменить 40-ю строку программы на

40 IF CODE А$<16 OR CODE А$>31 THEN PRINT A$

Согласитесь, получившиеся пять строк — неплохая заготовка для создания полноэкранного редактора программ Beta Basic. Но вот проблема: как включить введенную строку в текст программы? Beta Basic имеет решение и на этот случай: в нем предусмотрен оператор KEYIN, который мы рас смотрим чуть позже.




СОДЕРЖАНИЕ:
  1. Laser Basic - Вывод спрайтов на экран; Вывод на экран части спрайта; Перенос атрибутов; Преобразование окна экрана; Наборы переменных; Перемещение спрайтов; Наложение спрайтов; Копирование изображения с экрана в спрайт; Преобразование спрайтов; Скроллинг пейзажа; Изменение размеров области спрайт-файла; Вспомогательные графические операторы и функции; Определение столкновений спрайтов; Сервисные операторы и функции; Процедуры; Загрузка и запись программ.


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

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



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

Похожие статьи:
Обо всём - Амига в фактах (хронология 98 года).
Обзор - обзор современных ассемблеров: Alasm 3.8, Tasm 4.12, XAS 7.4, ZASM 3.10.
Тема - Тусовка: CSP'99 - интервью с отцом группы Playgear классным дядькой Ze Pagan.
Моя собака - Фокстерьер - мечты и реальность.
Реклама - Реклама и обьявления.

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