Книга
Книга
ИНФОРМАТИКАИНФОРМАТИКАвввшв CD СВ QBE)Ой оси се в б шшавв 000(30вввшв CD СВ QBE)Ой оси се в б шшавв 000(30/цебное пособиеY^wa педагогических институтов/цебное пособиеY^wa педагогических институтовы»си*пы»си*п
ИНФОРМАТИКА
ИНФОРМАТИКА
вввшв CD СВ QBE)Ой оси се в б шшавв 000(30
вввшв CD СВ QBE)Ой оси се в б шшавв 000(30
/цебное пособие
Y^wa педагогических институтов
/цебное пособие
Y^wa педагогических институтов
ы»си*п
ы»си*п
ИНФОРМ
Утверждено
Государственным комитетом СССР по народному образованию в качестве учебного пособия для педагогических специальностей высших учебных заведений
МОСКВА «ПРОСВЕЩЕНИЕ» 1991
ББК 73
И74
Авторы:
А. Р. Есаян, В. И. Ефимов, Л. П. Лапицкая,Э. А. Пащенко, Н. М. Добровольский
Рецензенты:
кафедра вычислительной математики ЛГПИ им. А. И. Герцена(зав. кафедрой доцент, кандидат технических наук Ю. К. Кузнецов);
доктор физико-математических наук В. В. Щенников
Информатика: Учеб, пособие для пед. спец. высш. учеб. И74 заведений/ А. Р. Есаян, В. И. Ефимов, Л. П. Лапицкая и др.— М.: Просвещение, 1991.— 288с.:ил.— ISBN
5-09-002699-8.
В книге излагается описание языка Бейсик, модели, методы, алгоритмы и программы обработки информации и решения задач. Первая часть книги, ориентируясь на неподготовленного читателя, призвана создать у него необходимый объем понятий по программированию. Вторая часть книги позволяет развить умение применять программирование для решения практических задач и использования компьютеров в учебном процессе.
21—9021—90ББК 73ББК 734309000000—240 и 103(03)—91
21—90
21—90
ББК 73
ББК 73
Учебное издание
Есаян Альберт Рубенович, Ефимов Владимир Иванович,
Лапицкая Людмила Петровна, Пащенко Эдуард Александрович,
Добровольский Николай Михайлович
ИНФОРМАТИКА
Зав. редакцией Т. А. Бурмистрова. Редактор Н. А. Шагирова.
Младший редактор О. В. Котенкова. Художник В. В. Костин.
Художественный редактор /О. А. Пахомов. Технический редактор М. М. Широкова
Корректор Н. С Соболева
ИБ № 12631
Сдано в набор 12 09.89. Подписано в печать 12 10 90. Формат 60Х 90*/i6. Бумага типограф № 2. Гарнит. литер Печать высокая. Усл. печ. л. 18 4- 0,25 форзац. Усл. кр.-отт. 18,69. Уч.-изд л. 17,29 4- 0,42 форзац Тираж 176 000 экз. Заказ № 627. Цена 95 к.
Ордена Трудового Красного Знамени издательство «Просвещение» Министерства печати и массовой информации РСФСР. 129846, Москва, 3-й проезд Марьиной рощи, 41.
Саратовский ордена Трудового Красного Знамени полиграфический комбинат Министерства печати и массовой информации РСФСР. 410004, Саратов, ул. Чернышевского, 59.
ISBN 5-09-002699-8ISBN 5-09-002699-8© Есаян А. Р. и др., 1991
ISBN 5-09-002699-8
ISBN 5-09-002699-8
ЧАСТЬ I. ЯЗЫК БЕЙСИК
Бейсик не нуждается в рекламе. Он нужен всем: и профессионалу-программисту, и в еш,е большей степени — любителю.
Г. Моррил
ВВЕДЕНИЕ
В прошлом веке один английский миссионер, желая облегчить контакт с туземным населением, выделил из английского языка самую простую и распространенную его часть, содержащую около 300 слов и не имеющую почти грамматики. Это подмножество языка, названное BASIC ENGLISH, действительно оказалось весьма простым для усвоения и поэтому вскоре завоевало популярность не только среди туземцев, но и иммигрантов.
Подобную цель создания средства для расширения и облегчения контактов, только не между различными группами людей, а между непрофессионалами и ЭВМ, поставили перед собой сотрудники Дартмутского колледжа Дж. Кемени и Т. Курц. Разработанный ими в 1964 году алгоритмический язык BASIC (Бейсик), как и всякий другой язык программирования, является формальной знаковой системой, используемой для связи человека с ЭВМ и предназначенной для описания данных и алгоритмов их обработки на вычислительной машине. Название BASIC является аббревиатурой английской фразы «Beginner’s All — purpose Symbolic Instruction Code», что в переводе означает «многоцелевой язык, символических команд для начинающих».
Важной чертой Бейсика является не только его простота и доступность, но и предоставляемая им возможность решать задачи в режиме диалога с ЭВМ.
Для многих современных мини- и микроЭВМ Бейсик предназначался в качестве единственного языка программирования высокого уровня. Это обстоятельство привело к появлению различных его версий, включающих в себя многочисленные эффективные средства программирования из других алгоритмических языков. Таким образом, на сегодняшний день мы имеем не конкретный Бейсик, а целую группу однотипных диалоговых языков, называемых этим же именем. В частности, нас будет интересовать версия 1.0 одной из его достаточно мощных и интересных разновидностей, именуемых MSX-Бейсиком. Именно о ней в основном и идет речь ниже. Изложение языка ориентировано на использование персонального MSX-компьютера «Ямаха».
Для дальнейшего изложения нам необходимо иметь предварительное разъяснение некоторых основных понятий Бейсика, которые затем будут расширяться и уточняться. Начнем с примера программы.
10 INPUT X
20 LET Y=X + 5:LET Z = X*Y
30 PRINT Y, Z
40 END
В общем случае программа на Бейсике есть нумерованная последовательность строк. Номер строки задается целым неотрицательным числом, служащим для ее идентификации. За номером располагаются команды (операторы, приказы, инструкции). Если команд в строке несколько, то друг от друга они отделяются символом двоеточия. Каждая команда представляет собой указание компьютеру — что по ней необходимо сделать и над какими данными. Набор допустимых команд строго ограничен. Для успешного использования Бейсика необходимо этот набор изучить. При этом придется обращать внимание как на синтаксис (правила записи), так и на семантику (смысловое значение) всякой команды.
Для выполнения программы она должна быть занесена в оперативную память компьютера. Первый раз запись в память ЭВМ производится с клавиатуры набором ее текста приблизительно так, как это осуществляется при печатании на пишущей машинке. Правда, здесь все значительно проще, ибо имеется возможность не только отслеживать вводимый текст на экране дисплея, но при необходимости и эффективно его редактировать. Заметим, что программная, или, по-другому, логическая, строка может занимать несколько физических строк экрана дисплея. Далее, ввод логической строки всегда должен заканчиваться нажатием клавиши «возврат каретки» (*-■).
Из памяти компьютера программа под каким-нибудь именем через специальные устройства (дисковод, магнитофон) может быть записана для хранения и дальнейшего использования на внешний магнитный носитель (дискета, кассета). При этом отпадает необходимость в повторном вводе такой программы через клавиатуру. Гораздо проще это делать считыванием ее в память с соответствующего носителя.
Нажатием кнопки ПУСК (команда RUN) находящаяся в оперативной памяти программа начинает автоматически выполняться. Делается это так. Сначала фиксируется строка с наименьшим номером и слева направо последовательно друг за другом выполняются ее команды. Затем эта же процедура повторяется со следующей строкой и т. д., пока не встретится команда END или не будет реализована последняя строка с наибольшим номером. Правда, следует иметь в виду, что, как правило, программы содержат так называемые команды передач управления, являющиеся «нарушителями» описанного идиллического порядка вычислений.
Возвращаясь к нашему примеру, можно отметить, что представляемая им программа содержит 4 строки с номерами: 10, 20, 30 и 40. В строке 20 — две команды, а в остальных — по одной. Дадим описание этих команд.
INPUT X — команда ввода данных с клавиатуры.
По команде INPUT (ввод) происходит приостановка вычислений. На экране дисплея появляется знак вопроса. Если ввести с клавиатуры число, то оно станет значением переменной X, и вычисления в программе будут продолжены.
LET Y = X + 5 — команда присваивания значений.
По команде LET (пусть) организуется вычисление выражения Х4-5 при текущем значении переменной X. Полученное значение присваивается переменной Y.
LET Z=X*Y — команда присваивания значений.
По команде LET организуется вычисление выражения X*Y при текущих значениях переменных X и Y. Полученное значение присваивается переменной Z. В записи команд присваивания служебное слово LET можно опускать.
PRINT Y, Z — команда вывода данных.
По команде PRINT на экране дисплея индицируются текущие значения переменных Y и Z.
END — команда завершения вычислений.
Теперь мы в состоянии проследить за значениями переменных величин программы (1) при ее конкретном выполнении. Например, если по команде INPUT ввести для X значение 3, то на экран будут выведены числа 8 и 24. .
Остановимся еще на одном обстоятельстве. Любая строка Бейсика, вводимая в память без номера, исполняется сразу. Подобные «непосредственные» вычисления допустимы, но носят вспомогательный характер.
Более полное изложение синтаксиса и семантики упомянутых выше команд будет дано в последующих разделах пособия. Сейчас же отметим, что при описании конструкций Бейсика для указания необходимости выбора одного из нескольких возможных элементов последние будем располагать столбиком и заключать в фигурные скобки {}. Далее, необязательные элементы конструкций будем записывать в квадратные скобки [ ].
ОСНОВЫ ЯЗЫКА БЕЙСИК И ПРОГРАММИРОВАНИЯ
Основные объекты языка
Алфавит. Основными объектами, используемыми в языке Бейсик, являются константы, переменные, выражения, функции и массивы. Каждый из этих объектов характеризуется именем (идентификатором), значением и типом принимаемых значений. Имена и значения строятся из фиксированного набора символов, или, по- другому, литер. Совокупность используемых литер, в которую входят прописные и строчные буквы русского и латинского алфавитов, арабские цифры и ряд дополнительных символов (см. таблицу 1), а также около 200 служебных слов (см. приложение I), и составляют алфавит Бейсика.
Таблица 1
Шестнадцатиричные коды ASCII некоторых символов Бейсика
V
А
2
3
4
5
6
7
8
9
A
В
c
D
Е
F
0
0
@
Р
<
P
^
a
5=
to
п
Ю
п
1
1
1
А
Q
а
q
X
P
4-
а
я
А
я
2
II
2
В
R
ь
r
a
и
r
>
в
р
Б
р
3
#
3
С
S
с
s
■*
■
w
<
U
с
Ц
с
4
♦
4
D
Т
d
t
•
■
E
г
A
т
Д
т
g
%
5
Е
и
е
u
о
■
<r
J
e
У
Е
У
6
&
6
F
V
•f
V
1
■
T
Ф
ж
Ф
ж
7
>
7
G
и
g
w
Й
T
A*
r
в
Р
в
8
(
8
Н
X
h
X
■
Д
i
О
X
ь
X
ь
9
)
9
I
Y
i
У
1
♦
e
•
и
ы
И
ы
А
X
S
J
Z
J
z
0
о
я
•
Й
э
Й
3
В
+
8
К
с
k
{
%
a
5
J
к
ш
К
ш
С
<
L
\
1
1
Si
■
о
n
л
э
л
3
D
—
SS
М
3
m
}
i
0
2
м
UI
м
ш
Е
•
>
N
Л
n
Пг
*
■
€
■
н
ч
н
ч
F
/
7
О
—
о
▲
►
■
n
Я
о
ъ
О
Шестнадцатиричный код символа, стоящего на пересечении столбца р и строки q в таблице 1, равен (p^)ie. Его десятичное значение равно \6p-Vq.
ПРИМЕР 1
символ|
1
ШЕСТНАДЦАТИРИЧНЫЙ 1
КОД|
ДЕСЯТИЧНЫЙ
КОД
W|
87
провел (_) |
201
32
=1
3D|
61
курсор|
FF|
255
Константы. В Бейсике используются константы четырех типов: строковые (или символьные); числовые целые; числовые вещественные одинарной точности; числовые вещественные двойной точ ности.
Строковые константы записываются в виде последовательности произвольных литер языка, начинающейся и заканчивающейся кавычками ". То, что находится между кавычек, называется значением строковой константы, а количество символов значения — ее длиной (см. пример 2). Длина не должна превосходить 255.
ПРИМЕРЫ 2.••КОНСТАНТА" "FLOATING-POINT""253.175""А ВС"ПРИМЕРЫ 2.••КОНСТАНТА" "FLOATING-POINT""253.175""А ВС"(L — длина константы)
ПРИМЕРЫ 2.
••КОНСТАНТА" "FLOATING-POINT"
"253.175"
"А ВС"
ПРИМЕРЫ 2.
••КОНСТАНТА" "FLOATING-POINT"
"253.175"
"А ВС"
, L=9
, L=14
, L=7 . L=ll
Числовые целые константы С лежат в диапазоне: - 32768<С <32767.
Записывать их можно в десятичной, шестнадцатиричной, восьмиричной и двоичной системах счисления (формах). При этом в трех последних случаях перед значением целой константы требуется проставлять соответствующее основание системы счисления в виде сочетания символов: &Н(16), &О(8) или &В(2).
ПРИМЕРЫ 3.
Константы
746, -2163 -
целые десятичные,
&Н22В, &HFF -
целые шестнадцатиричные (допустимые цифры :
0, 1, . . .9, A,B,C,D,E,F) ,
&01777, &0123 -
целые восьмиричные (допустимые цифры 5
0,1,...7),
&В1010Ц, &В0101 -
целые двоичные (допустимые цифры: 0,1).
Числовые вещественные константы двойной точности записы-
ваются в десятичном виде в фиксированной или плавающей формах. Количество цифр для фиксированной формы числа или количество Цифр мантиссы для плавающей формы числа не превосходит 14.
ПРИМЕРЫ 4. Формы констант
фиксированная форма (двойная точность)
157.8521
34. 1
5
93.64478#
плавающая форма (двойная точность)
1.22D-2(1.22Х10*2)
71.21231D12(71.21231X10^)
Здесь символы Ф и D используются как указатели двойной точности. При плавающей форме записи константы символ D служит еще и разделителем мантиссы и порядка.
Числовые вещественные константы одинарной точности записываются в десятичном виде в фиксированной или плавающей формах. Количество цифр для фиксированной формы числа или количество цифр мантиссы для плавающей формы числа не превосходит 6. ПРИМЕРЫ 5
фиксированная форма (одинарная точность)
5.171•
6!
731.1371!
12.56!
плавающая форма (одинарная точность)
3.74Е5(3.74X105 )
1Е-3(1X10 "5>
Здесь символы ! и Е используются как указатели одинарной точности. Кроме того, при плавающей форме записи вещественной константы символ Е служит еще и разделителем мантиссы и порядка. При отсутствии указателей точности вещественные константы в фиксированной форме при количестве знаков более 6 или с ненулевой дробной частью считаются двойной точности.
Переменные. Имя (идентификатор) переменной есть последовательность из произвольного количества латинских букв, арабских цифр и, возможно, некоторых специальных символов алфавита. Однако при выборе имен следует иметь в виду такие ограничения. Первый символ обязан быть буквой. Значащими являются лишь первые два символа. Служебные слова нельзя использовать в качестве имен.
Тип переменной определяется типом принимаемых ею значений и может или задаваться последним символом в самом имени, или определяться командой DEF декларации типа. Остановимся на этих случаях подробнее.
Тип переменной указывается в имени последним знаком вида: $ — для строковых переменных, % — для целочисленных переменных, ф — для вещественных (действительных) переменных двойной точности,
! — для вещественных (действительных) переменных одинарной точности.
По умолчанию, т. е. при отсутствии в имени знаков: $, %, ф и !, тип переменной считается вещественным с двойной точностью. ПРИМЕРЫ 6
А!, В%, CDF#, MAP, LS,
E(I), F(4,R), ЕХСКХ), Е7.<К), K*(L)
Здесь первые пять примеров определяют имена простых переменных, а последние пять — имена элементов массивов, в которых за простым именем в круглых скобках указываются один, два или более индексов.
Тип объявляется командой DEF:
DEFSTR — для строковых переменных,
DEFINT — для целочисленных переменных,
DEFDBL—для вещественных переменных двойной точности, DEFSGN — для вещественных переменных одинарной точности. ПРИМЕРЫ 7
DEFSTR MI, L, RES — все переменные, начина
ющиеся с Букв М, L и R, об’являются строковыми;
DEFINT A, K-Z — все переменные, начина
ющиеся с Буквы А ис
Букв диапазона от К до
Z об'являются целЪчис—
ленными;
DEFDBL Е-Б— все переменные, начина
ющиеся с вукв Е, F и Б, об’являются вещественными с двойной точно
стью;
DEFSGN E,GAME - все переменные, начинающиеся с Букв Е и G, об*являются вещественными с одинарной точ- стью.
Заметим, что объявление типа командой DEF распространяется и на массивы, имена которых начинаются с соответствующих букв, но не действует на переменные и массивы с явным указанием типа знаками: $, %, # и !.
Выражения. Выражения могут быть константами, переменными или комбинациями констант, переменных и функций, соединенных знаками операций так, что в результате выполнения соответствующих действий получается единственное значение. Все символы выражения располагаются последовательно друг за другом. Никаких верхних или нижних индексов в записи не допускается. Для указания приоритетности при вычислениях можно использовать круглые скобки. Различают 4 типа операций. Рассмотрим их.
Арифметические операции. В таблице 2 в порядке уменьшения приоритета перечислены 8 арифметических операций. В качестве разделителя при перечислении возможных вариантов там используется символ |.
Таблица 2
Знак операции
Название
Примеры выражений
1
А
возведение в степень
ХАУ
2
—
вычитание (одноместное)
-и
3—4
*1 /
умножение, деление
X* Y X/Y
5-6
+1 -
сложение, вычитание (двуместное)
X + Y X-Y
7
\
целочисленное деление
X\Y 10\4(2)
25.1 \6.9 (4)
8
MOD
нахождение остатка
XMOD Y 10 MOD 3 (1)
Если в выражении присутствуют лишь числовые константы, переменные, функции и только знаки арифметических операций, то такое выражение будем называть арифметическим.
ю
ПРИМЕРЫ 8
АРИФМЕТИЧЕСКОЕI АРИФМЕТИЧЕСКОЕ
ВЫРАЖЕНИЕI ВЫРАЖЕНИЕ
| НА БЕЙСИКЕ—
^2^| AXBA2+(C+D)/E
-т^—; I(XXSINCX)/Y+З)/<1*LOG(Z>)
14- йгй
Строковые операции. Строковыми (символьными) выражениями являются строковые константы, переменные и функции. О последних речь пойдет в пункте 1.2. Выполняя над строковыми выражениями операцию конкатенации (+), или, по-другому, присоединения, мы снова получаем строковое выражение. Смысл операции конкатенации разъясняет приведенный ниже пример.
ПРИМЕР 9
10АФ="КОНТРА"8ВФ«"БАС"run
20PRINT АФ+ВФКОНТРАБАС
30PRINT "НОВЫЙ "+АФ+ВФНОВЫЙ КОНТРАБАС
Операции отношения. Простым выражением отношения называют два арифметических или два символьных выражения, разделенных знаком операции отношения.„„
Таблица 3
Операции отношения
Знак операции
Название
Знак операции
Название
1=
2< >
3<
равно не равно меньше
4>
5<=
6>=
больше меньше или равно больше или равно
ПРИМЕРЫ 10
Х>3, R<Z(3,4) ВФ="ПОВЕРХНОСТЬ"
Ал2+Вл2<=Сл2
Значениями простого выражения отношения являются элементы множества (Т, F} (TRUE — истина, FALSE — ложь).При этом если соответствующее отношение удовлетворяется, то его значением бу-
11
дет Т, в противном случае — F. Используются выражения отношения в операторах IF (если) в качестве проверяемых условий для организации разветвлений при вычислениях.
Значения двух символьных выражений сравниваются посимвольно слева направо. При этом учитывается, что литеры алфавита упорядочены в соответствии с их шестнадцатиричными кодами и в возрастающем порядке располагаются так (см. таблицу 1):
пробел ! " # ... Щ Ч курсор
Логические операции. Используя простые выражения отношения с помощью логических операций (связок), получают выражение отношения более общего вида. Допустимы следующие связки: NOT (нет), AND (и), OR (или), XOR (исключающее или), EQV (экви- валенция) и IMP (импликация). В таблице 4 приведены значения истинности для подобных «составных» выражений отношения.
Таблица 4
X
Y
NOTX
XANDY
XORY
XXORY
XEQVY
XIMPY
т
Т
F
Т
Т
F
Т
Т
т
F
F
F
Т
Т
F
F
F
Т
Т
F
Т
Т
F
Т
F
F
Т
F
F
F
Т
Т
ПРИМЕРЫ 11
(X>Y> AND (C=D)(АЛ2+ВЛ2<=СЧ2) OR (A EQV В)
Заметим, что логические операции можно выполнять над значениями любых выражений х и у. Реализуются эти операции над соответствующими битами данных по правилам таблицы 4, где символ Т везде заменен на 1, а символ F — на 0.
1.2. Функции
В Бейсике различают 4 основных типа функций: числовые функции; функции для работы со строками; функции преобразования; функции пользователя.
Первые три из них относятся к так называемым стандартным функциям, вычисление значений которых реализуется специальными программами, находящимися в памяти ЭВМ. Каждая такая программа имеет уникальное имя (SIN, EXP, MID$, ASC и т. п.), по которому и происходит обращение к ней. К четвертому типу относятся те функции, которые пользователь определяет в программе сам.
Остановимся на каждом типе функций в отдельности.
Числовые функции. Аргументом любой стандартной числовой функции может служить произвольное арифметическое выражение, заключенное в круглые скобки.
12
——— -
Название
Выполняемые действия
Функция
1
ABS (X)
Абсолютная величина
Вычисляется величина |х|
2
LOG (X)
Натуральный логарифм
In X
3
EXP (X)
Экспонента
ех
4
SQR (X)
Квадратный корень
Square root — квадратный корень. Вычисляется величина -^х
5
SIN (X)
Синус
sin х (х в радианах)
6
COS (X)
Косинус
cosх (х в радианах)
7
TAN (X)
Тангенс
tg х (х в радианах)
8
ATN (X)
Арктангенс
arctg х
9
SGN (X)
Знак числа
Signum — знак. Вычисляется значение функции:
г0, если х = 0,
signx= J1, если х>0,
( — 1, есл и х < 0
10
INT (X)
Целая часть
Integer — целый. Находится максимальное целое число, меньшее или равное х
11
FIX (X)
Фиксация (отбрасывание дробной части)
Fix — фиксация. У значения х отбрасываются десятичная точка и все цифры, следующие за ней
12
RND (X)
Генерирование случайных чисел
Random — случайный. Генерируется псевдослучайное число из диапазона ]0, 1 [
13
CINT (X)
Преобразование к целому типу
Convert to integer type. X преобразуется к целому типу
14
CDBL(X)
Преобразование к двойной точности
Convert to double precision type X преобразуется к типу двойной точности
15
CSNG (X)
Преобразование к одинарной точности
Convert to single precision type X преобразуется к типу одинарной точности
Остановимся на двух моментах.
Во-первых, при вычислении значений тригонометрических функций SIN(X), COS(X) и TAN(X) аргумент X необходимо выразить в радианах. И здесь полезно помнить, что 4XATN(l)=n.
Во-вторых, более подробно опишем функцию RND(X), используемую во многих игровых и моделирующих программах.
Аргумент X (Х>0) для RND (X) является псевдопеременной и не влияет на значение функции. Обычно берут Х = 1. При запуске конкретной программы отдельные вычисления RND(l) приводят к выдаче равномерно распределенной на интервале (0,1) числовой последовательности следующего вида:
. 59521943994623
.10658628050158
. 76597651772823
. 57756392935958
Повторные запуски этой программы генерируют ту же самую последовательность. Этот факт оказывается удобным при отладке программ, т. е. при поиске в них тех или иных ошибок. Чтобы добиться появления другой последовательности, необходимо до использования функции RND (X) произвести так называемую инициализацию генератора случайных чисел любым неположительным числом. Для этого достаточно выполнить команду Y = RND (X), где Х^О. По умолчанию подобная инициализация выполняется сХ=0 при каждом запуске программы. Если взять Х=—TIME, т. е. реализовать команду Y = RND (—TIME), то затем от запуска к запуску будем получать непредсказуемые меняющиеся равномерно распределенные на (0,1) последовательности случайных чисел.
ПРИМЕРЫ 12
INT(10XRND(1))— генерирование деся
тичной цифры от 0 до 10.
A+(B-A)XRND(1) - генерирование слу
чайного числа из интервала (А,В).
3. 10 X=RND(-TIME)
- получение непред
20 FOR Х=1 ТО 500
сказуемой равномер
30 PRINT RND(l)
но распределенной
40 NEXT X
на (0,1) последо-
тельности из 500 чисел.
Строковые функции. Здесь будут рассмотрены следующие 5 функций:
MID*—функция(middle—середина),
LEFT*-функция(left-левый),
RIGHT*—функция(right—правый),
STRING*-функция(string-строка),
SPACE*-функция(space-пространство).
14
Другие функции для работы со строками рассматриваются в пункте «Функции преобразования».
функции 1—3 используются справа и слева от знака равенства в командах LET (пусть) и условной передачи управления IF (если), функции 4 и 5 используются для инициализации новых строк.
МЮ$-функция. Общий вид МЮ$-функции следующий: MID$ (a, m [, п]), где: а — строковое выражение, т, п — арифметические выражения.
Целые части значений выражений тип будем обозначать соответственно через М и N. По умолчанию N равно количеству символов значения а от позиции М и до конца строки.
Рассмотрим возможные случаи.
Функция MID$ слева от знака равенства в команде LET.
LET MID$ (a, m [, n]) = 0(1)
Пусть L — длина значения символьного выражения 0. При выполнении команды LET последовательные символы а, начиная с позиции М, замещаются на первые min (L, N) символов строки 0. Остальные символы в а остаются без изменения.
Заметим, что в рассматриваемом случае а должно быть определено до выполнения команды (1).
ПРИМЕР 13
10 Х$="1234567890"
run
20 INPUT Y»,M,N
? LL,5, 3
30 MID»(X*,M,N>=Y*
1234LL7890
40 PRINT ХФ
run
? ПЕТЯ,4,3 123ПЕТ7890
run
? КРОКОДИЛ,7,4 123456КР0К
Функция MID$ справа от знака равенства в команде LET. LETy = MID$ (a, m [, nJ)(2)
При выполнении команды LET N последовательных символов значения а, начиная с позиции М, становятся значением переменной у. Предварительное определение у не обязательно. При выполнении команды (2) возможно увеличение длины значения у.
runrun2 INPUT X$,M3 Z»=MIDt(X*,M)4 Y*=MID*(X»,M)5 PRINT Z$2 INPUT X$,M3 Z»=MIDt(X*,M)4 Y*=MID*(X»,M)5 PRINT Z$? JCUKENGEIZH,5ENGE IZH? JCUKENGEIZH,5ENGE IZHENGE IZHENGE IZH
run
run
2 INPUT X$,M
3 Z»=MIDt(X*,M)
4 Y*=MID*(X»,M)
5 PRINT Z$
2 INPUT X$,M
3 Z»=MIDt(X*,M)
4 Y*=MID*(X»,M)
5 PRINT Z$
? JCUKENGEIZH,5
ENGE IZH
? JCUKENGEIZH,5
ENGE IZH
ENGE IZH
ENGE IZH
ПРИМЕР 14
1 Zt="123**
6 PRINT Y*
Функция MID$ в команде IF.
(3)(3)IFy*MID$(a, m [,n]) THEN P
(3)
(3)
где: *£(<, >, =, <=, > =, <>}; P — номер программной строки; у — символьное выражение.
При выполнении команды (3) прежде всего из а, начиная с позиции М, выбирается N последовательных символов. Получившаяся строка р сравнивается с у. Если выражение отношения у*р имеет значение Т (истинно), то управление передается первой команде строки Р. В противном случае начинает выполняться команда, следующая за IF.
ЬЕРТ$-функция. ЕЕРТ$-функция является частным случаем MID 5-функции и через нее может быть определена так:
LEFT $(a, n) = MID$ (a, 1, n)
Иными словами, значением LEFT $ (a, n) является строка из N последовательных левых символов значения строкового выражения а.
ПРИМЕР 15
10 INPUT X$,N20 U$=MID$(X$,1,N)30 VS=LEFT*(X$,N)40 PRINT U$10 INPUT X$,N20 U$=MID$(X$,1,N)30 VS=LEFT*(X$,N)40 PRINT U$runrun? FYWAPR0LDV,6 FYWAPR? FYWAPR0LDV,6 FYWAPRFYWAPRFYWAPR
10 INPUT X$,N
20 U$=MID$(X$,1,N)
30 VS=LEFT*(X$,N)
40 PRINT U$
10 INPUT X$,N
20 U$=MID$(X$,1,N)
30 VS=LEFT*(X$,N)
40 PRINT U$
run
run
? FYWAPR0LDV,6 FYWAPR
? FYWAPR0LDV,6 FYWAPR
FYWAPR
FYWAPR
50 PRINT V$
Rights-Функция. RIGHTS-функция является частным случаем MID $-функции и через нее может быть определена так:
RIGHT $ (a, n) = MID$(a, L — n + 1, «)
где L — длина значения a. Иными словами, значением RIGHT $ (a, п) является строка из N последовательных правых символов значения строкового выражения а.
16
п р и м Е Р 16
10 INPUT X$,Nrun
20 U»=MID$(X#,LEN(X$>-N+1,N)? 1234567890,4
30 v*=RIGHT$(X$,N)7890
40 PRINT U$7890
50 PRINT V»
STRING$-фyнкция. Общий вид 5ТН1ЫО$-функции следующий: STRING (п, а), где: a — строковое выражение; n — арифметическое выражение.
Значением этой функции является последовательность из N = = INT (п) одинаковых символов, равных первой литере значения a. С помощью STRINGS-функции можно назначать длину и проводить начальную инициализацию строковых переменных. В STRINGS-функции а может быть не только строковым выражением, но и кодом ASCII. Тогда ее значением будет последовательность из N символов алфавита или управляющих сигналов с данным кодом а.
ПРИМЕР 17
10 YS=STRING$(10,"Х")run
20 PRINT LEN(Y$)10
30 PRINT "#"+Y$+"FILE"#XXXXXXXXXXFILE
SPACE $-функция. 5РАСЕ$-функция является частным случаем STRING $-функции и через нее может быть определена так:
SPACES (n)=STRINGS (п, "ш")
С помощью SPACES-функции назначается длина и проводится начальная инициализация строковых переменных пробелами.
Функция преобразования. Речь пойдет о следующих функциях.
LEN (а) —длина значения строкового выражения а.
INSTR — номер позиции вхождения одного строкового значения в другое.
НСХ$ (р) —функции преобразования десятичных чисел р ОСГ$ (р) в строковую форму с представлением их в BIN$ (Р)шестнадцатиричном, восьмиричном, двоич-
STR$ (р)ном или десятичном изображениях.
VAL (а)— десятичное число, получаемое преобразованием
символьного представления а к числовому типу.
17
ASC (a)— десятичный код первого символа значения
строкового выражения а.
CHR$ (Р) —символ с десятичным кодом р.
Остановимся на этих функциях подробно.
LEN-функция. Значение функции LEN (а) равно длине значения строкового выражения а.
ПРИМЕР 18
10 Х$="АВCDЕ"run
20 S=LEN(X»)12
30 PRINT S
I NSTR-функция. Функция INSTR ([n], a, P), где: a, p — строковые выражения; n — арифметическое выражение, равна номеру позиции в значении а, считая от его начала, с которой значение р входит от позиции N = INT (п) и дальше в а. По умолчанию п = 1.
ПРИМЕР 19
10 INPUT X$,Y$,Urun
20 L=INSTR(U,X$,Y$)? ABCRSTRSTRSTP,RSTj1
50 PRINT L4
run
? ABCRSTRSTRSTP,RST,B
10
HEX$, OCT$, BINS и STRS-функции. Значением функций НЕХ$ (у), ОСТ$ (у), BIN$ (у) и STRS (у) являются строковые формы соответственно шестнадцатиричного, восьмиричного, двоичного или десятичного представления десятичного числа у.
ПРИМЕР 20
10 INPUT X 20 U1$=HEX*(X):U2*=OCT»(X)
30 U3*=BINt(X) :U4*=STR$ <X>
40 PRINTUl*+"”+U2$+'’ "+U3*+""+U4*
runrun
? 123? 444
7B 1731111011123IBC 674110111100 444
18
VAL-функция. Функция VAL (а), где а — строковое выражение имеет значением десятичное число, полученное преобразованием его символьного представления в а к числовому типу.
run? 499500run? 499500ПРИМЕР 21
run
? 499
500
run
? 499
500
10 INPUT Z$
20 X=VAL(Z»+1
30 PRINT X
ASC-функция. Функция ASC (а), где а — строковое выражение, имеет значением десятичный код первого символа значения а.
ПРИМЕР 22
10 INPUT X*:Y=ASC(X»)
20 PRINT X*,Y
runrun
? J? aSP
J 187 aSP 165 (код <x)
CHRS-функция. Функция CHR$ (X) имеет значением символ, десятичный код которого равен X. ПРИМЕР 23 10 INPUT XsY»=CHR»(X>run
20 PRINT X,Y»? 164
164E
run ? 187 187J
Имеет смысл обратить внимание на то, что в области определения функций ASC и CHR$ справедливы соотношения:
ASC (CHR$ (р))=р (р— десятичное число), CHR$ (ASC (а))=‘а (а — символ). Другими словами, функция ASC обратна к CHR$ и, наоборот, Функция CHR$ обратна к ASC.
Функции пользователя. Пользователь имеет возможность определить в программах новые функции. Они должны быть описаны командой DEF (definition — определение) следующим образом:
DEFFNa [(Р,[,р2].-.)]=?(4)
19
где:
FN а — имя новой функции (FN — его фиксированная часть, а а выбирается по усмотрению пользователя);
Pi, ₽2 -. — имена переменных величин (аргументы функции);
у — выражение, зависящее от Pi, р2, ...
Если описание команды (4) дано, то затем функцию
FN а [(а. [,а2]...)](5)
где ак— выражения, имеющие тот же тип, что и рк (к = 1,2, ...), можно использовать в любых выражениях, входящих в те или иные команды программы. Значение FN а вычисляется так. В у каждому Рк присваивается значение ок (к = 1,2, ...). Затем вычисляется у и результат присваивается величине (5).
Величины рк в (4) и ок в (5) (к = 1,2, ...) называются соответственно формальными и фактическими параметрами.
ПРИМЕРЫ 24
10 DEFFNP(X)=ХЛ2+Х+1
20 PRINT FNP(l);FNP(10);FNP(2>A2
30 INPUT A
40 PRINT FNP(A)
run
311149
? 5
31
10DEFFNZ(A,B)^А^г+В^гrun
20INPUT X,Y? 3,4
30 PRINT FNZ(X,Y);FNZ(Y,8)2580
10-DEFFNSt(X»,K)=MID*(X*,K, Drun
20INPUT X$,K? TABLE,4
30PRINT FNS»(X*,K)L
1.3. Дисплей и клавиатура
Клавиатура является устройством ручного ввода программ и данных, кодируемых последовательными нажатиями расположенных на ней клавиш.
Дисплей, наряду с клавиатурой, является основным устройством оперативного взаимодействия человека и ЭВМ. Вводимые с кла- 20
виатуры символы визуально отображаются на экране дисплея и легко могут быть отредактированы. Получаемая в результате вычислений информация также может выводиться на экран в виде текстов, рисунков, графиков, диаграмм и т. п. Дисплеи бывают двух типов: цветные и монохромные. Отдельные участки экрана цветного дисплея и изображения на них допускают 16 различных цветов (оттенков). На монохромных дисплеях возможно до 16 оттенков одного, обычно зеленого, цвета.
Экраны дисплея. Физически дисплей имеет 1 экран. Однако качественных состояний (режимов), в которых он может находиться,— 4. Эти состояния пронумеруем от 0 до 3 и далее, всякий раз речь будем вести о конкретном экране К (К=0, 1, 2, 3).
Экраны 0 и 1 являются символьными. На них можно индицировать только символы алфавита Бейсика и ряд дополнительных символов псевдографики. Экраны 2 и 3 являются графически- м и. На них возможен вывод и графической, и текстовой информации. Переключение с одного экрана на другой осуществляется командой SCREEN (экран). При включении компьютера автоматически устанавливается экран 0.
О графических экранах речь пойдет в пункте 2.1. Сейчас же сосредоточим свое внимание на символьных экранах, где можно выделить две основные зоны: бордюр и фон. На экране 0 эти зоны всегда одного цвета. На экране 1 их цвета могут быть различными. Схематическое изображение символьных экранов дано на рисунке 1. Программы и данные в виде последовательности символов алфавита Бейсика отображаются на фоне экрана. Фон условно разделен на 24 строки, которые пронумерованы сверху вниз числами 0, 1,.... 23. Последняя строка называется строкой-подсказкой. На ней индицируются начальные символы значений спецклавиш (ключей). Пусть кх — последняя строка экрана, на которой могут отображаться символы, вводимые с клавиатуры. Обычно ^,=22. Однако можно сделать ^। = 23, превратив строку-подсказку в нормальную строку экрана.
Рис. 1Рис. 1СТОЛБЦЫСТОЛБЦЫ
Рис. 1
Рис. 1
СТОЛБЦЫ
СТОЛБЦЫ
О 1
- Курсор
- Фон
Рис. 2
Условно по вертикали разделим фон на столбцы и пронумеруем их слева направо последовательными числами 0, 1, .... кг. Тогда по умолчанию для экрана 0 ^2 = 38 (39 столбцов), а для экрана 1 ^2 = 28 (29 столбцов). В общем случае кг можно изменять по команде WIDTH в пределах: О^йг^ЗЭ (для экрана 0), О^Аг^З! (для экрана 1).
Параметры к\ и кг определяют поле ввода (фон) из (Ai + l)X Х(&2-М) позиций (х,у\ в каждой из которых может быть проинди- цирован ровно один символ. Здесь х— номер столбца (О^х^Аг), а у — номер строки (O^y^kiY При вводе данных с клавиатуры в любой конкретный момент времени одна из позиций поля ввода отмечена специальным знаком Q, называемым курсором, или маркером. Пару (х, у) можно считать координатами курсора (см. рис. 2). Пусть позиции фона упорядочены следующим образом:
(0,0), (1,0), .... ^кг, 0), (0, 1) (Л2,1), .... (А2, &1)
Переход курсора от (х, у) к последующей позиции назовем его движением «вперед», а к предыдущей — движением «назад». При этом последующей для (кгк\) и предыдущей для (0, 0) считаем сами эти позиции. Символ, набираемый на клавиатуре, появляется в текущей позиции курсора. При этом сам курсор смещается на одно знакоместо «вперед». Иными словами, при вводе символов курсор последовательно, каждый раз на 1 позицию, сдвигается вправо по текущей строке экрана, пока не дойдет до ее края. Затем он переходит на начало следующей строки и т. д. Исключением является позиция (&2&1), при которой набор очередного символа приводит к дополнительному перемещению всего изображения по фону на I строку вверх. Причем бывшая нулевая строка исчезает, а для ввода предоставляется строка к\ с курсором на месте (0, к\У
Управляющие клавиши. На клавиатуре имеется ряд так называемых управляющих клавиш, которые служат не для ввода символов, а для задания Бейсик-системе тех или иных команд, связанных с очисткой экрана, стиранием символов, перемещением курсора и т. п. В таблице 6 описывается назначение этих клавиш. При этом если некоторое действие производится при одновременном нажатии двух и более клавиш, то между их наименованиями ставится символ &.
Назначение управляющих клавиш
N
Управляющие клавиши
Название. Выполняемые действия
1
CTRL&\
Курсор «вперед». Курсор сдвигается на 1 позицию «вперед»
2
CTRL&]
Курсор «назад». Курсор сдвигается на 1 позицию «назад»
3
SHIFTS CTRL &
Курсор вверх. Курсор сдвигается, если это возможно на 1 позицию вверх
4
SHIFT & CTRL S_
Курсор вниз. Курсор сдвигается, если это возможно, на 1 позицию вниз
5
CTRL & В
Курсор в начало слова
6
CTRL & F
Курсор на следующее слово
7
CTRL & N
Курсор в конец строки
8
HOME
CTRL & К
Домой. Курсор перемещается в левый верхний угол экрана (фона)
9
DEL
Стирание символа в позиции курсора. Все символы логической строки от позиции за курсором и до ее конца сдвигаются на одну позицию «назад». Символ в позиции курсора пропадает, а в последней позиции строки появляется пробел
10
BS
CTRL & H
Стирание символа слева от курсора. Все символы логической строки от позиции курсора и до ее конца сдвигаются на одну позицию «назад». Символ, находящийся перед курсором, пропадает, а в последней позиции строки появляется пробел
и
CTRL & E
Стирание с экрана конца строки. Все символы строки от позиции курсора и до ее конца замещаются пробелами
12
CTRL & U
Стирание с экрана текущей строки. Все символы строки, отмеченной курсором, замещаются пробелами
13
CLS
CTRL & L
Очистка экрана. CLS (clear screen — очистка экрана). Изображение стирается с экрана
14
CTRL&M
Ввод текущей строки. Программная текущая строка фиксируется в памяти. Строка непосредственного счета выполняется
15
INS
CTRL & R
Переключение на режим вставки. Задание или отмена режима вставки, при котором курсор уменьшается в два раза и набор любого символа а приводит к сдвигу части логической строки от курсора и дальше на одну позицию «вперед». На месте курсора появляется а
N
Управляющие клавиши
Название. Выполняемые действия
16
ТАВ
CTRL & I
Табуляция. Курсор смещается в ближайшую правую позицию текущей строки, кратную 8. Если такой позиции нет, то он переходит в начало следующей строки. Проходимые курсором места в любом случае замещаются пробелами
17
STOP
Приостанов-пуск. При вычислениях по программе нажатие на эту клавишу приводит к их приостанову. Повторное нажатие на STOP возобновляет вычисления с прерванного места
18
CTRL & STOP
Прерывание. Прерывание вычислений. При счете по программе на экран выдается сообщение о номере строки, на которой произошло прерывание
19
РУС
Переключатель русского шрифта. Задание или отмена режима ввода русской символики. При включении режима РУС н-а соответствующей клавише загорается индикаторная лампочка.
20
CAPS
Переключатель заглавных и строчных букв. Задание или отмена режима ввода заглавных букв. При включении режима CAPS на соответствующей клавише загорается индикаторная лампочка
21
GRAPH
SHIFT & GRAPH
Регистры дополнительных значений клавиш (псевдографика). Каждая клавиша а определяет два дополнительных значения кроме тех, которые обозначены на ней. Для получения этих значений необходимо одновременное нажатие на клавиши: GRAPH и а или SHIFT, GRAPH и а
22
F1/F6
F2/F7
F3/F8
F4/F9
E5/F10
Функциональные клавиши. Имеется 10 функциональных клавиш (ключей). По умолчанию они имеют такие значения:
F 1 — print
F 2 — auto
F 3 — goto
F 4 — list
F 5 — run-t—1
F 6 —run "COM:"
F 7-save "COM:"
F 8 —load "COM:"
F 9 — merge "COM:"
F10 — comterm
Первые 5 значений ключей или их начальные части индицируются в 23 строке — подсказке. Остальные появляются там при нажатии клавиши SHIFT. Ввод любого из этих значений организуется одним нажатием на соответствующую клавишу (возможно вместе с SHIFT). Значения спецклавиш можно менять, а их засветку из 23 строки — убрать.
Команды для работы с экранами. В этом пункте речь пойдет о командах: SCREEN, COLOR, CLS, WIDTH, KEY OFF, KEY ON, KEY LIST и KEY, применяемых и в непосредственном счете, и при вычислениях по программе. С их'помощью можно выбрать тип экрана и производить его чистку, устанавливать цвет бордюра, фона и изображения, задавать ширину фона, удалять надписи со строки- подсказки и восстанавливать их снова, индицировать, а также изменять значения функциональных клавиш. В некоторых из указанных команд могут присутствовать по несколько параметров. Неиспользуемые параметры можно не указывать, но если они не последние в записи, то ограничивающие их запятые обязательны. При этом каждый назначенный параметр действует до тех пор, пока не получит иное значение в соответствующей последующей команде.
SCREEN. Общая форма записи команды SCREEN (экран) будет дана в пункте 2.1. Сейчас же ограничимся частным случаем.
SCREEN n(1)
где п С(0, 1, 2, 3). По команде (1) назначается экран номер п. По умолчанию п = 0.
п = 0. Символьный экран, имеющий 24 строки и максимум 40 столбцов. Цвета бордюра и фона всегда совпадают.
n= 1. Символьный экран, имеющий 24 строки и максимум 32 столбца. Цвета бордюра и фона могут быть различными.
п = 2, 3. Графические экраны (см. 2.1).
Заметим, что команду INPUT можно использовать только при символьных экранах. Далее, команды графики допустимы лишь при графических экранах.
COLOR. Записывается команда COLOR (цвет) в виде COLOR [а] LPJ [.У]» гДе а, Р и V— арифметические выражения, целые части значений которых являются кодами цветов изображения (а), фона (6) и бордюра (с). Они должны лежать в пределах от 0 до 15. В таблице 7 дано соответствие цветов и кодов для одного из типов многоцветных дисплеев. Для монохроматических дисплеев эти коды определяют различные оттенки одного и того же цвета.
Таблица 7
*
Код
Цвет
Код
Цвет
0
прозрачный
8
красный
1
черный
9
светло-красный
2
зеленый
10
темно-желтый
3
светло-зеленый
11
светло-желтый
4
темно-синий
12
темно-зеленый
5
синий
13
сиреневый
6
темно-красный
14
серый
7
голубой
15
белый
Каждый параметр в COLOR действует до нового назначения. Любой из них можно опустить. Однако если он не последний в записи, то необходимо обозначить его запятой. Значение пропущенного параметра и соответствующего цвета не изменяется.
Использование команды COLOR позволяет выводить на экран разноцветные тексты и рисунки, подбирать для них цвет фона, а для экранов 1, 2 и 3 и цвет бордюра.
ПРИМЕРЫ 25
COLOR 1,7,3
COLOR ,11
COLOR X,,Z
Уловные для работы сочетания цветов
Зеленый дисплей
Цветной дисплей
COLOR
0,1,10
COLOR 0,1,Д0
COLOR
0,11,0
COLOR 1,7,13
COLOR
1, 15,8
COLOR 1,11,12
10 SCREEN 1
20 I=INT(RND(1)%16)
30 F=INT(RND(1)Ж16)
40 B=INT(RND(1)X16)
50 COLOR I,F,B
60 LOCATE 9,10: PRINT I$F;B
70 FOR K=1 TO 700:NEXT К
80 GOTO 20
Остановимся на некоторых особенностях реализации команды COLOR. На символьных экранах цвет изображения при выполнении COLOR меняется сразу на всем экране, и потому многоцветные тексты здесь недопустимы. На графических экранах назначение нового цвета изображения не распространяется на ранее индицированные тексты или рисунки. Этим самым предоставляется возможность вывода многоцветных изображений. Далее, если на символьных экранах цвет фона меняется по одной команде COLOR, то на графических — фон можно сменить только парами команд COLOR и SCREEN или COLOR и CLS. При этом, разумеется, изображение будет потеряно.
Заметим, что прозрачный цвет есть текущий цвет бордюра.
CLS. По команде CLS {clear screen — очистка экрана) стирается изображение на символьных и графических экранах.
Точнее, цвет изображения сливается с цветом фона.
ПРИМЕР 26
100 INPUT А
Ц0 IF А=0 THEN CLS
WIDTH. Команда WIDTH (ширина) используется для установки на символьных экранах условных вертикальных границ по центру фона. В полосе между этими границами и будет фиксироваться изображение. Записывается команда в виде WIDTH а, где а — арифметическое выражение, целая часть значения которого должна лежать в диапазоне от 1 до 40 (для экрана 0) и от 1 до 32 (для экрана 1). По умолчанию для экрана 0 а = 39, а для экрана 1 а = 29. При выполнении команды WIDTH имеющееся на фоне изображение исчезает, а последующая индикация символов организуется в соответствии с новым назначением «ширины».
ПРИМЕРЫ 27
10 SCREEN 0:WIDTH 25
100 SCREEN 1:WIDTH 28
110 PRINT "ПРОВЕРКА"
120 FOR K=1 TO 1000:NEXT
130 WIDTH 1
Для изменения ширины экрана без его чистки необходимо использовать команду РОКЕ (см. п. 1.5.).
KEY OFF. По команде KEY OFF (убрать ключ) из 23 строки- подсказки символьных экранов удаляется засветка значений ключей F1 — F10. Тем самым эта строка становится доступной для ввода информации. При этом сами значения ключей не разрушаются и по-прежнему могут использоваться простым нажатием на соответствующую функциональную клавишу F1 — F10 (см. табл. 6).
ПРИМЕРЫ 28
1) KEY OFF
2> 10 KEY OFF:LOCATE 5,23
20 PRINT "ПРОВЕРКА KEY OFF"
KEY ON. Команда KEY ON (восстановить ключ) отменяет действие команды KEY OFF и индицирует на 23-й строке экрана те-
27
кущие значения ключей F1 — F10. Тем самым эта строка становится недоступной для ввода.
KEY LIST. По команде KEY LIST (список ключей) на экран дисплея построчно выводятся полные текущие значения функциональных клавиш F1 — F10. Это бывает необходимо в связи с тем, что любое конкретное значение ключа может содержать до 15 символов и не всегда целиком размещается на отводимом для него месте в строке-подсказке.
KEY. Для изменения значений функциональных ключей предназначена команда
KEY a, t(2)
где а — арифметическое, a t — строковое выражения. При этом число n = int(a) определяет номер функциональной клавиши и, следовательно, должно находиться в пределах от 1 до 10.
При выполнении команды (2) значение клавиши Fn становится равным значению t. Длина последнего не должна превышать 15. В противном случае будут использованы лишь первые 15 символов значения t. Заметим, что в ключе с помощью CHR$-функции можно задавать коды непечатаемых символов.
ПРИМЕРЫ 29
KEY 5,’’print X;Y”
KEY 2,”" (Чистка значения ключа 2)
KEY 4,”LIST"+CHR$(13)
10 K»=CHR»(34)
20 KEY 5,"LOAD”+K$+”ABC”+K$+CHR*(13)
В примере 29(3) инициализация ключа приводит к тому, что нажатие на клавишу F4 будет вызывать индикацию текста программы без дополнительной команды «ввод строки» (*-). Пример 29(4) демонстрирует задание знака кавычки в строковом значении.
Управление курсором. Оформлению результатов вычислений на экране дисплея и в некоторых иных случаях помогают многочисленные средства управления курсором. К ним следует отнести команду позиционирования LOCATE, функции CSRLIN, POS, ТАВ и SPC, а также серию CHR$ -кодов (см. таблицу 8). Параметры в LOCATE, ТАВ и SPC могут быть произвольными арифметическими выражениями, у которых используются целые части значений. Функции ТАВ и SPC, а также все CHRS-коды применяются только в команде PRINT.
Команда, функция. Код. Примеры
Выполняемые действия
1
LOCATE X, Y [, а]
Команда позиционирования курсора по экрану
Примеры
100 LOCATE 25,8
200 LOCATE 10,7 300 LOCATE А + В, С
LOCATE — размещать. Курсор перемещается из текущей позиции в позицию (X, Y), где X — номер столбца (Х>0), Y— номер строки (Y>0). Величина а является переключателем типа курсора и может принимать значения 0 и 1: где: 0 — курсор отображается на экране только при некоторых командах ввода данных, 1 — курсор отображается.
По умолчанию а = 0
2
CSRLIN Номер строки Пример
10 Y = CSRLIN
20 IFY = 23 THEN 50
Значением функции является номер строки курсора (Y — координата)
3
POS (0)
Номер столбца Пример
10 Z = POS (0)
20 F = 24 * CSRLIN
+ POS (0)
Значением функции является номер столбца курсора (X — координата)
4
TAB (n) Курсор в позицию N (N = int (n)) Пример
10 P = 5
20 PRINTA; TAB (P);B, TAB (2*P); C
Функция ТАВ (п) используется в команде PRINT. Пусть Т — текущая позиция курсора в строке. Возможны случаи.
1} Т ^ N. ТАВ перемещает курсор на N позиций «вперед», считая от позиции 0 текущей строки экрана. Одновременно производится заполнение пробелами всех позиций от Т до N включительно.
2) T>N. ТАВ никаких действий не производит
5
SPC (n)
Индикация N пробелов
(N = int (n))
Пример
70 PRINTU; SPC (4); V
Функция SPC (п) используется в команде PRINT. По этой функции, начиная с текущей позиции курсора, индицируется N пробелов
6
CHR $ (8)
Влево Пример
5 PRINT "ПАРА";
CHR $ (8);
"ОХОД" (ПАРОХОД)
Управляющий код, по которому осуществляется возврат курсора на 1 позицию назад
Команда, функция. Код. Примеры
Выполняемые действия
7
CHR $ (9)
На метку табуляции Пример
7 PRINT 3;
CHR $ (9); "В"
(3В)
Управляющий код, по которому курсор перемещается на следующую метку табуляции (0, 8, ...)
8
CHR $ (10)
На следующую строку Пример
10 PRINT "ЛЕВ"
CHR $ (10); "ТИГР"
(ЛЕВ ТИГР)
Управляющий код, по которому курсор перемещается на 1 строку вниз. При необходимости производится подтяжка строк
9
CHR $ (11)
Домой Пример 8 PRINT CHR $ (11);
POS (0); CSRLIN (00)
Управляющий код, по которому курсор перемещается в левый верхний угол экрана в точку (0, 0) (аналог НОМЕ)
10
CHR $ (12) Чистка экрана Пример
5 PRINT CHR $ (12);
POS (0); CSRLIN (99)
Управляющий код, по которому производится чистка экрана с установкой курсора а в позицию (0, 0) (аналог SHIFT & GLS)
11
CHR $ (13) Возврат каретки
Управляющий код, по которому курсор перемещается в начало текущей строки (*-*)
12
CHR $ (28)
CHR $ (29)
CHR $ (30)
CHR $ (31)
Управляющие коды, по которым курсор перемещается, если это возможно, на 1 позицию «вперед» (->), «назад» (-*-), «вверх» (|), или «вниз» (4)
Ввод и редактирование программ. Некоторые из команд Бейсик- системы (интерпретатора), используемые при вводе и редактировании программ, были рассмотрены ранее. Остальные команды этой группы приведены в таблице 9. Речь идет о командах: автоматической нумерации строк при вводе (AUTO), перенумерации (RENUM) и удаления (DELETE) строк, вывода списка команд на экран (LIST) и принтер (LLIST), чистки оперативной памяти (NEW) и запуска программы на счет (RUN).
Текущим является номер той строки программы, которая последней заносилась (—•) в оперативную память. Заметим, что это не обязательно наибольший из номеров строк. В некоторых командах ввода и редактирования допускается ссылка на текущий номер строки. Делается это проставлением на месте соответствующего параметра символа «точка»(.).
ПРИМЕРЫ 30
LIST .
LIST 50-.
AUTO .,3
DELETE .
Все параметры команд рассматриваемой группы являются целыми неотрицательными числами. При этом номера строк лежат в диапазоне от 0 до 65529.
Таблица 9
Команды интерпретатора, используемые при вводе и редактировании программ
Команда. Название. Примеры
Выполняемые действия
1
AUTO[nl] [;п2)
Автоматическая нумерация строк
Примеры
AUTO
AUTO 100 г
AUTO 50,3 г
AUTO., 5 г
Automatic — автоматический. По команде AUTO производится включение режима автоматической нумерации строк при вводе от nl и дальше с шагом п2 (п2^^). По умолчанию п1=п2=10. Если очередное число к, сгенерированное автоматической нумерацией, совпадает с номером уже находящейся в памяти строки, то на экране индицируется последовательность к*.
После ввода (-^) новой строки к происходит следующее. Если за символом * есть хоть один знак, отличный от пробела, то старая строка к в памяти исчезает, а ее место занимает вновь введенная строка. В противном случае прежняя строка сохраняется. Выход из режима AUTO осуществляется по команде:
CTRL & STOP
2
RENUM [nl] [, n2] [, пЗ] Перенумерация строк Примеры
Renumber—перенумеровать. По команде RENUM производится перенумерация программных строк от п2 и дальше с шагом пЗ, (п3>0). При этом
Команда. Название. Примеры
Выполняемые действия
RENUM
RENUM 200, 150, 5
RENUM 100, 200
RENUM \^
nl — это новый номер прежней строки п2. По умолчанию nl=пЗ=10, п2 — номер начальной строки программы При перенумерации выдаются ошибочные ссылки на номера несуществующих в программе строк
3
DELETE [nl][ —n2]
Стирание строк
Примеры
DELETE 70—100
DELETE 50
DELETE
DELETE — 200
Delete — стереть. По команде DELETE из программы удаляются строки от nl до п2 включительно. По крайней мере один из параметров nl и п2 должен присутствовать явно. По умолчанию nl и п2 равны соответственно наименьшему и наибольшему из номеров строк программы
4
NEW
Чистка памяти
New — новый По команде NEW из оперативной памяти удаляются все программы пользователя и значения переменных
5
LIST [n 1][— n2]
Индикация фрагмента программы
Примеры
LIST
LIST 20 — 70
LIST - 50
LIST 40
LIST 500
LIST 100
LIST — список. По команде LIST на экран дисплея выводятся строки от nl до п2 включительно Если указанный диапазон строк не умещается на экране целиком, то остается лишь его последняя часть Пусть аир — наибольший и наименьший из номеров строк программы По умолчанию действует такое соглашение. При oicyT- ствии только nl полагается п!=а. При отсутствии только п2 полагается п2 = п1. При отсутствии обоих параметров считается nl = а, п2 = р
6
LLIST [n 1 ] [— n2]
Распечатка фрагментов программы
По команде LLIST на печатающее устройство выводятся строки от nl до п2 По умолчанию действует такое же соглашение, как и в команде LIST
7
RUN [n]
Запуск программы Примеры
RUN
RUN 1000
RUN — запуск, прогон. По команде RUN производится чистка значений переменных и запуск программы на счет со строки п. По умолчанию п равно наименьшему из номеров строк
Базовые конструкции
Присваивание значений. При запуске программы числовые переменные получают значение 0, а строковые — пусто. В дальнейшем эти значения могут изменяться с помощью команд: присваивания (LET), ввода данных с клавиатуры (INPUT, LINE INPUT), обмена 32
значениями (SWAP) и считывания из блока данных (DATA, READ, RESTORE). О них и пойдет речь ниже.
LET. Команда LET записывается в виде
(1)(1)[LET]a = p
(1)
(1)
где: LET (пусть) — служебное слово; a — простая переменная, элемент массива или МЮ$-функция; 0— выражение.
Слово LET в (1) указывать не обязательно. При выполнении LET вычисляется значение выражения 0 и результат присваивается а. Если а — числовая переменная, ар — арифметическое выражение, то при необходимости перед присваиванием значение р преобразуется к типу а.
Примеры 31
1) 10 X%= 7345. 19087#20 Y! =574. 123456#30 Z! =76767878#1) 10 X%= 7345. 19087#20 Y! =574. 123456#30 Z! =76767878#40 PRINT X%; Y!; Z!40 PRINT X%; Y!; Z!10 LET X = Y + Z
1) 10 X%= 7345. 19087#
20 Y! =574. 123456#
30 Z! =76767878#
1) 10 X%= 7345. 19087#
20 Y! =574. 123456#
30 Z! =76767878#
40 PRINT X%; Y!; Z!
40 PRINT X%; Y!; Z!
200 A = SIN (X)
300 Y $ = MID $ (P $, 7, 12)
400 AB (K)=K+1
run
7345 574. 123 76767900
$ (8).$ (8).100 MID $ (E $, 5) = Z
$ (8).
$ (8).
В случае, когда a есть МЮ$-функция, строковая переменная в ней обязана быть определена заранее. Скажем, в последнем примере значение для Е$ должно быть сформировано до выполнения строки 100.
INPUT. Команда INPUT используется для ввода данных с клавиатуры и записывается в виде
(2)(2)INPUT [«у»;] ai,a2,...,ak
(2)
(2)
где: INPUT (ввод) —служебное слово; у— последовательность произвольных символов алфавита (кроме запятой); ai,a2...,ak— список переменных.
При выполнении команды INPUT вычисления приостанавливаются и на экран дисплея выводится поясняющее сообщение у, если оно имеется, и знак ? : у?. Далее ЭВМ ждет, пока с пульта клавишного устройства будут введены значения для всех переменных списка ai,a2,...,ak. После этого вычисления по программе возобновляются. Вводимые данные Pi,p2,...,pk представляют собой числовые или строковые значения. При наборе они отделяются друг от Друга запятыми. Тип (числовой, строковый) и количество их должны соответствовать типу и количеству переменных ai,a2,...,ak. После на- 2 Заказ 627 33
жатия на клавишу -*-1 значения Pi,p2,...,Pk последовательно присваиваются этим переменным. Впрочем, вводить данные можно и частями (см. пример 32(1)). Заметим, что если ввести пустую строку или строку из пробелов, то соответствующая переменная сохранит свое прежнее значение (см. пример 32(3)).
При наборе данных до нажатия на клавишу •—1 можно осуществлять их редактирование всеми имеющимися для этого средствами (см. табл. 6).
ПРИМЕРЫ 32
10 INPUT "СОРТ";X,У,ВФ
run СОРТ? 25( ^-> >
?? 15,EF6(*>)
?Redo -from start COPT? 25,15,EFE,D ?Extra ignored25 15 EFG?Redo -from start COPT? 25,15,EFE,D ?Extra ignored25 15 EFG10 INPUT "СОРТ";X,Y,B$
?Redo -from start COPT? 25,15,EFE,D ?Extra ignored
25 15 EFG
?Redo -from start COPT? 25,15,EFE,D ?Extra ignored
25 15 EFG
20 PRINT X;Y;B$ run COPT? 25 ?? L
10 A=5:INPUT As PRINT A
run
? 5
Сообщения Бейсик-системы, которые мы имели во втором примере, расшифровываются так:
Redo from start — вводи сначала,
Extra ignored — лишние данные проигнорированы.
Отметим следующие ограничения при вводе данных по команде INPUT. В строковое значение нельзя ввести символ запятой (,) или начинать его с кавычек (").
LINE INPUT. Команда LINE INPUT используется для ввода с клавиатуры значений для строковой переменной и записывается в виде
LINE INPUT [V;] аLINE INPUT [V;] а(3)(3)
LINE INPUT [V;] а
LINE INPUT [V;] а
(3)
(3)
где: LINE, INPUT — служебные слова; у — последовательность произвольных символов алфавита; а — строковая переменная.
Выполнение команды LINE INPUT проводится аналогично команде INPUT с той лишь разницей, что вводится обязательно строковое и только одно значение, за поясняющим сообщением у не 34
индицируется знак вопроса и, наконец, среди вводимых символов могут быть и запятые, и кавычки.
Команда LINE INPUT вместе с функцией VAL может использоваться и для ввода числовых значений.
ПРИМЕРЫ 33
D 10 LINE INPUT "X-'^XS
100 LINE INPUT YS:Y=VAL(YS)
10 LINE INPUT "A = ";А$
20 IF A*=M&M THEN 10
30 IF VAL(AS)=0 THEN 10
SWAP. Команда SWAP используется для обмена значениями двух переменных одного типа и записывается в виде
SWAP а, р(4)
где: SWAP (обмен) — служебное слово; а, р — переменные.
При выполнении команды SWAP переменные аир обмениваются своими значениями. При этом в силу специфики реализации SWAP необходимо явное предварительное определение а и р.
ПРИМЕРЫ 34
1)
10
SWAP X,Y
2)
10
INPUT А», В»
run
20
SWAP А»,В*
? MIX,Y
30
PRINT А$;В$
mix
Нетрудно понять, что команда SWAP заменяет три команды присваивания вида:
у = а:а = р:р = у
где у — вспомогательная переменная.
DATA, READ, RESTORE. Удобные средства для хранения данных в теле программы и манипулирования ими предоставляет группа из трех команд: DATA, READ и RESTORE. Остановимся на них подробнее.
Команда формирования блока данных DATA записывается в виде
DATA Pi,p2,...,pk
где: DATA (данные) —служебное слово; pi,P2,...,Pk — список ког
Строковые константы списка Pi,p2,...,Рк можно задавать в кавычках и без них. В первом случае в значении константы не должно быть кавычек, а во втором — недопустимы также знаки двоеточия (:) и запятой (,).
ПРИМЕРЫ 35
10 DATA 1,2,7,15,"ПАРК"
20 DATA 6,7,7,100,8
100 DATA АВТОБУС, ТРАМВАЙ
200 DATA HABC,X:ZH
Пусть в программе в строках ni,ri2,...,ns (m ^n2^...ns) имеются команды DATA. При запуске программы на счет по ним создается в памяти так называемый блок данных, который удобно представлять себе в виде линейной последовательности констант так, как это изображено на рисунке 3.
С блоком данных связана некоторая величина |, называемая указателем считывания. Она всегда настроена на конкретную константу блока. При запуске программы указатель | «метит» позицию первой константы блока. В дальнейших вычислениях по программе команды DATA участия не принимают.
Команда чтения из блока данных READ записывается в виде
READ ai,a2,...,an
где: READ (читать) —служебное слово; ai,a2,.••»«„ — список переменных.
При выполнении команды READ из блока данных последовательно извлекаются константы и их значения присваиваются соответственно пременным ai, 0С2, ..., an. Выборка начинается с той константы, на которую настроен указатель |. При этом сам указатель при каждом считывании смещается по блоку на 1 позицию вправо. Типы значений и переменных (числовые, строковые) должны совпадать. При считывании последней константы блока значение указателя | не определено.
Команда управления указателем считывания из блока данных RESTORE записывается в виде
RESTORE [m](5)
Указатель считывания
А, К - • • А, , Т;, 7г . • • • Тк2.• ■ • , б,, б2,бKs
Рис 3Рис 3константы б DATA из строки п5константы б DATA из строки п5Константы 5 DATA Константы б DATA из строки п1 из строки п:
Рис 3
Рис 3
константы б DATA из строки п5
константы б DATA из строки п5
где: RESTORE (восстановить) — служебное слово; m — номер программной строки с командой DATA.
При выполнении команды (5) указатель ф настраивается на ту константу блока данных, которая первой вошла в него из самой «левой» команды DATA строки т. Если параметр m отсутствует, То указатель | настраивается на первую константу блока.
ПРИМЕРЫ 36
10 DATA S,ABC,&Н6,&015,&В101
20 DATA 10E+2,8D—1,
•'START”
2)
10 DATA 5,6
run
20 DATA POLE,9,10
5 6POLE
30 DATA '•XZ”,!!
POLE 910 XZ
40 READ X,Y,Z$
50 PRINT X;Y,Z$
60 RESTORE 20
70 READ L$,A,B,M$
80 PRINT L$;A;B;M$
Передачи управления. По введенной в память ЭВМ программе вычисления проводятся в соответствии с составляющими ее строки командами (слева направо) и в порядке возрастания номеров строк. Однако по подобной линейной схеме решается весьма ограниченное количество задач. Во многих реальных ситуациях желательно уметь нарушать естественный порядок выполнения команд. Такие средства в Бейсике предусмотрены. Некоторые из них и рассматриваются ниже.
GOTO. Команда безусловной передачи управления записывается в виде
GOTO п(6)
где: GOTO (перейти к) — служебное слово; п — номер программной строки.
По команде (6) управление передается строке п. Иными словами, где бы ни находилась в программе команда GOTO п, после нее начинает выполняться первая команда строки п.
Пример. 10 GOTO 1000
IF. Команда IF используется для организации разветвлений ныччелительного процесса. Записывается она в виде
где: IF (если), THEN (то), GOTO (перейти к), ELSE (иначе) — служебные слова; о — выражение отношения (условие); nl, п2— номера программных строк; 01, 02 — последовательности команд, разделенные двоеточиями.
Пусть х и у — арифметические или символьные выражения. Условие о в IF или является простым отношением вида:
У, х>У, х>х<.=у, х> = у, х = у, х< >у,х<.=у, х> = у, х = у, х< >у,
У, х>
У, х>
х<.=у, х> = у, х = у, х< >у,
х<.=у, х> = у, х = у, х< >у,
или строится из них с помощью операций (связок)
OR (или), AND (и), NOT (не) ...
(см. 1.1). Во всех случаях о может принимать лишь два значения: Т (истина) и F (ложь).
При реализации IF выполняется или ее THEN (GOTO)-часть (значение о равно Т), или ее ELSE-часть (значение а равно F). Если ELSE-части в команде IF нет, то условно можно считать, что она есть, но состоит из «пустой» команды, не производящей никаких действий.
Отметим, что возможны случаи вложения команд 1F друг в друга и что IF должна полностью размещаться в одной программной строке.
ПРИМЕРЫ 37
1)200 IF Х<0 THEN 600
300 IF А=В GOTO 700,
400 IF C<D THEN Y=X^2 ELSE У=ХЛ3
100 IF A<X AND X<B
THEN Y=FNT(X):C*="B ОТРЕЗКЕ"
ELSE Y=FNQ(X):C»="BHE ОТРЕЗКА"
200 PRINT X;Y,C*
700 IF A=B THEN Y=A
ELSE IF A<B THEN Y=B-A
ELSE Y=A-B
ON. Общая форма записи команды-переключателя ON следующая.
0N 4 gosub) "" mn*
где: ON (на), GOTO, GOSUB (идти к подпрограмме) — служебные слова; 0— арифметическое выражение; т, Пг, ..., nk— номера программных строк. '
38
Выполнение команды ON начинается с вычисления целой части р значения выражения р. Далее, если р£{1, 2, ..., к), то управление переходит к строке пр. При р = 0 или р>к управление передается команде, следующей за ON. Другие значения р приводят к сообщению об ошибке.
Параметры GOSUB и GOTO в ON используются в зависимости от того, являются или нет величины ni, П2, ..., nk номерами строк подпрограмм. В первом из этих случаев после выполнения соответствующей подпрограммы управление передается команде, расположенной за ON.
ПРИМЕРЫ 38
10 INPUT Xrun
20 ON X GOTO 200,300,400:GOTO 10? 2
200 PRINT X+200:GOTO 10302
300 PRINT X+300:GOTO 10? 3
400 PRINT X+400:GOTO 10403
Циклы. С помощью команд условной передачи управления IF
нетрудно организовать повторные выполнения определенной'совокупности команд, называемой в этом случае циклом. Например,
100
для вычисления суммы 2 W2+3) можно использовать следующий фрагмент:
run4.0320702699077run4.032070269907710 К=1:8=0
run
4.0320702699077
run
4.0320702699077
20 8=8+К/(КЛ2+3)
30 К=К+1
40 IF К<=100 THEN 20
50 PRINT 8
При запуске этой программы команды 20—40 будут исполнены по 100 раз. Они и составляют цикл.
Понятие цикла является одним из основополагающих понятий информатики. Программы, содержащие циклы, называются циклическими. Цикл, не содержащий внутри себя других циклов, называется простым. В противном случае его называют кратным (сложным, составным) циклом.
Для эффективной организации циклических программ в Бейсике предусмотрены специальные средства. Речь идет о команде FOR, 0 Щая форма записи которой приведена на рисунке 4.
FOR 1=^ TOASTER 51 | Тело цикла | NEXT [z]FOR 1=^ TOASTER 51 | Тело цикла | NEXT [z]Здесь: FOR (для), ТО (до), STEP (шаг), NEXT (следующий) — служебные слова; i — числовая переменная; р, у, о — арифметические выражения.
FOR 1=^ TOASTER 51 | Тело цикла | NEXT [z]
FOR 1=^ TOASTER 51 | Тело цикла | NEXT [z]
Общепринята следующая терминология:
i — параметр цикла,
Р — начальное значение параметра цикла, у — конечное значение параметра цикла, а — шаг цикла (о=/=0, а по умолчанию о— 1), FORi = рТОу [STEPo] —заголовок цикла, NEXTi — окончание цикла,
команды между заголовком и окончанием образуют тело цикла. Выполнение команды FOR проводится так.
Вычисляются и запоминаются значения выражений р, у и о. Пусть они равны соответственно Ь, е и А.
Параметр цикла i получает начальное значение b: i = b.
Выполняются команды тела цикла.
Параметр I получает приращение h ; i — i-\-h.
Проверяется условие ^e — ^h^O. Если оно истинно, то следующим выполняется шаг 3, иначе выполняется шаг 6.
Команда цикла прекращает свою работу.
Заметим, что хотя бы один раз тело цикла будет выполнено при любых р, у и о. Значения выражений р, у и о внутри цикла изменить нельзя, значение параметра I — можно. Вход в цикл реализуется только через его заголовок. Возможен досрочный выход из цикла не через его окончание, а по командам IF, GOTO... . Вложенные циклы могут обслуживаться одной строкой окончания. Например, NEXT К, J, I. Одиночный параметр цикла в NEXT указывать не обязательно.
ПРИМЕРЗ?2)
300 FOR 1=1 ТО 20
1)100 5=0
110 FOR К=1 ТО 100
120 S=S+A(K)
130 NEXT К
3)100 INPUT А,В,Н
110 FOR Х=А ТО В STEP Н
120 PRINT X;EXP(SIN(X))
130 NEXT
Вывод данных. В этом пункте речь
310 FOR J=1 ТО 30
320 INPUT MAS(I,J)
330 NEXT J,I
пойдет о командах вывода
данных на символьные экраны 0 и 1
(PRINT, PRINTUSING),
Рис. 5Рис. 5Зона 1Зона 2Зона 1Зона 2
Рис. 5
Рис. 5
Зона 1
Зона 2
Зона 1
Зона 2
графические экраны 2 и 3 (PRINT#, PRINT#, USING) и принтер (LPRINT, LPRINTUSING). Впрочем, более подробно последний случай описан в пункте 3.
Вывод данных на символьные экраны 0 и 1.
PRINT. Условно разобьем поле ввода фона экрана дисплея на зоны по 14 позиций каждая. Зоны символьных экранов изображены на рисунке 5. Поскольку максимальная ширина фона не превосходит 40 позиций. то количество полных зон не может быть более 2.
По команде PRINT (печатать) данные индицируются на экранах 0 или 1. Возможности управления размещением выводимой информации ограничены. Общая форма записи PRINT следующая:
PRINT [pir1p2r2...pk[rk] ](7)
где: PRINT — служебное слово; Ps(s= 1, 2, ..., к) — выражения, значения которых должны быть проиндицированы; rs(s = 1, 2,..., к) — указатели формата, разделяющие выражения. Ими могут быть запятая, точка с запятой или последовательности этих символов. Для гк допускается и пробел.
При выполнении команды PRINT все значения ps(s = 1, 2, ..., к) выводятся, начиная с текущей позиции курсора. Причем индикация каждого символа смещает курсор на 1 позицию «вперед». Разделители rs действуют так: каждая запятая переводит курсор в начало следующей полной зоны, а точки с запятой на него влияния не оказывают. Разделитель rk, равный пробелу, смещает курсор в начало первой зоны следующей строки. Так же действует команда PRINT без параметров. За каждым выведенным числовым значением всегда помещается один пробел.
При вводе слово PRINT можно заменять символом ?.
ПРИМЕРЫ 40
1>10 PRINT "ПРО";"БА";7;"SMIT";4;55
run
ПРОБА 7 SMIT 455
100 PRINT ’•ЗАРПЛАТА”; 200; "РУБ11
run
ЗАРПЛАТА 200 РУБ
провел для знака
runrun30 X=7
run
run
40PRINTX,X~37343
50PRINTХ;ХЛ37343
60PRINTX;-X437-343
PRINTUSING. С помощью PRINTUSING (печать по шаблону) можно редактировать выводимую на экран информацию, располагая се требуемым образом. Общая форма записи этой команды следующая:
PRINTUSING t; Р1[гф2г2...ркгк](8)
где: PRINTUSING — служебное слово; Ps(s= 1, 2, ..., k) — выражения, значения которых выводятся; t — строковое выражение, задающее формат (шаблон) вывода; rs(s= 1, 2, ..., к) — разделители выражений. Ими могут быть запятая или точка с запятой. Для rk допускается и пробел.
Некоторые символы t являются управляющими и специальным образом влияют на формат вывода. Другие символы t «нейтральны» и просто переносятся в выводимые значения. Тип разделителей rs на вывод нс влияет.
Ниже перечислены основные управляющие символы шаблонов и даны поясняющие примеры.
!—вставка первого символа строкового значения.
Количество знаков ! в шаблоне должно совпадать с количеством элементов вывода в команде.
10 X$="XZZ":Z$="+"run
20 PRINTUSING "A?В—С!D/E";X$?Z$AXB-C+D/E
\i—j i_i...l_j\—вставка первых n + 2 символов строкового зна
чения (при п пробелах). Количество пар \...\ в шаблоне должно совпадать с количеством элементов вывода в команде.
10 Y$=”1234567890":Z$="КОМПЬЮТЕР"
20 PRINTUSING "А\ \В\\С\\D";Y$,Z$;Y$
run
A123ВК0МПС12345D
&— вставка полного строкового значения. Количе
ство символов & в шаблоне должно совпадать с количеством элементов вывода в команде.
10 У*="БЕйСИК":FO$="MSX-&"run
20 PRINTUSING FO$;YSMSX-БЕЙСИК
42
4) * * ***■*4) * * ***■*— примеры форматов для вывода чисел в фиксированной форме.
4) * * *
**■*
4) * * *
**■*
D 10 7USING "## ";25,-1,2;34$573 run 25 -12 34 7.573
100 DATA 7,4.576,45.8
110 FOR Х=1 ТО 3:READ Z 120 PRINTUSING "#.##РУБ";Z 130 NEXT X run'
7.00РУБ
4.58РУБ 7.45.80РУБ
фффф.ф— примеры форматов для вывода чисел в фикси* ф. * * # + рованной форме с указанием знака + (плюс) или — (минус) в начале или в конце записи.
10 F$="+#,##"
20 PRINTUSING F*;-1.852,3.46 run -1.85 +3.46
10 F$=“#.##+"
20 PRINTUSING Ft;-1.857,3.46 run 1.86- 3.46+
*.фф-— пример формата для вывода чисел с указанием
знака минус в конце отрицательных значений.
100 f$= ••##.#- -
200 7USING Ft;-75.3,14,-77.7,756 run
75.3—14.077.7-7.756.0
***### — пример формата для вывода чисел с забиванием пустого пространства перед ними символами *.
10 PRINTUSING “ХХ###.#”;7,945,1841.1
run
ХХХХ7.0 ХХ945.0 Х1841.1
ф ффлллд —пример формата для вывода чисел в плавающей форме.
10 7USING "#.###МАА";5844,2Е-03,5
run
0.584Е+04 0.200Е-02 0.500Е+01
**,.*ф* — пример формата для вывода чисел в фиксированной форме с разбиением записи их целой части на грани по 3 цифры в каждой.
GRt="##########,.####"
20 7USING GR$;87654321.77777
run
87,654,321.7778
Обратите внимание на то, что при необходимости числа перед выводом округляются и что если число шире формата, то оно все равно выводится, но перед ним ставится знак предостережения %. Далее разделители запятая (,) и точка с запятой (;) в списке вывода никоим образом не меняют положения курсора. Несколько значений, выводимых по одному шаблону, располагаются друг за другом без дополнительных пробелов.
Форматы могут иметь весьма замысловатую структуру и служить для вывода сразу нескольких значений.
44
ПРИМЕРЫ 41
10 Т$="НАРЯД-### СУММА ■«— ###.## Р"
20 7USING Т$;23,172.66
run
НАРЯД- 23 СУММА 172.66 Р
100 W$="##.# + ##.#Х1"
200 70SING W$;7.7,56.345
г un
7.7 + 56.3X1
Вывод данных на графические экраны 2 и 3. Для вывода символьной информации на графические экраны требуется предварительное «открытие» устройства вывода "GRP" (см. п. 4.4.). Сделать это можно, например, так
OPEN "GRP:" AS*!
PRINT# 1. Общая форма записи команды PRINT#! следующая:
PRINT#!, [р|Г1р2г2...рИ](9)
Здесь все параметры имеют тот же смысл, что и в команде PRINT. Выполняются команды (7) и (9) также одинаково. Исключением является лишь тот факт, что в данном случае при индикации текста прежняя информация с графического экрана не стирается и без специальных предосторожностей возможны нежелательные наложения символов и рисунков.
ПРИМЕР 42
10 COLOR 1,15,7:SCREEN 2
20 OPEN "GRP:"AS#1
30 PRINT #1,"графический экран"
40 FOR K=1 TO 3000:NEXT
PRINT # I, USING. Записывается данная команда в виде:
PRINT# LOSING t; p, [np2r2...pkrk](10)
Здесь все параметры имеют тот же смысл, что и в команде PRINTUSING. Выполнение (8) и (10) также одинаково, за исключением отсутствия в рассматриваемом случае чистки очередного знакоместа перед выводом очередного символа (см. PRINT#!).
Вывод данных на принтер. Рассмотрим два возможных варианта вывода данных на бумажную ленту печатающего устройства, которую удобно считать условно разбитой по ширине на зоны по 14 позиций в каждой.
Способ 1. Этот прием вполне идентичен выводу символов на графические экраны. Он возможен при предварительном «открытии» устройства печати по команде
OPEN "LPT:"AS#1
Дальнейшее использование PRINT# 1 и PRINT# 1,USING производится обычным образом.
Предлагаемый способ хорош тем, что фактически позволяет писать программы, заранее не ориентированные на конкретное устройство вывода.
С п о с о б 2. По командам
LPRINT[pirip2...pk Н
LPRINTUSINGt; pi[rip2...pkrk]
организуется вывод информации на принтер с управлением, аналогичным тому, который применялся в соответствующих командах (7) И (8).
ПРИМЕР 43. Печать таблицы шестнадцатиричных кодов ASCII символов БЕЙСИКА
10 LPRINT ”";
20 FOR S=2 ТО 15
30 LPRINT HEX*(S);"";
40 NEXT S
50 LPRINT:LPRINT
60 FOR K=0 TO 15
70 LPRINT HEXe(K);" ";
80 FOR S=2 TO 15
90 R=16XS+K
100 LPRINT CHR$(R);"”;
110 NEXT S
120 LPRINT
130 NEXT К
46
Результатом выполнения приведенной программы является таблица 1. ,
Подпрограммы. Прежде всего заметим, что подпрограммы — это специальным образом оформленные группы строк. Подпрограммы бывают двух типов: стандартные и нестандартные. Первые из них входят в состав математического обеспечения систем. Нам часто приходится неявным образом обращаться к ним, когда, например, вводим данные в память, печатаем результаты счета, вычисляем значения стандартных функций и т. п.
Нестандартные подпрограммы составляются самим пользователем и являются фактически фрагментами его программ. В этом пункте рассматриваются подобные подпрограммы, организуемые с помощью команд GOSUB — RETURN. Общая форма записи команды обращения к подпрограмме GOSUB п, где: GOSUB — служебное слово; п — номер программной строки.
При выполнении GOSUB (GO SUBROUTINE — идти к подпрограмме) происходит передача управления в подпрограмму строке с номером п. Подпрограмма обязана завершаться командой RETURN (возврат), с помощью которой организуется возврат к команде,- следующей за GOSUB. Войти в подпрограмму можно в любом месте, но не внутрь цикла. Иными словами, фиксированного начала она не имеет.
Из рисунка 6 можно уяснить механизм передач управления подпрограмме при наличии в основной программе нескольких команд GOSUB.
Возможны последовательные обращения из одних подпрограмм в другие с достаточной глубиной подобного вложения. Рисунок 7 иллюстрирует схему вызова подпрограмм Ak (к = 1, 2,.... 9) с максимальной глубиной вложения 4.
Рис. 7Рис. 7
Рис. 7
Рис. 7
Пример. Составить программу, по которой методом половинного деления (вилки) на отрезке [А, В] с точностью Е определяется какой-либо вещественный корень уравнения
(Н)(Н)F (х)=0,
(Н)
(Н)
где F (х) непрерывна на [А, В] и F (A) -F (В) <0.
Пусть, например,
F (х) =cos (ех) —sin (лх)А=1, В = 3, Е = 0,00001.
В приведенной ниже программе ядро составляют строки 90— 110. При счете из основной программы производится многократное обращение к подпрограмме (строки 200—230), в которой при текущем значении х вычисляется величина y = F (х). Каждому уравнению (11) соответствует своя подпрограмма вида:
220 Y = F (X)
230 RETURN
Заметим, что вычисления y = F (х) не обязательно должны быть организованы в одной программной строке.
ПРИМЕР 44
10 ’ МЕТОД ’ВИЛКИ’ ДЛЯ УРАВНЕНИЯ F(X)=0
20 ’ ======================================
30 CLS:PRINT "LA,Bl - отрезок, E - точность
48
33 и*="корень- ###.####, точность- ##лл''л"
40 INPUT "введите тройку чисел А,В,Е";А,В,Е
50 X=B:GOSUB 200:F2=SGN(Y):IF Y=0 THEN 120
60 X=A:GOSUB 200:F1=SGN(Y):IF Y=0 THEN 120
70 IF F1XF2>0 THEN 30
80 'ядро
90 X=(A+B)/2:GOSUB 200:F2=SGN(Y)
95 IF Y=0 THEN 120
100 IF F1XF2<0 THEN B=X ELSE A=X:F1=F2
110 IF B-A>E THEN 90’ядро
120 PRINTUSING U$;X,E
130 END
200 ’ вычисления значений функции F(X>
210. ’
220 Y=COS(EXP(X))-SIN(3.14156ЛХ)
230 RETURN
Замечание. Строки 10, 20, 80, 200 и 210 в примере 44 являются комментариями и не влияют на ее выполнение.
Массивы. Ранее мы имели дело с переменными, которые характеризовались именем, типом и в любой момент времени единственным текущим значением. Подобные переменные называют простыми. Наряду с простыми переменными в Бейсике допустимы и массивы. Фактически массив представляет собой индексированную одним или несколькими индексами последовательность простых переменных одного типа, обозначаемых одним именем. В программах массивы объявляются, или описываются командой DIM у,, уг, •••, Уы где: DIM (dimention— размеры) —служебное слово; ys (s=l, к) — компоненты объявления.
Каждый компонент объявления определяет имя (или имя и тип) массива, а также верхние границы его индексов. Нижние границы по умолчанию равны 0. Верхние границы индексов задаются целыми неотрицательными константами или числовыми переменными. Их значения ограничиваются только размерами оперативной памяти. Если массив не объявлен в DIM, верхние границы всех его индексов принимаются равными 10.
Командой DIM можно объявлять и простые переменные.
Пример 45.1) 10 DIM С% (100)Имя массиваТипРазмерность Имена элементовПример 45.1) 10 DIM С% (100)Имя массиваТипРазмерность Имена элементовКоличество элементов2) 10 DIMA (5,20)Имя массиваТипРазмерностьИмена элементовКоличество элементовКоличество элементов2) 10 DIMA (5,20)Имя массиваТипРазмерностьИмена элементовКоличество элементов3) 10 DIM С! (7,8, 9)Имя массиваТипРазмерностьИмена элементовКоличество элементов3) 10 DIM С! (7,8, 9)Имя массиваТипРазмерностьИмена элементовКоличество элементов— Е$— строковый— одномерный— Е$ (0), Е$ (1), ... Е$ (20)— Е$— строковый— одномерный— Е$ (0), Е$ (1), ... Е$ (20)
Пример 45.
1) 10 DIM С% (100)
Имя массива
Тип
Размерность Имена элементов
Пример 45.
1) 10 DIM С% (100)
Имя массива
Тип
Размерность Имена элементов
Количество элементов
2) 10 DIMA (5,20)
Имя массива
Тип
Размерность
Имена элементов
Количество элементов
Количество элементов
2) 10 DIMA (5,20)
Имя массива
Тип
Размерность
Имена элементов
Количество элементов
3) 10 DIM С! (7,8, 9)
Имя массива
Тип
Размерность
Имена элементов
Количество элементов
3) 10 DIM С! (7,8, 9)
Имя массива
Тип
Размерность
Имена элементов
Количество элементов
— Е$
— строковый
— одномерный
— Е$ (0), Е$ (1), ... Е$ (20)
— Е$
— строковый
— одномерный
— Е$ (0), Е$ (1), ... Е$ (20)
— целочисленный
— одномерный
-С% (0), С% (1), ... С% (100) С% (X), С% (А + В) и т. п.
— 100+1 = 101
-А
— числовой, двойной точности
— двумерный
— А (0,0), А (0, 1) ...
А (5, 20), А (1%, 1%) и т. п.
— (5+1) (20+1)= 126
— С!
— числовой, одинарной точности
— трехмерный
— С! (3,2, 1), С! (X,Y,Z) и т. п. _ (7+1) (8+1) (9+1)=720
10 DIM Е$ (20)
Имя массива
Тип
Размерность
Имена элементов
Количество элементов — 20 + 1 = 21
При выполнении команды DIM фиксируется наличие соответствующих массивов и проводится начальная инициализация их числовых элементов нулями, а строковых — нуль-строкой ("").
ПРИМЕРЫ 46
10 DIM А!(20),ВХ(20,30),С(3,3,3),ЕХ
50 DIM А(30)
60 FOR К=1 ТО 30
70 INPUT А (К)
80 NEXT К
Тип массива можно определять не только в самом имени знаками $, %, # и !, но и в команде DEF фиксаторами STR, INT, DBL и SGN (см. пункт 1.1).
50
ПРИМЕР 47
10 DEFSTR L:DIM L(100)
20 L(33)="строковое значение"
30 PRINT L(33) run строковое значение
Высвободить занятую под массив память можно по команде
ERASE уь 72, .... 7k
где: ERASE (стирать) — служебное слово; 7S (s = 1, k) — имена массивов (без скобок).
Высвобождаемые имена могут быть объявлены новой командой DIM. Команда ERASE является единственным средством управления оперативной памятью при ее нехватке.
ПРИМЕРЫ 482)10 DIM А(50)
10 ERASE A!,BX,C#,D20 FOR К=1 ТО 50
■ ■ ■■ ■ ■■ ■ ■
200 NEXT К 210 ERASE А
Дополнительные возможности языка
Управление ресурсами памяти. Персональный MSX-компьютер имеет небольшой объем оперативной памяти — 64 Кбайта. Поэтому полезной оказывается информация о распределении ресурсов памяти под различные цели и сведения о наличии и объеме в ней свободных мест в любой момент времени. На рисунке 8 представлена карта распределения оперативной памяти с указанием шестнадцатиричных адресов. Для недискового Бейсика a = F3B0, а для дискового значение а зависит от количества подключаемых дисководов. Из этой карты ясно, что вся память разбивается на три основные части: ПЗУ (постоянное запоминающее устройство), ОЗУ (оперативное запоминающее устройство) и рабочая системная область. В первой из них располагается Бейсик-интерпретатор, использующий при работе системную область. Во второй — программы пользователя, значения простых переменных и элементов массивов.
Адреса
0000 л
ИнтерпретаторI
msx-бейсика|ПЗУ
8000 ;
Программы пользователя
Простые переменные
Элементы массибоб > ОЗУ
Строкобая область
Блок управления файлами
ol и -
Рабочая системная область
Рис. 8 FFFF
Иногда требуется иметь предварительную оценку объема памяти, необходимой для размещения значений всех переменных конкретной программы. Сделать ее поможет таблица 10, в которой указы-
Таблица 10
Простые переменныеБайтыЭлементы массивов
Байты
Целая34-2Целая
Одинарной точности34-4Одинарнойточности
Двойной точности34*8Двойной точности
Строковая6-j-LСтроковая
2
4
8
34-L
вается количество байт памяти, отводимых под переменные разного типа. Через L там обозначена длина значения строковой переменной.
В Бейсике имеются средства для получения сведений о наличии свободного места в ОЗУ (функция FRE) и управления размером строковой области (CLEAR). Остановимся на них подробнее.
PRE. Записывается функция ERE (free — свободный) в одной из следующих двух форм: FRE (0), FRE (""). В первом случае FRE имеет значением количество байт свободной части памяти в ОЗУ без учета строковой области. Во втором — сколько свободного места в байтах имеется в строковой области. Кроме того, FRE С'") проводит так называемую «сборку мусора», реорганизуя расположенную в ОЗУ информацию и, по возможности, увеличивая свободную память. Однако следует иметь в виду, что «сборка мусора» выполняется медленно.
п р И М Е Р Ы 49
D PRINT FRE(0)
г ЦП
28815
100 IF FRE(0)>20000 THEN 250
Следующий пример дает более полную иллюстрацию использования функции FRE, и результат его прогона подтверждает данные таблицы 10. Обратим внимание, что значения строковых констант "десять букв", "К" и "фокус" берутся из самой программы и, таким образом, не занимают дополнительного строкового пространства.
ПРИМЕР 50
10 BOSUB 120
20 Х=451:GOSUB 120
30 Z#=7.5:BOSUB 120
40 Y!=555:BOSUB 120
50 W%=111:BOSUB 120
60 Ut=“десятьБукв”:BOSUB 120
70 DS="K":BOSUB 120
80 DIM Еф(150):BOSUB 120
100 FOR K=1 TO 150:E*(K>=CHR»(K):NEXT
105 .BOSUB 120
110 Е*(1)=“фокус”:Б03иВ 120:END
120 PRINT FREC0),FRE(““):RETURN
un
28586
200
28546
200
28575
200
28540
200
28564
200
28079
200
28557
200
28068
50
28552
200
28068
51
Функция FRE (0) с успехом может применяться и для защиты программы от чьих-либо попыток ее модифицировать. В некоторую точку программы вставляется дополнительная команда
IF FRE(O) < > a THEN NEW
проверяющая, соответствует ли реальное свободное пространство тому, которое должно быть на самом деле. При FRE (0)=#а IF производит чистку оперативной памяти, то есть организует самоуничтожение программы и значений переменных. При этом а для своей программы необходимо вычислить с учетом добавляемой команды IF.
CLEAR. Строковая область ОЗУ используется для размещения строковых значений. По умолчанию под нее отводится 200 байт. Однако размеры этой области можно менять командой CLEAR (чистить). В общем виде она записывается так: CLEAR [п], где: CLEAR — служебное слово; п — целое число.
CLEAR без параметров производит «чистку» в ОЗУ всех числовых и строковых переменных, элементов массивов и определенных пользователем функций DEFFN.
ПРИМЕР 51
10 М=9
20 T$=STRINS*(5,"+")
30 PRINT M;T*,FRE(0)>FRE<"">
40 CLEAR
50 PRINT M;T*,FRE(0>;FRE("")
run
9 +++++28720195
028737 200
CLEAR с параметром n, кроме «чистки», объявляет размер строковой области (см. рис. 8) для расположения строковых значений.
ПРИМЕР 52. < вез CLEAR п >
10 Т*=8РАСЕ*(198)
20 B*=STRIN6e(2, "#'•>
30 PRINT В*
40 X$=STRING$(1,"L")
50 PRINT X*
run
##
Out of string space in 40
54
При прогоне примера получили сообщение об отсутствии места в строковой области. Действительно, 200 байт, отведенных для нее по умолчанию, оказались уже исчерпанными.
п р И М Е Р 53. ( с CLEAR п >
10 CLEAR 300run
20 A$=SPACE$(255)LLLLL40
30 B$=STRING$(5,“L")
40 PRINT B»SFRE(M,,>
Дополнительные команды и функции. Ниже речь пойдет о некоторых важных дополнительных морфологических компонентах Бейсика, синтаксис и семантика которых по тем или иным причинам не были описаны ранее. Остановимся на командах комментария (REM), завершения вычислений (END), изменения значений в ячейках оперативной памяти (РОКЕ) и видеопамяти (VPOKE) и функциях: ввода одиночных символов (INKEY$), ввода последовательности символов (INPUT$), определения и изменения значений таймера (TIME), получения содержимого ячейки оперативной памяти (РЕЕК) и видеопамяти (VPEEK), программного распознавания типа клавиши управления курсором (STICK).
REM. Различные сообщения t, которые облегчают понимание текста программы, можно задавать командой REM t, где: REM (remark — замечание) — служебное слово; t — произвольная последовательность символов алфавита.
На ход вычислений команды REM никакого влияния не оказывают.
Другой способ включения в текст программы комментариев — это использование апострофа. Все, что стоит в команде за апострофом, рассматривается как поясняющее сообщение.
ПРИМЕРЫ 54
10 REM БИНАРНАЯ СОРТИРОВКА
100 REM “КОНТРОЛЬНАЯ РАБОТА #3”
1000 D=PKQ+2 ? это седьмое ответвление
Следует помнить, что не все комментарии одинаково полезны. Многие из них, в особенности написанные начинающими программистами, представляют собой лишь «шум» и не несут никакой полезной информации. Во всех случаях комментарии должны формироваться вместе с самой программой, разъяснять ее отдельные сложные фрагменты, подчеркивать использование нетривиальных идей и отражать этапы реализуемого вычислительного процесса. При наличии хороших комментариев значительно упрощаются
процессы тестирования, отладки, сопровождения и модификации программ.
END. По команде END (конец) вычисления по программе прекращаются, закрываются все файлы и компьютер переходит в режим непосредственного счета.
ПРИМЕРЫ 55
10 INPUT А
20 PRINT SIN (А) , COS (А) , TAN (А)
30 END
IF С=0 THEN END ELSE Y=X-2
Команда END не является обязательной для программы. Вычисления прекращаются также после выполнения последней команды строки с наибольшим номером, если, разумеется, эта команда не предусматривает передачи управления.
INKEY$. Для ввода данных с клавиатуры ранее мы имели две команды INPUT и LINE INPUT. Для ввода отдельных символов можно также использовать и функцию INKEY$.
В момент нажатия на какую-либо клавишу INKEY$ получает строковое значение, равное вводимому по ней символу. Если клавиши не нажимаются, то значением INKEY$ является нуль- строка (""). Специфика ввода по INKEY$ следующая. На экран не выводится ни знак вопроса, ни эхо символа, и, что самое существенное, не требуется нажатия на клавишу «ввод строки»
ПРИМЕР 56
W»=INKEY*run
20IF W$="” THEN10A
30PRINT W*:GOTO10E
По функции INKEY$ можно получать десятичные коды не только «печатаемых символов», но и коды управляющих и значения функциональных клавиш (см. таблицу 11).
ПРИМЕР 57
W$=INKEY*
20 IF W$="" THEN 10
30 PRINT ASC(W$):GDTO 10
56
Таблица 11
Клавиши
Коды
1
13
2
ESC
27
3
TAB
9
4
BS
8
5
SELECT
24
6
CLS HOME
11
7
CLS HOME & SHIFT
12
8
INS
18
9
DEL
127
10
4—
29
11
->
28
12
30
13
1
31
14
F1-F10
Коды символов значения функционального ключа
1NPUT$. Функция INPUTS (п), где n — арифметическое выражение, целая часть значения которого лежит в диапазоне от 1 до 255, прерывает вычисления до получения с клавиатуры п последовательных символов. Они и становятся значением функции.
ПРИМЕРЫ 58
10 Wt=INPUT$<3)
20 PRINT W»:GOTO 10
100 X$=INKEY>:IF X*="" THEN 100
200 X$=INPUT*(1)
В последнем примере строки 100 и 200 идентичны, не считая того, что по INPUTS на экран выводится курсор.
Функцию INPUTS можно также использовать и для получения последовательных десятичных кодов ASCII символов и Управляющих клавиш и значений функциональных клавиш (см. табл. И).
пример 5910 W$=INPUT*(2)20 FOR к=1 ТО 2пример 5910 W$=INPUT*(2)20 FOR к=1 ТО 230 PRINT ASC(MID*(W*,K,1))
пример 5910 W$=INPUT*(2)20 FOR к=1 ТО 2
пример 5910 W$=INPUT*(2)20 FOR к=1 ТО 2
40 NEXT:GOTO 10
TIME. MSX-компьютер обладает счетчиком, который называется таймером и запускается автоматически при включении машины. Таймер принимает следующие последовательные значения: 0, 1, 2, ..., 65535. Дойдя до 65535, он снова восстанавливается со значения 0 и т. д. Каждые 50 «тиков» таймера соответствуют одной секунде времени. Значения таймера и функции TIME (время) всегда совпадают. Впрочем, имеется возможность управлять этими значениями по команде
TIME = a(1)
где а — арифметическое выражение. При выполнении (1) TIME получает значение, равное INT (а).
ПРИМЕРЫ 60
10 PRINT TIME
200 X=TIME
500 Y=RND(-TIME)
60 TIME=0
10 INPUT T:TIME=T
20 FOR M=1 TO 1000:NEXT
30 PRINT TIME;:GOTO 20
run
? 0
138 276415 554693 ...
run
? 64982
6512065259 65397 0139 277 ...
100 TIME=0
900 PRINT "Время счета = ";TIME/50
Из-за небольшой разрядности таймера его обновление происходит довольно быстро — приблизительно каждые 21,8 минуты. Учет более длительных интервалов времени необходимо производить программным путем.
РОКЕ. По команде РОКЕ 1, а, где РОКЕ (совать, пихать) — служебное слово; t — арифметическое выражение, целая часть значения которого (Т) задает адрес ячейки памяти (конкретного байта); 58
аарифметическое выражение, целая часть значения которого (Л) лежит в пределах от 0 до 255.
При выполнении РОКЕ значение А записывается в ячейку с адресом Т.
ПРИМЕР 61
10 SCREEN 0:WIDTH 39
20 PRINT "КРАЙ ПОЛЯ"
30 POKE &HF3B0,20
40 FOR S=1 ТО 3000:PRINT "#";:NEXT
50 WIDTH 39
Команда строки 30 устанавливает ширину экрана в 20 позиций. При этом «чистки» изображения не происходит. Последующие изменения изображения на фоне организуются только на установленном поле ввода и не касаются его краев.
ПРИМЕР 62
200 POKE &HFCAB,255s RETURNS’ заглавные
300 POKE &HFCAB,0 sRETURNS’ малые
400 POKE &HFCAC,255sRETURNS’ русские
4> 500 POKE 8cHFCAC,0 sRETURNS’ латинские
Здесь демонстрируются возможности программного управления режимами: CAPS — ввод заглавных и строчных букв и РУС — ввод русских и латинских букв. Если, например, в вашей программе зафиксирован фрагмент примера 62(4) и произведено обращение
50 GOSUB 300: GOSUB 500
то в дальнейшем с клавиатуры будут вводиться малые латинские буквы до тех пор, пока программно или с пульта не будут установлены новые режимы. Заметим, что управление в примере 62(4) не изменяет текущего состояния индикаторных лампочек на соответствующих кнопках.
В примере 63 команда РОКЕ применяется для формирования новых программных строк в тексте программы в процессе ее выполнения. Это дает возможность по запросу с экрана дисплея вводить с клавиатуры не только числовые параметры задач, но и аналитические выражения. Можно, например, составить программу приближенного вычисления интегралов Римана по формуле Римпсона и запрашивать с экрана такие параметры: 1) нижний предел интегрирования; 2) верхний предел интегрирования; 3) подынтегральную функцию; 4) точность вычислений.
ПРИМЕР 63
10 ’ ввод программных строк*’
20 LINE INPUT АФ
30 NФ=,,999 ":L=39-LEN(NS)-1-8-1
40 IF LEN(AФ)>L THEN A»=LEFT»(A$,L)
50 AФ=NФ+AФ+CHRФ(13)+"goto 150,,+CHRФ (13)
60 FOR K=1 TO LEN(AФ>
70 POKE &HFBF0+K—1,ASC(М10Ф(АФ,K, 1))
80 NEXT К
90 POKE &HF3FA,&HF0
100 POKE &HF3FB,&HFB
110 D=8cHF0+LEN(A»)
120 POKE &HF3F8,D MOD 256
130 POKE &HF3F9,&HFB+D\256:’
140 END
150 ’передача управления
Несколько слов о том, как выполняется программа. Сначала по запросу LINE INPUT из строки 20 вводится произвольная последовательность А$ команд Бейсика. Наиболее часто А$ есть одиночное присваивание типа Y = F(X). Далее, строки 30— 80 формируют в буфере клавиатуры (адреса с FBF0 по FC17) строку следующей структуры:
999 А$ CHR$ (13) GOTO 150 CHR$ (13).
Для чего это делается? Дело в том, что при переходе компьютера по END в режим непосредственного счета сразу же начинают выполняться предписания из буфера клавиатуры. В нашем случае до первого кода CHR$ (13) они равнозначны вводу отредактированной строки 999 в оперативную память и далее, до второго CHR$ (13) — передаче управления на строку 150
В строках 90—130 устанавливаются так называемые «флажки», то есть по определенным адресам размещается необходимая служебная информация об адресах начала и конца записи в буфере клавиатуры.
Остановимся еще на двух моментах. Во-первых, длина буфера клавиатуры составляет всего лишь 39 байт, что существенно ограничивает и длину создаваемых с ее помощью программных строк. Во-вторых, ко всяким самомодификациям программ следует относиться весьма осторожно. Более того, многими специалистами она вообще отвергается как прием «хорошего» программирования.
РЕЕК. Функция РЕЕК (заглянуть) записывается в виде pEEK(t), где t — арифметическое выражение (O^INT(t) ^65535). Значением РЕЕК является содержимое ячейки INT(t). Наиболее часто РЕЕК используется для экспериментов с данными, хранящимися в ОЗУ.
УРОКЕ. В команде УРОКЕ t,a параметры t и а имеют тот же смысл, что и в РОКЕ, и действия этих команд во многом схожи. Только здесь t указывает адрес Т (О^Т^ 16383) в видеопамяти (ВП), куда и записывается байт данных A=INT(a).
Остановимся на одном из возможных использований рассматриваемой команды. В видеопамяти при выполнении SCREEN0 или SCREEN 1 инициируются шаблоны всех стандартных символов Бейсика, по которым впоследствии и организуется их индикация на экране. Поэтому если после назначения экрана провести изменение шаблона конкретного символа в ВП, то другим станет и сам выводимый символ. Так появляется возможность создавать отдельные новые знаки, национальные алфавиты, стилизованные буквы и т. п. Поясним, как это делается.
Под шаблон каждого стандартного символа с кодом ASCII ^32 в ВП отводится 8 байт, начиная с адреса
T = ASC ("символ") *8+ △
где
(О — для экрана 1△ I 2048 — для экрана 0.
Поэтому для изменения, например символа "@" на "ё" необходимо сформировать новый шаблон из восьми чисел:
80, 0, 112, 136, 24 8, 128, 112, 0(2)
и расположить их соответственно в ячейках ВП по адресам:
Т, Т + 1, ... Т + 7 (T = ASC("@") *8 + Д)
Откуда взялась последовательность (2)? На схеме рисунка 9 указано Г1Равило получения шаблона (2) по изображению символа "ё" На сетке размера 8X8. Подобная схема применяется и во всех других случаях. При этом следует учитывать, что для экрана 0 ^пользуются лишь старшие 6 бит каждого байта. Следовательно, и рисовать символы необходимо на первых 6 колонках сетки. В пРотивном случае выводимые знаки будут усекаться справа.
Указатели бесов битов
байта
128
64
32
16
8
4
2
1
Т
о
0
* 64+16= 80
Т+1
*0= о
7+2
0
•
0
*64*32*16= 112
7+3
О
0
*128*6= 136
7+4
0
•
•
о
0
* 128*64 *32*16*8 = 248
7+5.
•
*128= 128
Т*6
•
•
о
*64*32*16= 112
7+7
*0= 0
Рис. 9
Следующий пример демонстрирует, как реально VROKE размещает компоненты шаблона для "ё" в видеопамяти. Далее, после выполнения строк 10—80 нажатие на клавишу @ приводит к индикации на экране буквы "ё". Восстановление истинного (своего) шаблона для знака @ реализуется командами SCREEN0 или SCREEN 1.
ПРИМЕР 64
10 SCREEN 0:0=2048:’ или SCREEN 1:0=0
20 FOR J=0 ТО 7
30 READ X:VPOKE ASC("@")X8+J+D,X
80 NEXT J
90 A*=INPUT*(1):PRINT A»:60T0 90
100 DATA 80,0,112,136,248,128,112,0
VPEEK. Для функции VPEEK (t), где t — арифметическое выражение, значением является содержимое байта видеопамяти по адресу T=int(t) (0<ТС 16383).
STICK. Эта функция получает значения: 1, 3, 5 и 7 при нажатиях соответственно на клавиши: f, ->, |, *-. Она может служить для программного распознавания типа нажимаемой клавиши управления курсором. 62
,-j р И М Е Р 65
!0 X*=INKEY»:U=STICK<0)
20 IF UO0 THEN PRINT U;
30 GOTO 10
Программная обработка ошибок. Кроме сбоев в работе компьютера из-за неисправностей каких-либо его узлов, имеется достаточно много причин, по которым происходит прерывание вычислений по программе и при нормально работающей машине. Перечислим некоторые из них:
для элемента массива получено значение индекса, не лежащее в диапазоне, указанном командой DIM;
при вычислениях получено число большее, чем допустимо;
в программе встретилась функция пользователя FN, которая не описана;
компьютеру предложено произвести деление некоторого числового значения на нуль.
Все эти и многие подобные им причины, вызывающие прерывания, имеют конкретные номера от 1 до 255, называемые кодами ошибок. Если какая-либо ошибка происходит, то на экране индицируется соответствующее сообщение. Например:
NEXT without FOR in 40(NEXT без FOR в строке 40).
После устранения причин, вызвавших прерывание программы, как правило, приходится запускать ее заново. Однако имеется возможность «обработать» ошибку, не прекращая вычислений. Для этих целей используется команда
ON ERROR GOTO n(3)
где: ON (на), ERROR (ошибка), GOTO (идти) —служебные слова; п — номер программной строки.
При выполнении этой команды происходит назначение передачи управления на строку с номером п. Но сама передача реализуется лишь в случае возникновения ошибки.
Фрагмент программы, начинающийся со строки п и заканчивающийся командой
RESUMERESUME0 INEXT ?m /0 INEXT ?m /(4)(4)
RESUME
RESUME
0 I
NEXT ?m /
0 I
NEXT ?m /
(4)
(4)
называется подпрограммой обработки ошибок, где: RESUME (возобновлять, продолжать), NEXT (следующий)—служебные слова; m — номер программной строки.
После обработки ошибки в зависимости от значения параметра, расположенного за словом RESUME, возврат в основную программу осуществляется либо к команде, вызвавшей ошибку (0 или нет параметров), либо к следующей за ней (NEXT), либо к строке с номером т.
Всегда действует последнее из выполненных назначений (3), а его отмена реализуется командой
ON ERROR GOTO О
В подпрограммах обработки ошибок обычно используются значения функций ERR и ERL, равные соответственно коду последней ошибки и номеру строки, где она произошла.
Далее, командой ERROR а, где а — арифметическое выражение, можно искусственно вызывать ошибки с любыми кодами т — = INT (а) (0<т<255).
ПРИМЕР 66
10 ON ERROR GOTO 90
run
20 E=10:Z=0
3011
30 P=E/ZsPRINT ■•?=";?
P= 100
40 Q=LOG(E—11)
405
50 ERROR 250
5025»
60 PRINT "ЗАВТРА"s
70 ON ERROR GOTO 0:END
80 REM обработка ошибок
90 PRINT ERL,ERR
100 IF ERR=11 THEN 140
110 IF ERR=5 THEN 150
120 IF ERR=250 THEN 160
130 STOP
ЗАВТРА
140 Z=.lsRESUME 0
150 RESUME NEXT
160 RESUME 60
Переход к подпрограммам по событию. Имеется возможность организовать переходы на подпрограммы по совершению таких событий, как истечение определенного интервала времени, нажатие на клавиши: F1 — ЕЮ, CTRL/STOP, «пробел» и т. п. Об этом и пойдет речь в данном пункте.
Переход по временному интервалу. По команде
ON INTERVAL = t GOSUB n
где ON (no), INTERVAL (интервал), GOSUB (переход к подпрограмме) — служебные слова; t — целое из диапазона [0,65535], п — номер программной строки, назначаются интервалы времени, равные t/50 с, через которые периодически передается управление подпрограмме, расположенной со строки п. Отсчет временных интервалов реализуется специальным счетчиком, принимающим значения |,2,...,t,l,2,...,t,lЭтот счетчик запускается (ON), сбрасывается (OFF) или приостанавливается (STOP) по команде
{
ON Ч OFF I STOP J
Пример. В этом фрагменте демонстрируется возможная организация учета времени выполнения программ, если оно больше одного цикла таймера.
ПРИМЕР 67
10 Т=0:Т1МЕ=0:Н=60000
20 ON INTERVALS GOSUB 500
30 INTERVAL ON
90 PRINT "Время = ";(T+TIME)/50;"сек"
100 END
500 T=T+H:TIME=0
510 RETURN
Проследите за выполнением следующего примера при k= 1, 2, 6.
ПРИМЕР 68
10 INPUT К
20 ON INTERVAL=KX50 GOSUB 80
30 INTERVAL ON:GOSUB 100
40 INTERVAL STOP:GOSUB 100
50 INTERVAL ON:GOSUB 100
&® INTERVAL OFF:GOSUB 100
70 END
80 PRINT "ПРОВЕРКА":RETURN
100 FOR k=1 TO 7000:NEXT:RETURN
3 Заказ 62765
Переход по ключу. По команде ON KEY GOSUB П1,П2,...,пк, где: ON (по), KEY (ключ), GOSUB — служебные слова; ni, П2,...,пк — номера строк программы (к ^10), могут осуществиться передачи управления подпрограммам, расположенным со строк П|, П2,...,пк. При этом действие любого ключа FS (8=1,2, ..., к) должно быть или подтверждено (ON), или отменено (OFF), или приостановлено (STOP) командой
{
ON OFF STOP
Заметим, что если в момент действия параметра STOP для ключа FS произведено нажатие FS, то после KHYtS) ON сразу же реализуется соответствующая передача управления.
Прогон следующего фрагмента позволит более полно понять действие всех упомянутых выше команд.
ПРИМЕР 69
10 KEY<1) ON:KEY(2) ON
20 ON KEY GOSUB 70,80
30 GOSUB 90
40 KEY(l) STOP:GOSUB 90
50 KEY(l) ON:GOSUB 90:END
60 REM подпрограммы
70 PRINT “НАЖАТА КЛАВИША Fl":RETURN
80 PRINT "НАЖАТА КЛАВИША F2"
85 KEY(2) OFF:RETURN
90 FOR K=1 TO 2000:NEXT:RETURN
Переход no CTRL — STOP. По команде ON STOP GOSUB n, где: ON, STOP, GOSUB — служебные слова; п — номер программной строки, при нажатии на клавиши CTRL — STOP может осуществиться передача управления подпрограмме, расположенной со строки п. При этом действие CTRL — STOP должно быть подтверждено (ON), отменено (OFF) или приостановлено (STOP) командой
STOPSTOPON OFF STOPON OFF STOP
STOP
STOP
ON OFF STOP
ON OFF STOP
Переход no пробелу. По команде ON STRIG (0) GOSUB n, где: ON, STRIG — служебные слова; n — номер программной строки, 66
при нажатии на клавишу «пробел» может осуществиться передача управления подпрограмме, расположенной со строки п. При этом Действие клавиши «пробел» должно быть подтверждено (ON), отменено (OFF) или приостановлено (STOP) командой
ON )
STRIG(O)STRIG(O)OFF ISTOP J
STRIG(O)
STRIG(O)
ПРИМЕР 70
360 ON STRIG GOSUB 440
370 STRIG(0) ON:GOSUB 430
380 STRIG(0> STOP:GOSUB 430
390 STRIG(0) ON:GOSUB 430
400 STRIG(0) OFF:GOSUB 430
410 GOSUB 430:END
430 FOR K=1 TO 1000:NEXT KsRETURN
440 PRINT "ПРЕРЫВАНИЕ ПО STRIG":RETURN
Отладка программ. Написав программу, прежде всего необходимо проверить ее на данных, по возможности охватывающих все случаи, которые могут встретиться при реальном счете. Для этого составляются и «прокручиваются» различные тесты. Они создаются с учетом специфики решаемых задач, выбранного алгоритма и степени риска от возможных необнаруженных ошибок. Довольно часто это просто серия специально подобранных контрольных задач, не требующих значительных затрат времени на решение, в которых заранее известны конечные, а во многих случаях и промежуточные результаты вычислений. Их сопоставление со значениями, полученными при счете, позволяет высказать более или менее правдоподобные гипотезы о правильности программы. Если в ней обнаружится ошибка, а это почти всегда так, то процесс тестирования должен быть приостановлен. Далее начинается процесс отладки, т. е. выявление типа ошибок, их локализация и исправление. Успешному проведению отладки способствует выдача различных сообщений о ходе решения конкретных задач. В частности, начиная с любой команды, можно проследить «трассу» дальнейшего хода вычислений. Для этого в требуемом месте размещают команду TRON.
Ее реализация приводит к включению режима трассировки, при котором последовательно выводятся номера выполняемых в данный момент строк в виде: [nJ [п2] ... [nJ...
Между компонентами [ ] могут располагаться значения, печатаемые по командам PRINT или вводимые с клавиатуры по командам INPUT.
ПРИМЕР 71
10 TRON
run
20 A=5:B=6sPRINT А,В
1201 56
30 IF АХВ<99 THEN 100
E30IE100] 11
110 PRINT В-A
Е110Э 1
120 TROFF
E120]
Анализ полученной трассы, как правило, позволяет локализовать ошибку.
Отменяется режим трассировки командой TROFF.
Обе команды TRON и TROFF можно выполнять в непосредственном счете.
Другой, часто применяемый способ отладки, состоит в следующем. В «критических» точках программы расставляются вспомогательные команды STOP.
При выполнении STOP вычисления приостанавливаются и пользователь в непосредственном счете может вывести значения интересующих его переменных. Анализ их позволяет делать выводы о правильности хода вычислительного процесса и соответственно принимать те или иные решения.
После останова по команде STOP вычисления возобновляются командой CONT, которая должна быть выполнена в непосредственном счете.
ГРАФИКА
Айвен Сазерленд — пионер применения компьютеров для построения и обработки изображений — заметил как-то о своем излюбленном предмете: «Дисплей, подключенный к ЭВМ, представляется мне окном в Алисину Страну чудес, где программист может изображать любые объекты, описываемые хорошо известными законами природы, либо чисто воображаемые объекты, подчиняющиеся законам, записанным в программе. С помощью дисплеев я сажал самолет на палубу движущегося авианосца, следил за движением элементарной частицы в потенциальной яме, летал в ракете с околосветовой скоростью и наблюдал за таинствами внутренней жизни вычислительной машины».
Восторг доктора философии понять несложно. Возможности машинной графики воистину безграничны. Особенно впечатляющим представляется ее применение в системе образования при разработке и использовании педагогических программных средств. Простота
освоения элементов машинной графики способствует ее проникновению в разнообразные прикладные сферы и, несомненно, обеспечивает дальнейший рост ее популярности.
Экраны. Пиксели. Точки
Дисплей ЭВМ «Ямаха» имеет два режима для вывода графической информации. Их называют соответственно SCREEN2 и SCREENS (screen — экран). Закодированное изображение хранится в специальном участке памяти, называемом буфером образа, где оно представлено в форме матрицы двоичных значений интенсивностей свечения или цветов точек экрана. Блок сопряжения, именуемый дисплейным контроллером, обрабатывает содержимое буфера образа и преобразует двоичный код в видеосигналы, передаваемые дальше в телевизионный монитор. Возникающая в результате этого на экране картина воспринимается пользователем как устоявшаяся потому, что она возобновляется с частотой, не меньшей 30 раз в секунду.
Наименьшим неделимым элементом изображения, который может быть показан на экране, является маленькое светящееся пятно, именуемое пикселем. Общее количество пикселей экрана (режима) является важной его характеристикой.
Наряду с пикселями введем понятие точки на экране. Пусть задана декартова прямоугольная система координат так, как это показано на рисунке 10. Обратите внимание на непривычное расположение начала координат и направление оси ординат. Впрочем, как показывает опыт, приспособиться к этой системе довольно просто.
Множества координатных точек (а, Ь) и их общее количество для обоих экранов одинаковы:
( ,А a g {0, 1, ... 255}
(а’ ) b £ {0, 1,... 191}
Р = 256Х 192 = 49152
ОООднако допустимое адресуемое пространство значительно шире. Некоторые параметры графических команд разрешается задавать в диапазоне от —32768 до 32767.
О
О
Экраны 2и 3Экраны 2и 3256 х 192точек256 х 192точек191191Рис. 10Рис. 10*у*уПиксели для обоих экранов представляют собой маленькие квадратики, задаваемые координатами верхнего левого угла. Каждая координатная точка определяет по одному пикселю. Но размеры их для экранов 2 (слева) иЗ (спраВа) разные. Из рисунка 11 можно
Экраны 2и 3
Экраны 2и 3
256 х 192точек
256 х 192точек
191
191
Рис. 10
Рис. 10
*у
*у
понять, как точка (а, Ь) задает пиксель и каковы его размеры для обоих экранов.
Заметим, что один пиксель экрана 3 соответствует блоку из 4X4 пикселей экрана 2. Далее, нетрудно видеть, что для экрана 2 мы имеем взаимно однозначное соответствие между множествами координатных точек и пикселями.
В любой конкретный момент времени одна из точек (а, Ь) экрана находится в особом состоянии, или, как говорят, отмечена графическим курсором, а и b в этом случае называют текущими координатами курсора. При включении компьютера графический курсор устанавливается в положение (0, 0) — верхний левый угол экрана.
Пусть (а, Ь) — текущая позиция курсора, х и у — арифметические выражения, у которых используются целые части х0 и у0 соответствующих значений.
В описании графических команд будут встречаться следующие элементы:
1. @
— необязательный элемент команд никоим образом не влияющий на их выполнение. Этот символ фактически является лишь «фирменным» знаком совокупности графических команд;
2. (X, Y) без параметра STEP
— необязательный элемент, определяющий точку экрана (х0, уо). Если (х0, уо) вне пределов экрана, то элемент, как правило, не используется или вызывает прерывание при выполнении соответствующей команды;
3. STEP (X, Y)
— элемент, задающий смещение относительно текущей позиции курсора (а, Ь) и определяющий точку (a-j-xo, Ь + уо). Если эта точка лежит вне пределов экрана, то элемент, как правило, не используется или вызывает прерывание при выполнении соответствующей команды;
4 С (или Ci) —арифметическое выражение, целая часть значения которого лежит в диапазоне [0, 15] и определяет цвет точки, области и т. п. По умолчанию С есть цвет изображения.
Многие элементы в графических командах не являются обязательными и могут быть опущены. Однако соответствующая запятая в тексте должна сохраниться и тем самым указывать на отсутствие того или иного параметра. Это правило не касается завершающих запятых. Их оставлять нельзя.
В последующих пунктах дается описание каждой из системы базовых графических команд и функций Бейсика. С их помощью мы научимся выводить на экран точки, линии, прямоугольники, окружности, эллипсы и дуги, покажем, как заполнять области экрана однотонным цветом, и рассмотрим простейшие примеры использования этих средств.
Установка и стирание точек
В этом пункте речь пойдет о двух командах PSET и PRESET, используемых для перемещения графического курсора в требуемую точку с возможным изменением цвета соответствующего ей пикселя, а также функции POINT, позволяющей узнавать цвет конкретных пикселей.
. Команда VSEX ^установить точку). Записывается команда в виде
PSET [@] [STEP] (X, Y) [,С]
Выполняется PSET так. По элементам (X, Y) или STEP (X, Y) находится точка (хо, уо), а по ней — левый верхний угол (р, q) соответствующего пикселя. Графический курсор перемещается в точку (р, q) и раскрашивает пиксель в цвет С. Следует иметь в виду, что для экрана 2 это может привести к изменению цвета до 8 близлежащих пикселей, расположенных в строке р.
ПРИМЕР 1= Точки (пиксели) с
равном раскрас кой
IC COLOR 159ls8s SCREEN 2
СУ ^‘SET (7^3)
ЗУ FOR Х=С ТО 15
Аб РЕЕТ STEP(17,13), X
50 ^;ЕХТ X
GOTO 60
ПРИМЕР 2. Синусоида
10 COLOR 1,15,8:SCREEN 2
20 PSET (0,95)
30 FOR K=0 TO 255:PSET STEP(1,0),1:NEXT
40 PSET (128,0),
FOR K=0 TO 191:PSET STEP(0,1),1:NEXT
Z=8XATN (1) : ’2Хпи
7 FOR K=0 TO 255
PSET (K,50XSIN(ZXK/256)+95),5
NEXT
1 GOTO 100
Команда PRESET (стереть точку). Записывается команда в виде
PRESET [@] [STEP] (X, Y) [,С]
При выполнении команды PRESET без параметра С соответствующий ей пиксель «стирается», т. е. закрашивается под цвет фона. Если параметр С присутствует, то действия команд PRESET и PSET идентичны.
ПРИМЕР 3. Установка и стирание точек (Бегущий отрезок)
10 COLOR 1,15,8:SCREEN 2
20 FOR К=10 ТО 265
30 PSET (К,95),X:PRESET(К—10,95)
40 NEXT К:GOTO 20
Функция POINT (точка). Записывается функция POINT в виде POINT (X, Y).
Ее значением является код цвета соответствующего ей пикселя или — 1, когда координаты точки выходят за пределы экрана.
ПРИМЕР 4 = Случайное задание цвета
пикселей
Поиск среди них голубых пикселей
!0 COLOR 1,15,8:SCREEN 3
20 FOR K=1 TO 12
30 PSET (20XK,95),INT(RND(—TIME)X16)
40 NEXT K:P=1
50 FOR K=1 TO 12
60 IF POINT (20XK,95)=7 THEN P=2
70 NEXT К
80 FOR K=1 TO 500:NEXT К
90 SCREEN 0
100 ON P GOSUB 120,130
110 END:’подпрограммы
120 PRINT "голувых точек нет":RETURN
130 PRINT "голувые точки есть":RETURN
Круги. Эллипсы. Дуги
По команде CIRCLE, записываемой в виде
CIRCLE [@] [STEP] (X, Y), R, [С], [а], [р], [е] (1) вычерчиваются окружности (круги), эллипсы или их дуги и секторы. Смысл параметров в (1) следующий.
CIRCLE (круг, окружность)
(X, Y) или STEP (X, Y)
— служебное слово.
— параметры, определяющие абсолютные или относительные координаты центра окружности и новое место — положение курсора.
3. R
— арифметическое выражение. INT(R) задает радиус окружности.
4. сс, р
— арифметические выражения, фиксирующие углы в радианах, в пределах которых рисуется дуга окружности. По
5. с
умолчанию а = 0, Р = 2л (^ 6,28318) — арифметическое выражение, задающее
коэффициент сжатия окружности. Значение е должно лежать в пределах 1/260^е^260. При е<1 происходит сжатие вдоль оси Оу, а при е>1 — вдоль оси Ох. По умолчанию е=1
73
Как находятся координаты центра окружности? Если он определяется элементом (X, Y), то берутся целые части значений соответствующих выражений:
X0 = INT(X), Yo = INT(Y)
и по точке (х0, уо) отыскивается левый верхний угол (р, q) ее пикселя. Это и есть центр О окружности и новая позиция курсора после выполнения команды. Если центр О определяется элементом STEP (X, Y), то в нахождении (р, q) участвуют текущие координаты (а, Ь) курсора. А именно,
X0 = INT(X)+a, Y0 = INT(Y)+b
и далее все так же, как и в предыдущем случае.
Напомним, что для экрана 2 (х0, Уо) = (р, q).
Несмотря на необычное расположение осей координат, отсчет углов вполне традиционен. Он ведется от оси Ох против часовой стрелки. Поскольку углы измеряются в радианах, то в некоторых случаях для задания их значений удобно использовать стандартную функцию atn(x) (arctg(x)), для которой
atn (1) = л/4(45°)
ПРИМЕР 5. Смещенные фигуры
10 SCREEN 0:INPUT "вводите 1, 2 или 3 ";Х
20 COLOR 1,15,8:SCREEN 2
30 PSET (0,85)
40 FOR К=1 ТО 50
50 ON X GOSUB 80,90,100
60 NEXT К
70 GOTO 70: ’подпрограммы
80 CIRCLE STEP(5,0),50,4:RETURN
90 CIRCLE STEP(5,0),50,4,0,4KATN(1):RETURN
100 CIRCLE STEP(5,0),50,4,,,.5:RETURN
По данному фрагменту индицируются 50 одинаковых фигур со смещениями. Тип выводимой фигуры зависит от ответа пользователя на запрос с экрана дисплея. При х = 1, 2 и 3 получаем соответственно окружности, полуокружности и эллипсы. Проанализируйте команды CIRCLE в подпрограммах 80, 90 и 100, реализующие этот вывод.
ПРИМЕР 6. ’Ар-вуз’
10 COLOR 1,15,8:SCREEN 2
20 FOR К=1 TO 100
30 C=INT(RND(1));E=RND(1)
40 CIRCLE (128,95),80,C,,,F
50 NEXT К
60 GOTO 60
В этом примере вычерчивается ряд цветных эллипсов с совпадающей большей осью. На монохромном дисплее получается фигура, напоминающая арбуз.
Команду CIRCLE можно также использовать для вычерчивания секторов окружностей и эллипсов. Для этого необходимо задать отрицательные значения параметрам аир. При индикации соответствующей дуги будут взяты |сс| и |р|, но концы дуги соединятся отрезками с центром. Нуль для этого случая надо задавать малым отрицательным числом, например —0,001.
ПРИМЕР 7. Сектор окружности
10 COLOR 1,15,8:SCREEN 2
20 CIRCLE (100,95),60,С,—IE-03,-2XATN(1) 30 GOTO 30
Отрезки прямых. Прямоугольники
По команде LINE, записываемой в виде:
LINE [[@] [STEP] (Xi,Y,)] - [@] [STEP] (X2,Y2), [С],| [^ вычерчиваются отрезки прямых и прямоугольники с одновременной раскраской их в цвет. Смысл параметров здесь следующий.
LINE (линия) —служебное слово;
В—параметр, определяющий рисование прямоуголь
ника цветом С без закраски его внутренней части;
BF—параметр, определяющий рисование прямоуголь
ника с одновременной закраской его цветом С.
Элементы (хк, ук) или STEP (хк, ук) (к=1, 2) задают на экране две точки Mi и М2. Находятся Mi и М2 тем же способом, каким отыскивался центр О окружности в предыдущем пункте. Если первый из упомянутых элементов отсутствует, то в качестве Mi берется текущая позиция (а, Ь) графического курсора. Результирующей позицией курсора является точка М2.
На выполнение команды LINE существенное влияние оказывают параметры В и BF или их отсутствие. Рассмотрим три случая.
75
В и BF отсутствуют. Тогда на экране цветом С проводится линия, соединяющая точки Mi и М2.
Есть параметр В. Тогда цветом С со сторонами, параллельными осям координат, рисуется прямоугольник. Точки Mt и М2 оказываются его противоположными вершинами. Внутренняя часть прямоугольника не закрашивается.
Есть параметр BF. Тогда так же, как и в случае 2, рисуется прямоугольник, но внутренняя часть его закрашивается в цвет С.
ПРИМЕР 8. Возможные фигуры
10 COLOR 1,15,8:screen 2
20 ’отрезок
21 LINE (5, 5) — (25, 25)
30 ’прямоугольник
31 LINE -(70,60),,В
40 ’прямоугольник
41 LINE STEP(8,8)-STEP(130,70),,В
50 ’закрашенныйпрямоугольник
51 LINE STEP(10,10)-(90,80),,BF
60 GOTO 60
ПРИМЕР 9. Смещенные или вложенные
прямоугольники
10 SCREEN 0:INPUT"вводите 1 или 2 ";R
15 COLOR 1,15,12:SCREEN 2
20 FOR X=0 TO 15
25 A5=5XX:A6=A5+X:A7=A6+X:A8=A7+X
30 ON R GOSUB 45,60
35 NEXT:FOR S=1 TO 800:NEXT:GOTO 10
40 ’смещенные прямоугольники
45 LINE (40+A7,30+A5)—(130+A7,90+A5),15—X,BF 50 RETURN
55 ’вложенные прямоугольники
60 LINE (5+A8,10+A6)-(250-A8,185-A6),15-X,BF 65 RETURN
76
По данному фрагменту в зависимости от ответов пользователя на запрос с экрана дисплея индицируются 16 смещенных по отношению друг к другу или 16 вложенных разноцветных прямоугольников.
В следующем примере демонстрируется возможность использования в команде PSET и элементе STEP (X, Y) отрицательных значений.
ПРИМЕР 10. Отрицательные значения
10 COLOR 1,15,8:SCREEN 3:PSET(-4,160)
20 FOR X=0 TO 15
30 LINE STEP(8,-130)-STEP(8,130),X,BF
40 NEXT X
50 GOTO 50
ПРИМЕР 11. Звездное нево
10 COLOR 7,1,8:SCREEN 2
20 DEFFNS(Z)=INT(RND(1)XZ)
30 X=FNS(256)sY=FNS(192)
40 E=FNS(16):H=FNS(2)
50 LINE (X, Y)-STEP (H, H) , E, BF
60 FOR K=1 TO 40s NEXT KsGOTO 30
Закрашивание областей
Пусть G — некоторая, не обязательно односвязная область экрана и L — ее граница. Последняя может состоять из одной или нескольких замкнутых линий (см. рис. 12).
Для закрашивания области G используется команда PAINT (красить). Сразу же оговоримся, что для экрана 2 возможна раскраска G только под цвет границы L. Для экрана 3 это ограничение не действует. Внутренность G можно раскрасить любым цветом.
Записывается команда PAINT так:
PAINT [@] [STEP] (X, Y), [С], [С,](3)
Рис. 12
где: (X, Y) или STEP (X, Y) — элемент, определяющий координаты (р, q) пикселя внутри G (см., например, пункт 2.3); С — арифметическое выражение, задающее цвет закраски области G; С, — арифметическое выражение, задающее цвет границы L (для экрана 3!).
Опишем выполнение команды (3) отдельно для разных экранов.
SCREEN 2. Область G раскрашивается в цвет С, совпадающий с цветом границы L. По умолчанию С есть цвет изображения.
SCREEN 3. Область G раскрашивается в цвет С. По умолчанию С есть цвет изображения. Если раскраска G производится не под цвет L, то присутствие параметра Ci обязательно.
Подчеркнем, что во всех случаях точка (р, q) должна быть внутри G (не на границе !).
В примере 12 производится раскраска G под цвет, отличный от L. В примере 13 под цвет L раскрашиваются вложенные эллипсы.
ПРИМЕР 12. Раскраска многосвязной
Области
10 COLOR 1,15:SCREEN 3
20 LINE <30,30)-(225,162),,В:’прямоугольник
30 CIRCLE (80,95),30:’окружность
40 CIRCLE (175,95),30,,,,.5 :’эллипс
50 PAINT (125,95),7,1
60 GOTO 60
ПРИМЕР 13. Вложенные эллипсы
10 COLOR 1,15:SCREEN 2
20 FOR К=0 ТО 15
30 CIRCLE (128,95) , 127-8Ж, 15-К, ,, .7
40 PAINT (128,95),15-К
50 NEXT К
60 GOTO 60
Возникает вопрос: можно ли вообще раскрасить на экране 2 область G под цвет, отличный от контура? Для некоторых прямоугольников и других областей, границы которых состоят только из отрезков, параллельных осям координат, это сделать удается. Иллюстрацией тому является следующий фрагмент.
ПРИМЕР 14. Экзотическая раскраска 10 COLOR 1,15:SCREEN 2
20 LINE (79,79)-(120,120), ,B
30 LINE (80,80)—(119,119),7,В
50 PAINT (100,100),7
60 GOTO 60
Здесь команда 20 выводит прямоугольник Р, а команды 30 и 50 раскрашивают его в цвет 7. Наложения цветов не происходит из- за удачного расположения на экране вершин Р. Вообще, если Р определен точками (Хь Yi) и (Х2, Y2), где:
X,MOD 8 = 7 и X2MOD8 = 0
Y|MOD8 = 7Y2MOD 8=0,
то указанным приемом его всегда можно раскрасить в любой цвет без каких-либо искажений.
Язык GML
Для расширения возможностей, предоставляемых ранее разобранными средствами машинной графики, дополнительно разработан специальный макроязык GML (Graphics Macro Language), позволяющий в компактной форме кодировать любые фигуры и быстро выводить их на экран в требуемом масштабе и различных ориентациях. Каждая команда GML представляется одиночной ключевой буквой, за которой следует один или два числовых параметра. Последние, как правило, задаются целыми числами. В основном команды GML (см. табл. 12) предназначены для перемещения курсора из одних точек экрана в другие с одновременным вычерчиванием соединяющих их отрезков. Впрочем, они могут модифицироваться следующим образом.
Перед командой «движения» ставится параметр В. Тогда положение курсора изменяется, но линия не рисуется.
Перед командой «движения» ставится параметр N. Тогда курсор возвращается на место, которое он занимал до выполнения данной команды.
Там, где в команде GML в качестве параметров используются целые числа, можно указывать и числовые переменные у, в том числе и элементы массивов. Но у при этом следует записывать в форме = у;.
Примеры команд GML:
М 50, 60
ВМ 30, 40
NM 20, 10
R 10
С 7
M = X;, = Y;
U 20
С 15
С = АВ;
Е 30
S 8
U=A(3);
L 40
S 24
М+ =C;,-=D;
М —5, +15
А 2
H = Z;
Команда
Название и выполняемые действия
Перемещение курсора по направлению v. Здесь:
1. v — указатель одного из 8 возможных направлений (см. схему):
v£(R, Е, U, Н, L, G, D, F)
Углы между соседними направлениями равны 45°.
1
2 ... vn
HUE
G D F
8
2. n — целое число, задающее величину смещения курсора в точках экрана.
При выполнении команды курсор смещается от своего текущего положения на п единиц по направлению v
9 MX,Y
Перемещение курсора из текущего положения в точку с координатами (X, Y)
10 M + X. + Y
Смещение курсора по отношению к текущей позиции на ±Х единиц по абсциссе и ±Y единиц по ординате. На относительность смещения указывают знаки " + " или " —" у X, которые проставлять обязательно. Знак " + " у Y необязателен
11 Ср
Определение цвета вычерчиваемых фигур (р = 0,15 —код цвета). По умолчанию р есть цвет изображения. Действует Ср во всех командах DRAW до нового назначения
12 Sm
Задание масштабного множителя m (0^m^255). При выполнении Sm все числовые параметры всех команд движения, записанных без префикса В, получают масштабный множитель т/4. Действует Sm во всех командах DRAW до нового назначения. Заметим, что S0 = S4
13 At
Поворот изображения вокруг точки, с которой начиналось рисование, на 90° X / (/Е(0, 1,2, 3)) против часовой стрелки. Действует At во всех командах DRAW до нового назначения.
14 Ха;
Интерпретация значения строковой переменной а как последовательности команд GML. Знак ";" обязателен.
Таблица 12
Команды языка GMLКоманды языка GMLДля приведения в действие последовательности команд GML необходимо сделать ее значением некоторого строкового выражения р и затем воспользоваться командой DRAW (чертить, рисовать) :
Команды языка GML
Команды языка GML
DRAW р
Как правило, Р является константой. Выполнение этой команды состоит в последовательном выделении из значения р команд GML и реализации предписываемых ими операций. Длина р не должна превосходить 255 байтов. Однако имеется довольно простой механизм «вложения» одних значений в другие. Фактически в р можно вставлять команду обращения к другой серии команд GML. Записывается она так: Ха;. Знак ; обязателен. Выполнение этой команды активизирует подпрограмму на GML, являющуюся значением строкового выражения а. Возврат в р осуществляется к команде, следующей за Ха;. Допускаются многоуровневые обращения типа Ха;, т. е. из а можно обратиться к некоторой третьей подпрограмме и т. д.
Заметим, что если не предполагается масштабировать выводимую фигуру или поворачивать ее вокруг начальной точки, то все равно есть смысл указать в DRAW команды S4A0. Это позволит отменить возможные предыдущие назначения Sm и At, могущие исказить ваше изображение. Далее, чтобы текст на GML легко читался и корректировался, рекомендуется отделять его команды в р пробелами. На выполнении команды DRAW это никак не отразится.
ПРИМЕР 15. Правильный шестиугольник
10 COLOR 15,1,8:SCREEN 2
20 DRAW "ВМ70,15 S4 A0"
30 FOR K=1 TO 6:READ X,Y
40 DRAW ”M+=X;,=Y;"
50 NEXT К
60 GOTO 60
70 DATA 45,0,25,40,-25,40
80 DATA -45,0,-25,-40,25,-40
Здесь присутствуют следующие команды GML:
вм 70,15
— перемещение курсора в точку (70,15) без
S4
АО
=Х;,=
рисования;
— задание единичного масштаба;
— задание угла поворота в 0°;
= Y; —рисование сторон шестиугольника. X и Y в М — числовые переменные.
ПРИМЕР 16. Правильные шестиугольники. Масштабирование
10 COLOR 15,1,8:SCREEN 2
20 FOR Z=1 TO 9 50 DRAW "BM70,10 S=Z; A0" 40DRAW"M+45,0M+25,40M-25,40"
50DRAW"M-45,0M-25,-40M+25,-40"
60NEXTZ
70GOTO70
В этом примере демонстрируется другой способ рисования правильного шестиугольника. Команда S = Z; определяет масштаб, равный значению Z.
ПРИМЕР 17. Правильные шестиугольники. Повороты
10 COLOR 15,1,8:SCREEN 2 15 FOR U=0 TO 3
20 FOR Z=1 TO 5 30 DRAW "BM128,95 S=Z; A=U;" 40DRAW"M+45,0M+25,40M-25,40"
50DRAW"M-45,0M-25,-40M+25,-40"
60NEXTZ,U
70GOTO70
ПРИМЕР 18. Орнамент. Перемещение no направлениям
10 COLOR 1,15,8:SCREEN 2 20 FOR J=20 TO 160 STEP 20 30 FOR 1=20 TO 200 STEP 20 40 DRAW"S4 A0 BM=I;,=J;” 50 DRAW"E10 R10 F10 D10 G10 L10 H10 U10" 60 NEXT I,J 70 GOTO 70 82
2Л. Программа «Базовые структуры»
В качестве примера применения команд GML приведем программу «Базовые структуры», по которой организуется рисование основных структур действий, используемых при описании алгоритмов (см. рис. 13—15). Вывод конкретной схемы алгоритма организуется нажатием на клавиши F1 — F5. Завершается работа с программой при нажатии на клавишу F6.
10 ’ БАЗОВЫЕ СТРУКТУРЫ
20 ’
30 COLOR 1,15,12:SCREEN 2
40 ’Т1$ - ТЗ* - стрелки
50 ’Т4$— прямоугольник, Т5$— роме
60 T1*="NH3 NG3":T2»="NG3 NF3":T3$="NH3 NE3”
70 Т4*="М+0,14 М+56,0 М+0,-28 М-56,0 "
80 Т4$=Т4$+"М+0,28 ВМ+56,-14"
90 Т5*="Е14 F14 G14 Н14 E14":DRAW "А0 S4"
100 OPEN “GRP:"FOROUTPUT AS#1
110 FOR K=1 TO 6:KEYCK) ON:NEXT
120 ON KEY GOSUB 140,230,280,500,630,750
130 GOTO 120
140 *
150 CLS
160 DRAW "BM10,75M+42,0XT1$;XT4*;M+42,0XT1$;"
170 DRAW “XT4$5M+42,0 XT1$;BM-170,-3"
180 PRINT #1,"A";
190 DRAW "BM+90,0";PRINT#1, "B":DRAW”BM10, 140“
200 PRINT #1,"структура ’ПОСЛЕДОВАТЕЛЬНОСТЬ’"
210 DRAW "BM100,160":PRINT#1,"A :B”:RETURN
220 ’
230 GOSUB 350:DRAW "M+56,0 BM5,140"
240 PRINT#1,"структура ’ВЕТВЛЕНИЕ’(неполное)"
250 DRAW "BM70,160":PRINT #l,”if P then A"
260 RETURN
270 ’
280 GOSUB 350:DRAW "XT1$; XT4$; BM-31,-3"
290 PRINT #1,"B";:DRAW "BM15,140"
300 PRINT #1,"структура ’ВЕТВЛЕНИЕ’ (полное)"
310 DRAW "ВМЗЗ,160"
320 PRINT #l,"if P then A else B"
330 RETURN
340 ’
350 GOSUB 460
360 DRAW "XT5*; M+0,-14 14+28,0 XT1$; XT4$; "
370 DRAW "M+28,0 M+0,22 XT3$;"
380 CIRCLE STEP(0,6),5
390 DRAW "BM+6,0 M+28,0 XT1$; BM-34,6"
400 DRAW "ХТ2»; M+0,22 M-28,0 BM-58,0"
410 DRAW "M-26,0 M+0,-14 BM-2,-17"
420 PRINT#1,"P";:DRAW "BM-2,-16":PRINT#1,"+";
430 DRAW "BM-8,32":PRINT #1,"-";
440 DRAW "BM+41,-45“:PRINT #1,"A";
450 DRAW "BM-34,60":RETURN
460 CLS:DRAW "BM20,75 M+28,0 XT1$;":RETURN
470 GOSUB 460:CIRCLE STEP(6,0),5
480 DRAW "BM+5,0 M+28,0 XT1$?":RETURN
490 ’
500 GOSUB 470:DRAW "XT5$; F14 M+28,0 XT1$;"
510 DRAW "XT4$; M+14,0 M+0,-42 M-159,0"
520 DRAW "M+0,36 XT3$; BM+47,21 M+0,28"
530 DRAW "M+130,0 XT1$; BM-132,-46"
540 PRINT #1,"P”;:DRAW "BM+9,-5":PRINT #1,"+"
550 DRAW "BN-20,22":PRINT #1,"-";
84
560 DRAW "ВМ+57,-17":PRINT #1,"А";
570 DRAW "ВМ30,140"
580 PRINT #1 у"структура ’ЦИКЛ’ (пока)"
590 DRAW "ВМ20,160"
600 PRINT #1,"р if Р then А : GOTO р"
610 RETURN
Ь30 GOSUB 470
640 DRAW "ХТ4*;М+28,0 ХТ1$; ХТ5»; F14 М+28,0'
650 DRAW "ХТ1$; ВМ-42,-14 М+0,-28 М-131,0"
660 DRAW "М+0,36 ХТЗ$; ВМ+59,3":PRINT #1,"А";
670 DRAW "ВМ+62,0"sPRINT #1, "Р";
680 DRAW "ВМ-2,-15"SPRINT #1,"-";
690 DRAW "ВМ+4,20"SPRINT #1,"+";
700 DRAW "ВМ40,140"
710 PRINT #1,"структура ’ЦИКЛ’ (до)"
720 DRAW "ВМ36,160"
730 PRINT #1,"р A s if пР then р"
740 RETURN
750 END:’—имя программы на диске "СТРУКТУРЫ1
На рисунке 13 изображена базовая структура ПОСЛЕДОВАТЕЛЬНОСТЬ.
На рисунке 14 изображена неполная базовая структура ВЕТВЛЕНИЕ, а на рисунке 15 — полная.
Рис. 13
*■ А
Рис. 16Рис. 16Рис 17Рис 17
Рис. 16
Рис. 16
Рис 17
Рис 17
На рисунке 16 изображена базовая структура ЦИКЛ-ПОКА, на рисунке 17 ЦИКЛ-ДО.
Схемы, графики, рисунки или отдельные их фрагменты, выводимые на графические экраны, обычно нуждаются в обозначениях и поясняющих сообщениях. Сформировать их обычным оператором PRINT невозможно. На экранах 2 и 3 последний не действует. Можно было бы буквы рисовать командой DRAW, но это весьма трудоемко. Надписи в программе «базовые структуры» формировались так, как это демонстрирует следующий фрагмент.
ПРИМЕР 20. Символы на графическом экране (1)
COLOR 1,15,8:SCREEN 2
20 OPEN "GRP:"AS #140 PRINT #1,"пример"
30 PSET (100, 100), 1550 GOTO 50
Этот способ позволяет выводить символы фиксированного формата в блоках 8X8 точек. Другой прием вывода символов алфавита на графический экран, позволяющий регулировать как размер букв, так и расстояние между ними, приводится в следующем пункте.
Разработка программы «Базовые структуры» является простейшим педагогическим программным средством, которое с успехом может быть использовано преподавателем при объяснении соответствующей темы по информатике. Программная реализация подобных разработок несложна, но требует значительных временных затрат. Связано это с недостаточностью инструментальных средств Бейсика для эффективного проектирования изображения непосредственно на экране дисплея. Стоит заметить, что многие школьники и студенты в качестве первой попытки создать «большую» и интересную программу с удовольствием и небезуспешно берутся за разработку и реализацию той или иной версии «Графического редактора», позволяющего облегчить проектирование информационных кадров для обучающих систем.
8. Алфавит на графическом экране
Пусть а — стандартный алфавит Бейсика. Один из способов оформления графиков и чертежей надписями из символов сс демонстрировался в предыдущем пункте. При необходимости работать с символами различных форматов или с наборами знаков, 86
нс совпадающих с подмножествами а, используется другой прием. Суть его состоит в том, что заранее заготавливаются строковые константы. Их значениями являются тексты на GML «новых» знаков, которые могут быть любыми фрагментами произвольных изображений. Далее, каким-либо способом «новые» знаки кодируются элементами а и выводятся на экран заданием соответствующего кода. Описанный прием реализуется в примере 21.
ПРИМЕР 21. Символы на графическом
экране (2)
10 ’СИМВОЛЫ НА ГРАФИЧЕСКОМ ЭКРАНЕ
20 ^
30 ’ (X,Y) - начальная позиция
40 ’ В- размер символов
50 ’ L- расстояние между символами
60 COLOR 1,15,12s SCREEN 2:CLEAR 1000
70 ’символы
80 DIM АФ(255):АФ(235)="D6U3R1E3G3F3 ВМ+0,-6"
90 АФ(236)="BM+0,6 El U4 El R2 D6 ВМ+0,-6''
100 АФ(225)="BM+0,6U4E2F2D2 L4 R4 D2 ВМ+0,-6"
210 АФ(243)="ВМ+4,1H1L2G1D4 Fl R2 Е1 ВМ+0,-5"
120 АФ(53)="ВМ+20,4 NU20 NE20 NR20 NF20 XR*;"
230 РФ="МП20 N620 NL20 NH20"
2 -^ 0 ' ————————————————————————————————————————
150 ТЕФ="КЛАСС5": Х=30:Y=80:B=8s L=7
160 DRAW "BM=X;,=Y; A0 S=B; "
170 FOR К=1 TO ЕЕМ(ТЕФ)
180 2Ф=М1ОФ(5ТРФ(ASC(MID®(ТЕФ,К,1))),2)
190 РФ=РФ+"ХА$("+Z®+") ; "+"BR=L; "
200 NEXT:DRAW "ХРФ;"
210 GOTO 210:’
Пример носит чисто иллюстративный характер. Здесь в строках 30—130 заготовлено всего 5 «новых» символов (см. табл. 13 и рис. 18).
Рис. 18
Таблица 13
«Новые» символы и их коды для примера 21
Коды
А
К
Л
с
5
«Новые» символы
А
К
Л
с
Изображение, представленное на рисунке 18, получается при последовательной дешифровке значения строковой переменной ТЕ$. Реализуется это действие строками 170—200. Одновременно формируется подпрограмма вывода Р$. Если бы мы взглянули на значение Р$ перед выполнением DRAW, то увидели бы следующую последовательность команд GML:
ХА*(235);BR=L;ХА*(236);BR=L;ХА*(225);BR=L;
ХА*(243);BR=L;ХА*(243);BR=L;ХА*(53);BR=L;
предписывающих выполнить такие действия.
ХА$ (t); (te{235, 236, 225, 243, 53}) — вывести «новый» символ, код ASCII которого равен t;
BR = L; — перевести курсор без рисования на L единиц вправо (организация пробелов между символами).
Несколько слов о том, как получено (4). В разъяснении, по-види- мому, нуждается лишь 180-я программная строка. Ес выполнение можно представить в 4 этапа:
a=MID$(TE$, k, 1) —получение к-го символа ТЕ$(код одного из «новых» знаков);
p = ASC (a) —нахождение числового значения кода ASCII для а;
у = STR$ (Р) — представление кода ASCII для а в символьном виде;
Z$ = MID$(y, 2) —удаление 1-й знаковой позиции у у.
9. Распечатка экранного кадра
В реальных ситуациях довольно часто возникает необходимость в получении твердой копии изображения, находящегося в данный момент на экране. Для организации непосредственной распечатки" 88
экранного кадра через принтер на лист бумаги средств Бейсика недостаточно. Однако нетрудно написать компактную программу на ассемблере Z-80, которая будет выполнять эту процедуру. Поскольку обучение ассемблеру не является целью данного пособия, мы ограничимся тем, что приведем программу на Бейсике, которая содержит в командах DATA соответствующие машинные коды для распечатки кадров и при запуске загружает эти коды в определенный участок памяти.
ПРИМЕР 22. Распечатка экранного кадра 56000 ’РАСПЕЧАТКА ЭКРАННОГО КАДРА (экран 2)
56001 ’ 56002 DEFUSR=&HEF00: RESTORE 56007
56003 FOR R=0 TO 171: READ R»
56004 POKE &HEF00+R,VAL("&H"+R$) 56005 NEXT R:R=USR(0):RETURN
56006 ’подпрограмма в машинных кодах
56007 DATA 21,00,20,22, AC, EF, 21,91, EF, CD, 87
56008 DATA EF, 21,9B, EF, CD, 87, EF, 0E, 08, 2A, AC
56009 DATA EF, CD, 4A, 00, 57, E6,0F, 5F, CB, ЗА, CB
56010 DATA 3A,CB,3A,CB,3A,00,3E,0F,BA,20,0D
56011 DATA BB,20,03,AF,18,11,CD,7F,EF,EE,FF
56012 DATA 18, 0A, BB, 28, 04,3E, FF,18,03,CD,7F
56013 DATA EF, 23,22, AC, EF, 06, 08, 21, AE, EF, CB
56014 DATA 27, CB, IE, 23, 10, F9,0D, 20, BE, 06, 08
56015 DATA 21, AE, EF,7E,CD,A5,00,23,10,F9,2A
56016 DATA AC,EF,AF,BD,20,A9,3E,0D,CD,A5,00
56017 DATA ЗЕ,0A,CD,A5,00,3E,38,BC,20,94,21
56018 DATA A2, EF, CD, 87, EF, C9, CB, AC, CD, 4A, 00
56019 DATA CB,EC,C9,7E,FE,FF,C8,CD,A5,00,23
56020 DATA 18,F6,IB,54,31,36,IB,45,IB,ЗЕ,0E
5o021 DATA FF,IB,53,30,32,35,36,FF,1B,4E,0F
56022 DATA IB,41,IB,3C,0D,0A,FF
66?.'23 ’имя программы на диске "КАДР"
Пусть программа примера 22 зафиксирована на диске в кодах ASCII под именем КАДР. Делается это командой SAVE "КАДР", А, где последняя буква А — латинская. Как воспользоваться программой КАДР? Если в основной программе а нет строк с номерами, большими 55999, и требуется распечатывать кадры, то осуществить это можно так.
Загружаем а в оперативную память, вставляем в требуемые точки обращение к подпрограмме КАДР: GOSUB 56000
Производим слияние программ а и КАДР
MERGE "КАДР"
Запускаем модифицированную программу а на счет и получаем требуемые распечатки.
Заметим, что спрайты (см. раздел 5) указанным способом с экрана на распечатку нс копируются.
Рассмотрим пример. Пусть требуется вывести на экран 2 рисунок по фрагменту программы а примера 18 и получить его распечатку. Для этого осуществим такие действия. Загрузим а в память, добавим к ней строку обращения 55 (55 GOSUB 56000) и подпрограмму КАДР (MERGE "КАДР".). После запуска программы на счет получим распечатку орнамента, представленного на рисунке 19.
УПРАВЛЕНИЕ ВЫВОДОМ НА ПРИНТЕР
Изложение ориентировано на принтер GEMINI-10XR, относящийся к ударным точечно-матричным устройствам, широко применяемым в составе мини- и микроЭВМ. Нужное очертание символа воспроизводится ударами штырьков печатающей головки через красящую ленту по бумаге. Скорость печати—до 120 символов в секунду.
Принтер предназначен для вывода текстовой и графической информации. Предоставляемый им набор услуг весьма обширен. Возможна печать текста с изменением шага и наклона символов, выделением фрагментов полужирным шрифтом, расширением символов. Допускаются подчеркивания в тексте, а также использование верх- 90
них и нижних индексов. Организовано управление высотой строки и форматом выводимого текста. Разрешается конструирование собственных знаков. Имеются средства для вывода графической информации. Думается, что в ближайшем будущем такой набор услуг станет минимально возможным для любого принтера.
СНИ$-коды
В дальнейшем мы часто будем встречаться с функцией
CHR$ (п) (п£{0,1 255})
Значением CHR$ (п) является или некоторый управляющий сигнал, или символ, десятичный код ASCII которого равен п. Наиболее '•потребительный код CHR$ (27) называют кодом перехода. Введем лля него и специальное обозначение Ф:
Ф = CHR$ (27)
Во многих случаях управление выводом реализуется последовательностью нескольких CHRS-кодов или CHRS-кодов и букв. Активизация управляющих сигналов организуется программно. Для этого их CHRS-коды делают операндами в команде LPRINT. Приведем некоторые примеры.
ПРИМЕР 1. СНР$-КОДЫ В КОМАНДЕ LPRINT
10 LPRINT CHRt(27);"Б"
20 LPRINT CHR$(7)
30 LPRINT CHR$(27);"R043";"X"
40 Z$=CHR$(27)
50 LPRINT Z$;"+";Z$$"P";CHR$(14);CHR$(0)
Отметим следующие 3 обстоятельства.
He любые группы комбинаций CHRS-кодов допустимы.
Большинство CHRS-назначений, организованные командами LPRINT, справедливы и при выполнении команды LLIST.
CHRS-коды действуют именно так, как они описаны ниже, лишь при стандартном положении всех 12 двухпозиционных переключателей принтера.
Изменение шага печати
Шагом печати называют ширину прямоугольника, отводимого для вывода одиночного символа.
Допускается 6 различных шагов печати: 3 основных и 3 их расширения в два раза. Основные шаги имеют такие названия: «Цицеро», «Элите» и «Уплотненный». При включении принтер автоматически настраивается на печать «Цицеро» по 10 символов на дюйм, что позволяет на странице стандартных размеров (210 мм в ширину) размещать в строке до 80 знаков. При печати «Элите» на дюйм приходится 12 знаков и в строке размещается до 96 символов. При «уплотненной» печати на дюйм приходится 17 знаков и в строке размещается до 136 символов. Любой из трех основных шагов при необходимости можно удваивать. Получается так называемая расширенная печать, при которой выводимые символы в два раза шире обычных.
Задание печати с требуемым основным шагом, его расширение в два раза или отмена этого расширения производятся управляющими кодами, указанными в таблице 14.
Таблица 14
Управляющий код
Название шага и (или) выполняемые действия
Ф; "Р" или Ф; "N"
ф; //Е//
з Ф; "Q"
CHR $ (14)
CHR $ (15)
«Цицеро». 10 знаков на дюйм. Шаг задан по умолчанию
«Элите». 12 знаков на дюйм
«Уплотненный» шаг. 17 знаков на дюйм
Удвоение действующего основного шага печати
Отмена удвоенного шага печати
ПРИМЕР 2. ВЫБОР ШАГА ПЕЧАТИ
10
LPRINT CHR* С27)$"Р";"СТУДЕНТ" run
20
LPRINT CHR*(27);"Е";"СТУДЕНТ" СТУДЕНТ
30
LPRINT CHR*(27)$"Q“;"СТУДЕНТ" СТУДЕНТ
40
LPR I NT CHR* (14)$СТУДЕНТ
50
LPR I NT CHR* (27)$"P"; "СТУДЕНТ" О Г У /Д Е И' 1Г
60
LPRINT CHR*(27)$"Е";"СТУДЕНТ" СТУДЕНТ
70
LPRINT CHR*(27);"Q";"СТУДЕНТ" СТУДЕНТ
80
92
LPRINT CHR*(27);"Р";CHR*(15)
Рядом приведена полученная по программе распечатка. Обратите внимание на 80-ю программную строку. По ней восстанавливается основной тип печати «Цицеро» и отменяется расширение. Можно было бы и по-иному «сбросить» все предыдущие CHR$- пазначения, применив код
Ф; "cl" (с — малое, латинское).
При этом принтер переведется в такое же состояние, которое он получает при включении питания. Более подробно об этом см. в пункте 3.8.
Выделение фрагментов
Для того чтобы выделить в текстах отдельные слова или фрагменты, применяются различные приемы. Основные из них такие: использование наклонного, полужирного или жирного шрифтов и подчеркивания. Наклонная печать называется «Италик». При ней символы распечатываются в слегка наклоненном вправо состоянии. Полужирная печать получается при двойном выводе каждого символа с небольшим смещением от исходного положения или вниз, или вправо. Жирная печать организуется при выводе каждого символа со смещением от исходного положения и вниз, и вправо. Подчеркивания проводятся снизу текста. Управляющие коды для выделения фрагментов при печати приведены в таблице 15.
Таблица 15
Управляющий код
Название и (или) выполняемые действия
1 Ф, "4"
2 Ф, "5"
Ф; "G"
ф. 7/Н„
Ф; п\и
G Ф, CHR $ (34)
Ф, "Х”
ф "у"
Шрифт «Италик». Включение режима наклонной печати
Отмена режима наклонной печати
Полужирный шрифт. Включение режима печати двойным ударом со смещением изображения вниз
Отмена режима Ф, "G"
Полужирный шрифт. Включение режима печати двойным ударом со смещением изображения вправо
Отмена режима Ф; "!"
Включение режима печати с подчеркиванием
Отмена режима Ф; "X"
Двойной управляющий код
О;"!' ;Ф;"О"
определяет режим жирного шрифта. Его отмена реализуется комбинацией кодов
Ф; CHR$ (34) ^/ЧЕ7
Заметим, что режимы выделения можно использовать при любом шаге печати и комбинировать их с другими средствами вывода текстов.
ПРИМЕР 3. ВЫДЕЛЕНИЕ ФРАГМЕНТОВ
ПРИ ПЕЧАТИ
10 LPRINT CHR*(27)$"4";"ДИСПЛЕЙ" ЙИСППЕЙ
20 LPRINT CHR»(27) ;"5";6^™??
ДИСПЛЕИ
30 LPRINT CHR$(27);“!";“ДИСПЛЕЙ" ДИСПЛЕЙ, 40 LPRINT CHR$(27);CHR$(34) ;
50 LPRINT CHR*(27);”X“;“ДИСПЛЕЙ"
60 LPRINT CHR$(14);
70 LPRINT CHRS(27);“P“;“ДИСПЛЕЙ"
80 LPRINT CHR*(27);“c1“ run
В распечатке имеем 4 строки. Из текста программы и таблиц 14 и 15 нетрудно увидеть, при каком типе выделения и каком шаге они получены.
Индексирование
Символы, располагаемые в верхней или нижней части строки в половину своего размера по высоте, называются соответственно верхними и нижними индексами. Печать индексов, или, по-другому, индексирование, организуется специальными управляющими кодами (см. таблицу 16). Наличие кода, позволяющего возвращать печатающую головку на 1 позицию назад, обеспечивает возможность вывода на одно знакоместо сразу и верхнего, и нижнего индексов. Установленный тип индексирования действует до нового назначения или полной отмены.
Таблица 16
Управляющий код
Выполняемые действия
1 Ф, "s\"
2 Ф, "зЗ"
3 Ф, "sQ"
4 CHR $ (8)
Включение режима верхнего индексирования Включение режима нижнего индексирования Отмена режимов индексирования
Возврат головки принтера на 1 позицию назад
ПРИМЕР 4. ИНДЕКСИРОВАНИЕ 10 U$=CHR*(27):Т$="ТЕКСТ" 20 Н*="ВЕРХНИй ИНДЕКС"sN*="НИЖНИЙ ИНДЕКС" 30 LPRINT U$;"P";T«jU*j"sl";W$ 40 LPRINT U*;”s0";T*;U*;"s2";N* 50 LPRINT U«j"s0";"S =";:A=7 60 FOR K=1 TO A .
70 LPRINT U»;"s0";" X";U$;"s2"$CHRS(8);K; 80 IF KOA THEN LPRINT U»$ "s0" $ "+" ;
90 NEXT К:LPRINT ""
100 LPRINT U$5"s0";"T ="; 110 FOR K=1 TO A
120 LPRINT U$;"s0";" Y";U$;"si";CHR$(8);K; 130 IF KOA THEN LPRINT U$; "s0" j " + ";
140 NEXT К
150 LPRINT U$;"cl" run -p^l^QJBEI^XHHoi ИНДЕКС ТЕКСТнижний индекс 5 = Xi + X= + Хз + X4 + X= + Хб + X7 T = Y* + Ya + Y3 + YA + Y® + YA + Yy
Распечатка для примера 4 приведена за текстом программы.
3.5. Изменение высоты строк
При включении принтера высота строки автоматически устанавливается из расчета 6 строк на дюйм. Изменяется она в любой момент времени с помощью кодов, приведенных в таблице 17.
Таблица 17
Управляющие коды
Выполняемые действия
1 Ф; "к"
2 Ф; "В"
3 Ф;//п//
Установка высоты строки в 1/6 дюйма
Установка высоты строки в 1/9 дюйма
Установка высоты строки в п/144 дюйма. Здесь п — целое число, которое необходимо задавать двумя цифрами: 01, 02, ..., 99.
Варьируя параметр п, можно подобрать требуемую высоту строки. В следующем примере при основном шаге «Цицеро» распечатка получена при высотах 1/6, 1/4 и 1/3 дюйма.
ПРИМЕР 5. ИЗМЕНЕНИЕ ВЫСОТЫ СТРОКИ
10 LPRINT CHR$(27);"А”;:BOSUB 60
20 LPRINT CHR$(27);"Т";"36";:BOSUB 60
30 LPRINT CHR$(27);"T";"48";:БОЗОВ 60
40 LPRINT CHR$(27);"cl":END
60 LPRINT "ПРИ ВЫБОРЕ ВЫСОТЫ СТРОКИ"
70 LPRINT "ПАРАМЕТР п ЗАДАВАЙТЕ"
80 LPRINT "В ВИДЕ: 01, 02 99!"
85 LPRINT "г••
90 RETORN
ПРИ ВЫБОРЕ ВЫСОТЫ СТРОКИ ПАРАМЕТР п ЗАДАВАЙТЕ В ВИДЕ: 01, 02, ..., 99!
ПРИ ВЫБОРЕ ВЫСОТЫ СТРОКИ
ПАРАМЕТР п ЗАДАВАЙТЕ
В ВИДЕ: 01, 02, ..., 99!
Установка полей на странице
Как и в любой пишущей машинке, в принтере можно регулировать ширину текста и его расположение на странице. По управляющим кодам (см. табл. 18) независимо друг от друга устанавливается ширина левого и правого полей. В дальнейшем вывод будет осу-
Таблица 18
Управляющие коды
Выполняемые действия
1 Ф; "V, "п"
Установка левого поля с позиции и
(п € (ООО, 001, ... ))
2 Ф; "Г\ "п"
Установка правого поля с позиции п
(п е (ооо, соц ... о
шествляться между этими полями. Отмена зафиксированной разметки листа производится или новым ее назначением, или общей инициализацией принтера кодом Ф;"с1".
В распечатке приведенного ниже примера один и тот же текст выведен двумя различными способами.
ПРИМЕР 6. УСТАНОВКА ПОЛЕЙ !0 Т*="ЗАДАВАЙТЕ п В ВИДЕ:”
20 К*=”000, 001, 002, ...!":БОЗОВ 70
30 LPRINT CHR$(27);"L";"010”;:6030В 70
40 LPRINT CHR*(27);"L”;"020”;
50 LPRINT CHR$(27);"/”;"030”;:60SUB 70
60 LPRINT CHR$(27);"cl”:END
70 LPRINT T*:LPRINT К»;CHR$(10):RETURN run ЗАДАВАЙТЕ n В ВИДЕ: 000, 001, 002, ...!
ЗАДАВАЙТЕ n В ВИДЕ: 000, 001, 002, ...!
Горизонтальная табуляция
На пишущих машинках для расположения данных при печати с конкретных позиций предусмотрен механизм табуляции. Аналогичные средства имеются и для принтера. Для установки горизонтальных меток табуляции используется код
Ф; "("; "пь п2, ...пк."(1) еде ns(s=l,k) —номера позиций в строке (см. табл. 19). Величины ns называются метками табуляции. Задаваться они должны целыми трехзначными числами с обязательным указанием количества сотен, десятков и единиц и располагаться в коде (1) в порядке возрастания. Обратите внимание на разделители в коде (1). Между элементами ns ставятся запятые, а после пк обязательно фиксируется точка. Например, Ф; "^'\ "005, 020, 050, 070."
Если метки не устанавливались или стерты, то по умолчанию П|=0, п2= 10, п3 = 20, ...
Назначение горизонтальной табуляции само по себе ни к каким Действиям не приводит. Для использования меток ns требуется задать код
CHR$ (9)(2)
осуществляющим разовое перемещение печатающей головки принтера на следующую метку. Специфика рассматриваемого принтера требует предварить использование кодов (2) выполнением команды
POKE&HF418.1
Таблица 19
Горизонтальные метки табуляции
Управляющие коды
Выполняемые действия
1 Ф; "Г; "m, n2, ... nk."
2 ф;")";''т|,П12, ... mp."
Ф; "T
CHR $ (9)
Ф; "b";
CHR $ (n)
Установка меток табуляции ni, п2, .., nk
Выборочное стирание меток табуляции из позиций: mi, ш2, .... тр
Стирание всех меток табуляции, установленных пользователем Перемещение головки принтера на следующую правую метку Перемещение головки принтера на п позиций по строке вправо
ПРИМЕР 7. УСТАНОВКА ГОРИЗОНТАЛЬНЫХ
МЕТОК
10 LPRINT CHR$(27)j"("J"005,013,025."
15 Т=3:’ Т — количество меток
20 POKE &HF418,1
30 FOR К=1 ТО 30:READ X
40 LPRINT CHR*(9);X;
50 IF KMODT=0 THEN LPRINT
60 NEXT К
70 LPRINT CHR*(27);"cl"
80 DATA 345,12,2454,34,4,5,689,7,8,987
90 DATA -250,-1457,2,3,4,5699,6,7,8,9
100 DATA 0,13,247,3215,4,5,6,734,86,95 run
345
12
2454
34
4
g
689
7
8
98
987
-250
-1457
2
3
4
5699
6
7
8
9
0
13
247
3215
4
5
6
734
86
95
Вслед за программой приведена полученная по ней распечатка. Данные из блока, сформированного командами 80—100, выведены в 3 колонки в соответствии с метками табуляции: 005, 013 и 025. В чем смысл команды 50? Дело в том, что когда головка принтера попадает за последнюю метку табуляции nk, то CHR$ (9) перестает действовать. Поэтому после вывода очередных 3 чисел необходимо искусственно возвратить головку в начало следующей строки. Это и делает команда 50.
Из таблицы 19 мы видим, что имеются коды для выборочного или полного удаления горизонтальных меток табуляции, установленных пользователем. Их синтаксис и выполняемое действие после детального обсуждения кода (1), по-видимому, ясны. Отметим лишь, что параметры ms’(s = l,p) должны задаваться целыми трехзначными числами так же, как и ns в коде (1).
Далее, код, определяющий перемещение головки принтера на п позиций по строке, равнозначен функции SPACE$ (п), формирующей п пробелов.
Дополнительные управляющие коды
Кроме ранее рассмотренных, имеется еще целый ряд дополнительных кодов, облегчающих работу с принтером. В приложении (см. табл. 1) они указаны под номерами 28—51. Некоторые из них использованы в примере 8.
ПРИМЕР 8. НЕКОТОРЫЕ ДОПОЛНИТЕЛЬНЫЕ КОДЫ
10 ’звонок
20 Z$=CHR$(27):LPRINTCHRSC7);
30 ’повтор символа 30раз
40 LPRINTCHR$(27);"R030";"Н";
50 'протяжка на 2 строки
60 LPRINT CHR»(27>;"a";CHR*(2>;
70 ’повтор символа 20 раз
80 LPRINT CHR$(27);“R020";"Z
90 ’пропуск точечных позиций
100 GOSUB 160:LPRINT Z$;"F";"0001";:60SUB 160
110 LPRINT Z»;"F";”0002";:GOSUB 160
120 LPRINT Z*;"F";"0003";:GOSUB 160
130 LPRINT Z*;"F";"0050";:GOSUB 160
140 GOSUB 160:LPRINT Z$;"F";"0100";sGOSUB 160
150 END
160 LPRINT "ПРОПУСК ТОЧЕЧНЫХ ПОЗИЦИЙ": RETURN
Макрокоды
Для того чтобы программы управления печатью были более компактными и наглядными, можно использовать при их оформлении специальный механизм макроопределений. О нем и пойдет речь ниже.
Последовательную группу управляющих кодов, записанную в виде:
Ф; "+"; коды; CHR$ (0)
называют макроопределением (макрокодом или просто МАКРО).
Одно макроопределение может содержать до 16 кодов. Оно не воздействует на печать в процессе выполнения программы, пока не будет активизировано макрокомандой Ф; "%" (см. табл. 20).
Таблица 20
Управляющие коды
Название и выполняемые действия
1 Ф; "-Ь"; коды;
Макроопределение, представляющее собой совокупность управ
CHR $ (0)
ляющих кодов
2 ф;
Макрокоманда, активизирующая последнее из выполненных макроопределений
В программе могут встретиться несколько макроопределений. Действует всегда последнее выполненное МАКРО.
Для уяснения принципа действия МАКРО предлагается проанализировать следующий пример, где распечатка приводится сразу вслед за программой.
ПРИМЕР 9. МАКРООПРЕДЕЛЕНИЕ
5'МАКРООПРЕДЕЛЕНИЕ
10 LPRINT CHR* <27); •'+•';
20 LPRINT CHR$(27);“Р";CHR$(14) ;
30 LPRINT CHR$(27);"(";"003,012,020.“
40 LPRINT CHR»(0)
50
60 LPRI NT CHR$ (27) $ " 7. " : GOtiUB 110
70 LPRINT CHR$(15);CHRt(27);"X":GOSUB 110 80 LPRINT CHR$(27);"X":GOSUB 110 90 LPRINT CHR$(27);"cl”:END 100 'подпрограмма
110 POKE &HF418,1:T=2:RESTORE 190 120 LPRINT:LPRINT "ЯЗЫКИ" 180
130 LPRINT “ПРОГРАММИРОВАНИЯ:" 140 FOR K=1 TO 8 150 READ X»:LPRINT CHRS(9);X$;
160 IF KMODT=0 THEN LPRINT 170 NEXT К:RETURN
190 DATA БЕЙСИК,АЛГОЛ,СИ,АДА
200 DATA ЛИСП,ПАСКАЛЬ,ПЛ/1,ФОРТРАН run
ЯЗЫКИ ПРОГРАММИРОВАНИЯ 5
БЕЙСИКАЛПО Л
сиАДА
ЛИСППАСКАЛЬ.
Г1Л / 1ФОРТРАН
языки
ПРОГРАММИРОВАНИЯ8 БЕЙСИКАЛГОЛ
СИАДА
ЛИСППАСКАЛЬ
ПЛ/1ФОРТРАН
ЯЗЫКИ ПРОГРАММИРОВАНИЯs БЕЙСИКАЛГОЛ '
СИАДА
ЛИСППАСКАЛЬ
ПЛ/1ФОРТРАН
Механизм МАКРО является специфической формой организации подпрограмм. Однако стоит заметить, что использование стандартного механизма подпрограмм во многих случаях более естественно.
Создание новых символов
Принтер GEMINI- 10XR дает возможность пользователю создавать новые символы, загружать их коды в специально отведенное для этого место памяти (RAM), а затем выводить их на печать. Единовременно в RAM может храниться до 94 различных знаков, а общее их количество равно 2Х897. Прежде чем приступить к разговору о формировании новых символов, нам предстоит более детально ознакомиться с работой данного принтера и принятым в нем способом кодирования знаков.
Любой символ алфавита формируется принтером на листе бумаги с помощью 9 тонких штырьков (иголок) печатающей головки. Штырьки расположены в обойме в одном вертикальном ряду, и каждый из них управляется своим магнитом. В процессе печати на эти магниты подаются потенциалы и в зависимости от их величины соответствующие штырьки либо втягиваются внутрь обоймы, либо выталкиваются из нее и ударяют по красящей ленте. Каждый такой удар оставляет на листе бумаги небольших размеров круглое пятнышко цвета красителя ленты. Будем условно называть это пят-
рисуется отдельными точками. Например, из рисунка 20 (схематическое изображение некоторых символов в строке) видно, что буква С состоит из 11 точек.
Из сказанного ясно, почему принтер GEMINI-10XR относят к точечно-матричным печатающим устройствам ударного типа.
В одной строке выводимых символов условно можно выделить 9 горизонтальных рядов. Конкретная иголка участвует в создании точек своего ряда. Но любой символ, в том числе и заглавные буквы, должен полностью располагаться в 7 верхних или 7 нижних рядах. При формировании конкретного символа для точек доступны 9 вертикальных рядов. Нс допускается лишь, чтобы по горизонтали оказались рядом две соседние точки. Таким образом, если взять сетку размера 7X5 и отождествить се строки с горизонтальными рядами, а столбцы и разделяющие их линии — с вертикальными рядами, то легко нарисовать на ней любой символ алфавита Бейсика (см. рис. 21),
По типу расположения в выводимой строке символы можно разделить на две группы: те, которые не опускаются ниже основной горизонтальной линии, и значит, в их создании не принимают участия две нижние иголки (см. рис. 20), и все остальные. Первые будем называть символами без понижения и приписывать им характеристику то = О, а вторые — символами с понижением и
приписывать им характеристику то = 1. Например, для буквы «ё» то = О.
Параметр то одна из компонент специального кода mo, ть тг то(3)
любого, в том числе и нового, знака у. Как сформировать (3) ? Пусть у зафиксирован на сетке. Припишем ее горизонтальным рядам в порядке их следования весовые числа: 1, 2, 4, ..., 64 (см. рис. 21). Подсчитываем значения величин ms(s = 1,9), равные сумме весовых чисел тех горизонтальных рядов, в которых для вертикали s проставлены точки. Код (3) получен. Описанная процедура весьма наглядно просматривается на рисунке 21 для символа «ё».
Коды (3) всех стандартных символов хранятся в запоминающем устройстве принтера ROM. Кроме того, как мы уже отмечали, коды вновь создаваемых знаков загружаются в область памяти, именуемую RAM. Итак, пусть для знака у получена последовательность (3). По управляющему коду (см. табл. 21):
Ф; ","; CHR$ (в); CHR$ (m0); CHR$ (mi)... CHR$ (m9)
у загружается в ROM, где: n — десятичный код, приписываемый у (п£{33, 34, ..., 126)); то — характеристика понижения у;
ms (s= 1, 9) — весовые числа вертикальных рядов у.
Далее, чтобы напечатать у = CHR$ (в), необходимо включить режим вывода новых символов. Делается это по коду
Ф; V ("," = CHR$ (39))
Отмена режима Ф; "’" производится по любому из кодов
Ф; "&" или Ф; "$".(4)
При выполнении (4) CHR$ (в) опять становится стандартным символом алфавита с кодом ASClIn. Таким образом мы одновременно можем печатать и новый знак у, и соответствующий ему стандартный символ.
Таблица 21
Управляющие коды
Выполняемые действия
1 Ф; "Г; CHR$(n);
CHR $ (mo);
CHR $ (mJ;
CHR $ (т9)
ф. // и
Ф;или Ф; "$"
Загрузка нового символа у в память принтера RAM. Здесь:
п — код у (п £ (33, 34, ..., 126))
то — характеристика понижения у (m0€(0, 1))
ms (s= 1, 9) —весовые числа вертикальных рядов у Включение режима вывода новых символов Отмена режима Ф; ,н"
10 Z$=CHR$(27):LPRINT Z$;"Р”;CHR*(14)
20 ’ формирование нового знака
30 DATA 0,15,16,36,64,4,64,36,16,15
40 LPRINT Z$;",";CHRS(98);
50 FOR К=1 TO 10
60 READ M:LPRINT CHR$(M);
70 NEXT К
80 ' распечатки
90 LPRINT Z»;"’";:GOSUB 150
100
LPRINT
Z$;"&";:GOSUB
150
110
LPRINT
Z»;“,";:GOSUB
170
120
LPRINT
Z*; •*♦•*$ 8 BOSUB
170
130
140
LPRINT
Z$;"cl";:END
150
FOR K=1
TO 15:LPRINT
CHR$(98);:NEXT
160
LPRINT:
RETURN
170
FOR K=1
TO 15:LPRINT
"b";:NEXT
180 LPRINT:RETURN
run
В этом примере сформирован квантору. После включения режима печати новых символов он выводится и по коду 98, и с помощью символа "Ь" (строки 70 и 90). Отмена режима Ф; "'" приводит к выводу стандартного символа "Ь" (строки 80 и 100).
Заметим, что новые знаки исчезают из памяти RAM лишь в случаях, если на их место загружаются новые символы или выключается принтер.
ПРИМЕР 11. ДВА НОВЫХ СИМВОЛА V И 3
10 Z»=CHR»(27):J»=CHR»(95):IS=CHRS(96)
20 D*="x,y- вещественные"^T$=,,положительные"
30 LPRINT Z$;"P";CHR$(14)g
40 'формирование новых знаков
50 LPRINT Z*g","gJ$g:GOSUB 140
60 LPRINT Z$g","gI»g:GOSUB 140
80 LPRINT Z»g"’"gD$g",":LPRINT ""gT$
90 LPRINT:LPRINT "n - натуральное":LPRINT
100 LPRINT"АКСИОМА АРХИМЕДА: "
110 LPRINT " "gJ»g"х";J*g"у";1$;"п(х<п-у)*
120 ’
130 LPRINT Z»g"cl"g:END
140 FOR К=1 TO 10
150 READ M:LPRINT CHR»(M)g
160 NEXT K:RETURN
170 DATA 0,15,16,36,64,4,64,36,16, 15
180 DATA 0,65,0,73,0,73,0,73,0,127
run
x , у— звощес: ~гвенные „ n ол ожител fc>- НЫе
n— натуральное
АКСИОМА АРХИМЕДА5
УхУуЗп C x ^£ m - у >
Растровая графика
По аналогии с созданием и выводом новых символов рассматриваемый принтер может осуществлять печать произвольных изображений: картин, схем, карт, графиков и т. п. Подобная растровая (поточечная) графика допускает разрешающую способность до 160 106
точек на дюйм. Это существенно лучше обычного текстового режи ма, при котором все, в том числе и созданные пользователем, символы выводятся при разрешающей способности в 60 точек на дюйм.
Для изображения X, которое подлежит в будущем распечатке, необходимо создать специальный цифровой код. Опишем, как это делается.
Пусть X представлено на прямоугольной сетке с т горизонтальными и п вертикальными рядами, где т кратно 8. Каждая строка, состоящая из 8 последовательных горизонтальных рядов, будет кодироваться отдельно, выводиться без всяких понижений и формироваться первыми 8 штырьками головки принтера. Зафиксируем строку I и припишем ее последовательным горизонтальным рядам весовые числа: 1, 2, 4, ..., 128. По ним так же, как это делалось в предыдущем пункте, находим весовые числа вертикальных рядов
т,ь Щ.2, .... Шт (t=l, 2, ...)(5)
Каждое m,s(s=l, п) равно сумме весовых чисел тех горизонтальных рядов, в которых для вертикали s проставлены точки изображения X. Стилизованное изображение символа Р на сетке и его некоторые характеристики см. на рисунке 22.
Последовательность (5) является кодом t, строки L Построив все ti(i—\, т/8), получим матрицу
(m,j) (t=l, m/8; /=1, п\
Вывод изображения X реализуется построчно по управляющим кодам
Ф; „s„. „п„. CHRg (/Иа); CHRg (/и.2); CHR$ (/и.п)(6)
(i = 1, m/8),
где п — количество вертикальных рядов X (я £{0001, 0002, ...)), m,s— весовое число вертикального ряда s (s = 1, /г) для строки
i(j = 1, т/8).
При использовании управляющего кода (6) для слитного восприятия X высоту строки требуется установить в 16/144 дюйма. Это делается кодом
ф. ,/Т„. „16„
Кроме того, специфика данного принтера требует предварить использование кода (6) выполнением команды
POKE&HF418.1
ПРИМЕР 12. РАСТРОВАЯ ГРАФИКА. ВЫВОД СТИЛИЗОВАННОЙ БУКВЫ "Р" 10 Z»=CHR*(27)sLPRINT Z*;"Т";"16м;CHR»(14) 20 POKE &HF418,1 30 FOR 1=1 ТО 4iLPRINT Z«; "S"; "0015,,5 108
40 FOR J=1 TO 15:READ M:LPRINT CHR*(M);:NEXT 50 LPRINT:NEXT I
60 DATA 64,120,15,6,254:’1 строка
70 DATA 96,48,24,28,14,14,31,255,252,240
80 DATA 0,224,62,3,31:’2 строка
90 DATA 224,0,0,0,0,128,224,124,31,7
100 DATA 0,127,192,0,0:’3 строка
110 DATA 255,0,4,6,3,1,0,0,0,0
120 DATA 0,0,7,28,240:’4 строка
130 DATA 127,0,0,0,0,0,0,0,0,0
runrun
run
run
Таблица 22
Управляющие коды
Выполняемые действия
1. Ф; "s"; "п"; CHR$(mn); CHR $ (т^;
Вывод /-й строки изображения X
Здесь:
1. п— количество вертикальных рядов X («£{0001, 0002, ...))
CHR $(min)
2. mis — весовое число вертикального ряда s(s = 1, и) для строки 1
2. Ф; "N"
Включение режима нормальной плотности печати — 80 точек на дюйм.
Ф; "N" задан по умолчанию
3. Ф; "Е"
Включение режима средней плотности печати — 90 точек на дюйм
4. Ф; "Р" или Ф; "Q"
Включение режима двойной плотности печати — 160 точек на дюйм
Здесь символ «Р» печатается при шаге «Цицеро» с расширением в два раза за 4 прохода головки принтера (см. рис. 22). Подчеркнем, что если бы мы выводили не один знак, а более емкое изображение, то это не отразилось бы на ядре программы (строки 10—50). Разрослась бы только ее часть, связанная с данными.
Графики функций
Описанный в предыдущем пункте подход к использованию растровой графики не совсем удобен из-за большого количества
предварительных вычислений, которые фактически приходится выполнять «вручную». По-видимому, там, где это возможно, предпочтительнее формировать коды строк изображения с помощью компьютера. Например, это довольно просто делать при выводе графиков различных функций.
По программе «Графики» можно напечатать график произвольной явной функции действительного переменного X:Y = F (X). Для этого необходимо проделать такие операции:
В строках 710 и далее указать аналитическое выражение Дия F (X).
Запустить программу и ответить на запрос с экрана, в каком прямоугольнике R должен быть сформирован график F(X). Ввод четверки чисел (А, В, С, D) и определит
R_(zX Y) I А<Х<В1К— I (X, Y) | c^y<D J
Ответить на запрос о размере распечатки. Это позволит зафиксировать в точках величину второго прямоугольника (кадра) Т, в котором будет размещаться на бумаге изображение. Если (Р, Q) —введенная пара чисел и Р = 16*Р; Q=16*Q, то
Задать плотность распечатки U (1 или 2). При обоих значениях U количество точек в Т одинаково, но при U=2 кадр Т будет сжат в два раза вдоль оси абсцисс.
Описанная процедура позволяет получать графики довольно сложных функций. Непрерывность F(X) не предполагается. Некоторые примеры функций и их графиков, полученных по обсуж-
даемой программе,
. приведены на рисунке 23. Параметры ввода:
а) А=-8.5, Q=25,
В=8.1,С=-5,0 = 7
P = ll,U=1
в) А=—7, Q=25,
В =6,С=-6,0=7
Р = 6,U=2
с) А=-7, Q = 25,
ПРИМЕР
В =7,С=—2,0 = 2
Р=6,U = 2
13. ПРОГРАММА "ГРАФИКИ”
10 ’ ПЕЧАТЬ ГРАФИКА ФУНКЦИИ Y=F(X)
20 ’
30 COLOR 15,4:SCREEN 0:KEY OFF:WIDTH 40
40 DEFINT I, J, M, V, P,Q, L, R, E, Z
50 L#=STRING$(37,"-"):Z»=CHR»(27)
60 PRINT "ПЕЧАТЬ ГРАФИКОВ ФУНКЦИЙ"
ПО
КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:1. ось ОХ: -8,5 ; 8,12. ось 0Y: -5 ; 7КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:1. ось ОХ: -8,5 ; 8,12. ось 0Y: -5 ; 7КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:1. ОСЬ ОХ : —7; 62. ось 0Y: -6; 7КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:1. ОСЬ ОХ : —7; 62. ось 0Y: -6; 7КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:1. ось ОХ ; — 7 ; 72. ОСЬ 0Y: -2; 2РАЗМЕТКА В ЦЕЛЫХ ТОЧКАХКООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:1. ось ОХ ; — 7 ; 72. ОСЬ 0Y: -2; 2РАЗМЕТКА В ЦЕЛЫХ ТОЧКАХ
КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:
1. ось ОХ: -8,5 ; 8,1
2. ось 0Y: -5 ; 7
КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:
1. ось ОХ: -8,5 ; 8,1
2. ось 0Y: -5 ; 7
КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:
1. ОСЬ ОХ : —7; 6
2. ось 0Y: -6; 7
КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:
1. ОСЬ ОХ : —7; 6
2. ось 0Y: -6; 7
КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:
1. ось ОХ ; — 7 ; 7
2. ОСЬ 0Y: -2; 2
РАЗМЕТКА В ЦЕЛЫХ ТОЧКАХ
КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ:
1. ось ОХ ; — 7 ; 7
2. ОСЬ 0Y: -2; 2
РАЗМЕТКА В ЦЕЛЫХ ТОЧКАХ
76 PRINT L»
80 PRINT "КООРДИНАТЫ ПРЯМОУГОЛЬНИКА":PRINT
90 PRINT "1. интервал определения ЕА,В1"
100 INPUT
110 PRINT
"A=";A:INPUT "B=";B
120 PRINT
"2. интервал изменения £0,0]"
130 INPUT
140 PRINT
"C=”;C:INPUT "D=";D
150 PRINT
"РАЗМЕРЫ РАСПЕЧАТКИ":PRINT
160 PRINT
"1. по горизонтали (Q=l,2,...,25)
170 INPUT
"Q=";Q:Q=QX16:PRINT
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
470
INPUT "P=";P:L=PX2:P=PX16:PRINT
PRINT "ПЛОТНОСТЬ РАСПЕЧАТКИ <U=1,2>" PRINT INPUT " U="$U:IF UO1ANDUO2 THEN 220 CLS
LOCATE 8,9:PRINT “проводятся вычисления" ’ЯДРО
DIM M(L,Q),V(P):0N ERROR GOTO 690
Kl=(B—A)/(Q—1):K2=(D—C)/CP—1):K5=l/К1
K6=l/К2:K3=A-K1:K4=C-K2: E=P\8+1 R$=RIGHT$("0000"+MID$(STR$(Q),2),4) FOR 1=0 TO L-l: FOR J=1 TO 8 V(IX8+J)=2^(8-J) NEXT J,I 'кадр изображения
FOR 1=1 TO Q:M(1,I)=1:M(L,I)=128:NEXT FOR J=1 TO L:MCJ,1)=255:M(J,Q)=255:NEXT ’разметка кадра
IF B-A<2 THEN 430 FOR X=A TO B+1:Z=X IF Z<=A OR Z>=B THEN 420 I=(Z—КЗЖК5 MCL,1-1)=0:M(L,I)=0:M(L,1+1)=0 NEXT X IF D-C<2 THEN 550 FOR Y=C TO D+1:Z=Y IF Z<=C OR Z>=D THEN 530
J=(Z-K4)XK6:R=E—(J+7)\8:M=V(J) IF MOI THEN 490
480 M(R, 1)=M(R, 1)-3:M(R-1, 1)=M(R-1, D-128
490 IF MO128 THEN 510
500 M(R,1>=M(R,1)—192:M(R+l,1>=M(R+1,1> —1
510 IF M=1 OR M=128 THEN 530
520 M(R, 1)=M(R, 1)-M-V(J~1)-V(J+1)
530 NEXT Y
540 ’весовые числа для Y=F(X)
550 FOR 1=2 TO Q-1:X=K1*I+K3:GOSUB 710
560 J=(Y—K4)XK6:IF J<2 OR J>=P THEN 580
570 R=E-(J+7)\8:M(R, I)=M(R, D+VCJ)
580 NEXT Is’ВЫВОД ИЗОБРАЖЕНИЯ
590 CLS
600 LPRINT "КООРДИНАТЫ КАДРА ИЗОБРАЖЕНИЯ;"
610 LPRINT "1. ось OX: "A;"; ";B
620 LPRINT "2. ось OY: "C;"; ";D
630 LPRINT “РАЗМЕТКА В ЦЕЛЫХ ТОЧКАХ"
640 LPRINT Z$;"N";:IF U=2 THEN LPRINTZ*;"P";
650 LPRINT ZS;"T";"16";Z#;"’";:POKE &HF418,1
660 FOR 1=1 TO L:LPRINT Z»;”S";R»;
670 FOR J=1 TO Q:LPRINT CHR$(M(I,J));:NEXT J
680 LPRINT:NEXT:LPRINT Z*;"cl";CHR$(10>:END
690 Y=D+10:ON ERROR GOTO 0:RESUME 740
700 ’========ПОДПРОГРАММА ДЛЯ ФУНКЦИИ Y=F(X)
710 ’Y=F(X)
750 RETURN
Несколько слов о программе. Между точками (X, Y)£R и (1, J)€T по формулам
Х=(1-1)-^+А
D С(?)
Y=(J-l)-^+C
устанавливается взаимно однозначное соответствие. Но в Т нас интересуют лишь целочисленные пары (I, J). Они и являются возможными координатами изображения. Чтобы при фиксированном параметре Q разместить в Т максимально возможное количество точек F(X), в программе используется следующий алгоритм. Прежде всего для каждого I от 2 до Q — 1 выполняются пункты 1 —4.
По первой из формул (7) при фиксированном I находится аргумент X для F(X).
Вычисляется значение Y = F (X). Если (X, Y)^R или F не определена в точке X, то переходим к следующему I.
По второй из формул (7) при фиксированном Y находим J и округляем его до ближайшего целого. Если (I, J) ^Т, то переходим к следующему I.
Пара (I, J) есть точка изображения. Определяем для нее весовое число (см. пункт 3.11) и запоминаем его в массиве М.
Далее, полученный массив М фактически является матрицей изображения и выводится так, как это описано в пункте 3.11.
Кроме графика для F(X), программа рассчитывает и распечатывает рамку кадра, размеченную в целых точках. Делается это по операторам из строк 330—530. Если подобная рамка с разметкой в распечатке не требуется, то строки 330—530 из программы можно удалить. На существе дела это не отразится.
В заключение остановимся на таком моменте. Набор S встроенных стандартных функций Бейсика весьма ограничен. Поэтому, скажем, для функции
у = х-ф arcsin (sin х)(8)
непосредственно графика не построить. Но оказывается, многие элементарные функции могут быть выражены в виде комбинаций из S. В таблице 23 приведены соотношения между некоторыми элементарными функциями. Используя ее, мы смогли бы написать подпрограмму для вычисления (8) так:
710 Y=-SIN(X)Л2+1730 Y=X+ATN(Y>
720 Y=SIN(X)/SQR(Y>740 RETURN
Таблица 23
Название функции
Выражение
Область определения
1 Секанс
2 Косеканс
3 Котангенс
4 Арксинус
sc х = 1 /cos X
esc х= 1 /sin х
ctg Х = 1/tg X
arcsin x=arctg (W1 — я2)
x^ л/2 + л&
к = 0, dz 1, dz 2, ...
х -/— лк
к = 0, ±1, ±2, ...
х^ лк
к = 0, dz 1, zb2, ...
х€[— 1; 1]
Продолжение
Название функции
Выражение
Область определения
5 Арккосинус
arccos х—~^ — arctg (х/^/1 — х2)
xe[—1; 1]
6 Арккотангенс
arcctg х=—— arctg %
*E( — oo; + oo)
7 Гиперболический синус
sh x=(e* — е-х)/2
x£(— oo; + oo)
8 Гиперболический косинус
ch х^^ + е-*)^
x£(—oo; -f-oo)
9 Гиперболический тангенс
thx^-e-^/^+e"^
x£(—oo; + °o)
10 Гиперболический котангенс
cth х = (ек-\-е~"х)/(ех — е-х>)
11 Гиперболический арксинус
ash x = ln (x + Vx2 + О
*E(— oo; + oo)
12 Гиперболический арккосинус
ach x=ln (x-^-^jx2 — 1)
x> 1
13 Гиперболический арктангенс
athx=yln((l+x)/(l-x))
Ix|<l
14 Гиперболический арккотангенс
acth x=y In ((1 -x)/(l +x))
kl>l
15 Логарифм N по основанию а
logo N=(ln N)/(ln a)
a, N>0 0^=1
Мы не касались вопроса о построении графиков функций, заданных параметрически:
х=<р(/), у=^ (f) (а^/^р), где ср, ф— функции действительной переменной /; а, р — вещественные числа. Соответствующая программа может быть получена модификацией строк 550—580 фрагмента «Графика». При этом, разумеется, необходимо иметь подпрограмму вычисления значений ф (/) и ф (/).
ФАЙЛЫ
Общие сведения
Термин файл происходит от английского слова file, переводящегося на русский язык как «дело» или «досье». В информатике под файлом понимают совокупность в некотором смысле однородных данных, характеризующих какой-либо процесс или некоторый объ-
ект. Мы будем иметь дело с программными файлами, состоящими из одной или нескольких именованных программ, и файлами данных. Файлы обычно хранятся на тех или иных внешних носителях информации. Довольно часто, говоря о файле, имеют в виду не только определенные данные, но и соответствующую область носителя, на котором они размещены. Впрочем, из контекста всегда ясно, о чем идет речь, и к недоразумениям это не приводит.
Компоненты программного файла называют модулями или сегментами. Один из них считается основным. Он в первую очередь загружается в оперативную память и управляет всем процессом обработки информации. В частности, основной модуль по мере надобности проводит автоматическую подгрузку в память других сегментов файла. Именем файла считается имя его основного модуля. При небольших размерах программного файла разбивать его на модули нецелесообразно.
ПРИМЕР 1. Программный файл иэ одного модуля 10 ’ ФОРМУЛА СИМПСОНА 20 ’программа
30 COLOR1,7,15:SCREEN 0
40 INPUT"нижний предел";А
50 INPUT"верхний предел“;В
60 INPUT"количество точек";М
70 CLS:LOCATE 8,8 80 PRINT "ПРОВОДЯТСЯ ВЫЧИСЛЕНИЯ" 90 5=0:Н=(В-А>/М:51=0:52=0 100 FOR Х=А+Н/2 ТО В-Н/2 STEP Н 110 GOSUB 220:S1=S1+Y 120 NEXT X 130 FOR Х=А+Н ТО В-Н STEP Н 140 GOSUB 220:S2=S2+Y 150 NEXT X 160 Х=А:GOSUB 220;S=S+Y 170 X=B:GOSUB 220:S=S+Y 180 S=(S1X4+S2X2+S)XH/6 116
190 CLS:LOCATE 6,8
200 PRINT “интеграл = “^SsEND
210 подпрограмма
220 Y=(X^2)XSINCX):RETURN
Нас будут интересовать два вида файлов данных: прямого доступа и последовательного доступа.
Компоненты файла прямого, или, по-другому, случайного доступа — это отдельные нумерованные группы значений, называемые записями. Запись может быть считана с внешнего носителя в буфер оперативной памяти и наоборот — сформирована в буфере и затем переписана во внешнюю память. Иными словами, буфер является своеобразным окном, через которое можно «рассматривать» файлы данных. Обращение к конкретной записи осуществляется прямым заданием ее номера.
Компоненты файла последовательного доступа называются строками. Каждая строка имеет специальную концевую метку и, как и запись, состоит из отдельных значений. Однако строки не нумерованы и обрабатывать их можно лишь последовательно друг за другом. Причем запись организуется от начала или конца файла, а чтение — только от его начала.
Заметим, что отдельные сегменты программных файлов — это, вообще говоря, специфические файлы данного последовательного доступа.
Оба рассмотренных вида файлов с успехом могут быть использованы в рамках расширенного Бейсика при работе с дисководом. В качестве внешних носителей в этом случае применяются магнитные диски. Последовательные файлы могут использоваться с любым, в том числе и нерасширенным, Бейсиком. Здесь устройством обмена является магнитофон, а внешним носителем — магнитная лента.
Следует иметь в виду, что организация работы с файлами прямого доступа в некоторых отношениях сложнее, чем с файлами последовательного доступа. Однако возможность непосредственного обращения к требуемой группе значений, предоставляемая файлами прямого доступа, позволяет считать их наиболее предпочтительными структурами хранения данных во внешней памяти.
4-2. Дисковые файлы
В главе «Файлы» данный раздел является доминирующим как по объему, так и по содержанию излагаемого материала. Он посвяти описанию команд и функций расширенного Бейсика, а также их использованию при работе с файлами.
Сервисные команды. В расширенном Бейсике предусмотрены группы команд и функций, с помощью которых организуется работа
117
отдельно с программными файлами, файлами данных прямого доступа и файлами данных последовательного доступа. Однако эта версия языка имеет и ряд средств, пригодных для работы с файлами любого типа. К ним относятся следующие команды и функции.
FILES (LFILES)
— команда вывода на экран (принтер) списка имен файлов.
DSKF
— функция, имеющая значением размер в байтах свободной части диска.
NAME... AS
— команда изменения имени файла на диске.
COPY... TO
— команда создания дубликата файла на диске.
KILL
— команда стирания файла на диске.
В последующих пунктах этого раздела обсуждается синтаксис и семантика перечисленных команд и функций, а также коротко затрагиваются вопросы, связанные с форматированием дисков и правилами образования имен файлов.
Форматирование диска. Для работы с 3,5-дюймовым дисководом MSX-компьютера используются двухсторонние диски MF2-DD, односторонние диски MF1-DD или их аналоги. На рисунке 24 показан общий вид такого диска, заключенного в пластмассовый кожух и имеющего переключатель защиты от записи и скользящую шторку для прикрытия окна, через которое организуется чтение-запись информации. Вставлять диск в щель (карман) дисковода и извлекать его оттуда можно лишь при включенном устройстве.
Разрешается подключать к компьютеру как одиночные, так и спаренные дисководы. В первом случае за устройством закрепляется переменное имя, которое в любой конкретный момент времени принимает одно из двух возможных значений А или В. Во втором случае основной дисковод получает имя А, а дополнительный — В.
Передний край диска при его вставке 6 щель дисководаПередний край диска при его вставке 6 щель дисководаСкользящая шторки для защитыСкользящая шторки для защиты
Передний край диска при его вставке 6 щель дисковода
Передний край диска при его вставке 6 щель дисковода
Скользящая шторки для защиты
Скользящая шторки для защиты
Положение переключателя при запрещенной записи на дискПоложение переключателя при запрещенной записи на дискПоложение переключателя при разрешенной записи на дискПоложение переключателя при разрешенной записи на диск
Положение переключателя при запрещенной записи на диск
Положение переключателя при запрещенной записи на диск
Положение переключателя при разрешенной записи на диск
Положение переключателя при разрешенной записи на диск
Рис. 24
Везде ниже, если это не оговорено специально, изложение ориентировано на использование одиночного дисковода, а слова диск, дискета и флоппи-диск рассматриваются как синонимы.
Для подготовки диска к работе с командами и функциями Бейсика необходимо осуществить специальную разметку его по- рсрхности, называемую форматированием (форматизацией). Для этого диск вставляется в карман дисковода и выполняется команда CALL FORMAT. При вводе команды слово CALL (вызывать) можно заменить символом подчеркивания (). Выполнение CALL FORMAT вызывает индикацию на экране запроса
DRIVE NAME? (А, В)
Ответом на него должен быть ввод одной из букв А или В в зависимости от имени устройства, в котором находится диск. На появившийся второй запрос-подсказку
1 — DOUBLE SIDES
2 — SINGLE SIDES ? _
пользователь обязан отреагировать вводом 1, если диск двухсторонний, или 2, если диск односторонний. Далее, по указанию
STRIKE A KEY WHEN READY
необходимо нажать любую клавишу (при появлении сообщения «INSERT DISKETTE FOR DRIVE...» требуется произвести нажатие еще одной клавиши, это приведет к смене имени устройства). После этого и начинается процесс форматирования, т. е. размещение на диске управляющих меток. При этом ранее имевшаяся там информация разрушается. Правильное завершение этого процесса вызывает индикацию следующего сообщения:
FORMAT COMPLETE OK
Форматирование новых дисков обязательно!
Приведем некоторые характеристики диска MF2-DD. L Емкость при записи:
а) всегоа) всегоб) для файлов пользователяПлотность при записиСреднее время доступаМаксимальное количество файловб) для файлов пользователяПлотность при записиСреднее время доступаМаксимальное количество файлов— 720 Кбайт, — 713 Кбайт.— 720 Кбайт, — 713 Кбайт.— 8717 бит/дюйм.— 8717 бит/дюйм.— 95 мс.— 112.— 95 мс.— 112.
а) всего
а) всего
б) для файлов пользователя
Плотность при записи
Среднее время доступа
Максимальное количество файлов
б) для файлов пользователя
Плотность при записи
Среднее время доступа
Максимальное количество файлов
— 720 Кбайт, — 713 Кбайт.
— 720 Кбайт, — 713 Кбайт.
— 8717 бит/дюйм.
— 8717 бит/дюйм.
— 95 мс.
— 112.
— 95 мс.
— 112.
Имена файлов. При создании на диске любого нового файла ему необходимо присвоить определенное имя. Оно должно быть
119
уникальным, т. е. не совпадать ни с одним из уже имеющихся имен файлов, сформированных на данном диске ранее. •
Имя служит для идентификации файлов и строится из последовательности символов алфавита Бейсика. При этом должны учитываться следующие обстоятельства:
Количество символов имени нс может превосходить 11. Попытка сформировать имя большей длины ни к чему не приводит. Правые лишние знаки отбрасываются.
Соответствующие большие и малые латинские буквы, используемые в имени, равнозначны.
Соответствующие большие и малые буквы русского алфавита, используемые в имени, не равнозначны.
В имени не должно быть знаков:
;, + " = []* \ / ?
Символ двоеточие (:) используется только при задании составных имен для разделения их на две части, первая из которых идентифицирует устройство, а вторая — файл. В этом случае при записи файла на диск фиксируется лишь вторая часть имени.
Нельзя задавать имя, состоящее из одних пробелов, начинающееся с пробела или содержащее неконцевые пробелы.
Имя не должно начинаться с точки (.). В нем не может быть более одного такого символа и не более 8 знаков перед ним.
При задании имени «с точкой» ЭВМ интерпретирует ее в качестве символа девятой позиции. Тем самым имя разделяется на две зоны: основная часть (до точки) и расширение (после точки). Иногда расширение имени называют его индексной частью. Номер начальной позиции основной части — 1, а расширения— 10. Если пользователь фиксирует имя без точки с количеством символов, большим 8, то ЭВМ автоматически разбивает его на основную и индексную части, вставляя в требуемое место точку.
ПРИМЕР 2. Имена файлов
ЗАДАНИЕ I ИНТЕРПРЕТАЦИЯ h
ГУСИ1
P.Q53I
TIR.|
#1
ЛУЧ1
ВАЛ.процент|
ПРОТИВОГАЗ|
А:РОЗА1
120
ГУСИ
Р.053
TIR
#
ЛУЧ
ВАЛ.про
ПР0ТИВ0Г.АЗ
РОЗА
Справочная информация о файлах. Имеются довольно простые средства для получения списка имен файлов, размещенных на диске (FILES), размера его свободной части (DSKF) и некоторой другой справочной информации.
Вывод имен файлов осуществляется по команде
[L] FILES [i](1)
где: FILES (файлы), L — служебные слова; i — имя файла.
При выполнении команды (1) без параметра i список имен всех файлов диска или индицируется на экране (L отсутствует), или распечатывается принтером (L есть). В зависимости от типа экрана и его ширины индикация имен организуется в 3, 2 или 1 колонку. Распечатка списка проводится в 1 колонку — каждому имени отводится одна строка. При отсутствии файлов на диске выдается сообщение
FILE NOT FOUND (файл не найден)(2)
Если в команде (1) параметр i указан и на диске имеется файл с этим именем, то данный факт подтверждается выводом единственного имени i. В противном случае выдается сообщение (2).
ПРИМЕР 3
files3> 100 FILES
FILES "ИГРЫ" 4) LFILES
Обратите внимание на возможность использования в основной части имени или его расширении символов маскирования * и ?
ПРИМЕР 4
1) FILES "X.DOT”
— индикация всех файлов с расширением "DOT"
2) FILES"LUX.X"
индикация всех файлов с основной мастью ”LUX“
3) FILES"IX.X”
— индикация всех файлов, имена которых наминаются на единицу
4) FILES"*.7U?"
— индикация всех файлов, второй символ расширения у которых есть "U”
Функция DSKF (п), где: DSKF (d/sA free) (свободная часть диска) — служебное слово; п — арифметическое выражение, имеет значением размер в Кбайтах свободной части диска. Целая часть По значения аргумента п может быть равна 0, 1 и 2. Она определяет имя, закрепленное за дисководом:
По = О — текущее имя, n0= 1 — А, По = 2 — В.
ПРИМЕР 5
printDSKF(l)
printDSKF(2)
printDSKF(0)
X=l:print DSKF(X)
10 IF DSKF(0) > 300 THEN 1000
Для выяснения размера в байтах области диска, отведенной под произвольный файл i, можно воспользоваться строкой (см. «Файлы данных последовательного доступа»):
OPEN i FORINPUT AS*1:PRINT LOF(l)
Дополнительные сведения, относящиеся уже не к произвольным файлам, а лишь к файлам данных, можно получить с помощью функций LOF, LOC и EOF (см. «Файлы данных прямого доступа», «Файлы данных последовательного доступа»). 1
Изменение имен. Изменение имени программного файла или файла данных производится по команде
NAME i AS j(3)
где: NAME (имя), AS (как) —служебные слова; i — старое имя файла; j — новое имя файла.
При выполнении команды (3) прерывание происходит или при отсутствии на дискете файла с именем i (нечего переименовывать), или при наличии на ней файла с именем j (j зарезервировано). В противном случае файл i получает новое имя j.
При задании j допускается использование знака «?». Но при реальном формировании j на диске эти символы будут заменены на элементы из соответствующих позиций i.
ПРИМЕР 6
NAME "алфавит" AS "АЛФ"
NAME X» AS "X.1"
3> 200 NAME "PQR.XYZ" AS "?.?11"
122
В последнем случае новое имя будет выглядеть так:
Р u U U U U U U . XII.
Копирование файла. Для дублирования на дисках программных файлов и файлов данных применяется команда
COPY i ТО j(4)
где: СОРУ (копировать), ТО (в)—служебные слова; i — имя исходного файла; j — имя формируемого файла.
При выполнении команды (4) по файлу любого формата с именем i создается его копия j. Имена i и j не должны совпадать. В том случае, когда файл j уже существует на диске, наряду с копированием i в j проводится изменение до требуемых размеров файла j и свободной части диска.
Если i или j — файлы данных, то они не должны быть открыты.
ПРИМЕРЫ 7
COPY "AL" ТО "LA"
COPY "X" ТО "X.i“
20 FOR J=2 TO 20
30 COPY "U.l" TO "U."+MIDt(STRt(J),2)
40 NEXT
COPY "А:ПРОБА" TO "В;ПРОБА"
В команде COPY в основной части имени или его расширении можно использовать знак *, заменяющий произвольную последовательность символов.
Копирование всех файлов с одного диска на другой при спаренных дисководах проводится по командам:
СОРУ "А:*.*" ТО "В:*.*"(с А на В)
СОРУ "В:*.*" ТО "А:*.*"(с В на А)
На одиночном дисководе эта и подобные ей процедуры, например
COPY "A:*.MSX" ТО "B:*.MSX" реализуются по соответствующим сообщениям на экране периодической сменой дисков в кармане.
Стирание файла. По команде
KILL i(5)
где: KILL (разрушать, убивать) — служебное слово; i — имя файла, происходит разрушение на диске произвольного файла с
123
именем i и увеличение на соответствующую величину размера свободной части диска. Фактическому разрушению (стиранию) подвергается лишь справочная информация о файле.
Если i — файл данных, то при выполнении команды (5) он не должен быть открыт.
ПРИМЕРЬ! 8 1)KILL "БОЧКА"
2>KILL "R.T"
Х$="ЮюЮ"SKILL X»
100 FOR К=1 ТО 25
110 KILL "ЦЕХ."+MID$(STR$(K>,2) 120 NEXT 5> KILL "АВС.Ж"
В последнем примере удаляется справочная информация о всех файлах с основной частью имени «АВС» и произвольным расширением.
Программные файлы. Ниже описаны средства для перемещения программ из оперативной памяти на диск и в обратном направлении. Речь идет о командах SAVE, LOAD, RUN и MERGE.
SAVELOAD, RUNMERGESAVELOAD, RUNMERGE— команда записи программ на диск.
SAVE
LOAD, RUN
MERGE
SAVE
LOAD, RUN
MERGE
— команды чтения программ с диска.
— команда подгрузки в память программы, записанной на диске в формате ASCII.
Запись программы на диск. По команде SAVE i [,А], где: SAVE (сохранить), А — служебные слова; i — имя файла, программа из оперативной памяти под именем i записывается на диск. В зависимости от наличия или отсутствия параметра А запись проводится соответственно или в формате ASCII, или в форме внутреннего представления. Если данная программа впоследствии будет подгружаться в память для слияния с другими модулями (MERGE), то ее необходимо записывать в формате ASCII.
При наличии на диске программного файла или файла данных с именем i и записи на него новой программы под тем же именем старый файл пропадает и происходит пересчет размера свободной части диска в соответствии с новыми размерами L
Заметим, что формат ASCII приводит к увеличению в несколько раз времени записи программ из оперативной памяти на диск, а также их чтения с диска в память. К тому же для их размещения на диске требуется приблизительно на 30% больше места, чем для соответствующих программ во внутреннем представлении.
ПРИМЕР 9
SAVE "ЯГОДА",А4)SAVE "Ф.И”
SAVE X*5)10SAVE "MICRO”,А
3>Me=”PN":SAVE МФ6)10K=777
20 SAVE "ПАЛАТА." ♦MID»(STR*(К),2)
Чтение программы с диска. Для считывания программ с диска в оперативную память используются команды LOAD и RUN. Остановимся на каждой из них в отдельности.
По команде
LOAD i [,R](6)
где: LOAD (загрузить), R — служебные слова; i— имя файла, прежде всего закрываются все файлы и оперативная память очищается от программ и данных. Далее, программа, записанная на диске в машинных кодах или формате ASCII под именем i, загружается в оперативную память. При наличии параметра R после загрузки производится запуск программы на счет.
ПРИМЕР 10
LOAD"LUX"
LOAD"X.Y"
гФ=М10Ф(АФ,5,3>:LOAD 2Ф
LOAD"PR",R
5> 100 LOAD"TRACTOR",R
По команде
RUN i [, R]
где: RUN (запуск, прогон), R — служебные слова; i — имя файла, в оперативную память загружается и запускается на счет программа, записанная на диске под именем i в машинных кодах или формате ASCII. При отсутствии параметра R перед загрузкой i закрываются все открытые файлы и память очищается от программ и данных. При наличии в (6) параметра R из памяти удаляются программы и значения переменных. Однако файлы данных не закрываются.
ПРИМЕР 11
RUN "ALPHA"
2> RUN "Ведомость",R
50 RUN "ТИП-А"
Слияние программ. Интересные возможности по «соединению» (слиянию) программ предоставляются командой
MERGE i(7)
где: MERGE (слияние) — служебное слово; i — имя файла, записанного на диске в формате ASCII. Выполнение команды (7) начинается с закрытия всех файлов и чистки оперативной памяти от данных. Далее производится слияние программы к, находящейся в памяти, с программным файлом, записанным на диске в формате ASCII под именем I. При этом если в программах к и i совпадают некоторые номера строк, то сохраняются лишь соответствующие строки загружаемой программы L
ПРИМЕР 12
MERGE "ТТТ"
L$="ТЕХНИКA":MERGE L*
100 MERGE "LIST.3"
Файлы данных прямого доступа. Как мы уже отмечали, файлы данных прямого (случайного) доступа представляют собой последовательности нумерованных групп значений, называемых записями. Для работы с этими файлами в Бейсике предусмотрены следующие команды и функции.
MAXFILES-
VARPTR-
OPEN-
CLOSE-
FIELD-
LSET, RSET-
MKI$, MKS$,-
MKD$
CVI, CVS, CVD—
PUT-
•команда резервирования в оперативной памяти буферов для формирования или считывания записей файлов.
-функция, указывающая начальные адреса конкретных буферов в памяти.
команда открытия файла данных и привязки к нему одного из объявленных буферов.
команда закрытия файлов.
команда разбиения буфера файла на отдельные поля.
команды присваивания строковых значений буферным переменным.
функции преобразования числовых значений в строковые при их присваивании буферным переменным.
функции преобразования строковых значений переменных буфера в числовые.
команда обновления старых или формирования новых записей файла на диске (сброс записей из буфера на диск).
GET—команда считывания записей файла с диска
в оперативную память.
LOG—функция, имеющая значением номер текущей
записи файла.
LOF—функция, указывающая размер файла в байтах.
Ниже приведены две схемы, дающие наглядное представление о последовательности операций, которые должны быть выполнены при перемещениях записей файлов прямого доступа из оперативной памяти на диск и в обратном направлении.
Общая схема формирования новых записей уже существующего или вновь создаваемого файла 0:
В оперативной памяти резервируется буфер (MAXFILES).
Открывается файл 0 (OPEN).
Проводится распределение поля буфера файла под значения переменных (FIELD).
В буфере формируется запись (LSET, RSET, MKI$, MKS$, MKD$ ...).
Производится сброс записей из буфера на дней с присваиванием ей некоторого номера (PUT).
Пункты г) и д) повторяются столько раз, сколько это требуется, е) Файл 0 закрывается (CLOSE).
Общая схема считывания записей из уже существующего файла.
Должны быть выполнены пунктами а)—в) предыдущей схемы.
Производится считывание с диска в буфер оперативной памяти записи с конкретным номером (GET).
Bi) По записи из буфера в соответствии с распределением его поля формируются значения требуемых переменных (CVI, CVS, CVD, ...).
Пункты б] и Bi повторяются столько раз, сколько это требуется, ri) Файл 0 закрывается (CLOSE).
В последующих пунктах проводится детальное описание средств Бейсика для реализации предложенных схем работы с файлами данных прямого доступа.
Контрольные буферы файлов. По команде MAXFILES = а, где: MAXFILES — служебное слово; а — арифметическое выражение (0^INT(a) = ao^ 15), резервируются (объявляются) «о+1 участков оперативной памяти для последующего временного хранения записей конкретных файлов. Эти участки называются буферами, или, более полно, контрольными буферами файлов (File Control Buffers — FCB), и обозначаются так: FCBO, FCB1, ..., FCB ao. Каждый FCB занимает 265 байт, из которых 9 предназначены для управляющей информации, а 256 — для данных.
Следует иметь в виду, что FCB0 и FCB1 объявлены по умолчанию и что FCBo используется многими командами (SAVE, LOAD, MERGE, RUN и т. п.).
При выполнении команды MAXFILES, кроме резервирования буферов, производится «чистка» значений переменных и закрытие всех ранее открытых файлов данных.
ПРИМЕР 13 1) 10 MAXFILES=5 2) 50 MAXFILES=X+Y 3) MAXFILES=3
Функция
VARPTRVARPTRЛ # n 1 \ \l у J 7Л # n 1 \ \l у J 7(8)(8)
VARPTR
VARPTR
Л # n 1 \ \l у J 7
Л # n 1 \ \l у J 7
(8)
(8)
ДанныеДанныеАдреса -^х x+tх+8 х+9х+264Адреса -^х x+tх+8 х+9х+264Рис. 25Рис. 25Адреса*х-3 х-2 х-1 х х+1 х+2 х+3Адреса*х-3 х-2 х-1 х х+1 х+2 х+3Управляющая । информация vУправляющая । информация vЗначениеЗначениеАдреса -*- х х+1 х+2 х+зАдреса -*- х х+1 х+2 х+з
Данные
Данные
Адреса -^х x+tх+8 х+9х+264
Адреса -^х x+tх+8 х+9х+264
Рис. 25
Рис. 25
Адреса*х-3 х-2 х-1 х х+1 х+2 х+3
Адреса*х-3 х-2 х-1 х х+1 х+2 х+3
Управляющая । информация v
Управляющая । информация v
Значение
Значение
Адреса -*- х х+1 х+2 х+з
Адреса -*- х х+1 х+2 х+з
где: VARPTR (pointer of variation — указатель переменной) — служебное слово; n — арифметическое выражение, целая часть значения которого определяет номер FCB (от 0 до MAXFILES); у — идентификатор числовой или символьной переменной, указывает место расположения данных в оперативной памяти.
Рассмотрим возможные случаи.
VARPTR (*п).
Функция (8) имеет значением адрес X начального байта, с которого расположен в памяти FCBn (см. рис. 25).
Управляющаяинформация
Рис. 26
Рис. 27
128
Рис. 28Рис. 28Адреса -*■ х х+16)Адреса -*■ х х+16)Управляющая ।ЗначениеI
Рис. 28
Рис. 28
Адреса -*■ х х+1
6)
Адреса -*■ х х+1
6)
информация | значение|
. . .
Адреса-^х-3 х-2 х-1 х х*1
°)
Значение
. . .
VARPTR (у), у — строковая переменная.
В этом случае функция (8) имеет значением адрес X байта, находящегося на 3 позиции левее той, с которой располагается значение строковой переменной у. Схема размещения информации в памяти для простой строковой переменной изображена на рисунке 26, а для элемента строкового массива — на рисунке 27.
3)VARPTR (у), у — числовая переменная.
Здесь функция (8) имеет значением адрес того байта, начиная с которого располагается значение переменной у. Схема размещения информации в памяти для простой числовой переменной изображена на рисунке 28, а, а для элемента числового массива — на рисунке 28, б.
Функцию VARPTR можно использовать совместно с функциями РЕЕК (заглянуть) и РОКЕ (впихнуть) соответственно для просмотра или изменения на свой страх и риск содержимого любой области оперативной памяти.
ПРИМЕР 14
10 Y=VARPTR(#3)
70 V=VARPTR(L*>
PRINT VARPTR(X)
run-27512run-2751210 AX(3)=99:
run
-27512
run
-27512
20 PRINT VARPTR(A7. (3))
30 PRINT PEEK(VARPTR(AX(3>>)
5) 10
MAXFILES=2
40
Z=VARPTR(#2>
20
X=VARPTR(#0>
50
PRINT X,Y—X
30
Y=VARPTR(#1)
60
PRINT Y,Z-Y
Открытие файлов. Для работы с файлами данных, уже существующими на дисках или вновь организуемыми, необходимо произвести их открытие. Делается это командой
OPEN 0 AS [#] n [LEN = m](9)
где: OPEN (открыть), AS (как), LEN (length — длина) —служебные слова; 0— строковое выражение, задающее имя файла; n, m — арифметические выражения, целые части значений которых определяют соответственно номер контрольного буфера файла и длину его записей в байтах; # — необязательный символ, никоим образом нс влияющий на выполнение команды (9).
Величина INT(п) должна лежать в диапазоне от 0 до MAXFILES. INT(m) может принимать значения от 1 до 256. По умолчанию т = 256.
При выполнении команды OPEN файлу 0 назначается для работы контрольный буфер п. Кроме того, с диска в буфер заносится управляющая информация о файле (если 0 уже есть) или эта информация создается на диске (если 0 формируется заново). Вся эта процедура и называется открытием файла. Один файл 0 не может быть открыт сразу по нескольким контрольным буферам.
ПРИМЕР 15
10 OPEN 11 ФАК" AS #1
90 OPEN "клюква” AS #1 LEN=50
10 MAXFILES=2
20 OPEN "СТАРТ” AS #2
10 MAXFILES=5
20 OPEN "ФИНИШ” AS #3 LEN 100
Закрытие файлов. По команде
CLOSE [[#]nb [#]n2, [#]nzJ
где: CLOSE (закрыть) —служебное слово; П| п2, ..., гц— номера файловых контрольных буферов (FCB), организуется закрытие открытых по OPEN файлов данных, имеющих номера FCB:
П|, п2, ..., nk.
Последние должны быть в пределах от 1 до 15. При отсутствии параметров в поле CLOSE закрываются все открытые на данный момент файлы данных. Закрытый файл становится недоступным для чтения записей из него в оперативную память (GET) и для формирования новых или обновления уже имеющихся записей (PUT).
Заметим, что закрытие файлов организуется также по командам END, CLEAR, LOAD, MAXFILES = , NEW и при любом изменении текста программы. 130
ПРИМЕР 16
CLOSE
CLOSE #3
CLOSE 1,5,7
Поля буфера файла. Как мы уже отмечали, под каждый контрольный буфер файла отводится 265 байт, 256 из которых непосредственно предназначены для временного хранения записей файла (см. MAXFILES, OPEN). Перед началом непосредственной работы с буфером необходимо произвести его разбиение на отдельные поля для формирования в них конкретных значений по команде
FIELD [#]n, miASyi, ШгАЗуг, ... mkASyk (10)
где: FIELD (поле), AS (как) — служебные слова; п — арифметическое выражение, целая часть значения которого определяет номер буфера файла; ms (s = 1,2 k) — целые числа; ys (s = 1, 2,.... k) — строковые переменные.
При выполнении команды (10) производится задание формата записей. Это выражается в выделении каждому значению буферной переменной у5 поля из ms байт (s=l, 2, ..., к). Расположение этих полей показано на рисунке 29.
Отметим, что разрешается использовать несколько команд FIELD с разными форматами для одного и того же буфера п. Всегда действует то разбиение FCBn на поля, которое предложено последней выполненной командой FIELD.
ПРИМЕР 17
10 FIELD #5, 10ASLI», 20ASL2», 15ASL3»
100 MAXFILES=3
110 OPEN "STUDENT" AS #2 LEN=40
120 FIELD #2, 28ASM1», 12ASM2»
300 FIELD #2, 10ASM1», 5ASM2», 24ASK»
Рис. 29Рис. 29Управляющая информацияУправляющая информацияКоличество байтКоличество байт
Рис. 29
Рис. 29
Управляющая информация
Управляющая информация
Количество байт
Количество байт
Формирование строковых значений в буфере. Команда FIELD определяет формат записей файла и набор буферных переменных. Эти переменные не могут использоваться в предложениях LET, INPUT и LINE INPUT. При формировании в памяти конкретной записи с целью ее последующего сброса на диск значения переменным из FIELD присваиваются командами
LSET у = р (11)
RSET у = 0 (12)
где: LSET (le^t set — левое размещение), RSET (right set — правое размещение) — служебные слова; у — буферная переменная; Р— строковое выражение (Р#=у).
Пусть переменной у отведено в буфере поле из m байт. Выполнение команды (11) начинается с вычисления значения выражения р. Далее, если это необходимо, его длина приводится к величине m за счет отбрасывания лишних правых символов или добавления справа недостающего количества пробелов. Полученное значение присваивается у и размещается в соответствующем поле буфера файла.
Выполнение команды (12) проводится почти так же, как и команды (11). Разница состоит лишь в том, что при выравнивании значения р до длины m возможные недостающие пробелы добавляются к нему не справа, а слева.
ПРИМЕР 18
10 OPEN "ef" AS #1 LEN=9run
20 FIELD #1, 5ASMt, 4ASLt? TOP
30 INPUT RtzLSET Mt=Rt? ПАР
40 INPUT RtsRSET Lt=RtTOP
50 PRINT MtПАР
60 PRINT Ltrun
? КРАТЕР
? НЕБОСВОД
КРАТЕ
НЕБО
Команды LSET и PSET можно использовать не только при работе с файлами.
ПРИМЕР 19
10 Lt=SPACE$(20):Zt=”BOflK"
20 RSET L$=Z$:PRINT Lt
132
Формирование числовых значений в буфере. Буферные переменные являются строковыми. Пусть у — такая переменная и ей командой FIELD в FCBn отведено поле длины т. Если требуется «упаковать» в у числовое значение, то пользуются перечисленными ниже функциями.
а) МК1$ (а), где а — арифметическое выражение целого типа, m = 2; б) MKS$ (а), где а — арифметическое выражение одинарной точности, m = 4; в) MKD$ (а), где а — арифметическое выражение двойной точности, т = 8.
Каждая из этих функций преобразует значение арифметического выражения а к строковому типу. После этого командами LSET или RSET эти значения можно разместить в у и соответствующем поле буфера. В рассматриваемом случае LSET и RSET выполняются идентично.
ПРИМЕР 20
10 MAXFILES=5
20 OPEN "LU" AS #4
30 FIELD #4, 2ASAS, 4ASBS, SASES
50 INPUT XX: LSET AS=MKIS(X7.)
70 INPUT Y!:LSET BS=MKSS(Y1)
90 INPUT Z#:LSET ES=MKDS(Z#)
100 PRINT AS;" ";BS;“ ";ES
110 RSET AS=MKIS(X%)
120 RSET BS=MKSS(Y!)
130 RSET ES=MKDS(Z#)
140 PRINT AS;" ";BS;" ";ES
Получение числовых значений из буфера. Пусть в буфер с диска считана запись и в некотором ее поле, определенном в команде FIELD элементом mASy, «упаковано» числовое значение. Обратная его распаковка, или, по-другому, выборка из у этого значения реализуется одной из следующих функций.
СVI (у). При т = 2 и выборке значения целого типа.
CVS (у). При т = 4 и выборке значения одинарной точности.
CVD (у). При т = 8 и выборке значения двойной точности.
ПРИМЕРЫ 21
1> 100 PRINT CVI(AS),CVS(BS),CVD(CS)
10 OPEN "SL" AS #1 LEN=8
20 FIELD #1, 8ASRS
30 INPUTX:RSET R$=MKD»(X)run
40 PRINTR»,DVD(R»)7 123
'00123
10 INPUT X
20 PRINT CVD(MKD$(X)>
Сброс записей на диск, а) Для пересылки (сброса) сформированной в оперативной памяти записи на диск используется команда
,PUT[*]n[, р](13)
где: PUT (записать, разместить) — служебное слово; п, р — арифметические выражения, целые части значений которых задают соответственно номер контрольного буфера файла и номер записи.
До ыполнения команды (13) в оперативной памяти должен быть объявлен контрольный буфер файла FCBn (MAXFILES = ), открыт некоторый файл 0, связанный с FCBn (OPEN), задан формат его записей (FIELD) и, наконец, в FCBn создана сама запись (LSET, RSET). После всей этой процедуры по команде (13) содержимое FCBn будет выведено на диск под номером р, или, как говорят, будет сформирована новая или обновлена старая запись р файла 0.
Опишем выполнение (13) при отсутствии параметра р. Текущим значением р считается номер той записи, с которой работала последняя выполненная команда PUT или GET. При открытии файла р полагается равным 0. Далее, если в (13) р не указано, то берется его текущее значение, увеличенное на 1.
Напомним, что при создании записей числовые значения «упаковываются» в буферные переменные с помощью функций:
МК1$, МК8$ и MKD$.
ПРИМЕР 22
10 ’ 06”ЯВЛЕНИЕ FCB0, FCB1, FCB2 и FCB3
20 ’ ОТКРЫТИЕ ФАЙЛА "РЫБА" С БУФЕРОМ #2
30 MAXFILES=3:OPEN "РЫБА" AS #2 LEN=13
40 ’ ОПРЕДЕЛЕНИЕ ФОРМАТА ЗАПИСИ
50 FIELD #2, 8ASL$, 5ASM$
60 ’ ФОРМИРОВАНИЕ ПЕРВЫХ 10 ЗАПИСЕЙ
70 FOR К=1 ТО 10
80 INPUT "ХФ-8”;Х$:INPUT "Y$-5";Y»
90 LSET Le=X*:RSET M»=Y»:PUT #2, К
99 NEXT К:END
134
Пусть открыт некоторый файл данных 0, связанный с буфером FCBn. Полезную информацию о 0 можно извлечь с помощью функций LOF и LOC.
Функция LOF (п) имеет значением размер файла 0 в байтах.
Функция LOC (п) имеет значением номер текущей записи файла 0.
ПРИМЕРЫ 23
PRINT LOC(l)
10 X=L0F(3)
99 PRINT LOF(2)
Считывание записей с диска. Для считывания с диска в оперативную память записей файла данных используется команда
GET [*] п [, р](14)
где: GET (получить) — служебное слово; п, р — арифметические выражения, целые части значений которых задают соответственно номер контрольного буфера файла и номер записи.
До выполнения команды (14) необходимо объявить контрольный буфер FCBn (MAXFILES = ), открыть некоторый файл данных 0, связанный с FCBn (OPEN), и задать формат его записей (FIELD). После всей этой процедуры по команде (14) с диска в буфер #п будет считана запись с номером р. Фактически будут сформированы значения всех строковых переменных буфера (см. FIELD). Заметим, что числовые значения буферных переменных «распаковываются» с помощью функций: CVI, CVS и CVD.
Если в команде (14) р не указано, то берется текущее значение этого параметра, увеличенное на единицу (см. PUT).
В заключение этого пункта приведем пример, иллюстрирующий действие всех команд и функций при работе с дисковыми файлами данных прямого доступа.
ПРИМЕРЫ 24
10 ■' ФАЙЛЫ ДАННЫХ ПРЯМОГО ДОСТУПА ’
20 MAXFILES=5:PRINT VARPTR(#3)
30 OPEN "КАРАСЬ" AS #3 LEN=26
40 FIELD #3,8ASL*,4ASM$,2ASN^,5ASP»,7ASQ$
50 FOR K=1 TO 3:PRINT L0C(3)+l
60INPUT“Xдв. точность”;X:LSETL$=MKD$(X)
70INPUT"Yод. точность";Y:LSETM$=MKS*(Y>
75INPUT"Zцелое";Z:RSETN$=MKI$(Z>
80 INPUT "X* - 5
":X*:LSET P*=X*
90 INPUT "Y* - 7
";Y*:RSET Q*=Y«
100 PUT #3, к 110 NEXT К 115 print STRING*(34,"-”> 120 FOR K=3 TO 1 STEP -1 130 GET #3, К-.PRINT L0C(3) 140 PRINT CVD(L*);CVS(M*>;CVI(N*> 150 PRINT P*:PRINT Q* 160 NEXT:PRINT LOF(3):CLOSE #3 ’ run -9380
1 X дв. точность? 123E+45 Y од. точность? 123456 Z целое?32000
X* - 5?БОЧКА
Y* - 7?АЛГЕБРА
X дв. точность? 12345678901234 Y од. точность? 12 Z целое?123
X* - 5?ВОДА
Y* - 7?МЕД
X дв. точность? 1 Y од. точность? 156666666 Z целое?22
X* - 5?ПРОЛЕТАРИАТ
Y* - 7?ДИСКОВОД
1
156667000 22
ПРОЛЕ
ДИСКОВО
1234567890123412123
ВОДА
МЕД
1
1.23Е+47123456 32000
БОЧКА
АЛГЕБРА '
78
Файлы данных последовательного доступа. Файлы данных последовательного доступа состоят из отдельных групп значений, называемых логическими строками. Каждая строка имеет специальную концевую метку, а весь файл еще и метку EOF (конец файла). Строки рассматриваемых файлов не имеют номеров, и их можно считывать с диска в оперативную память или записывать из памяти на диск лишь последовательно друг за другом. Причем запись проводится от начала или конца файла, а чтение — только от его начала. Кроме того, любой конкретный файл открывается или только для чтения, или только для записи, но не для одновременного выполнения этих операций.
Для работы с файлами данных последовательного доступа в Бейсике предусмотрены следующие команды и функции.
MAXFILESMAXFILESVARPTROPEN • CLOSE , PRINT* PRINT*USINGINPUT*, 1LINE INPUT* JVARPTROPEN • CLOSE , PRINT* PRINT*USINGINPUT*, 1LINE INPUT* J— команда резервирования в оперативной памяти буферов для формирования или считывания строк файлов.
MAXFILES
MAXFILES
VARPTR
OPEN • CLOSE , PRINT* PRINT*USING
INPUT*, 1
LINE INPUT* J
VARPTR
OPEN • CLOSE , PRINT* PRINT*USING
INPUT*, 1
LINE INPUT* J
см. «Файлы данных прямого доступа».
— команды записи строк на диск.
— команды считывания строк с диска в оперативную память.
INPUTS
— функция, имеющая значением фиксированное количество очередных символов файла.
EOF
— булева функция, принимающая соответственно значения TRUE (истина) и FALSE (ложь) в зависимости от того, является ли очередной символ буфера меткой конца файла или нет.
LOF
— функция, указывающая размер файла в байтах.
LOG
— функция, имеющая значением текущее количество байт информации, считанных в буфер или записанных на диск.
Ниже приведены три схемы, определяющие последовательность операций, которые должны быть выполнены при перемещении строк файлов последовательного доступа из оперативной памяти на диск и в обратном направлении.
Общая схема формирования строк на диске от начала файла р.
. В оперативной памяти резервируется буфер (MAXFILES).
. Открывается новый или уже существующий файл р (OPEN с параметром OUTPUT).
. Формируется требуемое количество строк файла (PRINT#, PRINT * USING). На диск из буферов они сбрасываются автоматически.
. Файл р закрывается.
Общая схема пополнения файла р строками с его конца.
. Выполняется пункт а) схемы 1.
б,). Открывается уже существующий файл р (OPEN с параметром APPEND).
в,). Выполняются пункты в) и г) схемы 1.
Общая схема считывания строк с диска от начала файла р.
аг). Выполняется пункт а) схемы 1.
бг). Открывается уже существующий файл р (OPEN с параметром INPUT).
вг). Считывается требуемое количество строк файла (INPUT*, LINE INPUT*, INPUTS).
r2). Файл р закрывается.
Более подробно об упомянутых выше командах и функциях рассказывается в следующих пунктах. При их описании через п обозначается арифметическое выражение, целая часть значения которого определяет номер контрольного буфера файла (FCBn).
Открытие и закрытие файлов. Перемещение строк последовательных файлов из оперативной памяти на диск и в обратном направлении производится через контрольные буферы файлов. По- 138
следние объявляются командой MAXFILES (см. «Файлы данных прямого доступа»). Для работы с файлом он должен быть открыт.
Делается это командой
(INPUT
OPEN 0 FOR {OUTPUT} AS [#] n(15).
(APPEND J
где: OPEN (открыть), FOR (для), INPUT (ввод), OUTPUT (вывод), APPEND (присоединение), AS (как) — служебные слова; 0 — строковое выражение, задающее имя файла; п — номер контрольного буфера файла.
При выполнении команды (15) файлу 0 назначается для работы контрольный буфер п. Параметры INPUT, OUTPUT и APPEND указывают направление последующего движения информации относительно компьютера.
OPEN с параметром INPUT открывает файл для ввода строк с диска в буфер. Чтение будет организовано от начала файла.
OPEN с параметром OUTPUT открывает файл для вывода строк с буфера на диск. Запись осуществляется от начала файла.
OPEN с параметром APPEND открывает файл для вывода строк с буфера на диск. Запись будет производиться с конца файла.
ПРИМЕРЫ 25
10 MAXFILES=2
20 OPEN "МЕЛ" FORINPUT AS #2
100 OPEN "RISS" FOROUTPUT AS #1
200 OPEN "CAT" FORAPPEND AS #1
Закрытие файлов производится командой CLOSE.
Запись строк на диск. Для формирования строк последовательного файла используются команды PRINT# и PRINT#USING. А. Команда PRINT# записывается в виде
PRINT # n, s^ ; |(16)
где: PRINT (печатать, вывести) — служебное слово; п — номер буфера файла; s — список арифметических и (или) строковых выражений: 71, у2, Чк-
При выполнении команды (16) значения у; (/ = 1,2,..., к) последовательно байт за байтом выводятся в буфер почти так же, как это делается командой PRINT при индикации ys на экране. Разница состоит лишь в трактовке зонного формата. Здесь он понимается так. Если между двумя выражениями из S в команде (16) разделителем является запятая, то при выводе в буфер соответствующих значений между ними вставляется 14 дополнительных пробелов.
В том случае, когда последним символом в (16) является пробел, реализация этой команды приводит к формированию полной строки вместе с меткой ее окончания. Иначе создается лишь часть строки, а завершается ее формирование или последующими командами PRINT#, или закрытием файла. В любом варианте длина строки вместе с концевой меткой не может превысить 256 байт, а данные выводятся на диск в формате ASCII и только тогда, когда заполняется буфер или закрывается файл.
Для экономного размещения данных на диске и избежания ошибок при их считывании целесообразно S в PRINT# записывать в виде
Yi; ". ";"; vk { V }
В этом случае значения в создаваемой строке располагаются в плотном формате и отделяются друг от друга запятыми. Далее, если значение конкретного строкового выражения у, содержит символы ", " и "; ", то в качестве разделителей можно использовать кавычки, задаваемые с помощью кода CHR$ (34):
CHR$ (34) у; CHR$ (34)
Пример 26.
Открывается новый или ранее созданный файл «Щука» для вывода в него строк от начала и далее. Командой 50 в буфере формируется одна строка.
20 OPEN "ЩУКА" FOR OUTPUT AS #1
30 А=5: В$= "ТРАВА":0=83.157
50 PRINT #1,А;",";В$;",";С
Открывается ранее созданный файл «Щука» для вывода в него строк от конца. Затем по команде 60 формируются очередные строки файла. По мере заполнения буфера данные выводятся на диск, а за последней строкой ставится метка EOF окончания файла.
20 OPEN "ЩУКА" FORAPPEND AS #1
30 INPUT "A= ";A
40 INPUT "B$= ";B$
50 INPUT "0= ";C
60 PRINT #1,A;",";B$;",";C
70 IF CO0 THEN 30 ELSE CLOSE
Открывается новый или ранее созданный файл «Карась» для вывода в него строк от начала и далее. Двумя командами 40 и 50 формируется одна строка.
140
10 CLEAR 1000;MAXFILES=2 20 OPEN "КАРАСЬ” FOROUTPUT AS #2 30 A»="FL0PPYDISK":E=45:F=54.8 40 PRINT #2, A»;","; 50 PRINT #2, E;",";F
В файл «Карп» от его начала с пульта вводится S элементов числового массива. Длина создаваемых строк, кроме, возможно, последней, равна 256 байт.
10 MAXFILES=5 20 OPEN "КАРП" FOROUTPUT AS #4 30 INPUT "количество элементов ";S 40 FOR K=1 TO S:INPUT M
50 PRINT #4,M;",";
60 NEXT К
При формировании строки в качестве разделителей используются кавычки, задаваемые кодом CHR$ (34).
20 OPEN "САЗАН” FOROUTPUT AS #1 30 R=123.789:K$="KRA,,N;W2" 40 I*=CHR*(34)
50 PRINT #1, R; ",";1$;KS;IS
Команда PRINT#USING записывается в виде PRINT#n,USING t, S(17)
где: PRINT, USING — служебные слова; t — строковое выражение, определяющее формат (шаблон) вывода; n, S — параметры, имеющие тот же смысл, что и в PRINT#.
При выполнении (17) значения выражений у, (1=1, 2, ..., к) выводятся в соответствии с форматом t в буфер точно так же, как это делается командой PRINTUSING при выводе ys на экран.
ПРИМЕР 27 10 CLEAR 1000:MAXFILES=5:DIM М<200) 20 OPEN "ЛЕЩ" FOROUTPUT AS #4 30 INPUT "количество элементов ";S 40 FOR K=i TO S:X=INT(RND(1)X3000)/99 50 PRINT #4, USING "###.##";X; 60 NEXT K:CLOSE #4
Пусть открыт файл р, связанный с буфером FCBn.
Как и для файлов прямого доступа, здесь LOF (п) имеет значением размер файла р в байтах.
Функция LOG (п) для файлов последовательного доступа имеет значением текущее количество байт информации, считанных в буфер или записанных на диск.
Чтение строк с диска. Для чтения строк последовательного файла с диска в оперативную память используются команды INPUT*, LINE INPUT* и функции INPUTS и EOF.
По команде
LINE INPUT*n, у
где: LINE (строка), INPUT (ввод) —служебные слова; п — номер буфера файла; у — строковая переменная, считывается очередная строка файла р, связанного с буфером п, и присваивается переменной у.
ПРИМЕРЫ 28
10 LINE INPUT #1, L»
10 CLEAR 2000:MAXFILFS=2
20 OPEN "ЛЕС” FORINPUT AS #2
30 LINE INPUT #2, M$
10 CLEAR 1000sMAXFILES=5:DIM MC200)
20 OPEN "LINP" FOROUTPUT AS #4
30 INPUT "количество элементов ";S
40 FOR K=1 TO S
50 PRINT #4,K;","$:PRINT LOC(4);
60 NEXT K;CLOSE #4
70 OPEN "LINP" FORINPUT AS #4
80 PRINT:PRINT LOF(4)
90 LINE INPUT #4, Me
100 PRINT LOC(4>,:PRINT Me
110 IF NOT EOF(4) THEN 90
120 PRINT LOF(4):CLOSE #4
Обратите внимание на организацию завершения чтения строк в примере 28(3) по функции EOF (4).
В общем случае булева функция EOF (п) принимает значение TRUE (истина) или FALSE (ложь) в зависимости от того, является очередной символ буфера меткой конца файла или нет.
1 л<>
Команда INPUT # записывается в виде
(18)(18)INPUT*n, S
(18)
(18)
где: INPUT (ввод) — служебное слово; п — номер буфера файла; S — список переменных.
Опишем, как происходит выполнение команды (18). Если очередная считываемая строка файла состоит из значений а,, «2, .„, ак, то в соответствующей команде INPUT# список S должен иметь вид: |Ii, Рг, .... Рк, а каждая переменная 0j обязана быть того же типа, что и си (i = 1, 2,..., к). В этом случае реализация команды (18) приводит к присваиваниям переменным р( значений а, (i — 1, 2, ..., к). ПРИМЕР 29 10 CLEAR 1000:MAXFILES=5:DIM М<200) 20 OPEN "ШАР" FOROUTPUT AS #4 30 INPUT "количество элементов ";S 40 FOR K=1 TO S 50 X=RND(1):Y=RND<1> 60 Xt=CHRt(INT(RND( DM31)+224) 70 Y$=CHR$(INT(RNDC1)М31)+224> 80 PRINT #4, Xt+Yt;",";X;",";Y; 90 NEXT K:CLOSE #4 100 OPEN "ШАР" FORINPUT AS #4 110 INPUT #4, Mt,A,В 120 PRINT Mt;A;В 130 IF NOT EOF(4) THEN 110 140 CLOSE #4 run
количество элементов ? 5
ВЯ .59521943994623.10658628050158
КЩ .73474759503023.18426812909758
ЫО .63799556899423.47041117641358
OB .18586284343823.12951037284958
ТМ .02818381196223.48775999680558
Заметим, что строка НО в этом примере могла бы быть заменена на один из фрагментов:
a) 110 INPUT #4, MS 6) 110 INPUT #4, MS
111 INPUT #4, A,В 111 INpUT #4, A
112 INPUT #4, В
С. Для чтения очередного фиксированного количества символов (байт) с файла без учета его разбиения на строки используется функция:
INPUTS (m, #n)(19)
где: INPUTS — служебное слово; m — арифметическое выражение, такое, что mo = INT (m) лежит в пределах от 1 до 255; п —номер буфера файла.
В любой момент работы с файлом функция INPUTS «читает» то его очередных символов. Иными словами, последовательность этих символов становится ее значением. При этом метки окончания строк воспринимаются так же, как и любые другие знаки. Для полного уяснения семантики функции INPUTS рекомендуется «прогнать» следующий пример при различных значениях параметров S и х.
ПРИМЕР 30
10 CLEAR 1000:MAXFILES=5:DIM М(200>
20 OPEN "TOP" FOROUTPUT AS #4
30 INPUT "количество элементов ";S
40 FOR K=1 TO S
50 PRINT #4, "L";",";"W";","
60 NEXT K:CLOSE #4
70 OPEN "TOP" FORINPUT AS #4
80 INPUT "длина значения в INPUTS";X
90 Y=(LOF(4)—1)\X:Z=(LOF(4)—1)MDDX
100 IF Y=0 THEN 150
110 FOR K=1 TO Y
120 XS=INPUTS(X,#4):PRINT X»
130 NEXT К
140 IF Z=0 THEN 160
150 PRINT INPUTS(Z,#4)
160 CLOSE #4
144
Чтение программных файлов. Отдельные сегменты программных файлов — это специфические файлы данных последовательного доступа. Поэтому программы или их фрагменты можно загружать в память как данные. Ограничимся здесь двумя примерами. ПРИМЕР 31 10 * ЧТЕНИЕ ПРОГРАММНОГО ФАЙЛА 20 OPEN “СИМПСОН" FORINPUT AS #1 30 LINE INPUT #1, R»:PRINT R$ 40 FOR K=1 TO 1000:NEXT 50 IF NOT EOF(l) THEN 30 60 CLOSE
Выполнение этого фрагмента приводит к считыванию и индикации всех строк программы «Симпсон» (см. 4.1).
ПРИМЕР 32 10 ’ ЧТЕНИЕ ДИАПАЗОНА СТРОК 20 OPEN "СИМПСОН" FORINPUT AS #1 30 LINE INPUT #1. R$ 40 X$=MID$(R»,1,2) 50 IF XX"30" OR X$>"70" THEN 80 60 PRINT R$ 70 FOR K=1 TO 1000:NEXT 80 IF NOT EOF(l) THEN 30 90 CLOSE
Выполнение данного фрагмента дает возможность «просмотреть» в той же самой программе «Симпсон» строки с номерами от 30 и до 70.
Файлы на магнитной ленте
Вывод программных файлов и файлов данных из оперативной памяти на магнитную ленту и обратное их считывание с ленты в память реализуется через магнитофон. Для идентификации файлам присваиваются имена, конструируемые из символов алфавита языка. Длина имени не может превосходить 6 (SAVE, CSATE) или 11 (BSAVE). Уникальность имен не обязательна.
Работа с магнитофоном может быть организована в рамках любой, в том числе и нерасширенной, версии Бейсика. Для этих Целей предусмотрены следующие команды и функции.
SAVELOADMERGERUNCSAVECLOADBSAVEBLOADOPENCLOSE MAXFILESEOFPRINT# PRINT*USING INPUT# LINEINPUT# INPUTSSAVELOADMERGERUNCSAVECLOADBSAVEBLOADOPENCLOSE MAXFILESEOFPRINT# PRINT*USING INPUT# LINEINPUT# INPUTS
SAVE
LOAD
MERGE
RUN
CSAVE
CLOAD
BSAVE
BLOAD
OPEN
CLOSE MAXFILES
EOF
PRINT# PRINT*USING INPUT# LINEINPUT# INPUTS
SAVE
LOAD
MERGE
RUN
CSAVE
CLOAD
BSAVE
BLOAD
OPEN
CLOSE MAXFILES
EOF
PRINT# PRINT*USING INPUT# LINEINPUT# INPUTS
— команда записи в формате ASCII программ из оперативной памяти на магнитную ленту.
— команда чтения (загрузки) в оперативную память программ, записанных на магнитной ленте в формате ASCII.
— команда подгрузки (слияния) в память программ, записанных на ленте в формате ASCII.
— команда загрузки в память программ, записанных на ленте в формате ASCII, с автоматическим запуском их на счет.
— команда записи программы на Бейсике из оперативной памяти на ленту во внутреннем формате.
— команда чтения (верификации) в оперативную память Бейсик-программы, записанной на ленте во внутреннем формате.
— команда записи машинных кодов (программы или данные) из оперативной памяти на ленту.
— команда считывания модуля в машинных кодах (программы или данные) с ленты в оперативную память.
— команды и функции для работы с файлами данных последовательного доступа (см. «Файлы данных последовательного доступа»).
Приступим к краткому описанию синтаксиса и семантики упомянутых выше средств организации файлов на магнитной ленте и работы с ними.
Запись и чтение программ в формате ASCII. В этом пункте описаны команды SAVE, LOAD, MERGE и RUN.
По команде SAVE а, где а — строковое выражение, программа из оперативной памяти записывается в формате ASCII на магнитную ленту. Имя программы формируется из первых 6 симво- 146
лов значения а. Оно может начинаться фрагментом CAS:, который в этом случае рассматривается как имя устройства и не учитывается при подсчете длины а.
ПРИМЕР 33
1) SAVE "ГРИБЫ" 2) SAVE. "CAS:СОСНА"
Выполнение команды LOADa [, R] начинается с закрытия всех файлов и «чистки» оперативной памяти от программ и данных. Далее, программа, записанная на ленте в формате ASCII под именем, равным значению строкового выражения а, считывается в память. Наличие параметра R приводит к автоматическому запуску загруженной программы на счет.
Поиск конкретной программы на ленте сопровождается индикацией сообщений о всех «попавшихся» при этом других файлах, записанных в формате ASCII.
ПРИМЕР 34
LOAD "prim3"Skip :prim2
Skip :primlFound:prim3
Сообщения выводятся на экран (skip — перескочить, find — находить) .
Команда LOAD "CAS:" [, R] считывает в память первую встреченную на ленте в формате ASCII программу.
ПРИМЕР 35
LOAD "ФРУКТ"3) LOAD "CAS:"
LOAD “CAS:LUX",R
С. При выполнении команды MERGE a закрываются все файлы и организуется чистка оперативной памяти от данных. Далее, программа, записанная на ленте в формате ASCII под именем, равным значению строкового выражения а, сливается с программой 0, находящейся в памяти. При этом если в а и 0 совпадают некоторые номера строк, то сохраняются лишь соответствующие строки загружаемой программы а. Выдача сообщений на экране при поиске a здесь такая же, как и в случае с LOAD.
Команда MERGE "CAS:" подгружает в память первую встреченную на ленте в формате ASCII программу.
ПРИМЕР 36
MERGE "ТТТ” 3) MERGE "CAS:ALPHA"
MERGE "CAS:"
D. При выполнении команды RUN a прежде всего оперативная память очищается от программ и значений переменных. Открытые файлы не закрываются. Далее, программа, записанная на ленте в
147
формате ASCII под именем, равным значению строкового выражения а, загружается в память и автоматически запускается на счет. Выдача сообщений на экране при поиске а здесь такая же, как и в случае с LOAD.
ПРИМЕРЫ 37
1) RUN "NET" 2) 110 RUN "CAS:LF"
RUN X$ ’ X$ определено ранее
Запись и чтение программ во внутреннем представлении.
А. По команде CSAVE а, V, где а — строковое, a V — арифметическое выражение, программа из оперативной памяти во внутреннем представлении записывается на ленту под именем, равным значению а. V определяет скорость передачи информации (V=l— 1200 бод, V = 2—2400 бод). Впрочем, этот параметр может быть задан и в команде SCREEN.
ПРИМЕРЫ 38
1) CSAVE "ЛИСТ",22) CSAVE "ВЕРБА",1
А$="КЛЕН":CSAVE А$,2
По команде CLOAD а производится «чистка» оперативной памяти и загрузка в нее программы, записанной на ленте во внутреннем представлении под именем, равным значению строкового выражения а. Поиск а сопровождается индикацией на экране сообщений об именах всех «попавшихся» при этом файлов (см. LOAD).
ПРИМЕР 39
CLOAD "ТОРТ"
Skip :80008
Found:ТОРТ
С. По команде CLOAD ? а отыскивается программа, записанная на ленте во внутреннем представлении под именем, равным значению строкового выражения а, и побайтно сравнивается с программой, находящейся в данный момент в оперативной памяти. При идентичности сравниваемых текстов компьютер выходит в режим Ок. В противном случае получается сообщение
VERIFY ERROR (ошибка верификации)
ПРИМЕР 40
CLOAD? "СЛОВО"FOUND:СЛОВО
Skip :1Verify error
Skip :2
148
Команды BSAVE и BLOAD.
А. По команде BSAVE a, Pi, Р2, [, Рз], где: а — строковое выражение; Рь Рг, Рз — арифметические выражения, значения которых задают адреса, содержимое оперативной памяти от Pi до Рг в машинных кодах записывается на ленту под именем, равным значению строкового выражения а. Рз определяет адрес, с которого программа при загрузке ее в память будет запускаться на счет. По умолчанию Рз = Рь
ПРИМЕР 41
BSAVE "CAS: ГОСТ" , 8<HF000, &HF0EE
BSAVE "CAS:"+P$,A,B,C
По команде BLOAD a [, R] [,o], где: a — строковое выражение; R —- параметр; о — арифметическое выражение, в оперативную память загружается файл, записанный на ленте в машинных кодах под именем, равным значению а. При наличии параметра R прочитанная программа автоматически запускается на счет. Значение параметра о должно быть целым. Оно определяет величину смещения адресов Pi, Р2 и р3 загрузки и запуска (см. BSAVE). По умолчанию о = 0.
ПРИМЕР 42
1) BLOAD "CAS:DD"
2> BLOAD "CAS:LEW",&Н1500
BLOAD "CAS:TEST",R
BLOAD "CAS:",R
Замечание. Команды BSAVE и BLOAD можно применять и для работы с произвольными дисковыми файлами.
Работа с файлами данных последовательного доступа. В разделе 4.2 перечислены команды и функции, используемые для работы с файлами данных последовательного доступа. Все эти средства подробно там описаны. Несколько иной синтаксис для данного случая имеет лишь команда OPEN — открытия файлов:
(INPUT )
OPEN р FOR I оитрит) AS*n
Здесь р должно начинаться с символов "CAS:" и, кроме того, отсутствует возможность, предоставляемая параметром APPEND Для «наращивания» файлов.
ПРИМЕР 43
OPEN "CAS:AL” FOROUTPUT AS #1
20 FOR K=1 TO 500:PRINT #1, K;
30 NEXT:CLOSE #1
40 STOP
50 CLEAR 1000
60 OPEN "CAS:AL" FORINPUT AS #1
70 LINE INPUT #1,M$:PRINT M*
80 IF NOT EOF(l) THEN 70
90 END
Здесь строки 10—30 создают файл данных на магнитной ленте. Для его считывания в память требуется запустить этот фрагмент со строки 50.
Вывод файлов данных на экраны и принтер
Текстовые экраны 0 и 1, графические экраны 2 и 3, а также принтер в рамках любой, в том числе и нерасширенной (недисковой), версии Бейсика могут быть объявлены устройствами вывода файлов последовательного доступа (см. 4.2). Открытие таких файлов осуществляется командой
/"CRT:" ч
OPEN J "GRP:" I FOR OUTPUT AS [#] n (1).
I "LPT:" J
где: OPEN (открыть), FOR (для), OUTPUT (вывод), AS (как) — служебные слова; n — арифметическое выражение, целая часть значения которого определяет номер буфера файла; CRT, GRP, LPT — имена устройств.
При выполнении (1) в качестве устройства вывода файлов назначаются: текстовые экраны (CRT), графические экраны (GRP) или принтер (LPT). Вывод строк в любом случае осуществляется командами PRINT# и PRINT#USING (см. 4.2).
Пример 44.
Текст на графическом экране 2.
10 COLOR 1,11,7:SCREEN 2
20 OPEN "GRP:" FOROUTPUT AS #1
30 PSET (69,80)
40 PRINT #1, "РИС. 9.1 ЦВЕТА"
50 GOTO 50
150
Текст на графическом экране 3.
10 COLOR 1,11,7:SCREEN 3
20 OPEN "GRP:" FOROUTPUT AS #1
30 PSET (50,80)
40 PRINT #1, "БУКВЫ"
50 GOTO 50
Программа «777», записанная на диске в формате ASCII, выводится на графический экран 2.
10 COLOR 1,15,8:SCREEN 2
20 PSET (0,10),15:MAXFILES=2
30 OPEN "GRP:" FOROUTPUT AS #1
40 OPEN "777" FORINPUT AS #2
50 LINE INPUT #2, R$
60 PRINT #1, R»
70 FOR K=1 TO 1000:NEXT
80 IF NOT EOF(2) THEN 50
90 CLOSE:GOTO 90
Файл данных последовательного доступа, записанный на диске под именем «КАРП», выводится на принтер.
10 MAXFILES=2
20 OPEN "КАРП" FORINPUT AS #1
30 OPEN "LPT:" FOROUTPUT AS #2
40 INPUT #1, M:PRINT #2, M;
50 IF NOT EOF(l) THEN 40
Локальная вычислительная сеть
Между компьютерами «Ямаха», соединенными линиями передачи данных в локальную вычислительную сеть, возможен обмен информацией. Один из компьютеров сети получает статус «учительский» (головной), а остальные — «студенческий» (периферийный). Количество последних не должно превосходить 15. Взаимодействие между компьютерами сети сводится к нерегулярному обмену файлами между ними, а в остальном машины независимы. Поэтому рассматриваемую локальную сеть можно отнести к полностью распределенной системе.
Везде ниже при описании процедур передачи программ и данных по сети используются такие обозначения: Т — учительский компьютер; S — студенческий компьютер.
Для идентификации за Т закрепляется номер 0, а за S — номера: 1, 2, 3, ... . Определить номер конкретного компьютера можно по команде-запросу CALL WHO.
Пересылка файлов от головного компьютера (Г) к периферий» ным (8). При всех операциях, связанных с пересылкой программ и данных из Г в 8, информация пользователя в оперативной памяти учительского компьютера Т нс изменяется.
Загрузка программ из Т в 8.
На студенческих компьютерах 8, в которые необходимо загрузить программу из Т, нажатием клавиши F8 выполняем команду
LOAD "СОМ:" (клавиша F8)
Это приводит к чистке оперативной памяти соответствующих 8 и настраивает их на прием программы из Т.
На учительском компьютере Г, откуда пересылается программа, нажатием клавиши F7 выполняем команду
SAVE "СОМ:" (клавиша F7)
После этой процедуры происходит пересылка текущей программы из оперативной памяти компьютера Т в те 8, которые в данный момент находились в состоянии LOAD "СОМ:". Завершается пересылка выходом Г и 8 в режим Ок.
Загрузка программы из Т в 8 с запуском.
А1. На компьютерах 8, в которые необходимо загрузить программу из Т, нажатием клавиши F6 выполняем команду
RUN "СОМ:" (клавиша F6)
Это приводит к чистке оперативной памяти соответствующих 8 и настраивает их на прием программы из Т.
Выполняем пункт В (загрузка из Т в 8).
В результате этих действий происходит пересылка текущей программы из оперативной памяти компьютера Т в те 8, которые находятся в режиме RUN "СОМ:". Загруженные в 8 программы автоматически запускаются на счет.
Подгрузка программы из Т в 8.
А2. На всех студенческих компьютерах 8, в которые необходимо «подгрузить» программу из Т, нажатием клавиши F9 выполняем команду
MERGE "СОМ:" (клавиша F9)
Выполняем пункт В (загрузка из Т в 8).
Эти действия приводят к «подгрузке» текущей программы а из Г к соответствующим программам р тех 8, которые находятся в ре- 152
^име MERGE "СОМ:". Термин «подгрузка» означает такое слияние а и р, при котором в памяти S создастся новая программа из а и тех строк 0, номера которых не совпадают ни с одним из номеров строк ос.
Селективная загрузка программ из Т в S. Из учительского компьютера Т можно пересылать программу а не только сразу во вСС S, находящиеся в состоянии RUN "СОМ:", но и выборочно в некоторые такие S. Подобная селективная загрузка реализуется разными способами. Опишем один из них.
АЗ. Пусть пересылаемая из Т программа а начинается со строки п (п^6\ «Надстроим» ее вспомогательным фрагментом (строки 1—7 примера 45), где в команде DATA укажем сначала общее количество S, а затем номера тех S, которые должны получить а.
ПРИМЕР 45
1 DATA 3, 1,3,4
READ X
FOR К=1 ТО X:READ Y
IF Y=INF(2)AND15 THEN 7
NEXT
RUN "COM:”
DELETE 1-7
10 "PROGRAMMA
20 ?
Выполняем на T команду
SAVE "СОМ:" (клавиша F7)
После этой процедуры происходит следующее. Программа а пересылается во все S, находящиеся в состоянии RUN "СОМ:", и запускается на счет. Далее, если номер конкретного компьютера S присутствует в списке DATA, то фрагмент 1—7 организует чистку самого себя и выводит S в режим Ок. В противном случае, то есть когда номер S отсутствует в DATA, этот фрагмент производит чистку всей памяти, переводя S в состояние RUN "СОМ:". В результате этих операций программа а оказывается загруженной только в требуемые компьютеры.
Пересылка данных из Т в S. Программам 0, запущенным на счет на студенческих компьютерах S, можно передавать из Т значения простых переменных и элементов массивов. Проиллюстрируем На примерах один из возможных способов подобной пересылки данных.
А4. На всех студенческих компьютерах S, куда будут передаваться данные из Т, должна быть запущена подпрограмма (фрагмент), в которой:
объявлены массивы для приема значений;
открыт файл данных последовательного доступа "СОМ:" с параметром INPUT;
организовано чтение строк из Г в S.
ПРИМЕР 46
100 GOSUB 1000
1000 DIM А(30>,В$(30)
1010 OPEN "COM:" FORINPUT AS #1
1020 FOR К=1 TO 30
1030 INPUT #1, A(K),B$(K)
1040 PRINT A(K),B$(K)
1050 NEXT:CLOSE #1:RETURN
На учительском компьютере T, откуда будут передаваться данные в S, должен быть запущен фрагмент, в котором:
открыт файл данных последовательного доступа "СОМ:" с параметром OUTPUT;
организована пересылка строк из Г в S.
ПРИМЕР 47 (соответствует примеру 46)
2000 OPEN "СОМ:" FOROUTPUT AS #1
2010 FOR К=1 ТО 30
2020 PRINT #1, К+100;",";"ABS"
2030 PRINT К+100;"ABS"
2040 NEXT:END
Эти действия приводят к загрузке данных из Г в те S, которые находились в состоянии INPUT* (LINE INPUT*, INPUTS). После завершения этой процедуры программы в S продолжат свою работу.
Пересылка программы и данных из Т в S. Ограничимся здесь конкретными примерами. Пусть требуется переслать в S из оперативной памяти Т программу а и с диска — элементы массива Ak (k = 1, 2,..., 500), организованные там в виде файла последовательного доступа с именем "MAS".
154
А5. Будем считать, что наименьший номер строк программы — 10. «Надстроим» ее следующим вспомогательным фрагментом (строки 1—9 примера 48).
ПРИМЕР 48
1 DIM А(500):OPEN "COM:" FORINPUT AS #1
2 FOR К=1 TO 500:INPUT #1, A(K)
PRINT A(K);
NEXT:CLOSE #1:GOTO 10
r- MAXFILES=2: OPEN "MAS" FORINPUT AS #2
OPEN "COM:" FOROUTPUr AS #1
FOR 1=1 TO 500:INPUT #2, MiPRINT #1, M;
S PRINT M;
NEXT:END
’ ПРОГРАММА
На всех студенческих компьютерах S, куда будут пересылаться программа и данные, выполним команду
RUN "СОМ:" (клавиша F6)
Это приводит к чистке оперативной памяти соответствующих S и настраивает их на прием программы из Т.
С5. На учительском компьютере Т выполняем команду
SAVE "СОМ:" (клавиша F7)
В результате реализации этих действий в те S, которые находились в состоянии RUN "СОМ:", загружается и запускается на счет программа, а Т выходит в режим Ок.
D5. Для пересылки данных с диска в S выполняем на Т команду RUN .5.
Набор RUN 5 необходимо осуществлять по отдельным символам (RUN на спецклавише реализован вместе с кодом запуска CHRS (13)).
После «перекачки» данных программа S будет продолжать работу со строки 10.
Заметим, что предложенный способ организации передачи программы и данных удобен тем, что сводит.к минимуму действия, которые должны быть осуществлены за пультом студенческих компьютеров. Фактически на них требуется лишь нажать клавиши F6.
155
Однако следует иметь в виду, что в программах, загруженных в S, будет содержаться фрагмент из строк 1—9, являющийся для них «мусором».
Режим пояснений. С клавиатуры учительского компьютера Т на экранах S можно набирать различного рода сообщения, пояснения, тексты программ и т. д. Делается это так.
Аб. На студенческих компьютерах S, с которыми будет проводиться общение, набираем команду (клавиша F10)
comterm(1)
(в записи (1) символ "—м (подчеркивание) является обозначением для слова call (вызывать).
На Т выполняем ту же самую команду (1).
После этого нажатие на клавиатуре Т любой клавиши приводит к индикации соответствующего символа или выполнению надлежащего действия на экранах всех S, находящихся в режиме "comterm". При этом собственный экран Т оказывается заблокированным. Поэтому следить за правильностью сообщений учителю приходится по экрану какого-либо соседнего компьютера S.
Отмстим следующее немаловажное обстоятельство. Вся информация из Г в S поступает в так называемую видеопамять, а в оперативной памяти не запоминается.
Пересылка файлов от периферийного компьютера к головному. Все операции по пересылке программ и данных из конкретного студенческого компьютера S в учительский Т осуществляются точно так же, как и в обратном направлении. Лишь по отношению к действиям пользователей Т и S меняются ролями. При этом следует учитывать, что при любых пересылках из S в Т содержимое оперативной памяти S нс меняется, а попытки организовать передачу информации одновременно из нескольких $ в Г приводят к сбоям.
В заключение отметим, что за движением информации по сети можно «наблюдать» на экране дисплея любого компьютера S. Для этого его необходимо перевести в соответствующий режим, выполнив команду
comterm (клавиша F10)
БЕЙСИК MSX-2
По сравнению с Бейсик-системой MSX-1 ее дальнейшее развитие, Бейсик-система MSX-2 (версия 2.1), реализованная на компьютерах «Ямаха» MSX-2, предоставляет пользователю ряд интересных дополнительных возможностей. Стало больше доступных режимов видеопроцессора (экраны 0—8), расширен объем ОЗУ и за счет этого организована работа с виртуальным диском, появились средства для 156
начальной инициализации ряда параметров, изменились принципы функционирования локальной вычислительной сети. На этих и других вопросах и будет сосредоточено внимание в этом разделе.
Экраны
Основные характеристики. Каждый из 9 имеющихся режимов видеопроцессора будем именовать «экраном» с добавлением после этого цифры от 0 до 8. Основные характеристики экранов приведены в таблицах 24—25. Там использованы такие обозначения: Т — текст (текстовой), Г — графика (графический), S — спрайты, SC — цветные спрайты.
При включении компьютера по умолчанию устанавливается один из текстовых режимов SCREEN 0 или SCREEN 1. Для его изменения необходимо в непосредственном счете или программном режиме выполнить оператор SCREEN N, где значениями арифметического выражения N должны быть числа 0, 1,2, ..., 8.
Таблица 24
Основные характеристики экранов
№ экрана
MSX-1
MSX-2
Тип экрана
Разрешающая способность
Возможности вывода
0
1, 2
т
240X192
т
1
1, 2
т
256X192
T S
2
1, 2
Г
256X192
т, Г, S
3
1, 2
Г
64X48
Т, Г, S
4
2
Г
256X192
T, Г, S, SC
5
2
Г
256X212
T, Г, S, SC
6
2
г
512X212
T, Г, S, SC
7
2
г
512X212
т, Г, S, SC
8
2
г
256X212
т, Г, S, SC
Таблица 25
№ экрана
Номер цвета
Палитра
Изображение
Фон
Бордюр
0
0—15
0—15
+
1
0-15
0—15
0—15
+
2
0-15
0-15 (CLS)
0—15
+
3
0-15
0-15 (CLS)
0-15
+
4
0—15
0-15 (CLS)
0—15
+
5
0-15
0—15 (CLS)
0—15
+
6
0—31
0—31 (CLS)
0—31
+ (4)
7
0-15
0—15 (CLS)
0—15
+
8
0-255
0—255 (CLS)
0—255
—
Таблица 26
№ экрана
Матрица символов
Количество символов в строке
Многоцветные тексты
Стирание символов пробелом
Номер страницы
0
6X8
40, 80
—
4-
1
8X8
32
4-
4-
—
2
8X8
32 ("GRP:")
4-
—
—
3
8X8
8 ("GRP:")
4-
—
—
4
8X8
32 ("GRP:")
4-
—
—
5
8X8
32 ("GRP:")
4-
4-
0, 1,2,3
6
8X8
64 ("GRP:")
4-
4-
0, 1,2,3
7
8X8
64 ("GRP:")
4-
4-
0, 1
8
8X8
32 ("GRP:")
4-
4-
0, 1
Цвет изображения (И), фона (Ф) и бордюра (Б) задается one ратором
COLOR И, Ф, Б
Допустимые значения выражений И, Ф и Б приведены в колонках 2—4 таблицы 25. Из них видно, что цвет бордюра для экрана О не определяется. Он всегда совпадает с цветом фона. Далее, начиная с экрана 2 и выше, цвет фона непосредственно по оператору COLOR И, Ф, Б не изменяется. Это происходит лишь после переназначения экрана или выполнения оператора CLS. Для графических экранов 2—8 вывод текстов возможен только после назначения "GRP:" в качестве устройства вывода. В примере 1 предполагается, что вначале цвета установлены стандартным образом по COLOR 15, 4, 4.
ПРИМЕР 1
10 SCREEN 5:COLOR 15,12,4
20 OPEN "ERPs" AS #1
30 PSET (70,80),4:PRINT#1,"COLOR до CLS"
40 R$=INPUT$(1):CLS
50 PSET (58,80),12sPRINT#1,"COLOR после CLS"
Отметим также следующие обстоятельства.
В MSX-2 для экрана 0 максимальная длина строки, назначаемая оператором WIDTH, равна 80.
Для экрана 1 возможен вывод спрайтов, но отсутствует графика.
Для экрана 3 «точки» задаются блоками 4X4. Этим и объясняется его малая разрешающая способность.
Для экранов 2—8 вывод текстовой информации возможен с любой позиции графического курсора.
Для экранов 2—4 нельзя «чистить» текст пробелами.
Цветные спрайты реализованы только на экранах 4—8.
Для экранов 1—3 и 4—8 на одной горизонтальной линии могут находиться соответственно до 4 и до 8 спрайтов одно- временно.
Экран 6 допускает всего лишь 4 различных цвета.
С экранами 5—8 возможен многостраничный режим работы.
Для вывода многоцветных рисунков наиболее удобным, по-ви- димому, является экран 7.
Палитра. В RGB-мониторе1 зафиксировано 16 различных цветов, пронумерованных от 0 до 15 и представляющих собой определенные пропорции красного, синего и зеленого тонов (см. табл. 27). Эти пропорции могут быть изменены. Поэтому нет смысла говорить о номере конкретного цвета, а лучше использовать термин «номер палитры». В компьютерах MSX-2 изменение палитры реализуется простыми средствами. Делается это по оператору COLOR = (код, R, G, В), где арифметические выражения в скобках имеют смысл.
код — номер изменяемого цвета (0—15);
R, G, В — пропорции красного, зеленого и синего цветов (0-7).
Таблица 27
Код
Цвет
Красный
Зеленый
:Х X X X и
Код
Цвет
Красный
Зеленый
-X X X X и
0
прозрачный
0
0
0
8
красный
7
1
1
1
черный
0
0
0
9
светло-красный
7
3
3
2
зеленый
1
6
1
10
темно-желтый
6
6
1
3
светло-зеленый
3
7
3
11
светло-желтый
6
6
4
4
темно-синий
1
1
7
12
темно-зеленый
1
4
1
5
синий
2
3
7
13
сиреневый
6
2
5
6
темно-красный
5
1
1
14
серый
5
5
5
7
голубой
2
6
7
15
белый
7
7
7
В примере 2 при выполнении приведенного фрагмента программы последовательно получаем чистые синий, зеленый и красный цвета.
Оператор SCREEN, кроме чистки экрана, устанавливает па-
ПРИМЕР 2
1 * НАЖИМАЙТЕ1 * НАЖИМАЙТЕЛЮБУЮ КЛАВИШУЛЮБУЮ КЛАВИШУ
1 * НАЖИМАЙТЕ
1 * НАЖИМАЙТЕ
ЛЮБУЮ КЛАВИШУ
ЛЮБУЮ КЛАВИШУ
10 SCREEN 7:COLOR 15,4,4:CLS:GOSUB 50
20 COLOR-(4,0,0,4):GOSUB 50
30 COLOR-(4,0,4,0):GOSUB 50
40 COLOR-(4 , 4,0, 0) :GOSUB 50:GOTO 10
50 R$=INPUT$(1):RETURN
R— RED (красный), G — GREEN (зеленый), В — BLUE (синий).
литры в исходное состояние (см. табл. 27). Этот же эффект, но без стирания изображения, достигается любым из операторов COLOR или COLOR = NEW.
Замечание. Если изменение палитры реализуется непосредственно в видеопамяти с помощью VPOKE, то на изображение это не повлияет до тех пор, пока не будет осуществлено считывание таблицы палитр оператором COLOR = RESTORE.
Отметим также имеющуюся для экрана 1 причудливую возможность выводить в различных цветах определенные части фона и отдельные символы. Для этого необходимо непосредственно воздействовать на таблицу цветов видеопамяти оператором VPOKE. Расположена эта таблица по адресам &Н2000 — &H201F. Каждый ее байт кодирует цвета изображения (старшие 4 бита) и фона (младшие 4 бита) ровно для 8 последовательных символов. Точнее, по адресу &Н2000 + А (А=0, 1, ..., 31) кодируются цвета символов с СНК$-кодами от 8-А до 8-А + 7. В примере 3 приводится инвертирование цвета для символов: 0, 1, 2, 3, 4, 5, 6, 7.
ПРИМЕР 3
10 SCREEN 1:COLOR 15,4
20 VPOKE &Н2000+6,&H4F:GOSUB 50:R*=INPUT*(1)
30 VPOKE &H2000+6,&HF4:GOSUB 50:R*=INPUT*(1> 40 GOTO 20
50 LOCATE 7,10:PRINT"ТАРИФ-01234567":RETURN
В примере 4 показан вывод на экран всех знаков алфавита и случайное изменение цвета у отдельных групп символов. ПРИМЕР 4
’ НАЖИМАЙТЕ ЛЮБУЮ КЛАВИШУ
’
10 SCREEN 1:COLOR 15,4,4:X=RND(—TIME)
20 ’вывод символов псевдографики
30 FOR S=64 Т095:PRINT CHR*(1)+CHR*(S);:NEXT 40 ’вывод символов алфавита
50 FOR S=32 TO 255:PRINT CHR*(S)5:NEXT
60 DEFFNR(U)=INT(RND(1)XU)
70 X=FNR(32):C1=FNR(16):C2=FNR(16)
80 VPOKE &H2000+X,16XC1+C2
90 R*=INPUT*(1):GOTO 70
160
Из сказанного ранее вытекает, в частности, что возможен вывод на экран курсора в цвете, отличном от цвета изображения.
ПРИМЕР 5
10 SCREEN 1:COLOR 15,4,4:X=RND(-TIME)
20 LOCATE 3,10: PRINT “ЦВЕТ”
30 DEFFNR(U)=INT(RND(1)XU)
40 C1=FNR(16):02=FNR(16)
50 VPOKE &H201F,16XC1+C2
60 LOCATE 12,10:R$=INPUT$(1):GOTO 40
Несмотря на кажущуюся экзотичность рассмотренных приемов изменения цвета, для экрана 1 именно они и подобные им трюки позволяют создавать весьма эффективные игровые программы.
Цветные спрайты. При рассмотрении простейших графических динамических объектов, называемых спрайтами, отмстим, что каждый из них может быть раскрашен, но только в один конкретный цвет. Поэтому многоцветная мультипликация оказывалась возможной лишь при наложении спрайтов (спрайты с меньшими номерами перекрывают спрайты с большими номерами).
На экранах 4—8 допускаются и цветные спрайты. При этом шаблон спрайта формируется обычным образом (SPRITE? (п) = ), вывод его на экран также не претерпевает изменений (PUT SPRITE). Однако дополнительный оператор
COLOR SPRITE? (n) = а(1)
позволяет раскрашивать отдельные горизонтальные линии выведенного спрайта, смещать эти линии влево на 32 точки и отменять назначенное прерывание при столкновении данного спрайта с другими.
В операторе (1): п — номер спрайта, а — строковое выражение, значение которого состоит из 8 или 16 символов.
При выполнении этого оператора двоичная структура кода ASCII каждого символа а действует на спрайтовой линии в соответствии со значениями своих отдельных битов. Объясним, как это происходит для конкретного «символа» — линии.
Биты 0—3 Эти биты задают код палитры (0—15), присваивае- (четыре ле- мой соответствующей линии.
вых).
Бит 4. Нс используется.
Бит 5. Если бит равен 1, то отменяется прерывание при пересечении данного спрайта с другими.
161161В Заказ 627
161
161
Бит 6 Если бит равен 1, то происходит следующее.
отменяется прерывание при пересечении данного спрайта с другими;
при наложении спрайтов с цветами С1 и С2 их пересечение принимает цвет Cl OR С2;
линии, не затронутые пересечением, исчезают.
Если бит равен 1, то соответствующая линия отобра- Бит 7. жается на 32 точке левее абсциссы в PUT SPRITE.
Пример 6 иллюстрирует раскрашивание полос спрайта.
РИМЕР 6
10 SCREEN 4,1:COLOR 15,4,4:CLS
20 SPRITE*(0)=STRING*(8,255)
30 PUT SPRITE 0,(118,86),15,0
40 R*=INPUT*(1):GOSUB 80
50 R*=””:FOR S=1 TO 8:R*=R*+A*(S):NEXT
60 COLOR SPRITE*(0)=R*
70 GOTO 70
80 A*(l)= CHR*(&B00000001)
90 A*(2)= CHR*(&B00000011)
100 A*(3)=CHR*(&B00001000)
110 A*(4)=CHR*(&B00001111>
120 A*(5)=CHR$(&B00000111)
130 A*(6)=CHR$(&B00001011)
140 A*(7)=CHR*(&B00001101)
150 A*(8)=CHR*(&B00001100)
160 RETURN
В этом примере по операторам строк 10—30 проводится формирование шаблона спрайта и его вывод на экран в виде белого квадрата на голубом фоне. Нажатие на любую клавишу организует обращение к подпрограмме инициализации массива строковых переменных. Далее, в строке 50 формируется шаблон R$ и, наконец, по COLOR SPRITES (0) в соответствии с пред- 162
писанием R$ все линии спрайта раскрашиваются в различные цвета. Например, линия 2 получает цвет «зеленый» потому, что
А$ (2) = CHR$ (&В00000011)
В примере 7 показано смещение полос спрайта. (Рассматри вается программа примера 6 с измененной подпрограммой.
ПРИМЕР 7
80 А*(1)=CHR*(&В10001011)
90 А* (2)=CHR*(&В00001000)
100 А*(3)=CHR*(&В10000111)
110 А*(4)=CHR*(&В00001000)
120 A*(5)=CHR*(&B10000010)
130 A* (6)=CHR*(&B00001000)
140 A*(7)=CHR*(&B10000001)
150 A* (8)=CHR*(&B00001000)
160 RETURN
В этом случае спрайт как бы расщепляется на отдельные полосы так, что часть линий смещается на 32 точки влево и перекрашивается. Например, линия 7 принимает цвет «черный» и смещается влево потому, что
А$(7) = CHR$(&B 10000001)
В примере 8 иллюстрируется наложение спрайтов с измене нием цвета.
ПРИМЕР 8
10 SCREEN 4,3s COLOR 15,4,4sCLS
30 SPRITE*(0)=STRING*(32,255)
40 PUT SPRITE 0,(118,86),2,0
50 PUT SPRITE 1,(138,90),8,0
60 T*=INPUT*(1)
70 COLOR SPRITE*(1)=STRING*(32,&B01001000)
80 GOTO 80
По этому фрагменту программы операторы строк 40 и 50 выводят два спрайта-квадратика соответственно зеленого — 2 и красного — 8 цветов. Они имеют непустое пересечение и немного смещены относительно друг друга по вертикали. Поскольку зеле-
163
ный спрайт имеет экранный номер больший, чем красный спрайт, то их общая часть также оказывается зеленой. Учитывая, что 2OR8=10, нажатие на любую клавишу приводит к тому, что пересечение спрайтов становится желтым. При этом линии, не затронутые пересечением, сливаются с фоном.
В примере 9 показано движение спрайта.
РИМЕР 9
10 SCREEN 4,1:COLOR 15,4,4:CLS
20 SPRITE»(0)=STRING»(8,255)
30 PUT SPRITE 0,(0,86),15,0
40 Q»=CHR»(&B00001000):T»=CHR»(&B00001111)
50 COLOR SPRITE» (0) =Q»+Qt+T»+Q»+Q»4-T»4-Q»+Q»
60 FOR S=0 TO 256
70 PUT SPRITE 0,(S,86),,0
80 NEXT:GOTO 60
Здесь демонстрируется движение цветного спрайта. Поскольку управляющим параметром взята абсцисса точки в PUT SPRITE, то движение осуществляется по горизонтальной линии.
В случае раскраски спрайта сразу по всем линиям можно использовать оператор
COLOR SPRITE (п) =0(2)
Здесь: п — номер спрайта, 0 — арифметическое выражение со значениями от 0 до 127.
При выполнении (2) двоичная структура числа 0, дополненная до 8 бит слева нулями, действует на каждой спрайтовой линии так же, как один символ на конкретной линии в (1). В примере 10 иллюстрируется одновременная раскраска всех линий.
ПРИМЕР 10
10 SCREEN 4,3:COLOR 15,4,4:CLS
20 SPRITE»(0)=STRING»(32,255)
30 PUT SPRITE 0,(140,80),2,0
40 PUT SPRITE 2,(50,126),8,0
50 PUT SPRITE 3,(70,136),8,0
60 COLOR SPRITE(3)=71
70 GOTO 70
164
Отметим следующий факт. Поскольку в (2) седьмой старший бит структуры, воздействующей на спрайт, всегда равен нулю, то смещение полос по этому оператору невозможно.
Пример -11 показывает отмену прерывания по столкновению спрайтов.
ПРИМЕР 11
10 SCREEN 4,1:COLOR 15,4,4:CLS
20 OPEN “GRP:" AS #1
30 ON SPRITE GOSUB 90:SPRITE ON
40 SPRITE*(0)=STRING$(8,255)
50 PUT SPRITE 0,(118,86),2,0
60 PUT SPRITE 1,(128,96),8,0
70 COLOR SPRITE(1)=&B01001000 ’ <
80 GOTO 80
90 PSET (20,170),4
100 PRINT #1,“СТОЛКНОВЕНИЕ СПРАЙТОВ"
110 SPRITE OFF:RETURN
Если данный пример прогнать без строки 70, то на голубом фоне экрана появляются два пересекающихся спрайта: красный и зеленый. Поскольку в строке 30 назначено и включено пре рывание по столкновению спрайтов, то с позиции (20, 170) будет выведено сообщение
СТОЛКНОВЕНИЕ СПРАЙТОВ
Пусть строка 70 в программе восстановлена. Тогда, учитывая инициализацию в 70 (бит 6 равен 1), выведенные пересекающиеся спрайты не вызовут обращения к подпрограмме обработки прерывания.
Замечание. Прерывание по столкновению спрайтов выполняется всегда правильно лишь при выключении компьютера из локальной вычислительной сети операторомNETEND.
Экранные страницы. Наличие видеопамяти объемом 128 Кбайт позволило организовать многостраничные экраны для режимов от SCREEN 5 до SCREEN 8 (см. табл. 24—26). Что представляют собой страницы? Фактически это отдельные непересекающиеся Фрагменты видеопамяти. Для управления ими введен оператор
SET PAGE Pl, Р2(3)
где: SET (установить), PAGE (страница)—служебные слова; Pl> Р2 — арифметические выражения.
При выполнении этого оператора используются целые части значений Р1 и Р2. Они должны лежать в диапазоне: для экранов 5—6 от 0 до 3, для экранов 7—8 от 0 до 1. По умолчанию Р1 = Р2=0.
Р1 называется отображаемой страницей. Ее содержимое индицируется в' данный момент на экране.
Р2 называется активной страницей. С ней проводится текущая работа по операторам программы, то есть вводятся тексты, формируются рисунки и т. п.
Отметим, что любой из параметров в операторе (3) действует до нового назначения по SET PAGE и смена страниц проводится довольно быстро.
В примере 12 показана работа с 4 страницами.
ПРИМЕР 12
10 SCREEN 5;COLOR 15,4,4:CLS
20 DATA 1,3,8,15
30 FOR S=0 TO 3:SET PAGE 0,S:CLS:READC:R=S+1
40 LINE(30XR,18XR)-(60XR,48XR),C,BF
50 NEXT
60 FOR S=0 TO 380 NEXT
70 SET PAGE S:BEEP:A»=INPUT»(1)90 GOTO 60
По программе этого примера в строках 30—50 для режима SCREEN 5 формируется содержимое всех страниц от 0 до 3. Это квадраты разных размеров, положения и расцветки. Просмотр страниц реализуется по строкам 60—70. Для циклического перехода от одной страницы к другой надо нажать любую клавишу.
Имеются некоторые ограничения при совместном использовании спрайтов и экранных страниц. В этом случае вывод спрайта возможен только на странице 0, где он и должен быть сформирован.
В примере 13 демонстрируются спрайты на странице 0.
ПРИМЕР 13
10 SCREEN 5,1:COLOR 15,4,4:CLS
20 SPRITES!1)=STRING»(8,255):OPEN "GRP:“AS#1 30 SET PAGE 0,0:CLS
40 CIRCLE(120,100),50,15
50 PUT SPRITE 1,(112,92),8
60 PRESET(68,175):PRINT #1,"СТРАНИЦА (0,0)"
70 SET PAGE 0,3:CLS
166
80 CIRCLE(120,100),40,3,,, .5
90 LINE(70,75)-(170,125),7,В
100 PAINT(120,100),6,3
110 PRESET(68,175)SPRINT #1,"СТРАНИЦА (3,3)"
120 SET PAGE 0:A*=INPUT»(1)
130 SET PAGE 3:A$=INPUT»(1>
140 GOTO 120
Обратите внимание, что при прогоне данной программы в соответствии с операторами строки 70 рисунок и подпись на третьей странице формируются при отображаемой нулевой странице. Поэтому упомянутые действия остаются как бы скрытыми от нас, и на экране дисплея мы их просто не замечаем. Затем созданное «невидимое» изображение проявляется по оператору SET PAGE 3 строки 130.
Копирование блоков. Прямоугольник на экранной странице со сторонами, параллельными осям координат, удобно задавать двумя точками: верхней левой (XI, ¥1) и нижней правой (Х2, ¥2) вершинами. Будем называть такие прямоугольники блоками и обозначать их так: R=(X1, ¥1) — (Х2, ¥2).
Широкий спектр для различного рода манипуляций с блоками предоставляет очень полезный и эффективный оператор COPY. С его помощью можно копировать экранные блоки на данной странице, перемещать их на другие страницы, упаковывать в цифровом виде в числовые массивы, записывать в виде файла данных на диск и осуществлять ряд других операций.
Записывается оператор COPY в одной из 7 следующих форм 1. COPY R, Pl ТО (X, Y), Р2, & 2. COPY R, Pl ТО М 3. COPY R, PI ТО NAME 4. COPY М, F ТО (X, Y), Р2, & 5. COPY NAME, F TO (X, Y), P2, & 6. COPY M TO NAME 7. COPY NAME TO M Здесь:
COPY (копировать), TO (в)XI, Yl, X2, Y2, Pl, P2, X, Y, FCOPY (копировать), TO (в)XI, Yl, X2, Y2, Pl, P2, X, Y, F— служебные слова;— арифметические выражения у которых используются целые части значений;— служебные слова;— арифметические выражения у которых используются целые части значений;
COPY (копировать), TO (в)
XI, Yl, X2, Y2, Pl, P2, X, Y, F
COPY (копировать), TO (в)
XI, Yl, X2, Y2, Pl, P2, X, Y, F
— служебные слова;
— арифметические выражения у которых используются целые части значений;
— служебные слова;
— арифметические выражения у которых используются целые части значений;
NAME — строковая переменная;
М — имя одномерного числового массива;
& — определитель цвета точек.
&C{OR, AND, XOR, PSET, PRESET, TOR, TAND, TXOR, TPSET, TRESET}.
Смысл этих параметров в случаях 1—7 таков:
R — блок;
Pl, Р2 — номера экранных страниц;
(X, Y) —точка на экране (странице);
F — указатель типа симметрии копируемого блока;
NAME — имя файла;
М — цифровой образ блока в виде значений элементов массива;
& — элемент для задания цвета копируемого блока в зависимости от его первоначальной раскраски и текущего цвета экрана.
Остановимся на описании семантики каждого из случаев 1—7.
При выполнении COPY содержимое блока R со страницы Р1 пересылается на страницу Р2 в блок с левой верхней вершиной (X, Y). По умолчанию Pi есть активная страница, а Р2 = Р1. Параметр & определяет цвет CN каждой точки вновь созданного блока, исходя из цвета С этой точки в R и цвета S фона экрана. Делается это так, как указано в графе 3 таблицы 28, где NOT, OR и AND — обычные логические операции.
Определителю цвета может предшествовать префикс Т. При копировании точек R, не являющихся «прозрачными», Т никакого влияния не оказывает. Образы точек с прозрачной палитрой при наличии Т раскрашиваются в цвет фона.Таблица 28
Формирование цвета блока
Определитель цвета &
Получение цвета CN точек блока
PSET
PRESET
OR
AND
XOR
С
NOT С
С OR S
С AND S
(NOTC) AND S OR (NOTS) AND C
ПРИМЕР 14
10 SCREEN 5:COLOR 15,4,4:CLS
20 LINE(20,20)-(100,100),8,BF
30 COPY(60,70)-(140,120),0 TO (150,130),0,PRESET
40 SOTO 40
168
По данному фрагменту программы на нулевой странице экрана 5 рисуется квадрат красного цвета. Затем на эту же страницу копируется блок, имеющий непустое пересечение с квадратом. Образы точек блока оказываются раскрашенными в два цвета:
голубой; CN = NOT8 = 7;
светло-желтый; CN = NOT4=11.
В следующем примере демонстрируется копирование с одной страницы на другую.
ПРИМЕР 15
10 SCREEN 5;COLOR 15,4,4:CLS
20 SET PAGE 0,1:CLS
30 LINE(20,20)-(100,100),8,BF
40 SET PAGE 0,0:CLS
50 COPY(80,80)-(120,120),1 TO (150,130),0,PRESET
60 R$=INPUT$(1):SET PAGE 1
70 R*=INPUT»(1):SET PAGE 0:GOTO 60
При выполнении COPY содержимое R co страницы Pl копируется в числовой массив М. Оптимальный размер N массива, то есть наименьшая допустимая верхняя граница индексов его элементов, зависит от типа массива и режима экрана и определяется так, как это указано в таблице 29. Через Т там обозначено количество точек копируемого блока R:
T = (ABS (X1-X2) + 1)*(ABS (Yl-Y2) + 1)
Таблица 29
Оптимальные размеры массива для копирований
Режим экрана
Целый
Размеры массива Вещественный
15,7
(Т + 3)\4-Ц
(Т+7)\16
26
(Т+7)\8-Ц
(Т+15)\32
38
(Т+1)\2 + 1
(Т+3)\8
При выполнении СОРУ содержимое блока R со страницы Р1 копируется в виде файла данных под именем NAME на диск.
При выполнении СОРУ содержимое массива М помещается в некоторый блок страницы Р2. Действие определителя цветов & здесь такое же, как и в случае 1. Положением блока и размещением информации в нем управляют параметры: точка
169
(X Y) и указатель типа симметрии F. Остановимся на этом подробнее.
. F = 0. Блок в Р2 формируется с левой верхней вершиной (X, Y) в том виде, как он был записан в М. Изображение на экране, получаемое от этого блока, обозначим через F0.
. F=l. Местоположение и содержимое блока в Р2 таково, что формируемое от него изображение получается из F0 осевой симметрией относительно прямой х = Х.
. F = 2. Местоположение и содержимое блока в Р2 таково, что формируемое от него изображение получается из F0 осевой симметрией относительно прямой у = Y.
. F = 3. Местоположение и содержимое блока в Р2 таково, что формируемое от него изображение получается из F0 центральной симметрией относительно точки (X, Y). Иллюстрацией к действию указателя симметрии F служит следующий пример.
ПРИМЕР 16
10 SCREEN 5:COLOR 15,10,13:CLS:DEFINT A-Z
20 X1=60:Y1=60:X2=120:Y2=120:C=1
30 T=CABS(XI—X2)+1)XCABS(Yl-Y2)+1)
40 R=(T+3)\4+l:DIM LCR)
50 CIRCLE (XI,Y1),40,C:PAINT (X1,Y1),C
60 COPYCX1,Y1)-CX2,Y2),0 TO L
70 FOR F=0 TO 3
80 COPY L,F TO C150,130),0,XOR
90 R$=INPUT$C1):NEXT” НАНИМАЙТЕ КЛАВИШУ !
100 GOTO 100
Выполнение COPY протекает точно так же, как и в предыдущем случае. Только данные Здесь извлекаются не из массива, а с диска из файла "NAME".
При выполнении COPY числовой массив М записывается на диск под именем "NAME".
При выполнении COPY файл данных под именем NAME с диска записывается в массив М. Здесь необходимо согласовывать размеры М с объемом файла (см. пункт 2).
В примере 17 показаны различные типы копирований.
ПРИМЕР 17
10 SCREEN 8:COLOR 15,130,15CLS:DEFINT A-Z
20 Xl=60:Yl=60:X2=120:Y2=120:C=13
30 T=(ABS(X1-X2)+1)X(ABS(Y1-Y2)+1)
40 R=(T+1)\2+lsDIM L(R),M(R)
50 CIRCLE (XI,Yl),40,CiPAINT (X1,Y1),C
60 COPY(XI,Yl)— (X2,Y2) ,0 TO L
70 FOR S=0 TO 3
80 COPY L,S TO (150,130),0,PRESET
90 BEEP!R*=INPUT*(1):NEXT
100 COPY L TO "TOR”
110 COPY "TOR" TO M
120 COPY M,0 TO (20,60),0,PRESET
130 GOTO 130
. Виртуальный диск
Расширение объема ОЗУ в MSX-2 до 128 и более Кбайт не делает вновь появившееся свободное пространство памяти непосредственно доступным для интерпретатора Бейсика. По-прежнему для указания адреса отводится два байта, и потому прямая адресация возможна лишь в пределах от 0 до 65535. Как же использовать остальную память? Она рассматривается в качестве виртуального дискового устройства, называемого «диск ОЗУ», или, по- другому, "mem". В Бейсик добавлены 4 новых оператора расширения (_MEMINI, „MFILES, _MKILL, _MNAME). Остальные средства для раб ы с "mem" имеют синтаксис и семантику, в основном аналогичную соответствующим операторам и функциям в MSX DISK Бейсике. Однако слово "mem" перед именем файла здесь указывать обязательно. Например,
SAVE "mem: ВОЛНА"
Внимание! При выключении компьютера содержимое виртуального диска безвозвратно теряется.
Рассмотрим подробнее отмеченные выше операторы расширения.
CALL MEMINI. Данный оператор производит действия, аналогичные CALL FORMAT в MSX DISK Бейсике. По нему организуется форматирование устройства "mem". Выполнять CALL
171
MEMIN1 необходимо до первого обращения к "mem". Отметим, что формирование уничтожает все файлы, записанные на виртуальный диск ранее.
CALL MF1LES. Выполнение этого оператора приводит к выводу на экран каталога файлов диска "тетЛ. В отличие от FILES здесь операнды не допускаются. Нельзя использовать и префикс L для распечатки каталога на принтере.
CALL MKILL При выполнении оператора CALL MKILL (NAME) с диска ОЗУ стирается файл под именем NAME, например:
CALL MKILL "ТРОС")_ MKILL ("ДЫМ.2")
CALL MNAME. По оператору CALL MNAME ("имя 1" AS "имя 2") файл "имя 1" переименовывается в "имя 2".
Отметим два следующих обстоятельства.
Любые программы по оператору SAVE записываются на виртуальный диск в формате ASCII. Тем самым всегда возможно их слияние по MERGE.
Значения, возвращаемые функциями LOC, LOF и FPOS, могут вызвать переполнение при присваивании их целочисленным переменным. Поэтому для подобных целей лучше использовать переменные действительного типа.
Коды клавиш
Материал, излагаемый в этом пункте, относится к любой версии Бейсика.
Ранее мы встречались с двумя способами распознавания из программы кода ASCII вводимого с клавиатуры символа. Опираются они на использование функций INKEYS и INPUTS ( ).
ПРИМЕРЫ 18
10 ’ ФУНКЦИЯ INKEYt. КУРСОРА НЕТ
20 R$=INKEY*:IF R*="“ THEN 20
30 PRINT ASC(R*>,R*:GOTO 20
10 ’ ФУНКЦИЯ INPUT*. КУРСОР ЕСТЬ
20 R*=INPUT*(1)
30 PRINT ASC(R*>,R*:GOTO 20
Разница в этих вариантах не только в наличии или в отсутствии на экране курсора при реализации строки 20, но и в том, что в случае А, ожидая нажатия клавиши, процессор про-
172
должает выполнять программу, а в случае В он находится в режиме ввода символа. С одной стороны, оба этих способа идентификации клавиш и вводимых по ним символов просты и удобны. Однако по меньшей мере два факта заставляют нас применять для подобных целей и иные приемы. Рассмотрим их.
Некоторые коды ASCII в диапазоне от 0 до 31 вырабатываются лишь при одновременном нажатии клавиши CTRL и определенного символа. Часть этих кодов является управляющими сигналами, а остальные можно использовать при написании программ (см. табл. 30).
Клавиша
Символ
Код
Примечание
Клавиша
Символ
Код
Примечание
1 CTRL
2 CTRL
3 CTRL
4 CTRL
5 CTRL
6 CTRL
D О P Q
S T
04
15
16
17
19
20
7 CTRL
8 CTRL
9 CTRL
10 CTRL
11 CTRL
12 CTRL
V W
X ¥ Z C
22
23
24
25
26
27
=SELECT
= ESC
2. Шесть клавиш:
CAPS
GRAPH
РУС
SHIFT
CTRL
STOP
Таблица 30
Коды для двух клавиш
вообще не имеют кодов ASCII, и потому они «не читаемы» функциями INKEYS и INPUTS ( )• Однако распознать их из программы все же можно. Дело в том, что информация о последней нажатой клавише (именно клавише, а не символе!) хранится в буфере NEWKEY, расположенном с адреса &HFBE5.
Для клавиатуры без выделенной цифровой зоны NEWKEY занимает 9 последовательных байт памяти:
&HFBE5 — &HFBED
Для клавиатуры с дополнительной правой цифровой зоной буфер NEWKEY на два байта длиннее и расположен по адресам:
&HFBE5 — &HFBEF(7)
Каждой клавише соответствует ровно один бит NEWKEY, и при ее нажатии значение этого бита сбрасывается на нуль. При этом биты буфера для ненажатых клавиш становятся равными 1. Если (7) представить в виде матрицы с 11 строками (байты) и 8 столбца-
173
ми биты), то положение нулей (X, У)(0^Х^7, 0^ У^ 11 в ней и будет определять совокупность всех нажатых в данный момент клавиш В таблице 31 указаны клавиши, дающие нулевое значение своим битам.
Запустив на счет фрагмент программы примера 19 и нажимая те или иные клавиши, можно проследить за изменением матрицы клавиатуры и тем самым проверить таблицу 31.
ПРИМЕРЫ 19
10 SCREEN 0:COLOR 15,4,4:WIDTH 80
20 A=8cHFBE5:A$=-00000000"
30 LOCATE 8,3:PRINT "! МАТРИЦА ! Y ! Xм
40 LOCATE 6,4:G0SUB 140:LOCATE 6,16:G0SUB 140
50 FOR Y=0 TO 10
60 Z=PEEK(A+Y):ZS=RIGHT»(A»+BIN»(Z),8)
70 LOCATE 8,Y+5:PRINT *!"+Z»+”!!";
80 LOCATE 28,Y+5:PRINT SPACE» M6);
85 IF Z=255 THEN 130
90 BEEP:LOCATE 22,Y+5:PRINT Y:LOCATE 28,Y+5
100 FOR X=1 TO 8
110 IF MID»(Z»,X,1)=,,0" THEN PRINT 8-X;
120 NEXT X 130 NEXT Y:GOTO 50 140 PRINT STRING»(30,"-”):RETURN
По этой программе сканируется буфер NEWKEY и на экране индицируется как его текущее состояние, так и координаты (X, У) нулевых битов. В примере 20 показаны переходы по клавишам
SHIFT
CTRL
GRAPH
CAPS
и РУС
ПРИМЕР 20
10 SCREEN 0:COLOR 15,4,4:KEY OFF 20 E=PEEK(&HFBEB)
30 IF E=254 THEN 100’ > "SHIFT”
40 IF E=253 THEN 200’ > "CTRL"
174
Таблица 31
Матрица клавиатуры
Адрес & Н (Байты)
X (Биты)
Y
7
6
5
4
3
2
1
0
РВЕ 5
6
5
4
3
2
1
+
9
0
РВЕ 6
V
*
Н
—
=
0
8
7
1
РВЕ 7
I
F
?
@
В
>
\
2
РВЕ 8
0
г L
R
Р
А
и
W
S
3
РВЕ 9
к
J
Z
т j
Т
X
D
L
4
РВЕ А
Q
N
1
С
М
G
E
Y
5
РВЕ В
F3
F2
F1
РУС
CAPS
GRAPH
CTRL
SHIFT
6
РВЕ С
RETURN
SELECT
BS
STOP
ТАВ
ESC
F5
F4
7
FBED
—>
4
t
DEL
INS
HOME
ПРОБЕЛ
8
FBEE
4
3
2
1
0
*
+
RETURN
9
FBEF
•
>
—
9
8
7
6
5
10
50IFE=251THEN300’ >"GRAPH"
IFE=247THEN400’ >"CAPS"
70IFE=239THEN500’ >"РУС"
80 GOTO 20
Инициализация компьютера
Включение компьютера автоматически приводит его в некоторое исходное состояние: назначается режим экрана, устанавливается его ширина, формируются цвета фона и изображения, фиксируется значение подсказки и определяются многие другие параметры. В MSX-2 имеется ряд дополнительных операторов, проводящих начальную инициализацию, которая не разрушается при включениях-выключениях компьютера. Устанавливаемые ими назначения сохраняются в специальном небольшом участке памяти за счет питания от сменной аккумуляторной батарейки. Речь идет о 10 операторах, к описанию которых мы и приступим.
Подсказка, заголовок, пароль. Приглашение-подсказку "Ок" можно заменить последовательностью любых других символов, длиной не более 6. По оператору SET PROMPT & в качестве подсказки фиксируется значение строкового выражения & или первые 6 символов этого значения, если его длина больше 6 (set — установить, prompt — подсказка).
По оператору SET TITLE &, С переопределяется «заголовок» титульного экрана-заставки, появляющийся при включении компьютера.
Здесь:
title (заголовок) — служебное слово;
& — строковое выражение, у которого для заголовка используется до 6 первых символов значения;
С — арифметическое выражение со значениями от 1 до 4.
Заголовок располагается на экране после всех сообщений по центру фона. Если его длина равна 6, то для продолжения работы требуется «подтолкнуть» систему, нажав на любую клавишу. Параметр С не является обязательным. По умолчанию он равен 1 и служит для фиксирования раскраски экрана-заставки по одной из 4 возможных схем. По оператору
SET PASSWORD &
можно задать пароль, являющийся значением строкового выражения & (password — пароль). Длина этого значения не должна быть более 255.
Пусть пароль зафиксирован. Тогда каждый раз при включении компьютер будет требовать от пользователя его ввода с клавиатуры. А что делать, если пароль забыт? Необходимо осуществить его сброс. Для этого достаточно выполнить такую последовательность действий.
. При включении компьютера держать одновременно нажатыми клавиши STOP и GRAPH. Это не отменит пароля, но приведет к обходу экрана-заставки.
. Выполнить оператор SET PROMPT "Ok". Теперь уже пароль будет отменен. Дело все в том, что из трех рассмотренных в этом пункте установок — подсказки, заголовка и пароля — действует только одна, назначенная последней.
Звук, центрирование фона. Тон звука, выводимого по оператору ВЕЕР, и его громкость можно переопределять оператором
SET ВЕЕР звук, громкость
Здесь «звук» и «громкость» — арифметические выражения, у которых используются целые части значений. Лежать они должны в диапазоне от 0 до 3. Один из этих параметров может быть опущен.
Если фон, на котором выводится изображение, плохо отцентрирован на экране, то поправить это можно оператором
SET ADJUST (X, У)
Здесь:
adjust (регулировать) — служебное слово;
X, У — арифметические выражения со значениями от — 7 до 8.
Параметры экрана. Многие текущие параметры, связанные с экраном, можно сохранить для начальной инициализации компьютера. Для этого достаточно выполнить оператор SET SCREEN. Сразу же оговоримся, что запоминаются только те назначения, которые фиксируются операторами:
SCREEN, COLOR, WIDTH и KEY ON/OFF выполненными в непосредственном счете. Речь идет о таких параметрах:
М — режим экрана (0, 1);
S — размер и масштаб спрайтов;
К —наличие (1) или отсутствие (0) отзвука клавиш;
V — скорость обмена с кассетным накопителем (1 — 1200 бод, 2 — 2400 бод);
Р — варианты принтера (0 — MSX, =|=0 — другое печатающее устройство);
R — режим вывода на монитор (0—3; 0 — нор-
Cl, С2, СЗ ширина экрана строка-подсказкаCl, С2, СЗ ширина экрана строка-подсказкамальный);
Cl, С2, СЗ ширина экрана строка-подсказка
Cl, С2, СЗ ширина экрана строка-подсказка
— цвета изображения фона и бордюра (0—15);
— 1—80 при М=0, 1—40 при М=1;
— есть или нет.
Напомним, что первые 6 параметров можно задавать оператором SCREEN:
SCREEN М, S, К, V, Р, R
Цвета изображения, фона и бордюра формируются оператором COLOR Cl, С2, СЗ. Ширина а экрана назначается оператором WIDTH а. Отключение и подключение строки-подсказки на текстовых экранах 0 и 1 реализуется соответственно операторами KEY OFF и KEY ON.
Дата, время. Дата устанавливается оператором
SET DATE "ММ/ДД/ГГSET DATE "ММ/ДД/ГГ(8)(8)
SET DATE "ММ/ДД/ГГ
SET DATE "ММ/ДД/ГГ
(8)
(8)
Здесь "ММ/ДД/ГГ"— формат (месяц, день, год). При записи SET DATE вместо М, Д, Г должны быть проставлены десятичные цифры. Нули указывать обязательно. Если оператор (8) выполнен, то фактически запущен автоматический календарь, работающий автономно вне зависимости от включений и выключений компьютера.
По оператору GET DATE t (get — получить) строковая переменная t принимает из календаря текущее значение даты в том формате, в каком она фиксировалась в (8).
Время задается оператором
SET TIME "ЧЧ:ММ:СС"SET TIME "ЧЧ:ММ:СС"(9)(9)
SET TIME "ЧЧ:ММ:СС"
SET TIME "ЧЧ:ММ:СС"
(9)
(9)
Здесь: "ЧЧ:ММ:СС"— формат (часы, минуты, секунды). При записи SET TIME вместо Ч, М, С должны быть проставлены десятичные цифры. Нули указывать обязательно. Если оператор (9) выполнен, то фактически запущены электронные часы, работающие вне зависимости от включений и выключений компьютера.
По оператору GET TIME t строковая переменная t получает текущее значение времени в том формате, в каком оно фиксировалось в (9).
Отметим, что форматы в (8) и (9) можно задавать не только константами, но и произвольными строковыми выражениями.
Остановимся еще на одном варианте рассмотренных в этом пункте операторов. Если наряду с (8) и (9) выполнить еще два оператора:
(Ю)(Ю)SET TIME время, А
(Ю)
(Ю)
SET DATE дата, А
то зафиксированные в них новые «дата» и «время» будут рассмат риваться как дата и время подачи сигнала. Таким образом мы как бы имеем в наличии «будильник с календарем». Правда, автоматически такой будильник работать не будет. Необходимо, например, в подпрограмме организовать сравнение текущих даты и времени с соответствующими параметрами, заданными в (10), и при их совпадении выдавать серию сигналов ВЕЕР, проигрывать какой-либо музыкальный фрагмент или выводить некоторое сообщение.
При использовании параметра А всегда следует вводить сначала время, а затем дату.
Возвратить параметры «время» и «дату», сформированные по (10), можно по операторам
GET TIME &1, А
GET DATE &2, А(11).
Правда, здесь необходимо учитывать некоторые нюансы. Во- первых, строковой переменной &1 присваивается значение без учета секунд ("ЧЧ:ММ—00:"). Во-вторых, переменная &2 получает значение без учета месяца и года (,,00/ДД/00,/).
ПРИМЕР 21
10 SCREEN 0:COLOR, 15,4,4:KEY OFF
20 SET DATE "03/08/90":SET TIME "13: 44:33“
30 ’
40 SET TIME "13:45:33",A: GET TIME B$,A
50 GOSUB 70: GOTO 50
60 >
70 GET DATE D$: GET TIME TO
80 LOCATE 15,18: PRINT DS,,TS
90 IF T$=BSANDMID$(DS,4,2)="08" THEN GOSUB110
100 RETURN
110 FOR S=1 TO 25:BEEP:NEXT:RETURN
Локальная вычислительная сеть
Компьютеры "Ямаха" (MSX-2) объединяются в локальную вычислительную сеть, в которой одновременно может присутствовать один «учительский» и до 15 «студенческих» компьютеров. Сеть поддерживается MSX-DOS, MSX-CP/M и Бейсик-систе-
мой. В дальнейшем нас будет интересовать лишь последний случай. Сразу же оговоримся, что рассматриваемая сеть существенно отличается от сети версии 1 (MSX-1). Здесь гораздо больше команд, иной синтаксис и значительно расширены предоставляемые пользователю возможности.
Везде ниже учительский компьютер будем обозначать через Т, а студенческие — через Р. Для идентификации за Т закрепляется номер 0, а за Р — номера 1, 2, ..., 15. Номер каждого компьютера индицируется на экране дисплея при запуске Бейсик-системы. Впрочем, в любой момент его можно узнать и по запросуWHO. Кроме того, по команде WHO (V) номер компьютера присваивается числовой переменной V.
Список команд. В таблице 32 приведен полный список из 25 сетевых команд и знаком " + " отмечено, какие из них доступны Т иР. При описании форматов команд использованы такие обозначения:
name — имя файла;
п — номер студенческого компьютера;
m — номер строки программы;
A, Al, А2 —адреса оперативной памяти, видеопамяти или сетевого ОЗУ;
V, VI, V2 —числовые переменные;
W — арифметическое выражение; mes — пересылаемое сообщение; command — команда;
S — опция, указывающая на ви-деопамять (S—screen)-;
N — опция, указывающая на работу с сетевым ОЗУ (N — net).
Здесь:
п, гл, A, Al, А2, W — произвольные арифметические
V, VI, V2 name, mes, commandV, VI, V2 name, mes, commandвыражения;
V, VI, V2 name, mes, command
V, VI, V2 name, mes, command
— числовые переменные;
— строковые выражения.
Мы не будем подробно останавливаться на описании синтаксиса и семантики каждой сетевой команды, а ограничимся рассмотрением конкретных примеров. Заметим, что ключевые слова команд записывать в тексте программы и набирать на клавиатуре можно в сокращенном виде. После символа "" (CALL) достаточно указывать лишь первые 4 буквы слова. Например, _MESS (7)-.
Каждый студенческий компьютер может находиться в двух состояниях (режимах). В одном из них для Р доступен лишь мини-
мальный набор команд MIN, а в другом — расширенный набор команд МАХ. Эти случаи отмечены соответственно в колонках 4 и 5 таблицы 32. Запуск Бейсик-системы на Р устанавливает его в состояние с минимальным набором сетевых команд MIN. Смена режимов осуществляется из компьютера Т по командам
ENACOM и _DISCOM
Пример 1. Все нижеприведенные команды подаются из Т. Реализуются они или в непосредственном счете, или в программном режиме.
Перевод компьютеров Р в состояние с расширенным набором команд МАХ.
командакомпьютер
„ENACOM(10)-10
„ENACOM(0)-всестуденческие
_ENAC(0)—всестуденческие
X=8:_ENAC(X)-8
Перевод компьютеров Р в состояние с минимальным набором команд MIN.
командакомпьютер
_DISC0MC9) _DISCOM(0) _DISC(0) Y=2:_DISC(Y)_DISC0MC9) _DISCOM(0) _DISC(0) Y=2:_DISC(Y)- 9
_DISC0MC9) _DISCOM(0) _DISC(0) Y=2:_DISC(Y)
_DISC0MC9) _DISCOM(0) _DISC(0) Y=2:_DISC(Y)
- все студенческие — все студенческие - 2
Список команд, доступных в текущий момент на данном компьютере, можно вывести на его текстовые экраны 0 или 1 по командеHELP (йе/р — помощь).
Поэкспериментируйте с этой командой на Р и 7, выполняя на 7 поочередно командыENACOM иDISCOM.
Инициализация и состояние сети. При включении компьютера 7 проводится автоматическая инициализация сети, то есть по умолчанию выполняется команда
_NETINIT(1)
(net — сеть, initiation — инициализация).
Не все прикладные программы могут работать в сетевом режиме. Для «разрушения» сети и перевода компьютеров в индивидуальный режим достаточно выполнить на 7 командуNETEND (net — сеть, end. — конец).
Таблица 32
Список сетевых команд
Команда
T
P (MIN)
p (MAX)
1
— HELP
+
+
+
2
— WHO
(V)
+
+
+
3
—ENACOM
(n)
+
—
—
4
— DISCOM
(n)
+
—
—
5
— NETINIT
+
+
+
6
— NETEND
+
+
+
7
— ONLINE
—
+
+
8
— OFFLINE
—
+
+
9
— PON
+
—
—
10
— POFF
+
—
—
11
— CHECK
(VI, V2)
+
—
—
12
— SEND
(name, n)
+
—
+
13
—SNDRUN
(name, n)
+
—
—
14
—BSEND
(name, n, Al, A2, S)
+
—
+
15
— RECEIVE
(name, n)
+
—
+
16
—BRECEIVE
(name, n, Al, A2, N)
+
—
+
17
— SNDCMD
(command, n)
+
—
—
18
— RUN
(n, A, m)
+
—
19
— STOP
(n)
+
—
—
20
_ SNDMAIL
(n)
+
—
21
— RCVMAIL
(n)
+
—
—
22
— MESSAGE
(mes, n)
+
—
—
23
— TALK
(mes, V)
—
+
+
24
— PEEK
(V, A, n, N)
+
+
+
25
— POKE
(w, A, n, N)
-4—
+
+
Например, для запуска на Т встроенной программы PAINTER (художник) требуется реализовать последовательность команд:
— NETEND: — PAINTER
Последующий возврат в сетевой режим осуществляется по команде (1).
Замечание. Выполнение команды NETEND на конкретном компьютере приводит к увеличению скорости вычислений на нем до 25%. Это следует учитывать при длительной работе в несетевом режиме.
При включении любого компьютера Р проводится автоматическое подключение его к сети, то есть по умолчанию выполняется команда
(2)(2)— ONLINE
(2)
(2)
Для отключения Р от локальной сети и перевода его на индивидуальный режим работы требуется выполнить на Р команду ^OFFLINE. При этом прекращается всякий обмен в сети с данным компьютером, и тем самым он становится защищенным от различного рода вмешательств в работу и прерываний со стороны Т или других Р. Скорость вычислений на Р не изменяется. Последующее включение Р в сеть осуществляется по команде (2).
Перед началом работы Т с Р или Р с Р на Т необходимо «активировать» опрос, то есть выполнить команду
_PON(3)
Отменяется действие (3) по командеPOFF. Отметим, что если команда (3) не реализована, то не гарантируется возможность правильного определения из Т номеров, подключенных к сети компьютеров Р.
Следующая очень важная команда CHECK (check — проверка) позволяет нам выяснить на Г, какие из компьютеров Р подключены к сети и разрешен ли им обмен с другими Р (ENACOM, DISCOM). Записывается команда в одной из трех форм:
—CHECK (VI, V2)(4)-
_ CHECK (VI)(5)
_CHECK (, V2)(6)
где VI и V2 — числовые переменные.
При выполнении (4) и (5) в двоичном представлении значения VI отдельными битами фиксируется подключение или непод- ключение Р к локальной сети. При этом, если бит п (п = 1,2...,15) начиная от младшего (правого) бита равен нулю, то компьютер номер п подключен к сети. В противном случае он или вообще выключен, или находится в индивидуальном режиме (OFFLINE).
Пример 2. При запуске нижеприведенного фрагмента программы мы видим, что к сети подключены компьютеры 1 и 3-10.
10 „CHECK(А>run
20 PRINT BINS(А)111110000000010
При выполнении (4) и (6) в двоичном представлении значения V2 отдельными битами фиксируется разрешение на минимальный (DISCOM) или расширенный (ENACOM) набор сетевых команд. При этом если бит п (п = 1,2, ..., 15) начиная от младшего (правого) бита равен нулю, то компьютеру номер и разрешен Расширенный набор команд. В противном случае для него доступен лишь минимальный набор команд.
ПримерЗ. При выполнении фрагмента
мы видим, что расширенный набор команд доступен компьютерам 1—3 и 13—15.
„CHECK(,В)
20 B»=RIGHT»("000000000000000"+ВIN»(В),15)
30 PRINT В»
run
000111111111000
Пример 4. Составить программу для Т, по которой каждому подключенному к сети компьютеру Р с четным номером будет разрешен расширенный набор команд, а состояние других компьютеров не изменится.
Решение данной задачи получается, например, по такому фрагменту:
„CHECK(D)
20 D»=RIGHT»(STRING»(15,"0")+BIN»(D),15)
30 FOR K=2 TO 15 STEP 2
40 IF MID»(D»,16-K,1)="0" THEN _ENACOM(K>
50 NEXT
Передачи программ и данных из Т. С учительского компьютера Т программу на Бейсике можно пересылать в Р прямо с диска или из
оперативной памяти. Делается это по командеSEND (send — посылать), записываемой в одной из следующих 4 основных форм: _SEND (name,n).(7)
_SEND (name,0).(8).
_SEND (, n).(9).
_SEND (, 0).(10).
Рассмотрим семантику каждой из команд (7) — (10).
По команде (7) программа name с диска пересылается в компьютер номер п (п = 1, 2, ..., 15).
По команде (8) программа name с диска пересылается во все студенческие компьютеры Р.
По команде (9) программа из оперативной памяти Т пересылается в компьютер номер п (п=1, 2, ..., 15).
По команде (10) программа из оперативной памяти Т пересылается во все студенческие компьютеры Р.
При любых пересылках содержимое ОЗУ в Т не меняется. Во время передачи на экране Р высвечивается предупреждающее со- 184
обшен ие WAIT (ждите). Прежняя программа и данные в ОЗУ Р теряются
„SEND("СЛИВА",7)
А$="ВИШНЯ":„SEND(А$,0)
В этом примере с диска в Р с номерами от 1 до 10 пересылаются соответственно программы:
ЗАДАЧА. 1, ЗАДАЧА. 2, .... ЗАДАЧА. 10
10 Х$="ЗАДАЧА."40 _SEND(X*+At,S)
20 FOR S=1 ТО 1050 NEXT
30 A»=MID*(STR»(S),2)
Если пересылаемая из Т в Р программа должна быть сразу же автоматически запущена на счет, то вместо соответствующей команды SEND нужно использовать команду SNDRUN ^send— посылать, run — запуск). По аналогии с (7) — (10) для SNDRUN имеются следующие формы записи:
_ SNDRUN (паше, п)
_ SNDRUN (name, 0)
_ SNDRUN (, n)
_ SNDRUN (, 0)
Передача программ, данных или содержимого видеопамяти в машинном коде из Т в Р реализуется по команде
„BSEND (name, n, Al, A2, S)(11)
Все параметры в (11) не являются обязательными. Если п отсутствует или на его месте стоит нуль, то пересылка осуществляется во все студенческие компьютеры.
Рассмотрим некоторые конкретные случаи.
Случай 1.
„BSEND (name, n, Al)(12)
При выполнении (12) программа name в машинных кодах или данные, записанные из Бейсика по BSAVE,BSEND илиBRECEIVE, пересылаются с диска в оперативную память студенческого компьютера п начиная с адреса А1.
Пример 6.
_BSEND("SHIP.BIN",3,&HB000)
Случай 2.
"„BSEND (, n, Al, A2, S)(13)
При выполнении (13) содержимое видеопамяти (экрана) компьютера Т в диапазоне адресов от А1 до А2 передается по этим же адресам в видеопамять студенческого компьютера п. Перед передачей в принимающем компьютере автоматически устанавливается требуемый режим видеопроцессора (экрана). По умолчанию
А1 =& Н0000, А2 = & HFFFF
однако целесообразней А1 и А2 задавать в явном виде с учетом режима экрана, его ширины и страницы (см. табл. 33).
Таблица 33 Адреса видеопамяти
Экран
Ширина
Номер страницы
Адреса видеопамяти
Начало
Конец
1
0
40
—
0
&HFFF
2
0
80
—
0
&H1FFF
3
1
—
—
0
& H3BFF
4
2, 3, 4
—
—
0
& H3FFF
5
5, 6
—
1
0
& H7FFF
6
5, 6
—
2
&Н8000
& HFFFF
7
5, 6
—
3
&Н10000
&H17FFF
8
5, 6
—
4
&Н18000
&H1FFFF
9
7, 8
—
1
0
&HFA9F
10
7, 8
—
2
& Н10000
&H1FFFF
Пример 7
_BSEND(,,&Н0000,&K1FFF,S)
_BSEND(,9, , ,S)
В этом примере на графическом экране Т формируется ри сунок и затем изображение передается в компьютер 10.
10 • УБегающий квадрат
20 SCREEN 5:COLOR 15,4,4
30 DEFINT A—I,L—Z
40 X=48 ’абсцисса левого угла
50 N=25 ’число квадратов
60 К=.9 'коэффициент деления стороны
70 L=256-2XX:Y=(192-L)\2
186
80 * Вершины исходного квадрата
90 X(0)=Х:X(1) =X+L: X (2) =X+L: X(3)=Х
100 Y(0) =Y:Y(1) =YsY(2) =Y+LsY(3> =Y+L
110 FOR U=1 TO N
120 ' Рисование квадрата
130 FOR S=0 TO 3:T=(S*l)M0D4
140 LINE (XCS),Y(S>>-(X(T>,YCT)>
150 NEXT
160 ’ Вершины очередного квадрата
170 A=X(0):B=Y(0)
180 FOR S=0 TO 2
190 X(S)=X<S)+KX(X(S-H)-X(S))
200 Y<S)=Y(S)+KX(Y(S+1)-YCS>>
210 NEXT
220 X(3)=XC3)*KX(A-X(3)>
230 Y(3)=Y(3)*KX(B—Y(3))
240 NEXT U
250 * Пересылка рисунка
260 „BSEND <,10,0,&H7FFF,S)
270 GOTO 270
Случай 3 (см. 11).
Здесь файл name должен быть сформирован командой BSAVE или сетевыми командамиBSEND илиBREC с параметром S. Выполнение (И) приводит к передаче файла name с диска в видеопамять компьютеру п в диапазоне адресов от А1 до А2. При пересылке требуемый режим экрана автоматически не назначается. Иными словами, его необходимо установить на п до выполнения BSEND. По умолчанию А1 принимается равным начальному адресу, с которого данные записывались на диск. Если этот адрес окажется больше А2, то А2 игнорируется.
ПРИМЕРЫ 8
„BSEND("V.BIN",11,,,S)
В.„BSEND("DD",,&Н0000,&H17FFF,S>
Передача программ и данных из Р. Пусть конкретный студенчес кий компьютер q q= 1, 2,..., 15) находится в состоянии ENACOM Тогда для q доступны сетевые командыSEND и _BSEND и с него можно организовать пересылку программ и данных из оперативной памяти и видеопамяти в другие компьютеры Р и Т.
КомандаSEND записывается в одной из трех форм:
_SEND (, п) _SEND (, 0) _ SEND (name, 0)
В любом из этих вариантов при выполненииSEND пересылается программа из ОЗУ компьютера q.
В первом случае пересылка проводится в студенческий компьютер n (n^=0, n^q).
Во втором случае пересылка организуется в ОЗУ Т.
В третьем случае пересылаемая программа записывается на диск под именем паше. Оперативная память Т не изменяется.
КомандаBSEND также записывается в трех возможных формах:
_BSEND (, n, Al, А2, S) _ В SEND (, 0, Al, А2, S) _BSEND (name, 0, Al, А2, S)
В любом из этих вариантов при выполненииBSEND пересылается содержимое видеопамяти компьютера q в диапазоне адресов от А1 до А2.
В первом случае пересылка организуется в видеопамять студенческого компьютера n (ng^O, n#=q) с автоматическим настроем в п требуемого режима экрана.
Во втором случае пересылка организуется в видеопамять Т с автоматическим настроем там требуемого режима экрана.
В третьем случае пересылаемые данные записываются на диск под именем name. Режим экрана не запоминается. Оперативная память в 7 не изменяется.
ПРИМЕР 9
A._SEND(,7)С._BSEN(,7,8cH8000,8cHFFFF,S>
_SEND(,0)D._BSEN(,0,&H0000,&HFA9F,S>
Прием программ и данных в Г. С учительского компьютера Т программу на Бейсике можно принять от любого студенческого компью- 188
тера Р, подключенного к сети. Делается это по командеRECEIVE (receive — получать, принимать), записываемой в одной из следующих двух форм:
_ RECEIVE (name, n)(14)
_ RECEIVE (, n)(15)
Здесь name и n имеют тот же смысл, что и в командеSEND. Рассмотрим семантику каждой из этих команд.
По команде (14) программа из ОЗУ студенческого компьютера Р с номером п (п=1, 2, ..., 15) записывается на диск под именем name. Содержимое ОЗУ компьютера Т не меняется.
По команде (15) программа из ОЗУ студенческого компьютера Р с номером n (n= 1,2,.... 15) пересылается в ОЗУ компьютера Т. Прежняя программа и данные в Т теряются.
При пересылках из Р в Г работающая в Р программа прерывается, ОЗУ для Р не изменяется и во всех случаях на экране Р высвечивается сообщение WAIT (ждите).
ПРИМЕР 10
А. „РЕСЕСИГРА”^) В. _RECE(,9)
Здесь в первом случае программа из компьютера 9 записывается на диск под именем «ИГРА», а во втором случае эта же программа пересылается в оперативную память Т.
Прием программ, данных или содержимого видеопамяти из Р в 7 в машинном коде реализуется командой
_BRECEIVE (name, n, Al, A2, S)(16)
Здесь все параметры в В REC, кроме п, являются необязательными, а их смысл тот же самый, что и в командеBSEND.
Рассмотрим некоторые случаи.
Случай 1.
_BREC (name, n, Al, А2)(17)
При выполнении (17) программа или данные в машинных кодах из диапазона адресов от А1 до А2 ОЗУ студенческого компьютера с номером п пересылаются в Г и записываются на диск под именем name. Содержимое оперативной памяти передающего и принимающего компьютеров не изменяется. Если записывалась программа, то в последующем ее стартовым адресом для команды В LOAD будет А1.
Пример и
-BREC("ЦИРК",3,&Н8000,&Н9000)
Случай 2.
_BREC (, п, Al, А2, S)(18)
При выполнении (18) содержимое видеопамяти (экрана студенческого компьютера с номером п в диапазоне адресов от А1 до А2 пере сылается в видеопамять Т по тем же самым адресам. Предварительно в Т автоматически устанавливается требуемый режим видеопроцессора.
ПРИМЕР 12
_BREC(,4,,,S) С. _RUN
Случай 3 (см. (16)).
При выполнении (16) содержимое видеопамяти студенческого компьютера с номером п в диапазоне адресов от А1 до А2 принимается и записывается в машинных кодах на диск под именем паше. В дальнейшем при использовании name командой BLOAD требуется предварительная установка необходимого режима экрана.
Прием программ и данных в Р. Пусть студенческий компьютер Ч (Ч = Ь 2, .... 15) находится в состоянииENACOM, то есть ему доступен расширенный набор сетевых команд. Тогда, в частности, можно использовать и командыRECEIVE иBRECEIVE для приема в q программ и данных из оперативной памяти и видеопамяти других компьютеров Р и Т.
КомандаRECEIVE записывается в одной из возможных форм:
_RECE (, п) _RECE (, 0) RECE (name, 0)
В любом варианте при выполнении RECE в студенческий компьютер q принимается некоторая программа.
В первом случае прием проводится из компьютера n (n^O, n^q).
Во втором случае прием организуется из ОЗУ Т.
В третьем случае принимается программа, записанная на диске под именем name. Оперативная память Т не изменяется.
КомандаBRECEIVE записывается в следующих формах:
_BREC (n, Al, А2, S)
_BREC (, 0, Al, А2, S) _BREC (name, 0, Al, А2, S)
В любом из этих вариантов при выполненииBREC в видеопамяти студенческого компьютера q в диапазоне адресов от А1 до А2 принимается набор данных.
В первом случае прием организуется из видеопамяти компьютера n (n#=0, n=£q) из диапазона адресов от А1 до А2 с автоматическим настроем в q требуемого режима экрана.
Во втором случае прием проводится из видеопамяти Т из диапазона адресов от А1 до А2 с автоматическим настроем в q требуемого режима экрана.
190
В третьем случае данные принимаются с диска, записанные там командами BSEND или BREC с параметром S под именем паше. Режим экрана в q требует предварительной установки. Оперативная память в Т не изменяется.
Пример 13.
_BREC(,7,,,5)
.BREC<>0,,,S)
С. Пусть на компьютере 15 запущена на счет программа
С.10 SCREEN 0:COLOR 15,4,4sWIDTH 40
20 PRINT "... искать же чего-либо -"
30 PRINT "хотя вы гривов или "
40 PRINT 11какую-либо завимость 11
50 PRINT "нельзя иначе, как11
60 PRINT ”смотря и провуя.11
Если на компьютере 5 выполнить команду
_BREC (, 15, 0, &Н777, S)
то на его экране появится высказывание Д. И. Менделеева, набранное в операторах PRINT строк 20—60 и лучше всего объясняющее читателю, как усвоить сетевые команды.
Работа с байтами данных. Среди сетевых средств имеются и такие, которые позволяют непосредственно обращаться к байтам данных оперативной памяти (&Н8000—&HFFFF) или сетевого ОЗУ (&Н7800—&H7FFF) своего компьютера. Кроме того, из Т подобное обращение возможно и к студенческим компьютерам Р. Речь идет о командахРОКЕ иРЕЕК.
Команда РОКЕ имеет такие формы записи:
POKE (w, А)(для Г и Р)09)
POKE (w, А,п) (для 7)^20)
POKE (w, А,п, N) (для Т)(21)
Остановимся на каждой из них в отдельности.
Команда (19) используется в любом компьютере для записи значения арифметического выражения w в байт памяти по адресу А своего сетевого ОЗУ.
Команда (20) используется в компьютере Т для записи значения w в байт оперативной памяти по адресу А студенческого компьютера с номером п.
Команда (21) используется в компьютере Т для записи значения w в байт сетевого ОЗУ по адресу А студенческого компьютера с номером п.
ПРИМЕР 14
А.„РОКЕ(222,&Н7900)
В.W=50:„РОКЕ(W,&НВВВВ,5>
С.W=17!„POKE(W+2,8cH7800,3,N)
КомандаPEEK (v, А) имеет следующие формы записи
— PEEK (V, А)
(для Т и Р)
(22)
— PEEK (v, А, п)
(для 7)
(23)
_РЕЕК (v, A, n, N)
(для 7)
(24)
Опишем семантику этой функции для каждого из отмеченных случаев в отдельности.
Команда (22) используется в любом компьютере. При ее выполнении переменная v получает значение, равное числу из байта своего сетевого ОЗУ по адресу А.
Команда (23) используется в компьютере Т. При ее выполнении переменная v получает значение, равное числу из байта оперативной памяти по адресу А студенческого компьютера с номером п.
Команда (24) используется в компьютере Т. При ее выполнении переменная v получает значение, равное числу из байта сетевого ОЗУ по адресу А студенческого компьютера с номером п.
ПРИМЕР 15
А.„РЕЕК(X,&Н7800):PRINTX
В.„РЕЕК(Y,&Н8000,7)
„РЕЕК(Z,&H7FFF,8,N)
Более содержательные примеры с командамиРОКЕ иРЕЕК будут приведены в последующих пунктах.
Передача команд из Г. Любую команду на Бейсике можно переслать из учительского компьютера Т для выполнения в Р. Делается это по команде.
SNDC (command, п)
Здесь второй параметр п не является обязательным. Если он отсутствует или равен нулю, то command пересылается во все студенческие компьютеры и там выполняется. В противном случае пересылка организуется только в Р с номером п.
192
ПРИМЕРЫ 16
чистка экрана в компьютере 10 _SNDC("CLS",10)
удаление строки-подсказки в компьютере 5
_SNDC("KEY OFF",5)
Если в Р из Т передана некоторая команда, а там выполняется программа, то вычисления по ней прерываются и реализуется поступившая команда. Одновременно вSNDC можно посылать несколько команд. Между ними в качестве разделителя требуется размещать символ ";" или код CHR$(13).
ПРИМЕРЫ 17
10 A»="FOR 5=1 ТО 99:PRINT S;:NEXT"
20 C«="STOP"
30 _SNDC(A$+CHR$(13)+С$,8)
10 At="FOR 5=1 TO 99:PRINT S;:NEXT"
20 C$="STOP"
30 _SNDC(A$+":"+C$,8>
Общая «длина команд» в SNDC не может превосходить 38 символов. Поэтому в некоторых случаях приходится использовать подряд несколько командSNDC. Однако это может привести к сбойным ситуациям. Пусть, например, из Т требуется выполнить такие действия. Записать программу, находящуюся в ОЗУ компьютера 3, в виртуальную память (на диск mem) под именем "МОРЕ", а затем переслать в 3 программу с диска под именем "ОКЕАН". В примере 18 приведены два «решения» этой задачи. Первое из них несостоятельное. Здесь пересылка файла "ОКЕАН" начинается до окончания записи в mem файла "МОРЕ" (если последний не очень мал). Во втором случае этого не происходит. Там организован периодический опрос состояния в компьютере 3 ячейки &HF16E, «сигнализирующей» значениями 2 и 0 соответственно о продолжении или завершении операции SAVE "mem:МОРЕ".
ПРИМЕРЫ 18
10 K»=CHR»(34)ькавычки
20 V$=CHR$(13)'возврат каретки
30 _SNDC(” SAVE"+K#+"memsM0PE"+K$+V#,3)
40 _SEND("ОКЕАН",3)
7 Заказ 6271 93
10 K*=CHRt(34>:V*=CHR»(13)
20 „SNDC("SAVE"+K*+"mem:MOPE”+K«+V*S 3>
30 FOR S=1 TO 200:NEXT
40 „PEEK(X,&HF16E,3,N)
50 PRINT X;:IF X=2 THEN 30
60 „SEND<"ОКЕАН",3)
По SNDC можно посылать из T в Р и любые сетевые команды, кроме ONLINE, доступные для Р в данный момент времени.
Пример 19. Отключение из Т студенческого компьютера номер 7 от локальной сети.
„SNDC("„OFFLINE",7)
Команды запуска программ и их останова можно передавать из Т в Р непосредственно, безSNDC.
По команде RUN (п, гл) программа из ОЗУ студенческого компьютера с номером п запускается на счет со строки т. Если программа уже выполнялась, то она прерывается и заново запускается со строки т. Оба параметра в RUN не обязательны. При отсутствии m программа запускается со строки с наименьшим номером. При отсутствии п или п=0 запускаются программы во всех Р.
П И М Е Р Ы 20
. „RUN(3,20) В. „RUN(0,100)
По команде STOP(n) на компьютере с номером п производятся действия, аналогичные тем, которые вызываются нажатием на клавиатуре клавиш CTRL — STOP, то есть выполнение программы прерывается, вывод текста по LIST прекращается и т. п. Если параметр п не указан, то действиеSTOP распространяется на все Р.
ПРИМЕРЫ 21
А,А,STOP(5) В.STOP(5) В.„STOP„STOP
А,
А,
STOP(5) В.
STOP(5) В.
„STOP
„STOP
Почтовые ящики. В сетевом ОЗУ каждого компьютера имеется 2 специально выделенных участка памяти объемом по 256 байт, называемых соответственно передающим (SE) и принимающим (RE) почтовыми ящиками. Их начальные адреса можно получать так.
Для передающего ящика (SE):
РЕЕК(Х, &H7C84):_PEEK(Y, &Н7С85):А1 =X+256-Y
А1=&Н7900
Для принимающего ящика (RE):
_РЕЕК(Х, &H7C86):_PEEK(Y, &H7C87):A2=X + 256-Y
А2=&Н7В00
С компьютера Т обмен содержимым почтовых ящиков Т и Р осуществляется по командам SNDMAIL и RCVMAIL (mail— почта).
По команде SNDMAIL (п) содержимое передающего ящика SE компьютера Т пересылается в принимающий ящик RE студенческого компьютера с номером п. Если п не задан, то пересылка осуществляется во все Р.
ПРИМЕРЫ 22
SNDMSNDM- ПЕРЕСЫЛКА SE ИЗ Т- ПЕРЕСЫЛКА SE ИЗ Т
SNDM
SNDM
- ПЕРЕСЫЛКА SE ИЗ Т
- ПЕРЕСЫЛКА SE ИЗ Т
10 FOR К=4 ТО 710 FOR К=4 ТО 7ВО ВСЕ Р ПЕРЕСЫЛКА SE ИЗ ТВО ВСЕ Р ПЕРЕСЫЛКА SE ИЗ Т
10 FOR К=4 ТО 7
10 FOR К=4 ТО 7
ВО ВСЕ Р ПЕРЕСЫЛКА SE ИЗ Т
ВО ВСЕ Р ПЕРЕСЫЛКА SE ИЗ Т
20 _SNDM(K)20 _SNDM(K)В КОМП'ЮТЕРЫ 4-7В КОМП'ЮТЕРЫ 4-7
20 _SNDM(K)
20 _SNDM(K)
В КОМП'ЮТЕРЫ 4-7
В КОМП'ЮТЕРЫ 4-7
30 NEXT
Отметим, что специальных средств для формирования и чтения содержимого почтовых ящиков нет. Делать это можно, например, побайтно, с помощью командРОКЕ и функцииРЕЕК (см. примеры 23 и 24).
Пример 23. Формирование содержимого передающего почтового ящика SE на Т и его передача в компьютер 5.
10 А1*="Век живи - век учись! "
20 А2*="и ты наконец достигнешь "
30 А3*="того, что, подобно мудрецу, *
40 А4*=нБудешь иметь право сказать, "
50 А5*="что ничего не знаешь. "
60 А6*=”КОЗЬМА ПРУТКОВ В"
70 А*=А1*+А2*+А3*+А4*+А5*+А6*
80 „PEEK(X,&Н7С84):_РЕЕК(Y,&Н7С85)
90 A1=X+256XY* А1=&Н7900
100 FOR S=1 ТО LEN(At)
110 „РОКЕ(ASC(MID*(А*,3,1> >,A1+S-1>
120 NEXT
130 SNDMAIL(5>
Пример 24. Распаковка содержимого принимающего почтового ящика (RE) на студенческом компьютере 5.
10 _РЕЕК(Х,&Н7С86) :„PEEK(Y,&Н7С87)
20 A2=X*256XY*&Ь7В00
30 А*=
40 _PEEKCR,S):R»=CHR»(R>
50 IF RS<>"й" THEN A»=A$+R$:S=S+1:GDTO 40
60 PRINT AS
По команде RCVMAIL(n) содержимое передающего ящика SE студенческого компьютера с номером п записывается в принимающий почтовый ящик RE компьютера Т (см. примеры 25 и 26).
В примере 25 показано формирование содержимого передающего ящика SE в компьютере 6.
10 ’ целые неотрицательные числа в ящик
20 DATA 7:'количество чисел
30 DATA 260, 1, 700, 3, 150, 684, 900
40 Al=&h7900:READ К:RESTORE 20
50 FOR S=0 TO К:READ R:A=A1+2XS
60 _P0KE<RM0D256,A):„POKE(R\256,A+l)
70 NEXT
В примере 26 иллюстрируется прием на Г в почтовый ящик RE содержимого передающего почтового ящика SE с компьютера 6 и распаковка полученных данных.
10 _RCVMAIL(6>
20 A2=&H7B00:_PEEK(U,А2):_РЕЕК(Т,А2+1)
30 K=U+256XT
40 FOR S=1 ТО K:A=A2+2XS
50 _PEEK(U,А):„РЕЕК(Т,A+l)
60 R=U+256XT:PRINT R;
70 NEXT
Передача сообщений. Обмен короткими сообщениями между компьютерами можно проводить с помощью команд MESSAGE и ТАЕК. Сообщения индицируются на последней строке экрана и не должны превышать 56 символов и установленной ширины текстового
экрана. Если принимающий компьютер находится в графическом реяшме, то переданное ему сообщение будет выведено на экран лишь после перевода его в текстовый режим (SCREEN 0 или SCREEN 1).
По командеMESSAGE (mes, п) значение строкового выражения mes в качестве сообщения пересылается в студенческий компьютер с номером п. Если п отсутствует, то сообщение передается всем подключенным к сети компьютерам Р.
ПРИМЕРЫ 27
_MESS("ПРЕКРАЩАЙТЕ РАБОТУ !")
_MESS("РЕШАЙТЕ ЗАДАЧУ 3",11)
По командеTALK (mes, v)(25)
значение строкового выражения mes передается в качестве сообщения из любого студенческого компьютера п. Если передача проходит успешно, то числовая переменная v принимает значение 0, если нет — 255. Рассмотрим два возможных случая.
п находится в состоянииDISCOM.
Передача сообщения возможна только учительскому компьютеру Т. Переменная v в (25) должна иметь значение 0.
ПРИМЕР 28
V=0:Х$="МОЖНО ВЫЙТИ ?":„TALKСХ$,V)
п находится в состоянииENACOM.
Передача сообщения возможна любому компьютеру, подключенному к сети. Переменная v должна иметь значение, равное номеру компьютера, которому сообщение передается.
ПРИМЕР 29
10 У=7:У*="ПЕТЯ ! ПОМОГИ РЕШИТЬ ЗАДАЧУ"
20 _TALK(Y»,7)
Вот мы и ознакомились с довольно разнообразными и интересными средствами для работы с локальной вычислительной сетью в Бейсик-системе. Несмотря на простоту синтаксиса и прозрачность семантики рассмотренных команд и функций, их использование в реальных ситуациях в классе приводит к существенным потерям времени как учителя, так и студентов. Какой же отсюда следует вывод? Необходимо иметь удобные инструментальные средства для работы с локальной сетью.
ЧАСТЬ 2. АЛГОРИТМЫ
Применение математических методов не полезно» а вредно до тех пор, пока явление не освоено на доматематическом гуманитарном уровне.
Е.Вентцель
Во второй части пособия рассматриваются алгоритмы решения некоторых конкретных задач. В каждом случае дается полное описание алгоритма, а также или его обоснование, или обсуждение подходов к соответствующему обоснованию. Программы решения задач иллюстрируются многочисленными примерами. Выбор материала, на первый взгляд, может показаться весьма специфичным. Однако он продиктован отнюдь не случайными обстоятельствами, а отражает весьма широкий спектр возможных приложений приведенных алгоритмов и то незначительное внимание, которое отводится им в курсах численных методов по действующим программам естественнонаучных специальностей педагогических институтов.
Остановимся кратко на содержании данной части. Из методов внутренней сортировки подробно разобраны два наиболее интересных и эффективных по быстродействию и объему используемой дополнительной памяти алгоритма. Речь идет о так называемых пирамидальной и быстрой сортировках. Далее, на основе алгоритма генерирования перестановок решается задача коммивояжера при количестве пунктов п ^ 10. Симплекс-метод для общей задачи линейного программирования реализован двумя программами. При этом предварительного сведения задачи к канонической не требуется и ввод ограничений организуется весьма естественным способом. Из частных задач линейного программирования рассмотрены транспортная задача и задача о назначениях. Первая из них решается методом потенциалов, а для второй используется венгерский алгоритм. Наконец, обсуждаются три алгоритма приближенного вычисления корней многочленов с вещественными или комплексными коэффициентами. Стоит отметить, что последний из них — метод «обруча» — оказывается пригодным даже для нахождения корней большой кратности. Правда, в этом случае часто наблюдается потеря точности вычислений.
СОРТИРОВКА. ПОИСК. ПЕРЕБОР
Сортировка. Основные понятия
Пусть задан файл К, состоящий из записей
Ц1), Х(2), .... X(n)(1)
Припишем каждой записи % (i) некоторый признак или, по-другому, ключ KX(i)(i= 1. п). Обычно ключ — это какое-либо отдельное поле или комбинация полей записи. Будем считать, что на множестве ключей задано отношение линейного порядка или следования с обычными свойствами. Иными словами, элементы этого множества можно выстроить в порядке неубывания (невозрастания).
Задача сортировки файла ставится так. Найти такую перестановку записей (1):...,о., ....
Р(1), И (2), И (п)(2)
чтобы их ключи располагались в неубывающем порядке:
Кц(1) С Кц(2) < • < Ки(л).
При решении научных и технических задач довольно часто запись целиком составляет поле ключа.
Для получения из (1) файла (2), вообще говоря, требуется физическое перемещение записей в памяти ЭВМ. Во многих случаях нет надобности реально иметь перестановку (2). Достаточно описать ее тем или иным способом так, чтобы обеспечить непосредственный доступ к записям (1) в соответствии с порядком следования их ключей. Сделать это можно по-разному, например составлением списка адресов (индексов) элементов (2) в файле (1). Построение для (1) такого списка называют или адресным кодированием, или адресной сортировкой. Реализуется она просто, но требует дополнительной памяти. Часто адресное кодирование применяется в качестве первого этапа для обычной сортировки, то есть получения перестановки (2).
Пример 1. В таблице 1 приведен файл из 7 записей. Каждая из них представляет собой один элемент символьного массива и относится к конкретному студенту, имеющему задолженность по какому-либо предмету. Запись состоит из 5 отдельных полей- номер, фамилия и инициалы, курс, предмет, тип задолженности. Адресное кодирование данного файла в алфавитном порядке фамилий студентов осуществляется построением списка:
5, 6, 7, 2, 4, 1(3)
Таблица 1 Файл «Задолжники*
Ф. И. О.
Курс
Предмет
Тип задолженности
1 Щукина Э.
2Д
алгебра
зачет
2 Паниковский М. С.
1Б
физика
экзамен
3 Бендер О. И.
ЗА
физика
зачет
4 Синицкая 3. В.
1Е
геометрия
экзамен
5 Воробьянинов И. М.
4В
алгебра
экзамен
6 Востриков Ф.
1В
физика
зачет
7 Изнуренков А. В.
5Г
алгебра
зачет
Здесь 3 указывает на первую запись (Бендер О. И.), ..., 1 — на последнюю запись (Щукина Э.).
При необходимости список (3) можно использовать для реального перемещения соответствующих записей в файле «Задолжники».
Иногда конкретный файл приходится сортировать одновременно по нескольким ключам.
Традиционно различают внутреннюю сортировку, обрабатывающую данные, хранимые в оперативной памяти, и внешнюю сортировку, оперирующую с данными, расположенными на дисках. Проблемы оптимизации существенно различаются в обоих случаях. При внутренней сортировке стараются уменьшить число сравнений ключей и перемещений записей файла. Во внешней сортировке решающим фактором эффективности соответствующего алгоритма становится количество обращений к дисковым устройствам.
В дальнейшем мы будем вести речь только о внутренней сортировке и рассматривать файлы, представляющие собой числовые или символьные одномерные массивы. Записями и ключами таких файлов будем считать значения соответствующих элементов массивов. Это не является каким-либо существенным ограничением. Дело в том, что обсуждаемые алгоритмы легко переносятся и на более общие случаи внутренних сортировок.
Пример 2. Отсортировать числовой массив:
3, 8, 4, 8, 5.14, 9, 1.(4)
Обычная сортировка (4): 1, 3, 4, 5.14, 7.2, 8, 8, 9.
Адресная сортировка (4):
3,8,4,8,5.14,9,1
2,2,3,7,4,8,1
Имеется много разных алгоритмов сортировок. Самый простой и популярный из них — это «пузырьковая сортировка». Название ее происходит от образной интерпретации, при которой в процессе выполнения алгоритма более «легкие» элементы мало-помалу всплывают на «поверхность».
Пусть S — числовой массив
а (1), а (2), ... а (и)
Говорят, что элементы а(/) и а(/) из S образуют инверсию, если<•</ и а(0>а(/).
Алгоритм «пузырьковой сортировки» состоит в последовательных просмотрах снизу вверх (от конца к началу) массива S и обмене местами соседних элементов с инверсией. Более точно его можно понять из программы примера 3. Трудоемкость рассматриваемого алгоритма О (гг), то есть при любых S и п он решает задачу за С-п2 операций сравнений и обменов, где С — константа, от п не зависящая.
Пример 3. «Пузырьковая сортировка»
10 ’ПУЗЫРЬКОВАЯ СОРТИРОВКА
20 ’ ==================================
30 SCREEN 0:COLOR 15,4:KEY OFF
40 INPUT "количества элементов ";Ns DIM A(N> 50 FOR 1=1 TON:A(I)=INT(RND(-TIME)*100):NEXT
60 ’ЯДРО
70 FOR 1=2 TO N:FOR J=N TO I STEP -1
80 IF A(J—1)>A<J) THEN SWAP A(J-1),A(J)
90 NEXT J,I 100 ’
110 FOR 1=1 TO N:PRINT A(I);:NEXT I
120 END:’трудоемкость алгоритма - O(nXn>
По данной программе по введенному числу N создается случайный массив из N целых чисел со значениями от 0 до 99, организуется его сортировка и последующая индикация. Ядром алгоритма являются строки 60—100.
«Пузырьковая сортировка» не требует для реализации дополнительной памяти. Однако из-за плохих временных характеристик она имеет лишь исторический интерес и вряд ли может быть рекомендована для практического использования. В следующих пунктах будут приведены два весьма эффективных алгоритма: «Пирамидальная сортировка» и «Быстрая сортировка». Первый из них имеет трудоемкость О (п*1п п). Что касается второго алгоритма, то оценка трудоемкости у него не такая отличная, но большинство реальных массивов он сортирует быстрее первого.
2. Сортировка с помощью дерева
Все методы сортировок основаны на многократных просмотрах массивов S и выполнении определенных операций над их элементами. Как можно улучшить какой-либо из конкретных алгоритмов? По- видимому, путь один — за каждый просмотр всего S или его части получать как можно больше информации. Одна из возможностей на этом пути открывается при представлении сортируемого массива S в виде нелинейной структуры типа двоичного (бинарного) дерева D. На рисунке 30 показан такой граф D для S из п элементов, где 8 ^ и < 16. В кружках размещены элементы массива:
9, 14, 8, 1, 5, 4, 9, 12, 3, 17, 1, 3
Натуральными числами начиная от 1 И далее сверху вниз по уровням и слева направо на одном уровне пронумерованы все вершины D. Эти номера (адреса) проставлены около вершин. Именно такая адресация и будет использоваться в дальнейшем.
У бинарного дерева имеется, и притом только один, корневой узел, для которого нет предшественников (родителей). Адрес корня—1. Любой другой узел имеет только одного предшественника и одного или двух преемников (потомков).
Иногда деревья изображают в виде двумерного массива с явным указанием адресов родителей и потомков для каждого узла к^к=\, п). Однако в реальных ситуациях эти адреса проще не хранить, а вычислять по номеру к по таким формулам:
2*к, к = \, 2, .... п\2О, к > п\2'2*к, к = \, 2, .... п\2О, к > п\2'а) Для родителей х^ = к\2, к = \, 2, .... п.
2*к, к = \, 2, .... п\2
О, к > п\2'
2*к, к = \, 2, .... п\2
О, к > п\2'
б) в)б) в)Для потомка слева у (6) =
б) в)
б) в)
Для потомка справа
( 2*6+1, 6=1, 2 (п—1)\2
Л 0,к>^-\)\2•
Заметим, что любой узел в дереве может быть корнем другого дерева — поддерева, именуемого номером узла, выбранного в качестве его корня.
Описанное представление массивов S в форме бинарных деревьев D будет использовано в следующем пункте. Сейчас же мы остановимся на одном родственном представлении S и некоторой дополнительной для S информации в форме дерева. Это позволит понять суть целой серии так называемых бинарных, или, по-другому, турнирных, сортировок. Пусть элементы S размещены в узлах нижнего уровня D (см. рис. 31). Тогда отсортировать S можно в два этапа, называемые соответственно «построением исходного дерева выбора» и «непосредственной сортировкой». Опишем их.
Этап 1. На первом шаге с помощью п\2 сравнений определяем наименьший из каждой пары элементов S с общим роди- 202
-*- Шаг 4
Шаг 3
•*— Шаг 2
шаг 1
_ Нижний Уровень
телем. На втором шаге за не более чем п\44-1 сравнений находим наименьший элемент для пар уже отобранных ранее значений и т. д. В общем случае построение дерева выбора, корнем которого окажется наименьший в массиве ключ, потребует всего n —1 сравнений.
Этап 2. Объявляем число а в корне дерева очередным элементом отсортированного массива и спускаемся в D по пути, им обозначенному. При наличии нескольких таких путей при движении сверху вниз предпочтение будем отдавать тем из них, которые включают потомков слева. Исключаем а из нижнего уровня D, заменяя его на -|-оо, и проводим дополнительное сравнение элементов для пройденной ветви. При этом в корень D «всплывет» следующий наименьший элемент и т. д. Проход по ветви для отыскания очередного элемента отсортированного массива изображен на рисунке 32.
После n-кратного выполнения этапа 2 дерево D будет состоять из значений + оо и процесс сортировки закончится.
Для однократного выполнения второго этапа требуется выполнить log2 п сравнений. Поэтому общая трудоемкость описываемых сортировок составляет O(n-log2n) операций.
Отдельные алгоритмы турнирных сортировок строятся на основе изложенного метода и отличаются друг от друга способом представления исходной и сопутствующей информации, объемом дополнительно используемой памяти и т. п. При плохой организации вычислений трудоемкость оказывается хуже, чем О (п • log2 и).
Рис. 32
1.3 Пирамидальная сортировка
Алгоритм сортировки массивов S, предложенный Дж. Уильямсом и развитый Р. Флойдом, носит название «пирамидального». Он базируется на представлении S в виде бинарного дерева D, не требует дополнительной памяти и имеет трудоемкость О (п • log2 п). Об этом алгоритме и пойдет речь дальше. Начнем с определения.
Пусть задан массив
S (1), S (2)S (п)(5)
Пирамидой называется непустая последовательность элементов (5) вида
S(p),S(p+l),...,S(fl)(l<p«n)(6)
для которой выполнено одно из следующих условий.
2p>q
’2) 2p = q и S (p)>S (q)
2p<q и
S(/)>S(2/) Ip^j^q^
S (j^S (2/ +1) (р</<(^-1)/2)
Из определения немедленно вытекают такие утверждения:
Для любой последовательности (5) подпоследовательность
S(n\2 + 1), S(n\2+2), ..., S (n) является пирамидой.
Если последовательность (5) — пирамида, то
S(l)>maxS(j)
(7)
Если последовательность (5) — пирамида и представлена в виде бинарного дерева D, то значение любого узла в D будет не меньше значений его левого и правого потомков.
Пример 4. Последовательность
90, 70, И, 8, 3, 9, 7, 5, 6, 1, 2
является пирамидой. Наглядно это видно из рисунка 33.
Теперь можно приступить к описанию алгоритма пирамидальной сортировки. Состоит она в реализации двух этапов. Остановимся на них подробнее.
Этап 1. Построение пирамиды. В (5) «хвост», т. е. подпоследовательность
S (п\2+1), S (п\2 + 2), .... S (и) (8)
как мы уже отмечали, является пирамидой. Будем наращивать (8), добавляя к ней оставшиеся элементы из (5). Пусть S (/+1), S (/ + 2), .... S (п) — пирамида. Припишем к ней слева элемент S (/):
SO), S(/+l), .... S(n) (9)
и преобразуем (9) снова в пирамиду. Для этого «просеем» S 0) по соответствующей веточке двоичного представления (5). Делается это так. Рассмотрим S (/) и два его потомка S (2/) и S (2/4- 1). Если S 0) не меньше потомков, то вычисления прекращаем, ибо (9) — уже пирамида. В противном случае обмениваем значения
SO) и max (S(2/), S(2/4-1))
в соответствующих позициях D и «опустившийся» элемент продолжаем просеивать тем же самым способом. В конце концов преобразованная последовательность (9) станет пирамидой.
Продолжая наращивание (9), мы превратим весь массив (5) в пирамиду. При этом окажется выполненным неравенство (7).
Объявляем полученную пирамиду S текущей и переходим к следующему этапу.
Этап 2. Сортировка пирамиды. В текущей пирамиде S первый элемент не меньше остальных. Поступим с ним так. Обменяем значениями концевые элементы S и укоротим S справа на 1. Полученная последовательность уже может и не быть пирамидой Применим к ней процесс «просеивания» для элемента S (1), описанный на этапе 1. Преобразованная последовательность S становится пирамидой.
Повторяя этап 2 (п — 1) раз, отсортируем S по невозрастанию
Отдельные этапы проведения «пирамидальной сортировки» наглядно можно проследить на конкретном примере, прогоняя его или на бинарном дереве D, или непосредственно выписывая текущие последовательности S.
Пример 5. Для последовательности 23, 77, 12, 7, 44, 82, 16, 53 произвести «пирамидальную сортировку», выписывая текущие зна чения S в процессе выполнения алгоритма.
В строках таблицы 2 показаны требуемые значения S после каждой реализации этапов 1 и 2. При этом в первом случае ступенчатая линия отделяет остаток последовательности от наращи ваемой слева пирамиды, а во втором — сокращаемую справа последовательность перед просеиванием се первого элемента от формируемого с конца отсортированного массива.
!построение пирамиды!
•237712744821653!
!237712534482167!
•237782534412167*
!237782534412167!
!827723534412167!
!сортировка пирамиды!
!777235344121682!
•165323744127782!
!124423716537782•
•121623744537782!
!716122344537782!
!127162344537782!
!712162344537782!
Анализ «пирамидальной сортировки» показывает, что для ее выполнения требуется не более Зп log2 п элементарных операций типа сравнении и обменов. Подобная эффективность и гарантированная надежность для худшего случая часто оказываются решающими факторами, заставляющими в конкретных ситуациях отдавать предпочтение данному способу сортировки.
В примере 6 приводится программа для «пирамидальной сортировки» одномерных массивов по неубыванию. Для сортировок по невозрастанию в строках 320 и 330 необходимо знаки отношений "<" и "■>=." заменить соответственно на ">" и на "<=".
Ядром программы являются строки 250—350. Строка 260 организует построение пирамиды, а строки 270—290 — ее сортировку. На обоих этапах вычислений используется подпрограмма «просеивания», расположенная в строках 310—350. Некоторые временные характеристики программы при прогонке примеров на ЭВМ «Ямаха» указаны в строках 120—160. Например, массив из 2000 элементов сортируется менее чем за 11 минут. Учитывая весьма медленное быстродействие используемого компьютера, следует признать это время вполне приемлемым.
Пример 6. Программа «пирамидальной сортировки»
10 *ПИРАМИДАЛЬНАЯ СОРТИРОВКА
20 »
30 ’ХАРАКТЕРИСТИКИ ПРОГРАММУ
40 • —. 50 ’ По программе "ПИРАМИДА” проводятся
60 'сортировки одномерных массивов по неу— 70 'выванию. Ключами являются элементы мас- 80 'сива. Для сортировок по невозрастанию 90 'неовходимо в строках 320 и 330 знаки от- 100 'ношений заменить соответств. на > и <=. 110 ' Общее количество операций- OCNXLN(N)). 120 ' Время сортировки Т:
130
>
№100 ,
Т=
19.0
сек
140
>
№500 ,
Т=
2
МИН
8.0
сек
150
№1000,
Т=
4
мин
47.7
сек
160
9
№2000,
Т=
10
мин
37.1
сек
180
185
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
SCREEN 0:COLOR 15,4:KEY OFF DEFINT N,K,X,Y,J PRINT “ПИРАМИДАЛЬНАЯ СОРТИРОВКА” PRINT ""
INPUT "количество элементов ";N:DIM S(N) CLS
LOCATE 8,9:PRINT "проводятся вычисления" GOSUB 430
TI ME=0:K=N:'== ====================ЯДРО FOR J=N\2 TO 1 STEP-1:X=J:GOSUB 310:NEXT FOR K=N—1 TO 1 STEP -1
SWAP S(l),S(K+1):X=1:GOSUB 310 NEXT:GOTO 360 ’подпрограмма просеивания
Y=X+X:ON SGN(Y-K)+2 GOTO 320,330,350 IF S(YXS(Y+1) THEN Y=Y+1
IF S(X)>=S(Y) THEN 350
SWAP S(X>, S(Y>:X=Y:GOTO 310 RETURN:’===========================ВЫВОД CLS
PRINT "время сортировки —";TIME/50;"сек" PRINT "количество элементов -";N:PRINT PRINT "массив:";
FOR J=1 TO N:PRINT S(J);:NEXT J
END:*имя программы "ПИРАМИДА"
*ввод или генерирование массива
FOR J=1 ТО N:S(J)=INT(RND(1)X100>:NEXT J RETURN
1.4. Быстрая сортировка
При «пузырьковой сортировке» производились обмены ключей в соседних позициях. При «пирамидальной сортировке» такой обмен совершался между ключами в позициях, жестко связанных друг с другом соответствующим бинарным деревом. Здесь будет рассмотрен алгоритм сортировки К. Хоора, использующий несколько иной механизм выбора значений для обменов. Этот алгоритм называется или сортировкой с разделением, или «быстрой сортировкой». В первом случае подчеркивается положенный в его основу метод последовательного дробления массива на части, а во втором — неожиданная эффективность. В подавляющем большинстве реальных случаев использование «быстрой сортировки» дает лучшие временные результаты по сравнению с другими методами. Однако следует иметь в виду, что для нее нет гарантированной трудоемкости типа О (л • log2 п), где п — количество элементов массива. Более того, в иных ситуациях трудоемкость достигает О (п2) и не может быть снижена. Иллюстрацией к этому могут служить упорядоченные массивы. Исходя из сказанного, в особо критических ситуациях, где результат должен выдаваться в жестко очерченном интервале времени, применять «быструю сортировку» следует весьма осмотрительно. По образному выражению Н. Вирта [18], «...быстрая сортировка напоминает азартную игру, где следует заранее рассчитать, сколько можно позволить себе проиграть в случае невезения».
Перейдем к сути метода. Пусть S (6) (6=1, л)— одномерный массив их — какой-либо элемент из S (к\ Сначала обсудим, как разбить S на две непустые непересекающиеся части Si и S2(Si(JS2=S) так, чтобы в Si оказались элементы, не превосходящие х, а в S2 — не меньшие х:
а<х, agSi b^x, b£S2.
Начнем с примера. Пусть в массиве S:
23, 17, 8,23, 17, 8,14 , 25, 6, 3, 30, 714 , 25, 6, 3, 30, 76,
23, 17, 8,
23, 17, 8,
14 , 25, 6, 3, 30, 7
14 , 25, 6, 3, 30, 7
зафиксирован элемент х=14. Просматриваем S слева направо, пока не найдем а>х. Получим а = 23. Далее, просматриваем S справа налево, пока не найдем 6<х. Получаем 6 = 7. Меняем местами а и 6. Продолжая этот процесс, придем к последовательности
6, 7, 3, 8, 6 | 25, 14, 17, 30, 23
разделенной на две требуемые части Si и S2.
В примере 7 показан алгоритм разделения для общего случая. Пример 7. Алгоритм разделения
10 ’ ввод N ; S(K), K=l,2,...N ; X
20 ’ 30 I=1:J=N
40 IF S(IKX THEN 1=1 + 1:GOTO 40
50 IF X<S(J> THEN J=J-l:60T0 50
60 IF K=J THEN SWAP S(I),S(J):1=1+1:J=J—1
70 IF K=J THEN 40
80 IF K=N THEN P=I-1 ELSE P=N-1
90 ’
100 ’ вывод S(K)s K=1,2S...N ; P
110 ’ P - позиция разделения
Через P обозначена позиция разделения Si и S2. Элементы от 1 до Р относятся к Si, а остальные — к S2.
В дальнейшем значение х для разделения S мы будем выбирать из «середины» массива. Если количество элементов в S четно, то есть имеются два кандидата на х, то условимся использовать из них тот, который имеет меньший индекс.
Теперь до алгоритма «быстрой сортировки» остается сделать один незначительный шаг. Разобьем S на две части St и S2 так, как это описано ранее. Аналогично поступим с Si и $2 и так далее, пока каждая из частей не будет содержать ровно 1 элемент. Легко понять, что в результате получится отсортированный массив. При реализации этой процедуры на ЭВМ остается позаботиться лишь о хранении адресов раздваиваемых подмассивов. Если каждый раз продолжать работу с меньшей из полученных частей, отправляя адреса начала и конца второй части на хранение, то потребуется совсем немного дополнительной памяти. Одновременно придется помнить не более 2 log2 п чисел (адресов). Скажем, при п^4000, log2 п< 12.
В примере 8 приведена программа «Быстрая», реализующая описанный алгоритм Хоора. В ней адреса подмассивов хранятся в виде наращиваемого стека, выборка из которого производится в порядке, обратном занесению. Иными словами, последний подмассив, обозначенный в стеке, обрабатывается первым. В строках 140—180 программы указано время сортировки по ней случайных контрольных массивов при разных п. Интересно провести сопоставление этих цифр с соответствующими данными для «пирамидальной сортировки».
Пример 8. Программа быстрой сортировки Хоора
10 ’БЫСТРАЯ СОРТИРОВКА
20 ’
30 ’ХАРАКТЕРИСТИКИ ПРОГРАММЫ
40 ’
50 ’ По программе “БЫСТРАЯ” проводятся сор- 60 ' тировки одномерных, массивов по неувыва- 70 * ним». Ключами являются элементы массива.
80 * Для сортировок по невозрастанию неовхо- 90 * димо в строках 310 и 320 знак отношения 100 ’ ”<“ заменить знаком ”>“.
110 ’ Дополнительная память :
120 ’ СТЕК СТ1(13),Т2(13)I
130 ’ Время сортировки случайного массива:
140
*
№100
9
т=
16.0
сек
150
№500
9
т=
1
мин
31.2
сек
160
>
№1000
9
т=
3
мин
14.2
сек
170
>
№2000
9
т=
6
мин
34.9
сек
180
№3000
9
т=
10
мин
18.-7
сек
190 ,
200 SCREEN 0:COLOR 15,4:KEY OFF
210 DEFINT I,J,A,B,K,T,N
220 PRINT “БЫСТРАЯСОРТИРОВКА XOOPA"
230 PRINT “”
240 INPUT “количество элементов ”;N:CLS
250 LOCATE 8,9:PRINT “.проводятся вычисления"
260 DIM S(N),T1(13),T2(13):8OSUB 480
270 TIME=0:’============================ЯДРО
280 K=1:T1(1)=1:T2(1)=N:’иниц. стека
290 A=Tl(K)sB=T2<K)sK=K-l:’—чтение из стека
300 I=AsJ=B:X=S((А+В)\2) :’разделение
310 IF S(IXX THEN I=I+1:GOTO 310
320 IF X<S(J) THEN J=J-1:GOTO 320
330 IF K=J THEN SWAP S(I>,S(J):1=1+1:J=J-1
340 IF K=J THEN 310
350 IF J—A>=B-I THEN 380:’запись в стек
360 IF I<B THEN K=K+1:Т1(К)=1:T2(К)=B
370 B=J:IF A<B THEN 300 ELSE 400
380 IF A<J THEN K=K+1:T1(K)=A:T2(K)=J
390 A=I:IF A<B THEN 300
.400 IF K>0 THEN 290:’==================ВЫВОД
410 CLS:PRINT "время сортировки — ";TIME/50
420 PRINT "количество элементов — ";N
430 PRINT ""
440 PRINT "массив:";
450 FOR U=1 TO N:PRINT SIU);:NEXT U
460 END:’имя программы "БЫСТРАЯ"
470 *ввод или генерирование массива
480 FOR J=1 ТО N:S(J)=INT(RND(1)X1000): NEXT
490 RETURN:’
Поиск. Основные понятия
С задачами поиска требуемой информации человеку приходится сталкиваться постоянно. Типичными примерами могут служить работа с тем или иным справочником, телефонной книгой, картотекой в библиотеке или распространенная до недавнего времени практика вычислений с помощью специальных таблиц. В последнем случае поиск конкретного значения функции заменял собой весьма трудоемкий процесс его непосредственного вычисления.
Перейдем к более формальному разговору о задачах поиска. Будем предполагать, что файл X состоит из записей
X (1), Х(2), .... Х(л)
с ключами Кад (« = 1, л) и К — некоторое значение. Встречающиеся на практике разновидности простейших задач поиска могут быть сформулированы в одном из следующих четырех видов.
Требуется определить по крайней мере одну запись в X, имеющую К своим ключом.
Все записи в X, имеющие К своим ключом.
Если в X нет записей с ключом К, то добавить в X новую запись.
Включить в X новую запись.
К называют аргументом поиска или запросом, задачи А и В — простым поиском, а задачи С и D — поиском со вставкой. Поиск по запросу К в задачах А и В может быть безрезультатным.
Иногда в задачах А — С поиск организуется не по совпадению с запросом К, а по выполнению некоторых условий для определенной функции от ключей. Примером может служить поиск по интервалу значений ключа, когда отыскиваются записи X(z) с условиями: а^Клю^б, где а и b — константы.
Методы поиска можно классифицировать по разным признакам: местонахождению X, изменению X, схеме доступа к отдельным записям X(z)(Z=l, п), способу сравнения ключей или функций от них и т. п. Например, поиск считается внутренним, если X целиком размещается в оперативной памяти, и внешним — в противном случае. Далее, для задач А и В поиск называется статическим, а для задач С и D — динамическим.
Мы будем заниматься только внутренним поиском. При этом ограничимся рассмотрением сформулированных задач, совершенно не затрагивая таких интересных обобщений, как поиск по запросам с искажениями. В дальнейшем под файлом будем понимать одномерный или двумерный числовой или символьный массив и, следовательно, вести поиск в одномерной или двумерной таблице.
Отметим, что различные варианты задач поиска встречаются при решении многих других проблем. Достаточно вспомнить ранее рассмотренные методы сортировок, где постоянно приходилось находить пары значений для текущих обменов. Впрочем, от правильной организации исходной информации во многом зависит эффективность алгоритмов поиска. И здесь уже сама сортировка может оказаться полезным предварительным преобразованием X.
В различных АСУ поиск требует наибольших временных затрат. Поэтому качество соответствующего программного обеспечения находится в прямой зависимости от типа используемого в нем алгоритма поиска.
К просто реализуемым методам поиска относится так называемый последовательный поиск, при котором осуществляется просмотр подряд всех записей X до получения решения задач А — С или их обобщений. Предоставим читателю самостоятельно написать соответствующие программы при последовательном поиске в упорядоченной или неупорядоченной одномерной таблице (линейном списке) и проанализировать их.
В примере 9 приведена программа одного из наиболее употребительных и эффективных методов поиска в упорядоченных массивах. Он имеет несколько названий: бинарный поиск, логариф-
213
мический поиск или метод деления пополам. Основная идея бинарного поиска довольно проста. Сначала К сравнивается со средним ключом в таблице. Результат сравнения или приводит к решению задачи, или позволяет определить, й какой части массива — верхней или нижней — продолжать поиск. Применяя описанный процесс к полученному «укороченному» наполовину массиву через не более чем log2 п сравнений, получим позитивное или негативное решение.
Пример 9. Бинарный поиск в упорядоченном одномерном массиве
10 ’ БИНАРНЫЙ ПОИСК ПО РАВЕНСТВУ (задача А)
20 ’ МАССИВ SC) ОТСОРТИРОВАН ПО НЕУБЫВАНИЮ
30ВВОд
40 COLOR 15,1:SCREEN 0s KEY OFF
50 INPUT "количество элементов S,;N:DIM S(N)
60 FOR 1=1 TO Ns READ S(I):NEXT I
70 DATA 2,7,8,9,13,15,16,17,18,23,24,89
80 INPUT "ключ"jK
90 A=1:B=N:’===========================ЯДРО
100 IF B>=A THEN I=(A+B)\2 ELSE 150
110 IF K<S(I) THEN B=I-1:GOTO 100
120 IF K>S(I> THEN A=I+lsGOTO 100
130 ’=================================ВЫВОд
140 PRINT *'I="? I, "S(D =";K:GOTO 160
150 PRINT "неудача"
160 ENDS’
Поиск в сети
Пусть задана ориентированная сеть S=(P, R, d) (см. рис. 34), где Р — множество вершин; R — множество дуг; d — функция, определенная на R со значениями в множестве действительных чисел.
Иногда d (х; у) интерпретируют как длину дуги (х, y)£R.
В различных алгоритмах оптимизации на сетях во внутренних циклах многократно приходится решать следующие две задачи.
Для фиксированной вершины х^Р определить все дуги сети вида (х, у) (выходы из х).
Для фиксированной вершины х^Р определить все дуги сети вида (у, х) (входы в х).
214
Если находить дуги, выходящие из х или входящие в х, примитивной процедурой поиска с перебором всех элементов из R, то трудно ожидать получения качественных алгоритмов.
Здесь мы обсудим один из способов ускорения поиска в сети. Будем считать, что S представлена в оперативной памяти в виде массива дуг X так, как это указано в таблице 3, и что записями X являются его отдельные строки.
Пусть вначале решается задача А. Отсортируем файл X по ключу х. Тогда ясно, что среднее время нахождения всех дуг (х, у) даже при последовательном поиске сократится примерно наполовину.
эффективный бинарный поиск. Но мы пойдем не по этому пути. Пусть имеется некоторый вспомогательный массив А, в позициях х которого записан адрес А (х) расположения в X начальной дуги вида (х, у). В этом случае проблема поиска всех дуг (х, у) сводится просто к выборке адреса А (х). Если, например, требуется найти в X все дуги вида (6, у), то, получив А (6)=8, сразу же попадаем на требуемый подмассив выходов из 6 (см. рис. 35).
Описанный способ решения задачи А предполагает, что х^Р— это натуральные числа. При этом для минимизации объема дополнительной памяти, т. е. величины / = тах х, желательно иметь после- Х^Р
довательную нумерацию вершин начиная с 1.
построить аналогичный простой механизм поиска входов в конкретную вершину. Однако при этом будет утеряна возможность эффективно решать задачу А. Поэтому поступим несколько иначе. Введем
в рассмотрение два вспомогательных одномерных массива В (х) и С (х). Пусть В (х) устроен так же, как и А (х). В позиции х у В (х) указывается адрес а первой от начала строки в X с дугой (у, х). Далее, если по некоторому адресу а в X записана дуга (у, х), то в С (а) указывается адрес в X следующей такой дуги. Символ 0 в В (х) используется для указания отсутствия входов в вершину х, а в С (х) — как метка завершения соответствующего подмассива входов. При такой организации В (х) и С(х) проблема поиска всех входов в х сводится к выборкам сначала адреса В (х), а затем последовательных адресов из С. Наглядно описанный механизм поиска входов в конкретную вершину сети показан на рисунке 36.
Заметим, что формирование массивов В и С фактически приводит к адресному кодированию X. Иными словами, осуществляется адресная сортировка X по у. Более того, для рассмотренной ранее организации поиска выходов из конкретных вершин можно было бы отказаться от начальной сортировки X по х, заменив ее подобным адресным кодированием. Правда, при этом пришлось бы к массиву А добавить еще один вспомогательный массив D, устроенный аналогично С и используемый для хранения «последующих» адресов.
Массивы Л, В и С будем называть справочниками, а их совокупность — справочной для X. Таким образом, по массиву X нам необходимо научиться строить справочники: а) Л б) В и С в) Л ; В и С.
Сделать это несложно. При этом в самом общем случае после сортировки все организуется за один просмотр X (см. примеры 10—12).
Пример 10. Адреса выходов из х. Справочник А
10 SCREEN 0:COLOR 15,4;KEY OFF
20 INPUT "количество дуг сети ";N:DIM S(N,2)
30 ’
40 ’ввод массива SO
50 ’
60 INPUT "максимальный номер пункта ";М
70 DIM В(М),C(N):'======================ЯДРО
80 FOR I=N ТО 1 STEP -1
90 C(I)=B(S(I,1)):B(S(I,1))=I
100 NEXT !•’================================
Пример 11. Адреса входов в х. Справочники В и С
10 SCREEN 0:COLOR 15,4:KEY OFF
20 INPUT "количество дуг сети ";N:DIM S(N,2)
30 ’•
40 *ввод и сортировка массива SO
50>
60 INPUT "максимальный номер пункта " ;М
70 DIM А(М):'===========================ЯДРО
80 FOR I=N ТО 1 STEP —1:A(S(I,0>)=1:NEXT I
90 * ========================================
Пример 12. Входы и выходы. Справочники А, В и С
10 SCREEN 08 COLOR 15,4:KEY OFF
20 INPUT "количество дуг сети ";N:DIM S(N,2)
30 ’
40 * ввод и сортировка массива SO
50 >
60 INPUT "максимальный, номер пункта ";М
70 DIM АСМ) ,В(М) ,C(N) : ’ ================ЯДРО
80 FOR I=N ТО 1 STEP -1
90 C(I)=B(S(I,1))8A(S(I,0))=I:B(S(I,1))*I
100 NEXT I:’================================
Указанная организация справочной эффективна при реализации потоковых алгоритмов. Мы на этом останавливаться не будем.
Генератор перестановок
Иногда задачи решают полным перебором возможных вариантов. И хотя этот прием, как правило, является весьма трудоемким по времени, идти на него приходится, если ничего лучшего придумать не удается. В подобных «переборных» задачах полезным бывает алгоритм получения всех л! перестановок из элементов множества
S = {ai, а2, .... ал}>(Ю)
где a* (к — 1, л) — попарно различные действительные числа.
Ниже приведен вариант алгоритма генерирования перестановок.
Шаг 1. Отсортируем (10) в порядке убывания. Полученную перестановку объявляем начальной.
Шаг 2. Находим наименьший индекс t^{2, 3, ..., л}, при котором а<_1>а„
Шаг 3. Находим наименьший индекс/^{1, 2, ..., Z— 1}, при котором а/>а<.
Шаг 4. Обмениваем значениями а, и а,.
Шаг 5. Обмениваем значениями компоненты в парах:
(аь а,-1), (а2, ai-2)(а», а,_А) ^=^2^J_jy
Шаг 6. Выводим очередную сформированную перестановку и если их общее количество меньше л!, то переходим к шагу 2. В противном случае вычисления прекращаем.
Покажем, что, используя приведенный алгоритм, мы получим все л! различных перестановок. Не ограничивая общность, можно считать, что S состоит из последовательных натуральных чисел: 1, 2, ..., п. Зафиксируем />л и рассмотрим Лричную систему счисления с цифрами 0, 1, 2, ..., л, .... t— 1.
218
В множестве В п-значных t-ричных чисел выделим подмножество Во чисел, у которых цифры попарно различны и являются элементами S. Перестановки из S и элементы Во можно поставить во взаимно однозначное соответствие по правилу:
(ci, а2an)-H-an/n-1 + a„-l/n-2 + ...4-a2/+ai.
Следовательно, на проблему получения всех перестановок из 5 можно смотреть как на задачу выделения в В подмножества Во. Пусть элементы Во выписаны в порядке возрастания: t/i<y2<...<t/n! Тогда шаг 1 алгоритма определяет первоначальную перестановку (n, п — 1 1), соответствующую числу
z/i = l 2 3 ... nt.
Если уже сгенерирована перестановка для ук^Во (А<п!), то совокупность шагов 3—6 как раз и формирует перестановку, соответствующую числу yk+iQ Bq. Этим и доказывается, что будут получены все п\ перестановок из S.
Нелишне помнить, что функция п\ растет очень быстро. Например, вопрос о том, сколько списков можно составить из десяти различных фамилий, приводит уже к числу 10!=3628800. Поэтому практическое использование программы «Генератор перестановок» (см. пример 13) ограничено значениями п<10.
Пример 13. Генератор перестановок
10 ’"ГЕНЕРАТОР ПЕРЕСТАНОВОК"
20 ’ПОЛУЧЕНИЕ S! ПЕРЕСТАНОВОК ИЗ S ЭЛЕМЕНТОВ
30
40
’ характеристики быстродействия
50
’S=5, время6.1 сек
60
’S=6, время36,9 сек
70
’S=7, время 4 мин 19.2 сек
80
90
COLOR 15,4:SCREEN 0:KEY OFF:DEFINT A-S
100 I№*UT "количество элементов ";S:DIM PCS)
110 FOR 1=1 ТО S:PCI)=S+1-I:NEXT
120 Z=1:FOR 1=1 TO S:Z=ZKI: NEXT:’S!
130 TIME=0:Y=1:GOSUB 250:’==============ЯДРО 140 FOR Y=2 TO Z:I=2:J=1
150 IF PCI-1 X=PCI) THEN 1=1*1:GOTO 150
160 IF PCJX=PCI) THEN J=J*1:GOTO 160
170 SWAP PCI),PCJ):IF 1=2 THEN 190
180 FDR L=1 TO (I—1)/2sSWAP PCD,P(I-L)sNEXT
190 GOSUB 250
200 NEXT Y
210 PRINT "время =”;TIME/50:END
220 ’=_====================================
230 ’распечатка перестановки
240 *или иное ее использование
250 PRINT Yj") ”;
260 FOR Е=1 ТО S:PRINT Р(Е);:NEXT:PRINT
270 RETURN:’
В качестве примера применения генератора перестановок можно было бы рассмотреть такую задачу из механики.
Заданные п масс т* (Л = 1, п) требуется распределить в пространстве, например в капсуле космического корабля, в точках Mi, Мг, .... Мп так, чтобы их центр тяжести был максимально близок к фиксированной точке Мо.
Оставляя детальный разбор этой типично «переборной» задачи читателю, мы проиллюстрируем метод полного перебора на несколько иной проблеме. Речь пойдет о широко известной «задаче коммивояжера». Формулируется она так.
Коммивояжер (агент по сбыту), отправляясь из своего города, должен кратчайшим маршрутом посетить ровно по одному разу п — 1 заданных городов и вернуться назад.
Эта оптимизационная задача и различные ее модификации в действительности возникают не только при доставке товаров на дом, но и в ситуациях совершенно иного характера [22]. Математические модели «задачи коммивояжера» содержат большое количество переменных и ограничений. Поэтому для их решения общие методы линейного программирования обычно не используются. Предпочтение отдается вычислительной схеме, известной под названием метода ветвей и границ (ветвления и ограничения) [22].
При небольших п мы попробуем справиться с задачей коммивояжера перебором всех замкнутых маршрутов, проходящих по одному разу через каждый из городов. Будем называть такие маршруты допустимыми. Пусть города пронумерованы числами: 1, 2, ..., п, расстояния между ними равны m (i, /Х«, /= 1, и), причем значения m(i, /) и m (j, /) не обязательно совпадают. При отсутствии дороги между пунктами I и / можно считать, что она есть, но m (t, /) = оо.
Всякая перестановка (аь аг, .... ап) из элементов: 1, 2, ..., п определяет допустимый маршрут:
220
01 —> 02 ”>" ... ”>* Дп/ i 1 \
I’
Тогда для решения «задачи коммивояжера», перебирая все возможные перестановки (oi, аг, ...» dn\ достаточно вычислять длины соответствующих маршрутов и запоминать лучшие из них. Именно эта идея и реализована в программе КОММИ примера 14. Причем учитываются только перестановки (11), где ап = 1. Ввиду замкнутости (11) это делать можно. Таким образом, для п городов просматривается и анализируется (и—1)! маршрутов.
Пример 14. Задача коммивояжера
10 * ЗАДАЧА КОММИВОЯЖЕРА (полный перевор)
20 ’—ВВОД
30 SCREEN 0;COLOR 15,4:KEY OFF:DEFINT A-S
33 P$="оптимальные, маршруты коммивояжера:“
40 INPUT "количество пунктов ";S
44 IF S<2 THEN 40
50 DIM M(S,S),0(30,S),P(S):B=2A15-1
60 ’ M(,)- матрица расстояний
70 ’ О (, ) - матрица дл я маршрутов
80 ’ РО — перестановка
90 FOR 1=1 ТО 8: FOR J=1 ТО S
100 READ M(I,J>
110 NEXT J,I:CLS
120 LOCATE 8,9:PRINT "проводятся вычисления"
130 FOR 1=1 TO 8:P(I)=8+1—I:NEXT I
140 Z=1:FOR 1=1 TO 8-1:Z=ZXI:NEXT I:’-(5-1)!
150 TIME=0:Y=1:GOTO 210:’===============ЯДРО
160 I=2:J=1:,перестановка
170 IF P(I-1X=P(I) THEN 1 = 1 + 1:GOTO 170
180 IF P(J)<=P(I) THEN J=J+1:GOTO 180
190 SWAP P(I),P(J):IF 1=2 THEN 210
200 FDR L=1 TO (I—1)/2:SWAP P(L),P(I-L):NEXT
210 A=M (P (S) , P( 1) ) : ’длина маршрута
220 FOR E=1 TO S—1:A=A+M(P(E),P(E+1))sNEXT
230 IF A>B THEN 260:’запоминание маршрута
240 IF A<B THEN H=1:B=A
250 FOR E=1 TO S:Q(H,E)=P(E):NEXT:H=H+1
260 Y=Y+1:IF Y<=Z THEN 160
270 CLS:PRINT ?$;’===============—
290 PRINT:FOR 1=1 TO H-l:PRINT I;")";1;
300 FOR J=1 TO S:PRINT О(I,J)$:NEXT:PRINT
310 NEXT I:PRINT
320 PRINT "длина пути = “;B
330 PRINT "время счета =";TIME/50:END
340 ’пример
1
350 ’DATA 0,
5 ,9, 6 ,3, 5, 9
360 ’DATA 8,
0 ,8, 8 ,5, 9у 2
370 'DATA 6,
9 у 0, 1 ,6, 7 у 3
380 'DATA 7,
11,4, 0 ,4, 2, 9
390 'DATA 4,
6 ,3, 2 ,0, 2, 8
400 'DATA 5,
2 ,2, 8 ,4, У, 3
410 'DATA 8,
1 ,3, 16,5, 3, 0
420
'пример
2
430
DATA 0,
3 ,21,6 ,4 ,8, 11
440
DATA 7,
0 ,6 ,2 ,12,5, 3
450
DATA 8,
9 ,0 ,13,8 .2, 9
460
DATA 6,
10,31,0 ,7 ,7, 14
470
DATA 8,
7 ,6 ,5 ,0 ,4, 3
480
DATA 2,
5 ,7 ,9 ,3 ,0, 6
490
DATA 7,
5 ,4 ,7,15 ,4, 0
500 ’имя программы "КОММИ"
Пример 15. Решить «задачу коммивояжера» для 7 городов с именами 1, 27и матрицей расстояний:
222
(о, 7, 8, 6, 8, 2, 7,(о, 7, 8, 6, 8, 2, 7,3,21,6,4,8,11о.6,2,12,5,39,0,13,8,2,9ю,31,0,7,7,147,6,5,0,4,35,7,9,3,0,65,4,7,15,4,03,21,6,4,8,11о.6,2,12,5,39,0,13,8,2,9ю,31,0,7,7,147,6,5,0,4,35,7,9,3,0,65,4,7,15,4,0
(о, 7, 8, 6, 8, 2, 7,
(о, 7, 8, 6, 8, 2, 7,
3,
21,
6,
4,
8,
11
о.
6,
2,
12,
5,
3
9,
0,
13,
8,
2,
9
ю,
31,
0,
7,
7,
14
7,
6,
5,
0,
4,
3
5,
7,
9,
3,
0,
6
5,
4,
7,
15,
4,
0
3,
21,
6,
4,
8,
11
о.
6,
2,
12,
5,
3
9,
0,
13,
8,
2,
9
ю,
31,
0,
7,
7,
14
7,
6,
5,
0,
4,
3
5,
7,
9,
3,
0,
6
5,
4,
7,
15,
4,
0
Длина пути между пунктами I и j равна М (t, /).
В тексте программы КОММИ М должно быть зафиксировано 'в операторах DATA в строках после 330. В нашем случае это строки 430—490. При запуске программы на счет на экране дисплея получаем такое сообщение:
Оптимальные маршруты коммивояжера:
12457361 длина пути = 23
время счета =109.1 с
Найденное решение представлено на рисунке 37.
Возможная неоднозначность решения «задачи коммивояжера» учитывается программой КОММИ, запоминание маршрутов с равными длинами осуществляется в отдельных строках двумерного массива Q. Количество зарезервированных строк в нем при необходимости может быть увеличено.
Пример 16. Решить «задачу коммивояжера» при следующей матрице расстояний:.
/ °.
5,
9,
6,
3,
5,
9 \
/ 8>
0,
8,
8,
5,
9,
2 \
м= / 6>
9,
0,
1,
6,
7,
3 1
7,
П,
4,
0,
4,
2,
9
1 4,
6,
3,
2,
0,
2,
8 /
1 5>
2,
2,
8,
4,
0,
3 /
\ 8,
1,
3,
16,
5.
3,
0 /
В тексте программы
М
зафиксировано
в операторах DATA в
строках 350—410. После вычислении
на экране дисплея получаем
такое сообщение.
Оптимальные маршруты коммивояжера:
1) 15462731длина пути = 20
15627341время счета = 108.9 с
Найденные решения представлены на рисунке 38.
ЛИНЕЙНОЕ ПРОГРАММИРОВАНИЕ
Общая и каноническая задачи
Постановка задачи. Общей задачей линейного программирования (ОЗЛП) называется задача, состоящая в определении оптимального (максимального или минимального) значения линейной функции
f=S с/х, + со (1)
при условиях п
5 aijXjObi (z = l, 2, ..., m) (2) /=1
х^О (^ELczfl, 2, .... и)) (3) где: ац, с,, bi — фиксированные действительные числа; о — один из знаков отношения: ^, ^, =.
Другими словами, в ОЗЛП ищется оптимальное значение линейной функции (1) на множестве решений системы равенств и неравенств (2) при условии неотрицательности некоторых переменных. Заметим, что требование неотрицательности (3) может быть наложено на все переменные (L = {1, 2, .... и}) или вообще отсутствовать (L=0).
Функция F называется линейной формой или целевой функцией задачи (1) — (3), а условия— (2) — (3) —ограничениями.
Совокупность чисел X=(xi, Х2, .... хя), удовлетворяющая ограничениям (2) — (3), называется допустимым решением или планом задачи.
План Х*=(х*, х* .... х*), при котором целевая функция принимает минимальное или максимальное значение, называется оптимальным.
Таким образом, при любом плане X оптимальный план X* удовлетворяет условию F (X*)^ F (X) (или F (X*)^ F (X)).
Не всякая задача линейного программирования имеет оптимальный план. Это связано с тем, что множество решений D системы ограничений (2) —(3) может быть пустым или форма F на D не ограничена снизу (сверху).
' Х\ + Х2 ^ 3
Пример 1. Для ОЗЛППример 1. Для ОЗЛПF = xv + хг -► maxF = xv + хг -► maxХ1 + 1
Пример 1. Для ОЗЛП
Пример 1. Для ОЗЛП
F = xv + хг -► max
F = xv + хг -► max
Х2^1
t Xv, Х2^0
Z)=0, т. е. ограничения ный план отсутствует.Пример 2. Для ОЗЛПZ)=0, т. е. ограничения ный план отсутствует.Пример 2. Для ОЗЛПпротиворечивы, и потому оптималь-противоречивы, и потому оптималь-{Xl+%2^2-Х\ +*2^5 Х2>0{Xl+%2^2-Х\ +*2^5 Х2>0F=x\ + 2х2 -► minF=x\ + 2х2 -► min
Z)=0, т. е. ограничения ный план отсутствует.
Пример 2. Для ОЗЛП
Z)=0, т. е. ограничения ный план отсутствует.
Пример 2. Для ОЗЛП
противоречивы, и потому оптималь-
противоречивы, и потому оптималь-
{Xl+%2^2
-Х\ +*2^5 Х2>0
{Xl+%2^2
-Х\ +*2^5 Х2>0
F=x\ + 2х2 -► min
F=x\ + 2х2 -► min
при любом С^5 пара х\ = — С, Х2 = 0 является планом. F не ограничена снизу и потому оптимальный план отсутствует.
Среди множества задач линейного программирования выделяют класс так называемых канонических, или основных, задач (КЗЛП), в которых ищется минимум функции (1) при ограничениях (2) — (3), где о есть = , L={1, 2, ..., п}. Иными словами, в КЗЛП находится минимальное значение формы F на множестве решений системы уравнений при неотрицательности всех переменных задачи.
Несложными преобразованиями нахождение решения ОЗЛП всегда может быть сведено к решению некоторой канонической задачи. Покажем, как это делается.
Прежде всего нахождение максимума целевой функции F заменяется нахождением минимума формы — F. Делать это можно потому, что max F= — min (— F).
Всякое ограничение ОЗЛП вида 2 asjXi^bs (sEfl, 2m))
/=i
заменяется условием-равенством с неотрицательностью новой вспо
могательной переменной ys:
Всякое ограничение ОЗЛП вида: 2 aSjXj">bs ($Е(1, 2, .... m}) /=|
заменяется условиями:заменяется условиями:5 asj Xj — ys = bs i=i
заменяется условиями:
заменяется условиями:
У$>0.
Переменные xp^p^L\ на которые не наложены условия неотрицательности, представляются в (1) и (2) в виде разности неотрицательных величин: I xu = Wk — Vk
I > 0, ик > 0.
После всех этих преобразований нам удобно опять переобозначить Wk на Хк, а другие введенные вспомогательные неизвестные заменить на Хп + ь x„+2, .... х„ + ь Здесь t равно сумме количества неравенств в (2) и количества переменных без ограничений. Тогда получим следующую каноническую задачу:
минимизировать некоторую новую линейную форму Fx при ограничениях(4)
2 alixl = bi (i=l, 2, m)(5)
Х/>0(/= 1, 2, ..., « + /)(6)
Отметим, что каждому плану
(4, 4, .... х*)(7)
задачи (1) — (3) можно поставить в соответствие некоторый план (х* х*, .... X* х*+ х*+/)(8)
задачи (4) —(6), где числа х?(/ = 1,2, ..., n-V-f) получаются по той же схеме, по которой реализовывался переход от ОЗЛП к КЗЛП. Обратно, имея план (8) для задачи (4) — (6), получаем план (7) задачи (1) — (3), компоненты которого равны или соответствующим компонентам (8), или их некоторым разностям. Последний случай имеет место при наличии в ОЗЛП переменных без ограничений.
Кроме полученного взаимно однозначного соответствия между планами задач ОЗЛП и КЗЛП, нетрудно видеть, что значения целевой функции F на соответствующих планах одинаковы. Таким образом, оптимальному решению задачи (1) — (3) соответствует оптимальное решение задачи (4) — (6). В этом смысле указанные задачи эквивалентны.
Пример 3. Привести к эквивалентному каноническому виду задачу:
' Xi 4~Х2 4~Хз ^7
2xi — х2+х3 ^2(9)
х i — Х2 Т~ 5хз = 8ч xi^O
F = xx + х2 —х3 шах(10)
Сначала избавимся от отсутствия условий неотрицательности на переменные Х2 и хз. Для этого сделаем замены:
Х2Х2 — Х4Хз -> Хз — Х5,
где уже считаем х,^0(/ = 2, 3, 4, 5). Тогда задача (9) — (10) будет выглядеть так:,,__
Х1+Х2+ Х3 —Х4 — Х5<72xi—х2-|- хз + х4— х5>2
Х1 — X2 + 5X3-I-X4 — 5X5 = 8 х,^0 (t = 1, 2,5)
/■■= — х, — Х2 + Х3 + Х4 —Х5 ->- min
Вводя в систему еще две неотрицательные переменные хе и х7, избавимся от неравенств и получаем следующую каноническую задачу:
Xi-f-X24~ Л-3— Х4 — Х5-|-Хб = 7
2X1—Х2+ Хз + х4 —х5 —х7 = 2
Х| — Х2 + 5х3 + Х4 — 5X5 = 8 х,>0 (t=l, 2, .... 7)
F = — Xi — Х2 + Х3 + Х4 —Х5 ->- min
Симплекс-метод. Для решения задач линейного программирования имеется много различных методов. В особенности это касается конкретных экономических задач. Систематическое исследование ОЗЛП и разработка общих методов их решения были начаты в работах Л. В. Канторовича в 1939 г. В настоящее время основным общим методом решения ОЗЛП является так называемый симплекс-метод, предложенный Данцигом в 1949 году, и многочисленные его модификации. В этом пункте обсудим алгоритм симплекс - метода применительно к решению КЗЛП. Предварительно введем некоторые понятия и обсудим известные факты [20—23].
Множество D допустимых планов задачи (1) — (3) называют многогранником решений ОЗЛП. Может оказаться, что D=0. D представляет собой некоторое подмножество конечномерного Евклидова пространства Rn. Особую роль в многограннике D играют его вершины, т. е. такие точки, которые не могут быть внутренними для любого отрезка, соединяющего две точки D. Обозначим множество вершин D через Do. Элементы Do называются опорными планами ОЗЛП. Заметим, что Do всегда конечно. Известно, что если Do#=0 и оптимум F существует, то он достигается хотя бы в одной из вершин Do. В связи с этим утверждением напрашивается такой способ решения ОЗЛП: найти множест во Do опорных планов и простым перебором определить требуемый оптимум F на Do. Пусть он равен Fo и F^Xo")=Fo (Xo^Do). Если при этом удается установить существование искомого оптимума F на D, то ясно, что он равен Fo и Хо — соответствующий оптимальный план задачи (1)—(3). Однако практически воспользоваться предложенным способом решения задачи линейного программирова ния затруднительно. Дело в том, что даже при относительно не большом числе ограничений и неизвестных получается астрономическое количество вершин. Да и сам процесс отыскания вершин не является простой процедурой.
Симплекс-метод решения КЗЛП называют также методом последовательного улучшения плана. А название это объясняется тем, что в отличие от простого перебора вершин и вычисления значений формы F в них в симплекс-методе сначала определяют одну из вершин D, а затем последовательно переходят к соседним (по ребрам) вершинам D, в которых значение F ближе к оптимуму.
Итак, рассмотрим каноническую задачу.
{
2 aijXj = bi (/=1, 2, ..., m)(11)
/=i
Xj>0 (/=1, 2, ..., п)(12)
bi^O, т<_п(13)
п
F= 2 CjXj + co -> min.(14)
Условие bi^O (i=V 2, ..., /и), очевидно, не ограничивает общности. В противном случае соответствующие уравнения можно было бы домножить на — 1.
Расширением задачи (11) — (14), или, по-другому, В-задачей, называют следующую КЗЛП.
{
22, т)(15)
Xj>0(/=1, 2, .... n + m)(16)
bi^O, т<.п(17)
пгг-\-т
Fi = 2 C/Xj + co + B 2 х,-> min.(18)
j=ii = n-H
Здесь В — достаточно большое число.
Имеется довольно тесная связь между решениями расширенной и исходной задач (см. табл. 4) [20].
Таблица 4
В-задача
Исходная задача
Есть оптимальное решение (xL Хо, Хп> 0,0),
в котором последние т компонент равны нулю
Для всех достаточно больших В есть оптимальное решение
(Х|, Хг, • ••» хл,Xn-^-m^t
в котором хотя бы одна из компонент х* (1>п) отлична от нуля
Нет решения (форма не ограничена снизу)
Вектор (xL Х2 Хп)
является оптимальным решением
Система ограничений противоречива
Задача неразрешима или система ограничений противоречива
Кроме того, в В-задаче сразу же просматривается один из опорных планов
Х = (0, 0...0,&ь Ь^ ..., Ьт\
п-нулей
Роль В в (18) интуитивно ясна. Слагаемые с неотрицательными искусственными переменными х( (On) существенно увеличивают значение формы F\. Поэтому, если в В-задаче есть допустимое решение, в котором все х( = 0 при 1">п, то и в оптимальном решении эти переменные также должны обратиться в нуль'. Если в этом решении отбросить последние m компонент, тогда получим план задачи (11)—(14).
В форме F\ расширенной задачи величины х, (i>n) можно исключить, подставив их значения из (15). Сделаем это.
птппгп
F\=^ CjXj-\-Cq-]~В 2 xn.^i = 2 CjXj-|-Co4~В 2 ^bi— 2 dijXj) =
j=\i=\j=lZ=1/=1
= 2 (fj—в 2 Qij^ Xj -i- Co 4~ в 2 bi.i=\z=iz=i
Введем обозначения mm
4i = Cj — B 2 Qij (/= 1, 2,..., n) Yo = Co + B 2 bi
Z=1Z=1
n
ПолучаемF\ = 5 Т/Ху + уо(19)
Симплекс-таблица задачи (15) —(17), (19)Симплекс-таблица задачи (15) —(17), (19)Для расширенной задачи с преобразованной формой Fi построим так называемую симплекс-таблицу (см. табл. 5), на которой удобно разъяснить суть симплекс-метода решения КЗЛП. В таблице имеется т единичных векторов, располагаемых в столбцах с п + 1 по
Симплекс-таблица задачи (15) —(17), (19)
Симплекс-таблица задачи (15) —(17), (19)
0
1
2
п
п+1
п 4- 2
п-^т
гг4-т+ 1
Xi
Х2
Хп
Хп+1
*^л -{- 2
Хп + т
0
0
0
0
0
0
0
1
Ьх
Он
012
О, л
1
0
0
п+1
2
bi
^21
Оц
О2л
0
1
0
п, -}~ 2
т
Ьщ
0ml
dm2
Отп
0
0
1
п-\-т
m+ 1
— То
Yi
Т2
Тп
0
0
0
Таблица 5
n-Vm. Эти столбцы и соответствующие им переменные называют базисными, а множество базисных переменных — базисом. Номера базисных переменных фиксируются в соответствующих строках последнего столбца таблицы. В процессе обработки таблицы по симплекс-методу базис будет меняться. При этом в нулевой строке в столбцах от и+1 до п + т будут ставиться метки, фиксирующие факт удаления соответствующей искусственной переменной х, (/>я) из базиса.
В дальнейшем на таблицу 5 нам удобно смотреть как на матрицу А с т-}-2 строками и п + ^ + 2 столбцами и обозначать ее текущий элемент черезг ййi
Jр а^(z = 0, m-V 1; / = 0, n + m+1).
Алгоритм симплекс-метода.
Для КЗ ЛП (11) — (14) строим расширенную задачу и фиксируем симплекс-таблицу Л =(ач) (/ = 0, m+1; / = 0, n + m+1).
Поиск разрешающего столбца s.
В последней строке начиная с am + u и далее находим первый положительный элемент ат^и, такой, что a0s = 0. Если подобных s нет, то переходим к пункту 5.
Поиск разрешающей строки к.
Пусть для положительных элементов ais столбца s max — = у 1</<т Qis
и первый из индексов, для которых это отношение достигается, есть к. Если в столбце s в строках от 1 до т положительных элементов нет, то переходим к пункту 6.
Шаг жордановых преобразований.
Элементы строки к делим на разрешающий элемент aks:
akj = akj / aks(j = O, 1, ..., n-V-m\
Элементы строк и столбцов, отличных от разрешающих, преобразуем по формулам: aij = aij — ais*akj
(1=1, 2, ..., т; l^k; j = 0, 1, 2, ..., п-\-т; i^s\
Элементы столбца s, кроме aks, полагаем равными нулю: ais = 0(i=l, 2, ..., т; Ок\
Пункты а, б, в по сути означают ввод в базис переменной xs. Отмечаем это в столбце п-\-т-\-1:
=== ак л_|_т_|_|* aki n_|_m_|_|=s.
При этом xs замещает х(, и если On, то этот факт фиксируем меткой: о0/=1. Это позволит избежать повторного включения в базис искусственной переменной xt(tT>n\
Если среди базисных неизвестных есть искусственные Х/(/>п), то система ограничений исходной задачи противоречива. В про-
v4*( Г Де / Ui n J- m 4- 1 \
тивном случае оптимальный план: x*=ai0 I -_i 9‘
Остальные компоненты оптимального плана равны нулю. При этом min F = arnA.\,o.
Если среди базисных неизвестных есть искусственные xt^tT>n\ то система ограничений исходной задачи противоречива. В противном случае целевая функция не ограничена снизу.
Каждая итерация по симплекс-методу приводит, вообще говоря, к уменьшению значения формы F. Однако это значение может сохраниться и прежним. Более того, бывают и такие случаи, когда целевая функция F не изменяется в течение нескольких итераций. Наконец, возможен также возврат и к ранее уже встречавшемуся базису. Последнее явление называется зацикливанием. При решении практических задач зацикливание весьма маловероятно, и потому мы на нем останавливаться не будем. Отметим лишь, что имеются простые способы предупреждения зацикливания.
Уменьшение количества ограничений. При решении конкретных экономических ОЗЛП система ограничений довольно часто содержит условия, относящиеся к отдельным переменным, а не к их совокупностям. Речь идет о неравенствах вида:
а^х(а^О) *<₽«<*<₽.(20)
Наличие подобных ограничений при решении задач на ЭВМ заставляет придумывать различного рода неестественные формы ввода данных. Делается это для того, чтобы избежать непосредственного задания большого количества нулевых коэффициентов при неизвестных. Кроме того, условия (20) увеличивают размеры обрабатываемой симплекс-таблицы и, следовательно, время вычислений.
Однако простыми подстановками от большей части неравенства (20) вообще можно избавиться. Пусть множество {1, 2, ..., и} разбито на 5 непересекающихся подмножеств tp (р=1, 2, ..., 5). Рассмотрим постановку ОЗЛП, где условия (20) выделены из общей совокупности ограничений.
S Щ, Xj О bi /=1S Щ, Xj О bi /=1(i — 1,2, ..., nt\0<.m<.n>(i — 1,2, ..., nt\0<.m<.n>(21)(21)
S Щ, Xj О bi /=1
S Щ, Xj О bi /=1
(i — 1,2, ..., nt
\0<.m<.n>
(i — 1,2, ..., nt
\0<.m<.n>
(21)
(21)
Xj без ограничений (j£t\)
aj<Xj (a/#=0)(/€<2)
xi ^ Р/(/ € ^3)
a,O/<P/(j€/4)
I 0CxjG€k)
F = S CjXj + co-*opt (оптимум).(22)
/-i
Здесь любые tp могут оказаться пустыми. Покажем, как перейти к ОЗЛП с условиями неотрицательности на все переменные.
Избавляемся от отсутствия ограничений на ху(/£/|) так, как это рекомендовано в первом пункте.
Последовательно организуем замены переменных:
Xj = Xj — ау- (/£/2) xi~$i xi (j^^\
Формы для пересчета коэффициентов в (21) и (22) получаются просто, и мы их не выписываем.
Добавляем к (21) неравенства вида: х/^р/ (jEh) и далее во вновь полученной системе (21) и форме (22) последовательно организуем замены переменных:xl = x! — cc! (j£h\
В результате всех этих действий получим ОЗЛП с т+ 1^1 (через |/| обозначено количество элементов множества /) ограничениями и n+1/il неизвестными, каждое из которых неотрицательно.
Программа «Симплекс-1». Приведенная ниже программа «Симплекс-1» решает ОЗЛП (21) — (22) и состоит из 3 частей:
Ввод данных о конкретной ОЗЛП и построение симплекс- таблицы соответствующей эквивалентной расширенной канонической задачи с неотрицательными переменными (строки 10—920).
Симплексные преобразования (строки 940—1190).
Формирование и вывод результатов счета (строки 1200— 1370).
Части В и С оформлены в виде единой подпрограммы.
Работа пользователя с программой проводится в интерактивном режиме. В соответствии с запросами на экране дисплея с пульта заносятся данные о ОЗЛП в такой последовательности.
Количество уравнений (более 1 переменной).
Количество неравенств (более 1 переменной).
Общее количество переменных.
Количествопеременных без ограничений.
КоличествоограниченийвидаВ^х (В^0\
Количествоограниченийвидах^С.
КоличествоограниченийвидаВ^х^С.
Тип решаемой задачи (1—min, 2 —max).
Информация об ограничениях (равенствах и неравенствах) в виде: коэффициенты при Xi, х2, ..., хл, знак, свободный член.
Информация о линейной форме в виде: коэффициенты при X], х2, ..., хП1 свободный член.
Номера переменных без ограничений.
Для ограничений вида 6^х (6=^0): номер переменной, В.
Для ограничений вида х^С: номер переменной, С.
Для ограничений вида В^х^С: номер переменной, В, С.
В зависимости от содержания ответов пользователя на обязательные запросы 1—8 дальнейшее направление диалога выбирается программой так, чтобы по возможности упростить ввод данных.
232
После построения симплекс-таблицы и ее обработки фрагмент С программы «Симплекс-1» формирует и выводит на дисплей одно из трех возможных сообщений:
Оптимальное решение:
х, — А| Х2 = Аг
х — Д
MAXIMIN) формы=В Здесь Ai, Д2, •••, А„, В — действительные числа.
Форма не ограничена сверху (снизу).
Система ограничений противоречива. Пример 4. Программа «Симплекс-1»
10 ’ЛИНЕЙНОЕ ПРОГРАММИРОВАНИЕ.
20 ’СИМПЛЕКС-МЕТОД (симплекс 1)
30>
40 SCREEN 0:COLOR 15,4:WIDTH 40:KEY OFF
50 B= 100000000!:EPS=1E-10
60 J1S=" 5.ограничений вида: B<=X (В О0)" 70 Л2$="ввод коэффициентов линейной формы:" 80 J3S=" 1. уравнений (волее 1 переменной) 11 90 J4$=" 2.неравенств (волее 1 переменной)" 100 J5S="система ограничений противоречива" 110 36$="форма неограничена снизу" 120 Л7$="форма неограничена сверху" 130 J8$="MIN формы = ":Л9$="МАХ формы = " 140 I1Ф="введите черев запятые количество:" 150 PRINT "С И М П Л Е К С - М Е Т О Д" 160 ’ФОРМИРОВАНИЕ СИМПЛЕКС-ТАБЛИЦЫ
170 PRINT I1$:PRINT:PRINT J3$:PRINT J4* 180 PRINT " 3.переменных" 190 PRINT " 4.переменных вез ограничений" 200 PRINT JIS 210 PRINT " 6.ограничений вида:X<=C"
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
470
480
490
500
510
220220PRINT " 7.ограничений вида: В<=Х<=С
220
220
PRINT 11 8.тип задачи (min — 1, max — 2)" PRINT:INPUT Ml,М2,N1,N2,N3,N4,N5,T M=M1+M2+N5:M9=M1+M2+1:T=3-2XT
N=N1+N2+M2+N5:N7=N1+1
N8=N7+N2:N9=N+1:M0=M+1:N0=N+M0
DIM A (M0, N0) , A$ (M)
DIM X(N1),B(N1),C(N1),Y(N1+N2):PRINT ’система ограничений
PRINT "ввод коэффициентов ограничений:" IF Ml+M2=0 THEN 420 ELSE PRINT
FOR 1=1 TO Ml+M2:F0R J=1 TO N7 R=J:IF JON7 THEN 390 ELSE R=0 INPUT "знак";A$(D
IF A$(!)="=" THEN 390
IF A* (I)=»<=" THEN 390 IF A$(!)=">=" THEN 390 ELSE 350 PRINT "A(";I;",";J;") = ";:INPUT A(I,R) NEXT J:PRINT :NEXT I ’линейная форма
PRINT J2$:PRINT
FOR J=1 TO N7
PRINT "F(";J;") = ";:INPUT A(M0,J)
NEXT J:PRINT
A(M0,0)=—A(M0,N7):A(M0,N7)=0 ’X вез ограничений
IF N2=0 THEN 550
PRINT "для X вез ограничений:":PRINT L=N7
FOR K=1 TO N2:INPUT "номер X":J:X(J>=2
520520FOR 1=1 TO M0:A(I,L)=-A(I,J):NEXT I
520
520
L=L+1:NEXT K:PRINT
’B<=X (XO0)
IF N3=0 THEN 630
PRINT "для X с условием: B<=X (BO0)
FOR K=1 TO N3
INPUT "номер X,B";J, R:X(J)=3:В (J)=R FOR 1=1 TO M0 .
A(I,0)=A(I,0)-B(J)ХА(I,J)
NEXT I,K:PRINT
’-X<=C
IF N4=0 THEN 710
PRINT "для X с условием: X<=C" FOR K=1 TO N4
INPUT "номер X,C";J,C:X(J)=4:C(J)=0
FOR 1=1 TO M0
A(I,J)=-A(I, J) : A(I , 0)=A(I,0)+C(J)ХА(I,J) NEXT I,К
’B<=X<=C
IF N5=0 THEN 800
PRINT "для X с условием: B<=X<=C:L=M9 FOR K=1 TO N5:INPUT "номер X, В, C"; J, R, C X (J) =5: В (J) =R: C (J) =C: A (L, J) =1
A(Ls0)=C(J):AS(L)="<=":L=L+1
FOR 1=1 TO M0
A(I , 0)=A(I,0)-B(J)ХА(I,J)
NEXT I,K:PRINT
’неравенства в =,свободные члены >=0 L=N8:F0R 1=1 ТО М
530
540
550
560
570
580
590
600
610
620
630
640
650
660
670
680
690
700
710
720
730
740
750
760
770
780
790
800
810
IF AS(!)="<=" THEN А(I,L)=1:L=L+1
820 IF A$(I)=">=" THEN A(I,L)=-l:L=L+1
830 IF A(I,0)>=0 THEN 850
840 FOR 8=0 TO N:A(I,8)=-A(I,S):NEXT S
850 NEXT I
860 ’ E - матрица,# Базисных X,пересчет F
870 FOR 1=1 TO M:A(I,N+I)=1:A(I,N0)=N+I:NEXT
880 FOR J=0 TO N:8—0
g90 FOR 1=1 TO M:S=S+A(I,J):NEXT I
900 A(M0,J)=BXS—A(M0,J)*T
910 NEXT J:P=N+M:CLS
920 LOCATE 8,9:PRINT "проводятся вычисления"
930 TIME=0:GOSUB 940:END
940 ’===================================ЯДРО
950 поиск разрешающего столбца 8
960 8=0:FOR J=1 TO P
970 IF A(M0,J)>EPS AND A(0,J)<>1 THEN S=J:J=P
980 NEXT J: IF 800 THEN 1010
990 CLS:IF P>N THEN 1350 ELSE 1210
1000поиск разрешающей строки К
1010 R=B:K=0:FOR 1=1 ТО М
1020 IF A(I,SX=EPS THEN 1040
1030 C=A(I,0)/А(I,8):IF C<R THEN R=C:K=I
1040 NEXT I:IF K< >0 THEN 1070
1050 CLS:IF P>N THEN 1350 ELSE ,1360
1060 ’шаг жордановых исключений
1070 R=A(K,S>
1030 FOR J=0 TO P: A (K, J) =A (K, J) ,/R; NEXT J
1090 FOR 1=1 TO M0:IF I=K THEN 1130
1100 FOR J=0 TO P
1110 IF JOSTHEN A (I, J) =A (I, J) —A ( 1,8) ХА (K, J)
236
1120 NEXT J
1130 NEXT I
1140 FOR I=-l TO M0
1150 IF IOK THEN A(I,S)=0
1160 NEXT I:R=A<K,N0):A(K,N0)=S
1170 IF R>N THEN A(0,R)=1:W=W+1
1180 ’ усечение столбцов до N
1190 IF W<P-N THEN 960 ELSE P=N:GOTO 960
1200 ’ ====================-============ВЫВОД
1210 PRINT "оптимальное решение:":PRINT
1220 FOR J=1 TO N1+N2:C=0
1230 FOR K=1 TO M:IF A(K,N0>=J THEN C=A(K,0)
1240 NEXT K:Y(J)=C:NEXT J
1250 L=N7:F0R J=1 TO Nl:
1260 IF X(J)=2 THEN:Y (J) =Y (J)-Y (L):L=L+1
1270 IF X(J)=3 OR X(J)=5 THEN Y(J)=Y(J)+B(J>
1280 IF X(J)=4 THEN:Y(J)=C(J)—Y(J>
1290 PRINT "X(“;J;W) =";
1300 PRINTUSING "#####.###";Y(J)
1310 NEXT J:PRINT
1320 IF T=1 THEN PRINT J8$; ELSE PRINT J9»;
1330 PRINTUSING "#######.###";A(M0,0)XT
1340 GOTO 1370
1350 PRINT J5»:GOTO 1370
1360 IF T=1 THEN PRINT J6$ ELSE PRINT J7*
1370 PRINT "время = ";TIME/50:RETURN
1380 ’====имя программы на диске-СИМПЛЕКС.INP
Приведем несколько примеров работы с программой «Симплекс-1».
Пример 5. Решить задачу /Xi + х2 —Зхз^7 I х 1 -1-Зхг ~Ь- Хз^15 1X1— х2+ х3 = 3 кх3^4, х2>0
F = xv +х2 + хз max
Первая строка вводимых данных.
2, 3, 1. О, 1, 0, 2 t t 1тип задачи (МАХ)
Остальные данные. 1, 1, -3, >, 7 1 1, 3, 1, <, 15 ( 1,-1,1,=,3 )1, 1, 1, О 1Остальные данные. 1, 1, -3, >, 7 1 1, 3, 1, <, 15 ( 1,-1,1,=,3 )1, 1, 1, О 13, 43, 4ограничений:В ^х ^ С ограничений:х ^ С ограничений:В<.х переменных без ограничений общее количество переменных неравенств уравнений
Остальные данные. 1, 1, -3, >, 7 1 1, 3, 1, <, 15 ( 1,-1,1,=,3 )
1, 1, 1, О 1
Остальные данные. 1, 1, -3, >, 7 1 1, 3, 1, <, 15 ( 1,-1,1,=,3 )
1, 1, 1, О 1
3, 4
3, 4
информация об ограничениях
информация о форме F
номер переменной без ограничения
информация об ограничениях вида: Х<-С
В результате счета получаем сообщение:
ОПТИМАЛЬНОЕ РЕШЕНИЕ
Xi =5.5
х2 = 3
хз = 0.5
МАХ ФОРМЫ=9
Пример 6. Решить задачуПример 6. Решить задачу(xi + x2< 1
Пример 6. Решить задачу
Пример 6. Решить задачу
Xi — х2 ^ О
х2>0.5
F=3xi —х2 -* min
Вводимые данные:
О, 2, 2, 1, 1, 0, 0, 1
1, С, 1
-1, >, О 3, —1,0 1
0.5
Сообщение:
СИСТЕМА ОГРАНИЧЕНИЙ ПРОТИВОРЕЧИВА
{
%1+х2<5
X, — х2^ 1
Xi —5х2> —10
Е = Х| +х2+ 1 ->■ min
Вводимые данные:
0, 3, 2, 2, 0, 0, 0, 1
1,5
-1,<, 1
-5,>,-10
1, 1 1, 2
Сообщение:
ФОРМА НЕ ОГРАНИЧЕНА СНИЗУ
Программа «Симплекс-2». Довольно простая организация ввода данных в программе «Симплекс-1» требует совершенствования. Сбой при вводе конкретного значения не должен приводить к повторному вводу всех данных задачи. Необходимо также иметь возможность редактировать уже введенные данные. Простейший способ добиться этого состоит в полном отказе от использования оператора INPUT. Данные можно заготавливать в подпрограмме в операторах DATA и считывать их по мере надобности. В этом случае в распоряжении пользователя оказывается все многообразие сервисных средств корректирования данных, предусмотренных экранным редактором текстов. Именно так и решаются ОЗЛП (21) — (22) по программе «Симплекс-2». Причем данные в DATA необходимо располагать в той же последовательности, как они вводились бы по программе «Симплекс-1». Обработка и сообщения о результатах счета в обеих программах реализуются фрагментом, начинающимся со строки 940 и далее.
Пример 8. Программа «Симплекс-2»
10 ’ЛИНЕЙНОЕ ПРОГРАММИРОВАНИЕ
20 ’СИМПЛЕКС МЕТОД (симплекс 2)
30 ’========================================
40 ’ВНИМАНИЕ !!!ИНСТРУКЦИЯ
50 ’ для пользователя в строках 70-280
60 ’
70 ’расположить данные в DATA со строки 1400
80 ’ Ml — количество уравнений
90 ’ М2 — количество неравенств
100 ’N1 — овщее количество переменных
110 ’N2 - кол. переменных вез ограничений
120 ’ N3-кол.ограниченийвида:В<=Х(ВО0)
150 ’N4-кол.ограниченийвида:Х<=С
140 ’N5-кол.ограниченийвида:В<=Х<=С
150 ’Т-типзадачи (min— 1, max -2)
160 ’ Для всех граничений между переменными:
170 ’ коэффициенты при X (1) , X(2),. . . Х(М1),
180 ’ знак,свободный член.
190 ’ Для линейной формы:
200 ’ коэффициенты при X(1),X(2),...X(N1), 210 ’ свободный член.
220 ’ Номер X -для всех переменных X вез
230 ’ ограничений
240 ’
Номер
х,в
—для ограничений
вида:
250 ’
В<=Х
(В не нуль)
260 ’
Номер
х,с
-для ограничений вида: Х<=С
270 ’
Номер
х,в,
С -для ограничений
вида:
280 ’ В<=Х<=С
290 ’==========ФОРМИРОВАНИ^ СИМПЛЕКС—ТАБЛИЦЫ
300 SCREEN 0:COLOR 15,4:KEY OFF
310 J1*="MIN формы = ":J2$="MAX формы = "
320 Л3$="система ограничений противоречива"
330 Л4$=”форма неограничена снизу"
350
360
370
380
390
400
410
420
430
440
450
460
470
480
490
500
510
520
530
540
550
560
570
580
590
600
610
620
630
340340J5$="форма неограничена сверху
340
340
LOCATE 8,9:PRINT проводятся вычисления"
В=100000000!:EPS=1Е-10:’ чтение данных
READ Ml,М2,Nl,N2,N3,N4,N5,Т
М=М1+M2+N5:М9=М1+М2+1:Т=3-2ХТ
N=N1+N2+M2+N5
N7=N•+1: N8=N7+N2:N9=N+1:M0=M+1:N0=N+M0
DIM A(M0,N0),A$(M)
DIM X (N1) , В (N1) , C (N1) , Y (N1+N2)
FOR 1=1 TO M9:F0R J=1 TO N7
IF J<=Ni AND KM9 THEN READ A (I, J)
IF J>N1 AND KM9 THEN READ A$ (I) , A (1,0)
IF I=M9 THEN READ A(M0,J)
NEXT J,I:A(M0,0)=—A(M0,N7):A(M0,N7)=0 IF N2=0 THEN 530
’ОБравотка X(J) вез ограничений
L=N7:F0R K=1 TO N2:READ J:X(J>=2
FOR 1=1 TO M0:A(I,L)=-A(I,J):NEXT I L=L+1:NEXT К
IF N3=0 THEN 590
’обработка X(J) с условием: B<=X(J)
FOR K=1 TO N3:READ J: X (J) =3.: READ В (J)
FOR 1=1 TO M0
A(I,0)=A(I,0)—В(J)ХА(I,J)
NEXT I,К IF N4=0 THEN 650 'обработка X(J) с условием: X(JX=C FOR K=1 TO N4:READ J:X(J)=4:READ C(J) FOR 1=1 TO M+l
A(I,J)=—A(I,J):A(I,0)=A(I,0)+C(J)ХА(I,J)
640 NEXT I,К
650 IF N5=0 THEN 740
660 ’—овравотка X(J) с условием: B<=X(JX=C
670 L=M9: FOR K=1 TO N5
680 READ J:X(J)=5:READ B(J),C(J)
690 A(L,J)=1:A(L,0)=C(J):A$(L)="<=":L=L+1
700 FOR 1=1 TO M0
710 A (1,0) =A (1,0) —В (J) ХА (I, J)
720 NEXT I,К
730 ’неравенства в =,свободные члены >=0 740 L=N8:F0R 1=1 ТО М
750 IF A$(I)="<=" THEN А(I,L)=1:L=L+1
760 IF АХ I )='’>=” THEN А(I,L)=-1:L=L+1
770 IF A(I,0)>=0 THEN 790
780 FOR 8=0 TO N:A(I,8)=-A(I,8):NEXT 8
790 NEXT I
800 ’вспомогательный вазис, пересчет F
810 L=N9:F0R 1=1 TO M:Q=0
820 FOR J=1 TO N:IF A(I,JX>1 THEN 860
830 R=0:FOR X=1 TO M
840 IF XOI AND A(X,JX>0 THEN R=1:X=M
850 NEXT X-.IF R=0 THEN P=J:J=N:Q=1
860 NEXT J
870 IFQ=0THEN A(I, L) =1: A(M0,L)=BXT:P=L:L=L+1
880 A(I,N0)=P:NEXT I:P=L-1
890 FOR J=0 TO P:S=0•
900 FOR 1=1 TO M:S=S+A(I,J):NEXT I
910 A(M0,J)=BXS-A(M0,J) XT 920 NEXT J:TIME=0:GOSUB 930:END
930 ’===================================ЯДРО
242
940 *поиск разрешающего столбца S
950 5=0:FOR J=1 ТО Р
960 IF A(M0,J)>EPS AND A(0,J)<>1 THENS=J:J=P 970 NEXT J: IF 500 THEN 1000 980 CLS:IF P>N THEN 1310 ELSE 1180
990 ’поиск разрешающей строки К
1000 R=B:K=0:FOR 1=1 ТО М 1010 IF A(I,SX=EPS THEN 1030
1020 C=A(I,0)/A(I,S):IF 0<R THEN R=C:K=I
1030 NEXT I: IF KO0 THEN 1060
1040 CLS:IF P>N THEN 1310 ELSE 1320
1050 ’шаг жордановых исключений
1060 R=A(K,S)
1070 FOR J=0 TO P: A (K, J) =A <K, J)/R: NEXT J
1080 FOR 1=1 TO M0:IF I=K THEN 1120
1090 FOR J=0 TO P
1100 IF JOSTHEN A(I,J)=A(I,J>-A(I,S)XA(K,J) 1110 NEXT J
1120 NEXT I
1130 FOR 1=1 TO M0:IF IOK THEN A(I,S>=0
1140 NEXT I:R=A(K,N0):A(K,N0)=S
1145 IF R>N THEN A(0,R)=1:W=W+1
1150 IF W<P—N THEN 950
1160 P=N:60T0 950:’усечение столбцов до N 1170 ’=================================ВЫВОД 1180 PRINT "оптимальное решение:":PRINT 1190 FOR J=1 TO N1+N2:C=0
1200 FOR K=1 TO M:IF A(K,N0)=J THEN C=A(K,0) 1210 NEXT K:Y(J)=C:NEXT J 1220 L=N7:F0R J=1 TO Nl:
1230 IF X(J)=2 THEN:Y(J)=Y(J)-Y(L):L=L+1
1240 IF X(J)=3 OR X(J)=5 THEN Y<J>=Y(J)+B(J)
1250 IF X(J)=4 THEN:Y(J)=C(J)-Y(J)
1260 PRINT "X(";J;"> = ";
1270 PRINTUSING “#####.###";Y(J)
1280 NEXT J:PRINT
1290 IF T=1 THEN PRINT Jl$; ELSE PRINT J2$;
1300 PRINTUSING "#######.###";A(M0,0)XT
1305 GOTO 1330
1310 PRINT J3$:G0T0 1330
1320 IF T=1 THEN PRINT J4* ELSE PRINT J5*
1330 PRINT "время = ";TIME/50:RETURN
1340 ’===имя программы на диске-СИМПЛЕКС.DAT
Примеры решения задач с помощью программы «Симплекс-2».
Пример 9. Для решения ОЗЛП из примера 4 достаточно сформировать фрагмент:
2000 DATA 1,2, 3, 1, 0, 1, 0, 22010 DATA 1,1, -3, >, 72020 DATA 1,3, 1, ^, 152030 DATA 1,-1, 1, =, 32040 DATA 1,1, 1, o2050 DATA 12060 DATA 3,42000 DATA 1,2, 3, 1, 0, 1, 0, 22010 DATA 1,1, -3, >, 72020 DATA 1,3, 1, ^, 152030 DATA 1,-1, 1, =, 32040 DATA 1,1, 1, o2050 DATA 12060 DATA 3,4(23)(23)
2000 DATA 1,
2, 3, 1, 0, 1, 0, 2
2010 DATA 1,
1, -3, >, 7
2020 DATA 1,
3, 1, ^, 15
2030 DATA 1,
-1, 1, =, 3
2040 DATA 1,
1, 1, o
2050 DATA 1
2060 DATA 3,
4
2000 DATA 1,
2, 3, 1, 0, 1, 0, 2
2010 DATA 1,
1, -3, >, 7
2020 DATA 1,
3, 1, ^, 15
2030 DATA 1,
-1, 1, =, 3
2040 DATA 1,
1, 1, o
2050 DATA 1
2060 DATA 3,
4
(23)
(23)
Сообщение о результатах счета, естественно, будет таким же, как и в примере 4.
Заметим, что поскольку блок данных создается интерпретатором в оперативной памяти сразу же после запуска программы, то специального обращения к (23) не требуется.
Пример 10. Решить задачу
' Х| 4- -V4 — 2хз=1х» —2а^ —|— Х5 = 2
Х3 4“ 3^4 4" Х5 = 3
х(>0 (t=L5)
F —х4—xs -*■ min
Фрагмент с данными запишем так.
2000DATA3,0,5,О,О, О, О, 1
2010DATA1,О,О,1,-2, = ,1
2020DATAО,1,0,-2, 1, = , 2
2030DATAО,О,1,3,1, = , 3
2040 DATA О, О, О, 1, —1, 0
Сообщение:
ОПТИМАЛЬНОЕ РЕШЕНИЕ
%i =5.6
^2=0 %з = 0 л'4=0.2 х5 = 2.4
MIN формы=—2.2
В заключение этого пункта добавим, что программа «Симплекс-2» работает, вообще говоря, быстрее программы «Симплекс-1». Дело в том, что по ней более экономно создаются симплекс- таблицы. Скажем, в последнем примере переменные хь Х2 и х3 уже составляют базис задачи. Этот факт учитывается программой «Симплекс-2», и дополнительные искусственные переменные вводиться не будут. В общем случае при построении базиса количество вводимых искусственных переменных минимизируется. Подобный анализ программа «Симплекс-1» не проводит.
Транспортная задача
Постановка задачи. Одной из частных задач линейного программирования является транспортная задача, состоящая в наиболее рациональном закреплении пунктов отправления некоторого однородного продукта к пунктам назначения. При этом в качестве критерия оптимальности обычно берется либо минимальная стоимость перевозок требуемого количества груза, либо минимальное время его доставки. Важность этой задачи для приложений и специфика получающихся ограничений позволили разработать более эффективные по сравнению с симплекс-методом алгоритмы ее решения. К ним можно отнести распределительный метод, метод дифференциальной ренты, метод потенциалов, венгерский алгоритм и т. д. Существуют матричная и сетевая постановки транспортной задачи.
Мы будем заниматься первой из них, где в качестве критерия оптимальности берется минимизация стоимости всех перевозок.
Перейдем к более точной формулировке задачи.
В пунктах отправления Ai сосредоточены соответственно запасы Qi (/=1, m) единиц однородного груза. Этот груз следует доставить
в пункты В, в количествах 6j(/=l, п\ Выполнено условие баланса, т. е. совокупный запас груза в Л, (/=1, т) равен общей его потребности в Bj (/ = 1, п\ Кроме того, известны т\п тарифов (издержек, стоимостей, транспортных расходов): С,/ (Z=l, m; j=\tn) на перевозку единицы груза из Л, в В,. Требуется организовать перевозки за минимум стоимости.
Планом задачи назовем всякое се решение из тХп чисел х/у (/= 1, т; /=1, п), представляющих собой объемы перевозок из Ai в В^
Матрицы C = (cz/) и Х = (хч) (z=l,m; / = 1,п) будем называть соответственно матрицами стоимостей и транспортных перевозок.
Теперь мы в состоянии написать математическую модель транспортной задачи (ТЗ).
Найти матрицу перевозок X = (xz/), доставляющую минимум форме
F = 2 2 сц хц(1)
/=1 z=i
при следующих ограничениях.
Все грузы должны быть вывезены:
S Xij = Qi (/=1, т; ai^0\(2)
j=i
Все потребности должны быть удовлетворены:
2 Xij = bj (/ = 1, п ; bj > 0).(3)
i = 1
Движение грузов должно происходить от пунктов отправления к пунктам назначения:
хц^0 (z= 1, m; /=1, п\(4)
Выполнено условие сбалансированности, или, по-другому, замкнутости задачи:
2 а,= 2 Ь,=М (М>0).(5)
1=\/=1
Нетрудно видеть, что мы получили каноническую задачу линейного программирования. Более того, в ней коэффициенты при всех тХп переменных х^ равны 1, а каждая переменная входит лишь в два уравнения. Далее, задача (1) — (5) всегда имеет решение. Докажем это.
Прежде всего множество Dt решений системы ограничений (2) — (4) не пусто. Действительно, величины хи = (а(- bj)/M (1=1, т; j = 1, п) удовлетворяют условиям (2) — (4): 246
2 хц = 5 (а,-6,)/Л1=(а(7М) 5bj = at(z =1, m^
i=\ j=i/=i
2 x,/=2 (a,-6/)/M = (6//M) 2a, = bj(j=\Tn)
i=\i=\z=l
Хц ^ 0 (/ = 1, /n; / = 1, n ).
Кроме того, многогранник D есть ограниченное множество Евклидова пространства ЕПт*.О^xt, ^тах ^ bj\ Эти факты и означают существование решения транспортной задачи (ТЗ).
Отметим, что замкнутость ТЗ, задаваемая соотношением баланса (5), является необходимым и достаточным условием существования решения системы ограничений и ТЗ в целом. Достаточность (5) мы уже фактически установили, а его необходимость доказывается так. Пусть (2) — (4) совместна. Тогда
тт пптп
5 й/ = 5 5 Хц=^ 5 Хц=У1 ьг
z=l z=lj=l j=\ i=\, = \
Наряду с рассмотренной классической замкнутой ТЗ иногда приходится иметь дело с открытыми моделями ТЗ, в которых нарушен баланс запасов и потребностей. Остановимся на случаях.
ТЗ с избытком запасов:
6л + 1=2 а—2 bj>0.(6)
Z=1/=1
Для отыскания оптимального плана в случае (6) вводят фиктивный (п+1)-й пункт назначения Вп^\ с потребностью Ьп^\ и полагают стоимости перевозок грузов в Вп-н равными нулю. Полученная новая ТЗ является уже замкнутой. Найдя оптимальный план (x/j) (/ = 1, т; /=1,п+1) этой ТЗ и отбрасывая в полученной матрице последний столбец, получим оптимальный план исходной ТЗ.
ТЗ с избытком заявок:
<zm + l= 2 bi- 2 а,>0.(7)
j=lZ=1
Эта задача несколько сложнее предыдущей. Дело в том, что, как ни развози грузы, все заявки удовлетворить все равно не удастся. Поэтому постановка задачи нуждается в уточнении.
Все пункты назначения требуется удовлетворить пропорционально поданным заявкам.
В этом случае, подсчитав коэффициент пропорциональности тп
6 = ( 2 а,) /( 2 6,)
и «подправив» заявки: $j = k«bj (j=\,n\ получим замкнутую ТЗ.
247
Если вовсе не заботиться о «справедливости» удовлетворения заявок, а по-прежнему интересоваться лишь минимизацией транспортных расходов, то для отыскания оптимального плана при условии (7) вводят фиктивный (т+ 1)-й пункт отправления Лт + 1 с запасом груза Qm^\ и полагают стоимости перевозок грузов из Лт + 1 равными нулю. Полученная ТЗ является замкнутой.
Найдя оптимальный план хц (Z = 1, т + 1; / = 1, я) этой ТЗ и отбрасывая в полученной матрице последнюю строку, получим оптимальный план исходной ТЗ.
В заключение пункта отметим, что многие экономические задачи, далекие по постановке от ТЗ, приводят к той же самой математической модели (1) — (4). Ограничимся одним примером.
Имеется т видов сельскохозяйственных культур и п хозяйств, где их можно выращивать. Из-за различных условий доход, получаемый с 1 га посева одной и той же культуры, в разных хозяйствах неодинаков. Обозначим его для Z-й культуры и /-го хозяйства через Сц. Общие площади посева культур az-(Z = 1, т) и площади пашни в хозяйствах Ь,^=\,п) известны. Требуется составить такой план размещения сельскохозяйственных культур по хозяйствам, чтобы общий доход был максимальным.
Обозначим площадь посева Z-й культуры в /-м хозяйстве через х4,. Тогда получаем задачу.
Найти план X=(xz/) такой, что: 2 2 Cq Xi, ->- max
Z=1 j=\ при условиях:
план посева по каждой культуре должен быть выполнен
2 Xij = Qi (Z = 1, m) j = i
пашня в хозяйствах должна быть использована полностью
2 Xij = b j ^j = 1, я)
Z= 1
Xij^O.
Мы получили задачу, аналогичную транспортной, но здесь ищется максимум линейной формы.
Метод потенциалов. В этом пункте описывается метод потенциалов решения ТЗ, предложенный Л. В. Канторовичем и М. К. Гавури- ным еще до разработки симплекс-метода. Общий принцип определения оптимального плана методом потенциалов аналогичен симплекс- методу, а именно: сначала находят опорный план ТЗ, а затем его последовательно улучшают. Итак: рассмотрим замкнутую ТЗ.
т п
2 S Сц Xi, -> min(8)
Z=1 /=1
при условиях:
пт
2 Xij = Qi (z=l, m) 5 Xij = bj (j = 1, /1)
/=1/=i
m n(9)
Xij 0 (7=1, m ; / = 1, n) 2 Qi= 2 bj.i=\j=\
Объяснять алгоритм метода потенциалов удобно на специальном
макете, который выглядит так, как показано в таблице 6.
Таблица 6
Макет транспортной задачи
с 11Х,1£нХ\2С ] пХ\п£11С22С2п^21^22Х2пс ГП 1Cm2СтаXtn 1X m2X тпс 11Х,1£нХ\2С ] пХ\п£11С22С2п^21^22Х2пс ГП 1Cm2СтаXtn 1X m2X тпВ| в2в„В| в2в„
с 11
Х,1
£н
Х\2
С ] п
Х\п
£11
С22
С2п
^21
^22
Х2п
с ГП 1
Cm2
Ста
Xtn 1
X m2
X тп
с 11
Х,1
£н
Х\2
С ] п
Х\п
£11
С22
С2п
^21
^22
Х2п
с ГП 1
Cm2
Ста
Xtn 1
X m2
X тп
В| в2в„
В| в2в„
Ь\
Ь2
Ьп
Остановимся прежде всего на одном из способов построения первоначального опорного плана ТЗ. Речь идет о так называемом методе «северо-западного угла». Суть его состоит в следующем. Пусть вначале все xz/ = 0 (z=l,m; / = 1, п). Будем последовательно менять величины хц начиная с клетки (1, 1). На каждом шаге, невзирая на тарифы, назначим перевозку от одного пункта отправления к одному пункту назначения так, чтобы либо исчерпался имеющийся запас груза в первом пункте, либо удовлетворилась потребность в грузе во втором пункте. В любом из этих вариантов один из пунктов исключим из дальнейшего рассмотрения. Пункты Ат и Вп должны быть исключены одновременно.
Более четко процедуру «северо-западного угла» можно понять из примеров, представленных макетами таблиц 7 и 8.
Пример 11. В таблице приведен первоначальный план, построенный способом «северо-западного угла». Стоимости в клетках не проставлены. При построении плана они не используются.
Опишем шаги заполнения таблицы 7.
Х// = 0 (Z = T?3; /=Т4)
Таблица 7
Построение начального плана ТЗ методом
«северо-западного угла»
10
50
30
40
Таблица 8
Построение начального плана ТЗ методом«северо-западного угла»
0
20
30
50
Перевозка из Л| в Вх. Исключение В\
а1=30>6, = 10а1=30>6, = 10хп = 6ь ai =ai —&i =20, 61=0.
а1=30>6, = 10
а1=30>6, = 10
Перевозка из Л1 в Вг. Исключение Л1
О|=20<6г = 50Х1г = О|, 62 = 62— О|=30, О|=0.
Перевозка из Лг в В 2. Исключение Ва
Ог = 40>6г = 30х22=6г, O2=a2 —6г = 10, 62 =0
Перевозка из Лг в Вз. Исключение Лг
a2=10< 63 = 30 Хгз = Ог, 63 = 63 —а2 = 20, о2=0.
Перевозка из Лз в Вз. Исключение Вз
о3 = 60>63 = 20х33 = 63, a3 = a3 —63 = 40, 63=0.
Перевозка из Лз в В4. Исключение Лз и В4
Оз = 40 = 63 х34 = б3, а3 = 6з = 0.
Пример 12. В первоначальном плане таблицы 8 подчеркнутые нули в макете — это те нули, которые вписывались в нее по методу «северо-западного угла».
Здесь шаги заполнения таблицы 8 выглядят так.
Х// = 0 (Z = T?3; j=M)
Перевозка из Ах в Вх. Исключение Вх
ax = <lQ>bx=Q xxx = bx> «1 = «i — Ьх = 20, 61 = 0.
В макете Хн отмечен нулем с подчеркиванием.
Перевозка из Ах в В2. Исключение в2
«1 = 20 = 61хх2 = Ьх, ах = ах — Ьх =0, 6| = 0.
Перевозка из Ах в В3. Исключение Ах
Gi=0<63 = 30A*13 = ab b3 = b3 — a! =30» ai =0.
Перевозка из А2 в В3. Исключение В3
а2 = ЗО = 63х23 = 63, а2 = а2 — 6з = 0, 63 = 0.
Перевозка из А2 в В^. Исключение А2
я2 = 0<б4 = 50х24 = а2, 6 4 = 6 4 — 02 = 50, о2 = 0.
Перевозка из А3 в В^. Исключение Л3 и В4
аз = 50 = б4Хз4 = 64, 03 = 64 = 0.
В общем случае количество элементов плана, вписываемых в макет методом «северо-западного угла», всегда равно n + m— 1. При этом, разумеется, учитываются и подчеркнутые нули. Эти нули появляются в первоначальном и других планах, получаемых методом потенциалов, тогда, когда или есть пункты А; с нулевыми запасами, или есть пункты Bj с нулевыми потребностями, или, наконец, в исходной ТЗ можно выделить замкнутую транспортную подзадачу. Наличие подчеркнутых нулей приводит, вообще говоря, к дополнительным вычислениям при поиске оптимального плана. Впрочем, от первых двух случаев, порождающих эти нули, легко избавиться простым выбрасыванием из макета соответствующих строк и столбцов. В полученной ТЗ уже все а, и bj будут положительными. Иногда так и поступают. Однако делать это не всегда целесообразно. Например, при многократном решении на ЭВМ конкретной ТЗ с фиксированной матрицей стоимостей и изменяющимися щ и 6/ (z=l,m; j=l,n) проще всего каждый раз вводить в память лишь значения запасов и потребностей грузов, а матрицу стоимостей считывать с какого-либо носителя и не заботиться о ее преобразованиях.
Для дальнейшего изложения нам нужны некоторые понятия.
Клетки макета, соответствующие плану ТЗ, назовем базисными, а их совокупность — базисом.
Циклом L назовем последовательность клеток макета, обладающих свойствами*
(4'ЛЛ (UJl)* U^’Jz)» (l3’Jz) ••• (4dl)
Рис. 39
первая и последняя клетки L совпадают;
каждые две соседние клетки расположены в одном ряду;
две первые клетки расположены в одном столбце;
никакие три клетки в одном ряду не располагаются.
На рисунке 39 показано схематическое изображение цикла. На рисунке 40 приведены некоторые разновидности циклов. Клетки в них заштрихованы и соединены отрезками прямых.
План, построенный методом «северо-западного угла», является ациклическим в том смысле, что из базисных клеток цикла не построишь. Однако если п, т^2, то начиная с любой небазисной клетки можно построить, и притом единственный, цикл, все клетки которого, кроме начальной, будут базисными. Доказываются эти утверждения индукцией по p = n + m.
Остановимся еще на одном факте, на котором и базируется метод потенциалов. Формулируется он так.
Если для некоторого плана X = (xz/) ТЗ можно подобрать систему из п-^т чисел: аь а2, ..., am; Pi, р2, ...» рл, такую, что для небазисных клеток P/ + az<G/, а для базисных Ру + а^Сф то X — оптимальный план. Числа az и ру называют соответственно потенциалами или платежами пунктов отправления и пунктов назначения.
Докажем сформулированное утверждение. Пусть X* = (yz/)— произвольный план. Тогда
т пт п
2 2 Cij yij^^ 2 2 (Р/ 4“ &i) у и= i=\ j=\i=\j = l
птт ппт
=2 Ру (2 Уо) +S a.(2 Уо) =2 Рубу+5 ВД =
Таким образом, стоимость перевозок любого плана (j^ не меньше стоимости плана X. Следовательно, X оптимален.
Теперь можно непосредственно перейти к описанию алгоритма решения ТЗ методом потенциалов.
Алгоритм метода потенциалов
Для замкнутой ТЗ (8) — (9) строим макет (табл. 6), где х,/ = 0 V=V т; j = l, п\
Методом «северо-западного угла» формируем первоначаль
ный план Х=Цх^ (1=\, т; / = 1, и), в котором ровно n + m—1 элементов, каждый из которых или положительное число, или подчеркнутый нуль.
Вычисляем совокупность потенциалов а,, р, (/=1, т, /=1, /г) так, чтобы в любой базисной клетке выполнялось условие р,4-а/ = = Cij. Для этого необходимо решить систему из n + m— 1 уравнений с /г + m неизвестными. Считаем ai=0 и последовательно определяем остальные потенциалы.
Проверяем текущий план на оптимальность. Если для всех клеток макета Pj + a/^Gj (z = l, m; /=1, /г), то план оптимален, и переходим к пункту 9.
Ищем в макете клетку (р, q\ являющуюся началом будущего цикла перераспределения перевозок, для которой
Р^ + ар — cpq = max (р, + a, — с^.
it i
Вычеркиваем из макета все ряды, кроме строки р и столбца q, имеющие не более одной базисной клетки. Этот процесс повторяем над оставшейся частью макета и т. д. до тех пор, пока еще есть что вычеркивать.
От клетки (р, р) строим цикл L. Все клетки L, кроме (р, q\ должны быть базисными.
Пусть значением подчеркнутого нуля является нуль и w = = minx/j, где min берется по всем клеткам, стоящим на четных местах в цикле. Организуем «сдвиг груза по циклу пересчета».
Во всех нечетных клетках перевозки увеличиваем на w;
xij = xij + w(10)
Во всех четных клетках перевозки уменьшаем на w;
Хц = Xij — W(11)
При этом все нули, получающиеся в результате пересчета (10) и (11), кроме первого, отмечаем как нули подчеркнутые. Тем самым во вновь полученном плане опять будет п-\-т — 1 базисных клеток.
Следующим выполняем шаг 3.
Выписываем из макета полученный оптимальный план в виде I, j, Xij для всех клеток, где х,/>0. Подсчитываем стоимость этого плана. Вычисления прекращаем.
Отметим, как решать по предложенному алгоритму ТЗ, имеющие некоторые усложнения в постановке.
AL ТЗ с нарушенным балансом запасов и потребностей.
Решение такой ТЗ простыми преобразованиями сводится к нахождению оптимального плана некоторой вспомогательной ТЗ. Об этом уже было сказано выше.
А2. ТЗ с поиском максимума линейной формы F.
Перейдем к форме Fx = — F и найдем план X*, доставляющий ей минимум. Тогда X* будет оптимальным и для исходной задачи, причем max F= — Fx ^Х*\
АЗ. ТЗ с запретными маршрутами.
Речь идет о задачах, в которых нельзя перевозить груз из некоторых пунктов отправления А, в некоторые пункты назначения В/. В этом случае стоимости соответствующих перевозок полагаем равными достаточно большому числу. Тогда при отыскании оптимального плана соответствующие перевозки будут блокированы.
А4. ТЗ с обязательными поставками.
Иногда приходится решать ТЗ, в которых дополнительным условием в ограничениях является обязательное обеспечение конкретных перевозок по определенным маршрутам. В этом случае каждую обязательную перевозку Xij = dij реализуем условно, уменьшая на di, запасы в Ai и потребности в В/. Если это сделать не удается, то исходная задача решения не имеет. В противном случае стоимости обязательных поставок полагаем равными достаточно большому числу, решаем полученную задачу и от ее оптимального плана переходим к оптимальному плану исходной ТЗ.
А5. ТЗ с ограничениями снизу.
Пусть требуется решить ТЗ, в которой некоторые из перевозок ограничены снизу ец<.хц. Организуем условные перевозки, уменьшив на ец запасы в Ai и потребности в В/. Если это сделать не удается, то исходная задача решения не имеет, в противном случае решаем полученную задачу и от ее оптимального плана переходим к оптимальному плану исходной ТЗ.
Аб. ТЗ с ограничениями сверху.
Этот случай не является столь простым, как предыдущие, но и он сводится к определению решения некоторой вспомогательной замкнутой ТЗ (см. [20, 23]).
Программа «Транспорт». Рассмотренный ранее метод потенциалов решения ТЗ реализуется программой «Транспорт». Следует иметь в виду, что оптимизация может проводиться на максимум и минимум, замкнутость ТЗ не предполагается, но ограничения на переменные, кроме неотрицательности, не допускаются. Программа состоит из трех основных частей.
Ввод данных о конкретной ТЗ. f
Преобразования по методу потенциалов.
Вывод оптимального плана.
Часть В (строки 450—1340) является ядром программы. Она оформлена в виде подпрограммы.
В соответствии с запросами на экране дисплея с пульта заносятся данные о конкретной ТЗ в такой последовательности:
Тип решаемой задачи (min — 1, max — 2).
Тип вывода (экран — 1, принтер — 2).
Количество пунктов отправления.
Количество пунктов назначения.
Данные о запасах груза в пунктах отправления Л, в виде: запас в Ль запас в Л2, ... .
Данные о потребностях груза в пунктах назначения В, в виде: потребность в В\, потребность в в2, ... •
Стоимости Сц перевозок единицы груза из Л,- в ВР Эти данные представляют собой матрицу, элементы которой должны вводиться последовательно по строкам.
В зависимости от ответов пользователя на запросы решается ТЗ на min или max, и на экран или принтер выводятся результаты счета в следующем виде:
Оптимальный план:
откуда:куда:сколько:
г 1/1х 1
/2/2^2
MIN (MAX) F = уS
время = г Здесь:
U — номера пунктов отправления (k = \, s);
jk— номера пунктов назначения (к = \, s);
Хк — перевозка по маршруту (it, jt);
у — оптимальное значение F;
z — время в секундах решения задачи (без учета времени ввода-вывода).
Пример 13. Программа «Транспорт».
10 ’ ТРАНСПОРТНАЯ ЗАДАЧА
20 ’=============================ВВОД ДАННЫХ
30 SCREEN 0:COLOR 15,4,4:KEY OFF:B=lE+50
40 Л$="Т РАНСПОРТНАЯ ЗАДАЧА
50 J2$="Запас А(1) в пункте отправления I;"
60 Л3$="3аявка B(J) в пункте назначения J:“
70 J4$="Стоимость единицы перевозки из I в J 80 PRINT Jl$:PRINT
90 INPUT "Задача (min -l,max -2)";0
100 INPUT "Вывод (экран-1,принтер—2)";Н
110 IF Н=1 THEN OPEN "crt:" AS #1
120 IF H=2 THEN OPEN "Ipt:" AS #1
130 1МРиТ"Количество пунктов отправления";S0 140 1НРиТ"Количество пунктов назначения ";Р0 150 0=3—2X0:S=S0: P=P0:PRINT:L=S+1:M=P+1
160 DIM Z(L,M),X(L,M):'стоимости и перевозки 170 DIM A(L),В(M):PRINT J2S:PRINT
180 FOR 1=1 TO S
190 PRINT "A(";I;")= ”;:INPUT A(I)
200 NEXT I
210 PRINT:PRINT J3*:PRINT
220 FOR J=1 TO P
230 PRINT "BI";J;">= ";:INPUT В(J)
240 NEXT J
250 PRINT:PRINT J4$:PRINT
260 FOR 1=1 TO S:FOR J=1 TO P
270 PRINT "Z(";I;",";J;")= ";
280 INPUT W:Z(I,J>=OXW
290 NEXT J:PRINT:NEXT I
500 GOSUB 450’==========================ЯДРО
310 H=TIME/50:CLS:U=0: ’ВЫВОД
320 PRINT #1,"ОПТИМАЛЬНЫЙ ПЛАН :";CHR*(13>
330 PRINT #1, "откуда! куда*! сколько"
256
350
360
370
380
390
400
410
420
430
440
450
460
4.70
480
490
500
510
520
530
540
550
560
570
580
590
600
610
620
630
340340PRINT #1PRINT #1
340
340
PRINT #1
PRINT #1
FOR 1=1 TO 80:FOR J=1 TO P0 IF X(I,J)<=0 THEN 390 U=U+X(I,J)XZ(I,J) PRINT#!,” " ; I; "";J;"";X(I,J)
NEXT J:PRINT #1,CHR$(13) NEXT I:PRINT #1,CHR$(13):U=ABS(U> IF 0=1 THEN PRINT #1,"MIN F = ";U IF 0=-l THEN PRINT #1,"MAX F = ";U PRINT #1,"время =";INT(H)+1 END:==========’имя программы "транс.пот" ’МЕТОД ПОТЕНЦИАЛОВ
TIME=0:CLS
LOCATE 8,9:PRINT "проводятся вычисления" Q=S0+P0:DIM Е(Q),F(Q) 'сведение к Балансу
X=0:FOR 1=1 TO 8:X=X+A(I):NEXT I Y=0:FOR J=1 TO P:Y=Y+B(J):NEXT J IF XXY=0 THEN 1340 IF X>Y THEN P=P+1:B(P)=X-Y IF X<Y THEN 8=8+1:A(8)=Y-X 'метод севере западного угла
1=1:J=1:H=1 R=A(I)-B(J) IF (R<=0) AND (RO0 OR B(J)=0) THEN 620 W=B(J):GOSUB 1260 IF J<P THEN J=J+1:GOTO 570 IF KS THEN 1=1+1:GOTO 570 ELSE 660 W=A(I):GOSUB 1290 IF KS THEN 1 = 1+1: GOTO 570
640 if J<P THEN J=J+1:GOTO 570
65b ’формирование платежей
0 T=B:GOSUB 1320:A(1)=0
70 R=0:FOR H=1 TO Q: I=E(H):J=F(H)
680 IF X(I,J)=0 THEN 720
90 X=A(I):Y=B(J)
700 IF X=B AND YOB THEN A(I>=Z(I,J)-Y:R=1 710 IF XOB AND Y=B THEN В(J)=Z(I,J)-X:R=1 720 NEXT H:IF R=1 THEN 670
730 ’проверка на оптимальность
740 R=0:FOR 1=1 TO S:FOR J=1 TO P
750 F=A(I)+B(J)—Z(I,J)
760 IF F>R THEN R=F:X=I:Y=J
770 NEXT J,Is IF R=0 THEN 1340
780 ’вычеркивание рядов
790 T=0:GOSUB 1320:FOR 1=1 TO S:FOR J=1 TO P
800 IF X (I, J> O0THEN A(I)=A(I)+1:B(J)=B(J)+1 810 NEXT J,I
820 R=0:FOR 1=1 TO S
830 IF A(I)=-1 OR A(I)>1 OR I=X THEN 880
840 A(I)=-1:R=1:FOR J=1 TO P
850 IF B(J)=-1 OR X(I,J>=0 THEN 870
860 B(3)=B(J)-1:IF B(J)=0 THEN B(J)=-1
870 NEXT J
880 NEXT I
890 FOR J = 1 TO P
900 IF B(J)=-1 OR B(J)>1 OR J=Y THEN 950
910 В(J)=—1:R=1:FOR 1=1 TO S
920 IF X(I,J>=0 OR A(I)=—1 THEN 940
930 A(I)=A(I)-1:IF A (I)=d THEN A(I)=-1
258
940 NEXT I
950 NEXT J:IF R=1 THEN 820
960 I=X: J=Y: W=B: ’нахождение цикла
970 K=I:1=1
980 IF A(I)=-1 THEN 1=1+1:GOTO 980
990 IF I=K OR X(I,J)=0 THEN 1=1+1:GOTO 980
1000 R=X(I,J):IF W>R THEN W=R
1010 IF IOX THEN K=J:J=1 ELSE 1050
1020 IF B(J)=-1 OR J=K THEN J=J+1:GOTO 1020
1030 IF X(I,J)=0THENJ=J+1:GOTO 1020 ELSE 970
1040 ’перевозка по циклу
1050 I=X:J=Y:V=0:IF W=-l THEN W=0
1060 K=I:I=1
1070 IF A(I)=-1 THEN 1=1+1:GOTO 1070
1080 IF I=K OR X(I,J)=0 THEN I=I+1:GOTO 1070
1090 R=X(I,J):IF R>=0 THEN 1110
1100 GOSUB 1220:X(I,J)=0:X(X,Y)=-l:GOTO 660
1110 IF R>W THEN X(I,J)=R-W:GOTO 1140
1120 IF VO0 THEN X(I,J)=-1
1130 IF V=0 THEN GOSUB 1220:X(I,J)=0:V=1
1140 IF I^X THEN X(X,Y)=W:GOTO 660
1150 IF IOX THEN K=J:J=1 1160 IF B(J)=-1 THEN J=J+l:60T0 1160
1170 IF J=K OR X(I,J)=0 THEN J=J+1:GOTO 1160
1180 IF X(I,J)<=0 THEN 1200
1190 X(I,J)=X(I,J)+W:60T0 1060
1200 IF W>0 THENX(I,J)=W:GOTO 1060 ELSE 1090
1210 ’подпрограммы
1220 FOR H=1 TO Q
1230 IF E(H)OI OR F(H)OJ THEN 1250
1240 E(H)=X:F(H)=Y:H=Q
1250 NEXT H:RETURN:’
1260 BOSUB 1310
1270 E(H)=1:F(H)=J:H=H+1:A(I)=R:В(J)=0
1280 RETURN
1290 BOSUB 1310:E(H)=I
1300 F(H)=J:H=H+1:A(I)=0:В(J)=-R:RETURN’
1310 IF WO0 THEN X(I,J)=W:GOTO 1313
1312 IF W=0 THEN X(I,J)=-1
1313 RETURN.
1320 FOR 1=1 TO S:A(I)=T:NEXT
1330 FOR J=1 TO P:В(J)=T:NEXT
1340 RETURN:’=====имя программы "транс.пот"
Приведем несколько примеров работы с программой «Транспорт».
Пример 14. Найти план, минимизирующий расходы от перевозок для следующей задачи.
Запасы груза в складах Л,: 20, 30, 40, 10.
Потребности в грузе в магазинах В,: 17, 15, 12, 8, 3, 4.
Матрица транспортных расходов на перевозку единицы продукции от склада А, в магазин 8;:
В\ В? Вз Вл В5 Вй
Л,/234213\
А,24112II
Л3311421
Л4\1I2223/
Вводимые данные:
2, 4, 6
30, 40, 10
15, 12, 8, 3, 4
3, 4, .... 3, 1, 1, ..., 2, 3
Сообщение:Смотри слева на схеме 1.
Пример 15. Найти план в предыдущей задаче, максимизирующий расходы от перевозок.
Вводимые данные:
2, 4, 6.
Далее — как и в примере 14.
Сообщение: Смотри справа на схеме f.
Оптимальный план: откуда! куда! сколько!
Схема 1 Оптимальный план: откуда! куда!сколько!
1
1
7
1
3
12
1
5
3
1
6
4
2
3
12
2
2
15
2
4
8
2
5
3
2
6
4
3
1
17
3
2
15
3
4
8
4
1
10
MAX F
= 209
MINF = 66
Время
= 42
Время
= 34
Обратим внимание, насколько разнятся планы в двух последних задачах по расходам на перевозки: 66 и 209. Этот факт является косвенным подтверждением того, что «угадать» оптимальный план, не используя специальные алгоритмы (программы), даже для небольших задач весьма сложно.
В заключение этого пункта отметим наличие отличных от метода потенциалов весьма эффективных алгоритмов решения ТЗ. К ним относится так называемый «венгерский алгоритм», основные идеи которого обсуждаются в следующем пункте на примере частной задачи транспортного типа.
Задача о назначениях
Постановка задачи. Алгоритм. Одна из распространенных формулировок задачи о назначениях (ЗН) выглядит так.
Пусть имеется т работников Л1, Л2, ..., Ат и п должностей Вь 62, ..., Вп. Известна мера с,, полезности (эффективности, цен
ности, стоимости) работника Л/ на должности В, (/=1, т; / = 1, п\ Требуется организовать такое закрепление работников на должности, при котором суммарная стоимость назначений будет максимальной.
Если Сц интерпретировать как издержки назначения Л, на Ви то естественно решать задачу закрепления работников на должности, при котором минимизируются общие затраты.
Построим математическую модель этой задачи.
РУ f L если Ai назначается на Bj
Усть и —| Q, если д. не назначается на Bj.
Рассмотрим булеву матрицу (х^ размера т X и, такую, что: mпт п
2х0< 1 (/ = 1,2 ^7^ \ (1 = \, гп) 2 2 ^7^min (m, /г)(1)
^1/=1/=!/=!
При этих условиях (х,,) называется планом или матрицей назначений. Среди планов выделяют такие, для которых в (1) достигается равенство. Они называются насыщенными.
Стоимость любого плана (х,-,) выражается суммой Г=5 5 /=|j=i
Окончательно математическая модель задачи будет такой.
Найти матрицу X=(xi/) (/ = 1, т; / = 1, и), такую, что:
w=S 2—> opt (max или min)(2)
<=i/=1
при условиях
Sx.j^l (/=1. и); S^/^l (< = 1. от)(3)
-=|/=|
2 2 = min(n, m)(4)
/=i/=i
х,/6{0, l)(z=L m; / = 1, и)(5)
Другими словами, ищется насыщенная матрица назначений, оптимизирующая форму F.
Фактически мы получили задачу линейного программирования, но с булевыми переменными. Однако если отбросить ограничение (5), заменив его более простым условием неотрицательности х,/, то задача о назначениях превращается в частный случай транспорт
ной задачи, где все запасы a, (/=1, m) и потребности Ь, (/=1, п) равны единице. Если решать эту задачу любым методом, приводящим при целых Qi и Ь, к целочисленному оптимальному решению, то неучтенные условия (5) удовлетворяются автоматически. Таким образом, для решения задачи о назначениях оказывается пригодным рассмотренный ранее метод потенциалов. Необходимо лишь
положить там а<=1, 6/=! (/=1, т; /=1, п\
Но именно эти особенности задачи о назначениях позволяют разработать для нее более эффективные модификации соответствующих алгоритмов. Ниже приводится подобная модификация «венгерского алгоритма».
Предварительно сделаем несколько замечаний. Решение исходной ЗН всегда можно свести в некотором смысле к эквивалентной ЗН с одинаковым количеством работников и должностей.
Пусть р = тах (п, tri) (п^т\ t
Рассмотрим возможные случаи.
т-Сп. Добавим к работникам п — т «подставных» лиц, для которых цены назначения на любые должности равны нулю Найдя оптимальный план этой ЗН и не учитывая в нем подставных лиц, получим оптимальное назначение исходной ЗН.
m>n. Добавим к имеющимся должностям т — п условных мест, цены назначения на которые положим равными нулю. Найдя оптимальный план этой ЗН и не учитывая в нем работников, назначенных на несуществующие должности, получим оптимальный план исходной задачи.
Таким образом, всегда можно считать п = т = р.
Макет задачи о назначенияхМакет задачи о назначенияхОписание алгоритма будем проводить с использованием специального макета (см. табл. 9). Поскольку план Х=(хц) мы будем по-
Макет задачи о назначениях
Макет задачи о назначениях
В,
В2
В,
е2
е4
А,
Си
С12
С\р
i\
si
Аг
С 22
С22
С2р
<2
s2
Ар
Ср 1
Ср2
Срр
ip
Sp
Е,
Ез
/1
/1
/2
/г
ip
tp
Таблица 9
следовательно формировать в основной матрице макета, где перво- начально проставлены стоимости, то для однозначной идентификации значений нам придется ввести для клеток три типа нулей.
— простой нуль (текущая стоимость — 0, значение компоненты плана — 0);
— нуль со звездочкой (текущая стоимость — 0, значение компоненты плана — 1);
— нуль со штрихом (текущая стоимость — 0, значение компоненты плана — 0, но при следующем улучшении плана оно может обратиться в 1). В программе «Назначение» эти нули кодируются соответственно символами: 0, — 1, —2.
EvU)Q = L р)EvU)Q = L р)Одномерные массивы £| — £4 являются вспомогательными и служат для указания в основной матрице адресов определенных элементов. Они будут заполняться в процессе вычислений. Их значения интерпретируются так.
EvU)Q = L р)
EvU)Q = L р)
— номер строки в столбце /, где расположен 0 Если £i (/) = 0, то подобные нули отсутствуют.
263
E2^(i=L p)E2^(i=L p)— номер столбца в строке I, где расположен О*. Если £2(z) = 0, то подобные нули отсутствуют.
E2^(i=L p)
E2^(i=L p)
£4(z) (/=1, р) —номер столбца в строке z, где расположен О'.
Если £4(z) = 0, то подобные нули отсутствуют.
£3 (/) (/ = 1, р)—метка столбца j. Столбец считается занятым
при £3(/)=#0 и свободным при £3(/) = 0.
Теперь приступим к описанию обещанной модификации «венгерского алгоритма» задачи о назначениях.
Алгоритм решения задачи о назначениях (модификация «венгерского алгоритма»).
Формирование макета. Для ЗН (2) — (5) строим макет (табл. 9), где p = max(m, п\ если решается задача на максимум, меняем знаки у С,/. Элементы массивов £i —£3 полагаем равными нулю.
Предварительное преобразование матрицы стоимостей С.
Из каждого элемента столбца j (/=1, р) вычитаем его наименьший элемент: Cij = Cij— min Cs/(z = l, р).
l^x^p
Из каждого элемента строки z (/=1, р) вычитаем ее наименьший элемент: CZ/ = CZ/ — min C,s (/ = 1, р).
Полученная матрица С имеет по крайней мере один нуль в каждой строке и каждом столбце. Суммируем все находимые в процессе счета минимумы с,-/ по строкам и столбцам и полученное значение присваиваем величине F.
Формирование начального назначения. Просматриваем по
очередно слева направо каждую z-ю строку (z = l, р) матрицы стоимостей C = (cij\ Если встретится нуль и в его столбце отсутствует элемент О*, то метим 0 звездочкой. В каждом ряду (строке и столбце) должно быть не более одного элемента 0*. Одновременно создаем массивы адресных ссылок £i и £2 и массив занятости столбцов £3. Делаем это так. Если (z, /) — клетка расположения в макете 0*, то £1(^ = 1, £2 $ = }, £3 (/)=!. Подсчитываем в С количество Н элементов 0* и переходим к пункту 9.
Все строки объявляем свободными: £4(z) = 0 (/=1, р). В дальнейшем будут появляться и занятые строки (£4(z)=#0). Элементы матрицы С = (Сц\ стоящие на пересечении свободных рядов, называются свободными. Остальные элементы С — занятые.
Если в С нет свободных нулей, то переходим к пункту 8.
Разметка макета. Просматриваем поочередно слева направо строки матрицы С, выбираем в ней первый свободный нуль и метим 264
его штрихом. Пусть (/, /) — местоположение в макете нового О'. Фиксируем его адрес: Еа(1) = j. Тем самым строка I объявляется занятой. Если в ней нет элементов 0*, то переходим к пункту 7.
Пусть (ц $) — местоположение в строке / элемента Ст Снимаем метку занятости столбца S: £3(S) = 0 и переходим к пункту 5.
Дополнительные назначения. Начиная с только что отмеченного нуля, строим цепочку: от данного О' по столбцу к 0*, от него по строке к О' и т. д. Поиск соответствующих элементов облегчают адресные массивы £i, Е2 и Е^. Цепочка оборвется на О'. Возможно, что она вообще будет состоять из одного начального О'. Заменяем в цепочке каждый 0* на 0 и О' на О*. В процессе этой замены актуализируем значения элементов массивов Еь Е2 и £3. Количество Н элементов 0* увеличиваем на 1: Н = Н+\. Переходим к пункту 9.
Изменение стоимостей. Пусть w — минимальный среди всех свободных элементов матрицы С. Преобразуем С так. Элементы свободных строк уменьшим на w, а элементы занятых столбцов увеличим на w. При этом 0* и О' оставляем без изменения. Эти операции приводят к появлению в С свободных нулей.
Пусть изменениям подверглись L\ строк и L2 столбцов. Тогда текущее значение F стоимости плана вычисляем следующим образом: F = F-V(L\ — L2) *w и переходим к пункту 6.
Проверка окончания счета и вывод результатов. Если количество Н отмеченных звездочкой нулей меньше Р, то переходим к пункту 4, иначе процесс окончен. Места, занимаемые элементами О*, соответствуют переменным х,/, равным единице. Формируем и выводим оптимальный план X = (xz/) исходной задачи:
ХцХц(/ = 1, т; / = 1, п\(/ = 1, т; / = 1, п\(1, если Сц есть О*
Хц
Хц
(/ = 1, т; / = 1, п\
(/ = 1, т; / = 1, п\
если Cij не есть 0*
Выводим значение стоимости плана X:
для заДачи на минимум' I — F для задачи на максимум.
Вычисления прекращаем.
Непосредственное обоснование алгоритма предлагаем провести читателю самостоятельно.
Заметим следующее. Если в ЗН имеются несовместимые пары (Д/, 5/), то есть назначение Ai на должность В, невозможно, то для ее решения ничего нового придумывать не требуется. Достаточно соответствующую стоимость задать так:
q f В для задачи на минимум
—"I —В для задачи на максимум,
где В — достаточно большое число.
Программа «Назначение». Приведенный в предыдущем разделе алгоритм решения ЗН (2)(5) реализуется программой «Назна
чение». Оптимизация по ней может проводиться на максимум и минимум. Равенство количества работников и должностей не предполагается. Структура программы соответствует структуре алгоритма.
По запросам с экрана дисплея с пульта заносятся данные о конкретной ЗН в такой последовательности:
Тип задачи (min — 1, max —2).
Тип вывода (экран — 1, принтер —2).
Количество работников.
Количество должностей.
Цена назначения (работник — должность). Эти данные представляют собой матрицу, элементы которой должны вводиться последовательно по строкам.
В зависимости от ответов пользователя на запросы решается ЗН на min или max и на экран или принтер выводятся результаты счета в следующем виде.
Назначениеработник: должность
<2/2
MIN (MAX) F=y время = z
Здесь:
q = min (m; n);
it—номера работников (^ = 1, q\
jk—номера должностей (A = l, q);
у — оптимальное значение формы F;
z—время в секундах решения ЗН (без учета времени ввода- вывода)
Пример 16. Программа «Назначение».
10 *ЗАДАЧА О НАЗНАЧЕНИЯХ
20 ”(МОДИФИКАЦИЯ ВЕНГЕРСКОГО АЛГОРИТМА)
30 ’=============================ВВОД ДАННЫХ
40 SCREEN 0:COLOR 15,4аWIDTH 40:KEY OFF
50 PRINT "ЗАДАЧА О НАЗНАЧЕНИЯХ":PRINT
266
bS INPUT "Тип задачи (min -l,max —2) ";0
70 INPUT "Тип вывода (экран—1,принтер—2) ";Н
80 IF Н=1 THEN OPEN "crt:“ AS #1
90 IF H=2 THEN OPEN "Ipt:" AS #1
100 INPUT "Количество работников";S1
110 INPUT "Количество должностей";S2
120 O=3-2XO:B=lE+50
130 IF SKS2 THEN P=S2 ELSE P=S1
140 DIM Z(P,P),A(P),B(P),C(P),D(P)SPRINT
150 PRINT "Издержки назначения":PRINT
160 FOR 1=1 TO SI
170 FOR J=1 TO S2:PRINT "Z(";I;",";J;") = ";
180 INPUT W:Z(I,J)=OXW
190 NEXT J:PRINT:NEXT I
200 CLS:TIME=0:’========================ЯДРО
210 LOCATE 8,9:PRINT "проводятся вычисления"
220 *начальное назначение
230 IF SKS2 THEN 300
240 FOR J=1 TO S2:W=Z(1,J)
250 FOR 1=2 TO P: IF Z(I,JXW THEN W=Z(I,J>
260 NEXT I
270 FOR 1=1 TO P
280 Z(I,J)=Z(I,J)-W:NEXT I:Z=Z+W
290 (MEXT J
300 IF S2<S1 THEN 360
310 FOR 1=1 TO SI:W=Z(I,1):FOR J=2 TO P
320 IF Z(I,JXW THEN W=Z(I,J)
330 NEXT J
340 FOR J=1 TO P: Z(I, J)=Z(I,J>—W:NEXT J
350 Z=Z+W:NEXT I
370
380
390
400
410.
420
430
440
450
460
470
480
490
500
510
520
530
540
550
560
570
580
590
600
610
620
630
640
360360FOR 1=1 TO P:FOR J=1 TO P
360
360
IF A(J)<>0 THEN 400 IF Z(I,J><>0 THEN 400 Z(I,J)=-1:A(J)=I:B(I)=J:J=P:U=U*1 NEXT J,I:IF U=P THEN 670 *разметка
FOR J=1 TO P:C(J)=A(J):D(J)=0:NEXT R=0:FOR J=1 TO P;IF C(J)<>0 THEN 470 FOR 1=1 TO P IF D(I)=0 AMD Z(I,J)=0 THEN X=I:Y=J:I=P: NEXT IJ=P:R=1
NEXT J:IF R=0 THEN 570 Z(X,Y)=-2:IF B(X)=0 THEN B(X)=Y:GOTO 510 D(X>=Y:C(B(X))=0:GOTO 430 ’дополнительные назначения
Z (X, Y) =—1: R=A (Y) : A (Y> =X: IF R=0 THEN 530 X=R:SWAP B(X),D(X):Y=B(X):GOTO 510 FOR 1=1 TO P J=D(I):IF JO0 THEN Z(I,J)=0 NEXT I:U=U+1:IF LKP THEN 420 ELSE 680 ’‘•изменение стоимостей
H=B:FOR 1=1 TO P:FOR J=1 TO P IF C(J)<>0 OR D(I)<>0 THEN 600 IF H>Z(I,J) THEN H=Z(I,J)sX=I:Y=J NEXT J,I:W=0 FOR.1=1 TO P:IF D(I)<>0 THEN 630 FOR J=1 TO P:Z(I,J)=Z(I,J)-H:NEXT:W=W+1 NEXT I FOR J=1 TO P:IF C(J)=0 THEN 660
650 FOR 1=1 TO P:Z(I,J)=Z(I,J)*H:NEXT:W=W-1
bb® NEXT J:Z=Z+HXW:GOTO 430
670 ’==================================выво
680 T=TIME/50:CLS
690 PRINT #1,“H A 3 H А Ч E H И E";CHR*(13)
700 PRINT # 1, "работник!должность"
710 PRINT #1,"!"
720 FOR 1=1 TO SI:FOR J=1 TO S2
730 IF Z (I, J)0-1 THEN 750
740 PRINT#1,"";I;"!";J
750 NEXT J,I:PRINT #1,CHR*(13):Z=ZXO
760 IF 0=1 THEN PRINT #1,"MIN F =";Z
770 IF 0=—1 THEN PRINT #1,"MAX F =";Z
780 PRINT#1,"время =";INT(T)+1
790 END:”’имя программы "назнач.вен"
Приведем два примера работы с программой «Назначение».
Пример 17. Пусть имеется 5 типов работ и 5 механизмов для их выполнения, причем каждый механизм может использоваться на любой работе. Производительность механизма Л,- на работе В,
(z, / = 1, 5) известна и задается следующей матрицей:
в.
В2 Вз В4 В5
Aiq
Аг
Азf
А4‘
А5J
2545'
3214
2632
3541
2215,
Требуется распределить механизмы по работам так, чтобы суммарная производительность была максимальной.
Ясно, что это типичная задача о назначениях.
Вводимые данные:
1, 5, 5
2, ..., 5 (матрица цен).
Сообщение (смотри слева на схеме 2):
Пример 18. Найти оптимальный план, минимизирующий издержки назначения для задачи, исходные данные которой задаются следующей матрицей цен:
А| В, Вг Вз В4 В5 В6 В7
А!/10232441\
А2|210382171
Аз\15102133
А4\14110725/
Вводимые значения:
1, 1, 4, 7
10, 25 (матрица цен)
Сообщение (смотри справа наСообщение (смотри справа наработникДОЛЖНОСТЬ1421334255работникДОЛЖНОСТЬ1421334255НазначениеНазначениеMAX F = 23 время = 2MAX F = 23 время = 2работникдолжность17263143работникдолжность17263143схеме 2):Схема 2 Назначениесхеме 2):Схема 2 НазначениеMIN F = 4время = 2MIN F = 4время = 2
Сообщение (смотри справа на
Сообщение (смотри справа на
работник
ДОЛЖНОСТЬ
1
4
2
1
3
3
4
2
5
5
работник
ДОЛЖНОСТЬ
1
4
2
1
3
3
4
2
5
5
Назначение
Назначение
MAX F = 23 время = 2
MAX F = 23 время = 2
работник
должность
1
7
2
6
3
1
4
3
работник
должность
1
7
2
6
3
1
4
3
схеме 2):
Схема 2 Назначение
схеме 2):
Схема 2 Назначение
MIN F = 4
время = 2
MIN F = 4
время = 2
Остановимся на некоторых характеристиках программы «Назначение». Во-первых, в ней используются всего 4 линейных рабочих массива, что позволяет размещать в оперативной памяти довольно «большие» задачи. Во-вторых, быстродействие программы также вполне приемлемо. На ЭВМ «Ямаха» ЗН размером 45X45 выполняются за 20—40 минут. Упомянем об одной разновидности постановки задачи о назначениях.
Пусть имеется т групп лиц А, по a, (/=1, m) человек в каждой и п типов работ Bj по Ь, (/‘=1, и) единиц в каждой. Известна производительность сц лица i-й группы при выполнении /-го типа работ. Необходимо определить, сколько лиц, из какой группы и на какую категорию работ назначить, чтобы суммарная производительность была максимальной.
Обозначим через хц количество лиц /-й группы, назначаемых для выполнения работ /-го типа. Тогда математическая модель задачи будет такой.
270 *
Найти план назначения Х=(х,,), максимизирующий значение т п
линейной функции 5 5 с^хц при ограничениях:
<=|/=1
2 хц = а,- (t = 1, m).2. 2 хц = bq (j — \, nY
i='i=\
Xij — целые неотрицательные числа.
Фактически мы получили модель транспортной задачи, но с целочисленными переменными. Поскольку алгоритм потенциалов и «вен
герский метод» решения ТЗ при целых a, (i=l, m) и b, Ц=Х, п) дают целочисленное решение, то сформулированную ЗН можно решать любым из этих методов.
КОРНИ МНОГОЧЛЕНОВ
Пусть п — натуральное число и
f (г^с^Н-а^"-1 4-... + a„ (ao^O)(1)
полином, или, по-другому, многочлен, комплексного переменного с комплексными коэффициентами ак (fc = 0, п). В соответствии с основной теоремой алгебры /(2) имеет ровно п корней (нулей):
Wb W2, ...» wn.(2)
До появления компьютеров нахождение всех величин Wk (к = 1, п) считалось весьма трудоемкой задачей и для каждого конкретного случая опиралось, как правило, на выбор специальных приемов и методов, учитывающих свойства f (z). В настоящее время разработаны весьма простые и эффективные алгоритмы нахождения корней полиномов, ориентированные на использование ЭВМ. Три таких алгоритма и будут рассмотрены ниже. Все они являются итерационными и весьма просты в реализации.
Методы Ньютона и секущих
Рассматриваемые методы обеспечивают довольно быструю сходимость при наличии у многочлена корней не выше второй кратности.
В методе Ньютона нуль ws функции f (2) находится, исходя из начального приближения 20, как предел последовательности комплексных чисел Zk*.
2k-vx = Zk — f(zk)/f,^(k = O. h 2, ...)(3)
при условии f'(Zk^O.
В методе секущих нуль ws функции f (z) находится, исходя из начальных приближений zo и 2, как предел последовательности комплексных чисел z^.
zk*\=Zh — f (zt)/[(f (z»)— f (гк-^Цгь — z*_,)] (6=1, 2, 3, ...) (4)
271
В каком случае итерации по формулам (3) или (4) следует приостанавливать? Как правило, это делают тогда, когда для очередного Zu выполняется условие If (z»)| <е, где е>0 — заранее фиксированное малое положительное число. При этом считают, что ws«zk. Далее, после понижения степени f: f (z) = f (z)/(z —zA) определяют другие корни исходного полинома. Учитывая крайнюю неустойчивость корней ws (s = 1, п) некоторых полиномов от их коэффициентов, целесообразно отыскивать величины ws различными способами. Это позволит организовать анализ полученных прибли
жений к ws (s = l, п) и уточнение последних.
В программе примера 1 реализована комплексная арифметика. По ней, в соответствии с диалогом, корни {(г) могут находиться и методом Ньютона, и методом секущих.
Пример 1. Программа нахождения корней полиномов с вещественными или комплексными коэффициентами методами Ньютона и секущих.
10 ’ НАХОЖДЕНИЕ КОРНЕЙ ПОЛИНОМОВ
20 ’МЕТОДЫ НЬЮТОНА И СЕКУЩИХ
30 >
40 ’F(Z)= a(0>Xz'n + а(1)XzA(n-1)+ ...+
50*a(n-l)Xz+ a(n)
60 ’1) a(k)=A(k)— коэфф, вещественные
70’<k=0,l..»n)
80?2) a(k)=A(k)+1XB(k)— коэфф. комплексные
90’(k=0,l...n)
100 ’
110 SCREEN 0:COLOR 15,4:KEY OFF:E2=lE-05
120 A$="##)#####.#######+#####.#######Xi"
130 D$="3. вещественные части коэффициентов:
140 E$="4. комплексные части коэффициентов:”
150 F$="3. коэффициенты:"
160 ’===================================ВВОД
170 PRINT " КОРНИ МНОГОЧЛЕНОВ":PRINT
180 INPUT "1. степень многочлена ";N0
272
190 R=N0+1:DIM C (R) , D (R) , A (R) , В (R)
200 PRINT "2. тип коэффициентов:"
210 PRINT "вещественные — 1"
220 INPUT "комплексные — 2";T:PRINT
230 IF T=1 THEN PRINT F$ ELSE PRINT DS
240 FDR K=0 TO N0
250 PRINT "A(";K$") = ";:INPUT C(K)
260 NEXT
270 IF T=2 THEN PRINT ES ELSE 310
280 FOR K=0 TO N0
290 PRINT "B(";K;") = ";:INPUT D(K)
300 NEXT
310 PRINT
320 IF T=1 THEN PRINT "4."; ELSE PRINT "5."$
330 INPUT" ’точность’ вычислений "$Е1:Е=Е1А2
340 PRINTsPRINT "ВОЗМОЖНЫЕ МЕТОДЫ:"
350 PRINT:PRINT " НЬЮТОНА 1"
360 PRINT ”СЕКУЩИХ 2"
370 INPUT "выход 3 ";O:CLS
380 LOCATE 8,0:PRINT "проводятся вычисления"
390 PRINT:LOCATE 3,4:ON О GOTO 400,410,920
400 PRINT "метод НЬЮТОНА":GOTO 420
410 PRINT "метод СЕКУЩИХ"
420 N=N0:W=1
430 FOR S=0 TO N:A(S)=C(S>:B(S)=D(S):NEXT
440 LOCATE 3,6:PRINT “корни многочлена:"
450 PRINT:T=TIME:IF 0=2 THEN 560’=======ЯДРО
460 GOSUB 860:’метод НЬЮТОНА
470 GOSUB 760:R=CA2+DA2
480 IF R<E THEN GOSUB 870:GOTO 920
490 GOSUB 720:L=(AXC+BXD)/R:M=(BXC—AXD)/R
510
520
530
540
550
560
570
580
610
620
630
640
650
660
670
680
690
700
710
720
730
740
750
760
770
780
790
800
810
500500IF ABS(L)+ABS(MX=E1 THEN 520
500
500
X=X-L:Y=Y—M:GOTO 470
PRINTUSING A$;W,X,Y N=N—1:W=W+1:GOSUB 820 IF N>0 THEN 460 ELSE GOSUB 890:GOTO 340 ’метод СЕКУЩИХ
U=0: V=0: C=A (N) : D=B (N)
GOSUB 860
GOSUB 720
R=LX2+MX2
IF R<E THEN GOSUB 870:GOTO 920
L=(AXL1+BXM1)/R
M=(BXL1-AXM1)/R:R=ABS(L)+ABS(M) IF R<=E1.THEN 670
U=X:V=Y:C=A:D=B:X=X-L:Y=Y-M:GOTO 580
PRINTUSING A»;W,X,Y
N=N—1:W=W+1:GOSUB 820 IF N>0 THEN 560 ELSE GOSUB 890:GOTO 340 ’подпрограммы
’вещественная и мнимая части F
А=А(0):В=В(0)
FOR К=1 ТО N
L=AXX—BXY+A(К):B=BXX+AXY+B(К):A=L
NEXT:RETURN
C=A(0)XN:D=B(0)XN:IF N=1 THEN 810 FDR K=1 TO N—1
L=CXX-DXY+(N-K)ХА(K)
D=DXX+CXY+(N-K)XB(K):C=L
NEXT
RETURN: ’понижение степени F
820 FOR K=1 TO N:L=K-1
830 А (К) =A (К)+A (L) XX—В (L) XY
840 В(К)=B(K)+B(L)XX+A(L)XY
850 NEXT:RETURN:’
860 X=RND(-TIME)X3:Y=RND(-TIME)X3+1:RETURN
870 PRINT "приближение к кратному корню" 880 PRINT:PRINTUSING А»;W,X,Y:RETURN:’
890 PRINT
900 PRINT "время снега = ";(TIME-T)/50;"сек" 910 RETURN
920 END:'===========им я программы "КОРНИ-1"
Пример 2. По программе примера 1 методом Ньютона найти приближенные значения корней полинома f (z)=z4 —4z3+5z2 — —4z+4.
Соответствующие диалог и сообщение о результатах счета ниже.
ДИАЛОГ
КОРНИ МНОГОЧЛЕНОВ
степень многочлена ? 4
тип коэффициентов: вещественные — 1комплексные — 2? 1
коэффициенты:
А( 0 ) = ? 1
А ( 1 ) = ? —4А ( 3 ) = ? —4
А( 2 ) = ? 5А( 4 ) = ? 4
’точность* вычислений ? 0.0000001
ВОЗМОЖНЫЕ МЕТОДЫ:
НЬЮТОНА 1 СЕКУЩИХ 2
выход3? 1
СООБЩЕНИЯ И РЕЗУЛЬТАТЫ ВЫЧИСЛЕНИЙ проводятся вычисления метод НЬЮТОНА
корни многочлена:
0.0000000+1.0000000X1
2.0000000+0.0000003X1
2.0000000-0.0000003X1
0.0000000-1.0000000X1
время счета =28.9 сек
ВОЗМОЖНЫЕ МЕТОДЫ:
НЬЮТОНА 1СЕКУЩИХ
выход3 7
Отметим следующее обстоятельство. Поскольку начальная точка для последовательных приближений генерируется случайным образом, то повторный прогон того же самого примера может привести как к иному времени счета, так и к небольшим отклонениям от полученных значений корней.
Пример 3. По программе примера 1 методом секущих найти приближенное значение корней полинома ^ (2) = z3 —z2 —zz + z".
Соответствующие диалог и сообщение о результатах счета ниже.
ДИАЛОГ КОРНИ МНОГОЧЛЕНОВ 1. степень многочлена ? 3 2. тип коэффициентов:
вещественные — 1 комплексные —27 2
вещественные части коэффициентов:
А( 0)=71А(2)=70
А( 1)=?-1А(3)=70
комплексные части коэффициентов:
В( 0)=70В(2)=7-1
В( 1)=?0В(3)=?1
'точность” вычислений ? 0.0000001 ВОЗМОЖНЫЕ МЕТОДЫ:
НЬЮТОНА1 СЕКУЩИХ2
выход3 ? 2
СООБЩЕНИЯ И РЕЗУЛЬТАТЫ ВЫЧИСЛЕНИЙ
проводятся вычисления метод СЕКУЩИХ корни многочленам
1.0000000+0.0000000X1
0.7071068+0.7071068X1
-0■7071068-0.7071068X1
время счета =13.02 сек
22ВОЗМОЖНЫЕ МЕТОДЫ:
2
2
НЬЮТОНА 1 СЕКУЩИХ
выход3 ?
3.2. Метод «обруча»
Приведенный ниже метод нахождения корней ws (s= 1, и) многочлена f (z) с успехом можно применять вне зависимости от порядка кратности ws. Он опирается на тот факт, что f (z) — аналитическая во всей комплексной плоскости функция, и на принцип максимума модуля аналитической функции. Этот принцип формулируется так.
Модуль функции f (z). аналитической в области G и не равной тождественно постоянной, не может иметь максимума ни в одной точке области.
Из принципа максимума модуля вытекает важный для нас принцип минимума модуля.
Модуль аналитической функции f(z)^const не может иметь минимума ни в одной точке области, не являющейся нулем функции / (z).
В самом деле, если /(zo^O, то в силу непрерывности f (z) неравенство f(z)^O имеет место в некоторой окрестности U точки z0, принадлежащей G. Следовательно, в U функция q) (z) = 1 //(z) является аналитической и не равной тождественно постоянной. Поэтому модуль <p(z) не может иметь максимума в точке z0. Но тогда If (z)| не имеет минимума в z0.
Над комплексной плоскостью мысленно сконструируем поверхность F (z)= If (z)|, называемую аналитическим ландшафтом f (z). Далее, из совпадения нулей f (z) и F (z) и тога, что F (z)^0, вытекает, что нули f (z) соответствуют наиболее «глубоким впадинам» аналитического ландшафта. Но из принципа минимума модуля функции следует, что в аналитическом ландшафте других впадин просто нет. Таким образом, двигаясь по ландшафту от любой его точки «вниз» к комплексной плоскости, будем приближаться к одному из корней f (z). На подобном движении и основан предлагаемый ниже алгоритм «обруча» отыскания корней полиномов. Этот алгоритм следует отнести к разновидности многочисленных методов спуска при
определении минимума функции многих переменных. Правда, здесь для F (х, t/) = If (z)| несколько своеобразно организуется спуск, а его направления и даже их количество заранее не определены. Фактически они являются параметрами алгоритма и должны заново фиксироваться при каждом его выполнении. Варьирование направлений спуска дает возможность получать различные минимизирующие последовательности для каждого конкретного корня f (2). Иногда это позволяет проводить уточняющий анализ полученных приближений к корням.
Приступим к описанию алгоритма.
Зафиксируем следующие величины.
начальный угол а0 (О^ао<2л);
шаг для угла h (0</г^2л/3);
«точность» вычислений Е (£>0);
количество направлений & (& = INT (2л/Л)).
Пусть £о = ((7о, 60) — точка комплексной плоскости, /?>0 и О (£о, /?)— окружность с центром в £0 и радиуса R. Будем называть О (£о, /?) «обручем». Исходное положение «обруча» и его размер определим числами: ао = 6о = О, R=\.
На «обруче» О (£0, /?) зафиксируем к точек (см. рис. 41)
Ei=^, Ь^} = Т7к\
где
aj = a0 + /?-cos (a0+(j— 1) ft)6j = 6o + /?-sin (a0 + (/ — 1) ft).
Вычислим в точках E, (j=0, ft) значения модуля F (x, у) много
члена f (z). Получим числа F, Q = 0, k\
Находим наименьший индекс s такой, что Р5^Е, (/ = 0, ft). Если s = 0, то радиус «обруча» уменьшаем вдвое (R = R/2). В против-
Рис. 41 278
ном случае центр «обруча» перемещаем в точку Es (EO = ES), а его радиус увеличиваем в два раза (/? = 2-/?).
Если R>E, то переходим к шагу 3.
Если для zo = ao-V-ibQ |B(zo)|^e, то объявляем (а0, Ьо) корнем f(z) и организуем «выщип» корня zo: f (z)=f (z)/(z — z0)
При R<E и |F(zo)|>E (например, не можем спуститься из седловой точки) считаем вычисления завершившимися неудачно. Иными словами, при данных ао и й f (z) не входит в область определения алгоритма. В этом случае счет можно повторить с другими значениями ао и h.
Если степень f (z) больше 1, то переходим к шагу 2.
Решаем линейное уравнение f (z) = 0 и находим последний из корней. Вычисления прекращаем.
В дополнение к приведенному алгоритму заметим, что вычисление значений F (х, у) и выделение найденного корня целесообразно проводить по схеме Горнера так, как это реализовано в предыдущей программе. Далее, шаг 9 предполагает непосредственное решение последнего линейного уравнения f (z)=0. Если оно выглядит так:
(Ао+<Во) (х+iy)+(Л 1-HBi)=0,
то ясно, что
х= -(ЛоЛ! +ВоВ1) / (ЛНВ§) у=(Л1Во-ЛоВ1) / (Л^ + ВЙ).
И еще один вопрос, в сущности, остался открытым. Какие значения выбирать для ао и й? Относительно а0, не зная корней $ (z), по-видимому, ничего определенного сказать нельзя. Что касается й, то здесь нужно исходить из следующих соображений. С одной стороны, хотелось бы перемещаться в сторону минимума F (х, у) по более «правильному» направлению. И это требует брать больше точек на обруче, то есть задавать й небольшим. С другой стороны, при малых й на шагах 3 и 4 алгоритма придется выполнять большой объем вычислений. А это, конечно, плохо. Как же поступать? Исходя из анализа решений тестовых задач, можно рекомендовать пары (ао, й), в которых компоненты берутся из множеств:
ао6(О°, 30°, 45°, 60°, 90°)йС{120°, 90°, 72°, 60°).
Описанный алгоритм реализуется программой примера 4. При этом в случае «плохого» исхода: R<E, \F(z<j)\>E— значения «о и ft подправляются автоматически.
Пример 4. Программа нахождения корней многочленов с комплексными или действительными коэффициентами методом «обруча».
10 ’ КОРНИ МНОГОЧЛЕНОВ
20 * (метод ’ОБруча’ для модуля многочлена)
30 ’ ==:====:=============================ВВОД
40 SCREEN 0:COLOR 15,4:KEY OFF:WIDTH 39
50 A$=STRING$(38, "-") : D«=STRING* (38, "=")
60 B$="####.##### *###.#####XI"
70 PRINT " КОРНИ МНОГОЧЛЕНА":PRINT А»
80 INPUT "степень многочлена";N:M=N
90 DIM A(N),В(N):PRINT
100 PRINT "вещественные части коэффициентов: 110 FOR S=0 TO N
120 PRINT "A(";Sj“> = "$:INPUT A(S)
130 NEXT:PRINT
140 INPUT "коэф, вещественны (1-ДА,2-HET)";W
150 IF W=1 THEN 200
160 PRINT "мнимые части коэффициентов:"
170 PRINT:FOR S=0 TO N
180 PRINT "B(";S;"> = ";:INPUT B(S)
190 NEXT
200 PRINT:INPUT "’точность’ вычислений ";E
210 PRINT At:PRINT "ДЛЯ ТОЧЕК НА ’ОБРУЧЕ’:"
220 INPUT "начальный угол (градусы)";U
230 INPUT "шаг для угла (1 - 120)";Н
240 T0=ATN(l)/45
250 K=360\H:DIM SI(К),СО(К):U=UXT0:H=HXT0
260 FOR S=1 ТО К
270 СО(S)=COS(U):SI(S)=SIN(U):U=U+H
280 NEXT:CLS
290 LOCATE 8,3:PRINT "проводятся вычисления"
300 TIME=0:PRINT АФ: ’===================ЯДРО
310 R=1:X=0:Y=0:F0=lE+50:GOSUB 460:’овруч
320 A=X:B=Y
330 FOR S=1 TO К
340 X=A+RXCO(S):Y=B+RXSI(S):GOSUB 460
280*
350 NEXT
360 X=01:Y=02:IF XOA THEN R=R+R:GOTO 320
370 R=RX.5:IF R>E THEN 320
380 IF F0>E THEN U=U+11XT0:GOTO 260
390 N=N-1:GOSUB 560:GOSUB 520
400 IF N>1 THEN 310
410 N=0: D=A (0) ^2+6(0) ^2: ’досчет
420 X= (—A <0) XA ( 1) —В (0) XB (1))/D
430 Y=(A(1)XB(0)-A(0)XB(1))/D
440 GOSUB 560:GOTO 580
450 ’модуль многочлена
460 T=T+1:D1=A(0):D2=B(0)
470 FOR J=1 TO N
480 L=D1XX—D2XY+A(J):D2=D2XX+D1XY+B(J):D1=L
490 NEXT
500 F=D1"2+D2"2:IF F<F0 THEN F0=F:01=X:02=Y
510 RETURN
520 FOR J=1 TO N:L=J-1:’’выщип* корня
530 A (J) =A (J)+A (L) XX—В (L)'XY
540 В(J)=B(J)+B(L)XX+A(L)XY
550 NEXT:RETURN:’======================ВЫВОД
560 PRINT "КОРЕНЬ #";M-N;":";
570 PRINTUSING B$;X,Y:RETURN
580 PRINT D$
590 PRINT"oBmee количество вычислений F =";T
600 PRINT:PRINT "время счета =";TIME/50;"сек
610 END:’============имя программы "КОРНИ-2"
Пример 5. Используя программу примера 4, найти все нули многочлена f (2) = z3 — 2z2 + (2 +1) z — (< +1 )•
Диалог и результаты счета в данном случае выглядят так.
КОРНИ МНОГОЧЛЕНА
степень многочлена ? 3 коэф. вещественны (1-ДА, 2-НЕТ) ? 2 вещественные части коэффициентов!
АС 0)=?1А(2)=?2
АС 1)=?-2АС3)=?-1
мнимые части коэффициентов: ВС 0)=?0ВС2)=?1
ВС 1)=?0ВС3)=?-1
’точность’ вычислений ? 0.00001
ДЛЯ ТОЧЕК НА ’ОБРУЧЕ': начальный угол Сградусы)? 0 шаг для угла С1 — 120)? 90 проводятся вычисления
КОРЕНЬ #1:1.00000+0.00000X1
КОРЕНЬ #2:-0.00000+1.00000X1
КОРЕНЬ #3:1.00000-1.00000X1
Общее количество вычислений F = 154 время счета = 39.2 сек
Пример 6. Используя программу примера 4, найти все i многочлена
f (х) = х6 - 25х5 +1 ЗЗх4 - 789х3 + 2780х2 - 41 ООх + 2000 =
=(х - 20) (х2 + 25) (х -1) (х + 2)2.
Полный диалог и результаты счета выглядят так.
КОРНИ МНОГОЧЛЕНА
степень многочлена ? 6
коэф» вещественны (1—ДА, 2-НЕТ) ? 1 вещественные части коэффициентов:
282’
AC0)=?1AC4)=?2780
AC1)=?-25AC5)=?-4100
AC2)=7133AC6>=?2000
AC3>=?-789
’точность’ вычислений ? 0.00001
ДЛЯ ТОЧЕК НА ’ОБРУЧЕ’: начальный угол (градусы)? 60 шаг для угла (1 - 120)? 120 проводятся вычисления
КОРЕНЬ
#
1
•
2.00000
+0.00000X1
КОРЕНЬ
#
2
•
1.00000
+0.00000X1
КОРЕНЬ
#
3
■
2.00000
+0.00000X1
КОРЕНЬ
#
4
•
-0.00000
+5.00000X1
КОРЕНЬ
#
5
0.00000
-5.00000X1
КОРЕНЬ
#
6
2
20.00000
+0.00000X1
овщее количество вычислений F =512 время счета = 181.56 сек
В заключение хотелось бы сказать несколько слов о том, что в некоторых случаях задача нахождения корней многочлена оказывается весьма чувствительной к изменению его коэффициентов.
Например, полиномы f(z)=(z —З)14 и g (z) = (z — З)14 — 10-14 отличаются только свободными членами на величину 10“14. У первого многочлена один вещественный корень z = 3 четырнадцатой кратности, а у второго многочлена 14 однократных корней
г» = 3+КГ'(со5^-+/5т^)(6 = 0, 1, 13).
Подобную неустойчивость можно наблюдать не только при кратных или почти кратных корнях. Это обстоятельство заставляет с некоторой осторожностью относиться к приближенным значениям корней, полученным тем или иным способом, и требует их тщательного анализа.
Приложение 1. Коды управления принтером [Ф = CHR$ (27)]
Управляющие коды
Название и (или) выполняемые действия
Ф; "Р" или Ф; "N"
Ф; "Е"
Ф; "Q"
CHR $ (14)
CHR $ (15)
Ф; "^
ф; »^
Ф; "G77
Ф; "Н"
Ф; "1"
Ф; CHR $ (34)
Ф; "X"
Ф; "У"
14 Ф; "si"
15 Ф; "s2"
16 Ф; "s0"
17 Ф; "А"
18 Ф; "В"
19 Ф; "Т"; "п"
20 Ф; "L"; "п"
21 Ф; "/"; "п"
22 Ф; "("; "щ, n2, ...nk"
23 Ф; ")7/; "m^ m2,..., mp."
24 Ф; "2"
25 CHR $ (9)
26 Ф; "b"; CHR $ (п)
27 CHR $ (8)
28 CHR $ (13)
29 CHR $ (10)
30 Ф; 77a77; CHR $ (п)
Шаг печати "цицеро" — 10 знаков на дюйм. Шаг задан по умолчанию
Шаг печати "Элите"— 12 знаков на дюйм "Уплотненный" шаг печати — 17 знаков на дюйм Удвоение действующего основного шага печати Отмена удвоения основного шага печати
Шрифт "Италик". Включение режима наклонной печати
Отмена режима наклонной печати Ф; "4"
Полужирный шрифт. Включение режима печати двойным ударом со смещением изображения вниз
Отмена режима Ф; "G"
Полужирный шрифт. Включение режима печати двойным ударом со смещением изображения вправо
Отмена режима Ф; "1"
Включение режима печати с подчеркиванием
Отмена режима Ф; "X"
Включение режима верхнего индексирования
Включение режима нижнего индексирования
Отмена режимов индексирования
Установка высоты строки в 1/6 дюйма
Установка высоты строки в 1/9 дюйма
Установка высоты строки в п/144 дюйма (п=01, 02, ..., 99)
Установка левого поля с позиции п (п=000, 001, ...)
Установка правого поля с позиции п (п = 000, 001, ...)
Установка горизонтальных меток табуляции: пь п2, ..., nk (ns = 001, 002, ...; S = l, 2, ..., k) Выборочное стирание меток табуляции из позиций: mi, ш2, ..., mp (ms=001, 002, ...; S = l, 2, ..., Р) Стирание всех меток табуляции
Перемещение головки принтера на следующую правую метку
Перемещение головки принтера на п позиций по строке вправо
Возврат головки принтера на 1 позицию назад
Возврат головки принтера к началу текущей строки Перемещение головки принтера к началу следующей строки
Протяжка бумаги на п строк сусохранением позиции головки принтера*
Продолжение
Управляющие коды
Название и (или) выполняемые действия
31 CHR $ (12)
Переход к началу следующего листа
32 Ф; "F"; "п"
Перемещение головки принтера на п точечных позиций
(п = 0000, 0001, ...)
33 Ф; "Rn"; "а"
Повтор п раз символа а
(п = 001, 002, ...)
34 Ф; ">"
Включение режима однонаправленной печати (медлен-
нее, но качественнее!)
35 Ф; "]"
Отмена режима однонаправленной печати
36 CHR $ (7)
Подача звукового сигнала в течение 1/4 секунды
37 Ф;
Включение датчика отсутствия бумаги
38 Ф; "рО"
Выключение датчика отсутствия бумаги
39 CHR $ (19)
Перевод принтера в автономный режим, при котором
игнорируются все команды с компьютера, кроме
CHR $ (17)
40 CHR $ (17)
Вывод принтера из автономного режима
41 CHR $ (24)
«Чистка буфера» принтера
42 Ф; "4-"*, коды;
Макроопределение, представляющее собой совокупность
CHR $ (0)
управляющих кодов
43 Ф; "%"
Макрокоманда, активизирующая последнее из выполнен
ных макроопределений
44 Ф; "cl"
Инициализация принтера. Отмена всех введенных
CHR $-кодов, кроме новых знаков, созданных пользо
вателем
45
Загрузка нового символа а в память принтера. Здесь:
Ф; "У; CHR $ (п);
1) п— код а (п = 33, 34, ..., 126) ;
CHR $ (т0);
CHR $ (mi);
2) то — характеристика понижения a (m = 0, 1);
CHR $ (т9)
3) ms — весовые числа вертикальных рядов а
(s=l, 2, ..., 9)
46 Ф; "'"
Включение режима вывода новых символов
47 Ф; "&" или Ф; "V
Отмена режима Ф; н',г
48
Вывод 1-й строки изображения л. Здесь:
Ф; "S"; "п"
1) п —количество вертикальных рядов л (п = 0001,
CHR $ (тп);
0002, ...);
CHR $ (mi2);
2) mfs — весовое число вертикального ряда для строки i
CHR $ (min)
(s=l, 2, ..., 9).
Сообщение
Код
Перевод и пояснения
1
NEXT without FOR
1
NEXT БЕЗ FOR. Параметры цикла в FOR и NEXT разные
2
Syntax error
2
Синтаксическая ошибка
3
RETURN without GOSUB
3
RETORN БЕЗ GOSUB. Выполнилась команда RETURN без обращения к подпрограмме
4
Out of DATA
4
Недостаток данных в DATA. Не может выполниться очередная команда READ — чтение из блока данных
5
Illegal function call
5
Неправильный вызов функции. Попытка вычислить значение функции при недопустимом аргументе
6
Overflow
6
Переполнение.
7
Out of memory
7
Недостаток памяти.
8
Undefined line number
8
Неопределенный номер строки. Произведено обращение к несуществующей строке
9
Subscript out of range
9
Выход за пределы массива.
10
Redimensioned array
10
Повторное объявление массива. Объявляется массив, место под который уже отведено или по умолчанию, или предыдущей командой DIM
11
Division by zero
11
Деление на нуль.
12
Type mismatch
13
Несоответствие типа. Организуется присваивание переменной одного типа значения другого типа
13
Out of string space
14
Исчерпана строковая область. Командой CLEAR сформируется дополнительное место для строковых значений
14
Device I/O error
19
Ошибка при вводе-выводе.
15
No RESUME
21
Отсутствует команда RESUME.
16
Missing operand
24
Пропуск операнда.
17
Bad file number
52
Неправильный номер файла.
18
File not found
53
Файл не найден. Обращение к файлу, не существующему на данном диске
19
File already open
54
Файл уже открыт.
20
File not OPEN
59
Файл не открыт.
21
File already exists
65
Файл уже существует.
22
Disk full
66
Диск заполнен.
23
Too many files
67
Слишком много файлов.
24
Disk write protected
68
Защита диска от записи. Переключатель на диске находится в положении, при котором возможно лишь считывание с него
25
Disk 1/0 error
69
Ошибка при вводе-выводе
26
Disk offline
70
Дисковод выключен
СПИСОК ЛИТЕРАТУРЫ
Пул Л. Работа на персональном компьютере.—М.: Мир, 1986.
М о р р и л Г. Бейсик для ПК ИБМ.— М.: Финансы и статистика, 1987.
Уолш Б. Программирование на Бейсике.—М.: Радио и связь, 1987.
Никс Дж. Бейсик: решение производственных задач.—М.: Машиностроение, 1987.
Справочное руководство по языку программирования Бейсик для КУВТ «ЯМАХА».— YAMAHA corporation, 1986.
YAMAHA. Справочное руководство по языку программирования Бейсик для КУВТ на базе персональных компьютеров «Ямаха MSX-2».— YAMAHA corporation, 1988.
Эберт К. Компьютеры: Применение в химии.— М.: Мир, 1988.
Кет ко в Ю. Л. Диалог на языке Бейсик для мини- и микроЭВМ.— М.: Наука, 1988.
Дьяконов В. П. Справочник по алгоритмам и программам на языке Бейсик для персональных ЭВМ.— М.: Наука, 1987.
Информатика и образование.— М.: Педагогика, 1987—1989.— № 1—6.
И.Степанов М.‘Е. Практические занятия на ПЭВМ Ямаха Минпрос РСФСР. НИИ школ.— М.: 1987.
Электронные вычислительные машины: В 8 кн. / Под ред. А. Я. Савельева.— М.: Высшая школа, 1987.
Системы автоматизированного проектирования: В 9 кн. / Под ред. И. П. Но- ренкова.— М.: Высшая школа, 1986.
Компьютеры: Справочное руководство: В 3 т. / Под ред. Г. Хелмса. — М.: Мир, 1986.
Иодан Э. Структурное проектирование и конструирование программ.— М.: Мир, 1979.’
Гудман С., Хидитниеми С. Введение в разработку и анализ алгоритмов.— М.: Мир, 1981.
Лорин Г. Сортировка и системы сортировки.— М.: Наука, 1983.
В и р т Н. Алгоритмы + структуры данных = программы.— М.: Мир, 1985.
Мейер Б., Бодуэн К. Методы программирования.— М.: Мир, 1982.— Кн. 1, 2.
Кулич И. Л. Математическое программирование.— М.: Высшая школа, 1986.
Кофман А. Введение в прикладную комбинаторику.— М.: Физматгиз, 1975.
Кофман А., Анри-Добордер А. Методы исследования операций.— М.: Мир, 1977.
Моудер Дж., Элмаграби С. Исследование операций.— М.: Мир, 1981.—Т. 1, 2.
Заварыкин В. М., Житомирский В. Г., Л апчи к М. П. Техника вычислений и алгоритмизация.— М.: Просвещение, 1987.
Л а п ч и к М. П. Вычисления. Алгоритмизации. Программирование.— М.: Просвещение, 1988.
ОГЛАВЛЕНИЕ
ЧАСТЬ 1. ЯЗЫК БЕЙСИК
Введение 3
/. Основы языкаБейсик ипрограммирования 5
Основные объекты языка—
Функции 12
Дисплей и клавиатура20
Базовые конструкции 32
Дополнительные возможностиязыка 51
Графика 68
Экраны. Пиксели. Точки69
Установка и стирание точек 71
Круги. Эллипсы. Дуги73
Отрезки прямых. Прямоугольники75
Закрашивание областей 77
Язык GSL 79
Программа «Базовые структуры»83
Алфавит на графическом экране86
Распечатка экранного кадра88
Управление выводомнапринтер 90
СНК$-коды 91
Изменение шага печати —
Выделение фрагментов93
Индексирование94
Изменение высоты строк95
Установка полей на странице96
Горизонтальная табуляция97
Дополнительные управляющие коды99
Макрокоды100
Созданиеновыхсимволов102
Растровая графика .106
Графикифункций109
Файлы 115
Общие сведения —
Дисковые файлы117
3.Файлы на магнитной ленте145
4.Вывод файлов данных на экраны и принтер150
Локальная вычислительнаясеть151
Бейсик MSX-2156
5 1.Экраны157
5 2.Виртуальный диск171
5 3.Коды клавиш172
5 4.Инициализациякомпьютера176
5.5 Локальная вычислительная сеть179
ЧАСТЬ 2 АЛГОРИТМЫ'
Сортировка. Поиск. Перебор198
Сортировка. Основные понятия
Сортировка с помощью дерева201
Пирамидальная сортировка204
Быстрая сортировка209
Поиск. Основные понятия212
Поиск в сети214
Генератор перестановок218
Линейное программирование224
Общая и каноническая задачи —
Транспортная задача245
Задача о назначениях261
Корни многочленов271
Методы Ньютона и секущих—
Метод «обруча»*277
Приложения284