Книга
Книга
Ю.Л.КЕТКОВЮ.Л.КЕТКОВГ
Ю.Л.КЕТКОВ
Ю.Л.КЕТКОВ
Г"^7'|I Turbo- I
QuickBASIC
I для .
IIBMPC ■
Москва"Финансы и статистика”1992
ББК 32.973 К 37
УДК 681.3.06
Кетков Ю.Л.
К37 GW-, Turbo- и Quick-BASIC для IBM PC.- М: Финансы и статистика, 1992.-240 с.; илл.
ISBN 5-279-00840-0
В книге представлены входной язык и технология работы в среде наиболее современных систем программирования на базе Бейсика. В нее включены описания двух программных продуктов фирмы Microsoft Corporation (GW- BASIC v. 3.23 и Quick-BASIC v. 4.0) и системы Turbo-BASIC — 1.1 фирмы Borland International, широко распространенных на персональных ЭВМ типа IBM PC/XT и АТ. •
Для широкого круга пользователей современных персональных ЭВМ, студентов средних и высших учебных заведений, слушателей курсов повышения квалификации, преподавателей программирования.
2404090000—030„ББК32.973
K-O16(oi)-92 15°-’2
ISBN 5-279-00840-0ISBN 5-279-00840-0© Ю.Л. Кетков,1992© Ю.Л. Кетков,1992
ISBN 5-279-00840-0
ISBN 5-279-00840-0
© Ю.Л. Кетков,1992
© Ю.Л. Кетков,1992
ВВЕДЕНИЕ
Датой рождения наиболее популярного диалогового языка программирования Бейсик считается 1 мая 1964 г. Более чем 25 лет назад сотрудникам Дартмутского колледжа во главе с Дж.Кемени и Т.Кур- тцем удалось запустить разработанный ими интерпретатор и выполнить первую Бейсик-программу.
Развитие нового алгоритмического языка на первом этапе диктовалось в основном шестью авторскими редакциями (Дартмут, 1965 — 1975 гг.), разработки которых поддерживались фирмой General Electric. Массовому распространению Бейсика содействовал интерес, который проявили к нему такие передовые производители мини-ЭВМ, как Digital Equipment Corporation (PDP/8, PDP/11), Hewlett-Packard (HP-21X, HP-2000), Wang Laboratories (Wang-2200). Среди оригинальных разработок для отечественных ЭВМ того периода наиболее известны реализации Бейсик-компилятора на ЭВМ типа М-20 (Горьковский университет, 1970 г.), интерпретирующих систем BASIC-6 на ЭВМ БЭСМ-6 (Вычислительный центр СО АН СССР, 1972 г.) и Бейсик-Гамма на ЭВМ Минск-32 (Институт математики АН БССР, 1974 г.). ....
Второе поколение Бейсйк-систём (1975 — 1985 гг.) тесно связано с появлением первых персональных ЭВМ, которые сначала обладали сравнительно малой оперативной памятью (32 — 64 Кбайта). Для них Бейсик-интерпретатор стал поистине “золотой жилой”. Именно с него начал свою карьеру Билл Гейтс, основавший фирму Microsoft Corporation. В середине 70-х годов он разработал интерпретатор BASIC-80, который функционировал на наиболее популярных восьмиразрядных микропроцессорах того времени Zilog-80 и Intel-8080.
Игровая ориентация бытовых ПЭВМ привела к появлению таких
языковых средств, как элементы машинной графики, процедуры организации звуковых эффектов и взаимодействия с активными внешними устройствами. Для Бейсик-систем того времени уже характерны достаточно развитые процедуры обработки текстовой информации и управления файлами. Наиболее полно эти возможности представлены в одной из лучших версий второго поколения — GW BASIC. Среди оригинальных отечественных разработок того периода отметим серию интерпретаторов компилирующего типа Бейсик/F, Бейсик/Fs и Бей- сик/Fsc, разработанных на Рижском производственном объединении ВЭФ и доведенных до уровня программного продукта.
В 1984—1985 гг. наметились два новых подхода к развитию систем программирования на базе Бейсика. Один из них, активно поддерживаемый фирмами Microsoft Corporation и Borland International, был направлен на создание быстрых систем компилирующего типа, обеспечивающих достаточно комфортабельные условия работы для пользователей. Для поддержания Бейсика на современном уровне в его состав включались наиболее распространенные элементы структурного программирования, вводились новые типы данных, предпринимались усилия по организации взаимодействия с внешними процедурами, по раздельной компиляции модулей и использованию библиотек программ. Так появились серии Quick- и Turbo-систем, которые вплотную приблизились по своим возможностям к профессиональным системам программирования на базе языков Паскаль и Си.
Второе направление, связанное с принципиальным совершенствованием структуры языка и попыткой его стандартизации, было положено авторами Бейсика, которые 20 лет спустя опубликовали книгу “Back to BASIC”. В ней была изложена версия, получившая название “истинного Бейсика” (True BASIC). С основными положениями этой версии наши читатели могут познакомиться по переводу книги Э.Кэт- лина (Программирование на языке Бейсик: Версия True BASIC.- М.: Мир, 1990). Среди других версий, которые были реализованы на IBM PC и примыкали ко второму направлению, следует отметить системы BASIC-Standard (поставлялась в комплекте с ПЭВМ Роботрон-1910) и Better BASIC (разработка американской фирмы Summit Software Technology).
Трезво оценивая обстановку, сложившуюся к концу 1990 г. на рынке программных продуктов вокруг Бейсик-систем третьего поколения, я отдал предпочтение более распространенным реализациям фирм Microsoft Corporation (GW BASIC, Quick BASIC) и Borland International (Turbo BASIC).
Среди систем, описание которых включено в настоящую книгу,
4
интерпретатор GW-BASIC морально устарел. Под его управлением программы выполняются примерно в 10 раз медленнее. Он плохо использует ресурсы ПЭВМ, так как предоставляет пользователю только 64 Кбайта оперативной памяти. Однако эта система активно эксплуатировалась более пяти лет, и под ее управлением разработано очень богатое программное хозяйство. Его использование в значительной мере облегчается тем, что входной язык GW-системы практически полностью перекрывается языковыми средствами систем Quick- и Turbo-BASIC.
В книге не ставится задача сравнения описываемых систем. Сопоставления такого рода достаточно сложны, так как приходится учитывать класс решаемых задач, принимать во внимание зачастую противоречивые критерии, экспериментировать с различными режимами работы и т.п.
С некоторыми курьезами самого тривиального тестирования компиляторов по быстродействию изготавливаемых программ мне пришлось столкнуться совсем недавно. В одном из выпусков журнала Mikroprozessortechnik (1990, Heft 8) была приведена серия простейших BASIC-тестов с результатами их прогона на IBM РС/ АТ (табл. 1).
Таблица 1
Номер теста
Время прогона, с.
Quick-2.0
" Quick-4.0
Turbo-BASIC-2.0
Turbo-Pascal-5.0
1
0.441
0.378
0.439
0.445
2
6.641
1.980
2.363
5.998
3
16.148
4.558
4.228
6.598
4
34.328
12.027
17.848
10.392
5
1.648
1.308
1.593
1.480
6
1.867
1.980
1.812
1.980
Из этой таблицы можно было заключить, что версия Quick-4.0, как правило, изготавливает более скоростные программы. Поскольку среди доступных мне версий имелись и другие реализации, то возникло естественное желание расширить табл. 1. Вот что из этого вышло.
Первую же неожиданность принесло тестирование программы PROG1, когда при 1%-4096 (по замыслу автора журнальной публикации цикл должен был выполняться 30 000 раз) возникло переполнение в строке 60. Экспресс-анализ показал, что это вполне естественно, так как значение Х% при каждом повторении цикла возрастало на 8. Для выхода из создавшегося положения можно было сократить число
повторений до3000, изменить начальное значение Y% или подкорректировать формулу в строке 60:
60 х% - х% + (Y% * 2% - Y%) \ Y%
Однако только этим дело не ограничилось. При малом числе повторений цикла (3000) на частоте 12 МГц время работы теста в Turbo-системе оказалось отрицательным (порядка-0.1Е-03). Распечатка показаний таймера перед началом цикла (20 PRINT TIMER) и по его окончании (80 PRINT TIMER) показала, что полтергейст здесь не при чем. Причина неправильного хронометража заключалась в округлении достаточно большого числа (дело было вечером), которое происходило в 20-й строке из-за несовпадения типов переменных. После замены Т на переменную T# эффект “сверхскорости” испарился.
Остальные тесты прошли без приключений, но получившиеся циф- ры(табл.2) в большинстве случаев свидетельствовали в пользу Turbo- системы.
Таблица 2
Номер теста
GW -
3.23
Quick - 4.0
Turbo-1.1 /
8 МГц
' 12 МГц
8 МГц
12МГц
8 МГц
12 МГц
1
4.84
3.18
1.54
0.23
0.33
0.06
2
37.35
24.55
6.37
4.61
3.41
2.42
3
69.92
45.58
8.35
5.82
6.43
4.45
4
71.13
56.58
12.03
10.60
13.29
9.78
5
9.29
6.15
2.19
1.43
1.76
1.21
6
3.07
2.42
2.36
1.70
1.65
1.65
7 ■
4.28
2.81
0.39
0.28
0.11
0.006
Однако некоторые обстоятельства вызывали сомнение в достоверности и этих результатов. Исключим подозрение, что разные исследователи представляли интересы конкурирующих фирм. Но ведь данные таблиц 1 и 2 могли расходиться, во-первых, из-за несоответствия параметров технических средств. Во-вторых, у каждой из систем программирования имеется довольно много управляемых характеристик (размер стека, динамический контроль индексов и переполнения, имитация сопроцессора и т.п.), влияющих на быстродействие программы.
Более точные измерения времени работы тех или иных компонент можно было получить, исключив из общих показаний таймера наклад-
ные расходы по организации циклов. Для этой цели и был добавлен тест PROG7, выполнявший “пустой” цикл 20 000 раз.
Продолжая эксперименты с тестами, я обнаружил ряд эффектов, происхождение которых затрудняюсь объяснить. Например, для теста PROG4 увеличение окна Run до полного экрана приводило к замедлению времени работы программы примерно вдвое (9.78 -* 20.76, 13.29 -» 25.15). Какие-то разумные оправдания этому можно было бы придумать: тест печати, площадь вывода резко увеличилась ... Но почему аналогичные действия существенно сокращали время вывода графической информации (PROG5, 1.70 -* 1.15) ? Влияло на время выполнения тестов и наличие номеров программных строк, которые я включил из-за GW-системы. В Quick- и Turbo-системах программы без номеров строк выполнялись чуть-чуть быстрее. Округление при запоминании показаний таймера приводило к тому, что два последовательных прогона одной и той же программы давали разброс результатов в пределах до 5%. Как после этого можно было доверять 4-й или 5-й значащим цифрам ?
Для дотошных читателей, желающих провести самостоятельное исследование, сообщаю некоторые технические детали своего эксперимента: машина АТ-286 с тактовыми частотами 8 и 12 МГц, сопроцессор 80287, оперативная память 1 Мбайт, монитор EGA-256, винчестер со временем доступа 70 мс. Распечатки тестовых программ приведены в приложении D. В каждой из них рекомендуется заменить переменную Т переменной с удвоенной точностью. Результаты тестовых прогонов, приведенные в табл.2, получены при трансляции в оперативную память.
Оценивая свое отношение к описываемым системам, выскажу несколько положений дискуссионного характера.
Систему GW-BASIC целесообразно эксплуатировать только на ПЭВМ с ограниченными ресурсами (отсутствует винчестер, объем оперативной памяти менее 512 Кбайт).
Quick-системы выглядят самыми мощными, но и самыми громоздкими. Их авторы уделили большое внимание средствам отладки, межязыковому общению и разделению этапов конструирования программ (трансляция, сборка модулей, работа с библиотеками).
Turbo-системы более практичны и быстры. В них лучше продуманы средства общения с пользователем, а в последних версиях появились очень удобные элементы контекстной подсказки и новые возможности для отладки программ. Так что учебный процесс целесообразнее ориентировать на версию Turbo BASIC - 2.0, которая, к сожа-
7
лению, еще не получила достаточного распространения в нашей стране.
При подготовке рукописи я отважился набрать ее текст на дискете, полагая, что это существенно ускорит процесс формирования издательского макета.Наиболее привычным инструментом для меня был текстовый редактор Turbo С, который, как оказалось, довольно плохо совместим с редакционно-издательской системой Ventura Publisher.
Исходные файлы были набраны не с первой позиции, в них использовались ручные переносы слов и управляющие символы Tab, признак конца каждой строки воспринимался как конец абзаца. Пришлось писать программы конвертирования текстовых файлов. Неоценимую помощь в этой работе оказал А.Ю.Кетков. Кстати, указанные программы были написаны на Turbo-BASIC.
ЭЛЕМЕНТЫ ВХОДНОГО ЯЗЫКА
Алфавит языка и спецификаиспользования символов
Алфавит Бейсика включает все отображаемые и управляющие символы, представленные в кодировочной таблице, которая в настоящий момент загружена в оперативную память или хранится в постоянном запоминаюi ем устройстве вашего компьютера. Каждому символу алфавита соответствует индивидуальный числовой код из диапазона от О до 255.
Первую половину кодировочной таблицы занимают символы с кодами от 0 до 127. Их состав и порядок определены американским стандартом на коды обмена информацией, известным под названием ASCII. На всех IBM-совместимых ПЭВМ эти части копировочных таблиц идентичны.
Символы с кодами от 0 до 31 называют управляющими. Некоторые из них можно отобразить на экране дисплея с помощью следующей программы:
5 LOCATE 1,1
10 INPUT “Введи код символа из диапазона от 0 до 31 ”; с
20 IF с >31 THEN STOP
25 CLS : LOCATE 2,1
30 PRINT "Символ с кодом “;с;”имеет вид: “ CHR$(c)
40 GOTO 5
Среди символов, которые не удалось отобразить на экране, находятся знаки “выдача звукового сигнала” (символ Bel с кодом 7), “горизонтальная табуляция” (символ НТ с кодом 9), “перевод строки” (символ LF с кодом 10), “прогон до конца страницы” (символ FF с кодом 12), “возврат каретки” (символ CR с кодом 13). Символ Esc с кодом 27
предшествует разнообразным приказам для принтера - переключение на один из запаянных шрифтов или загрузка нестандартного, переход из текстового режима в графический или, наоборот, установка ширины строки или полей и т.п. Многие из управляющих символов, в том числе и воспроизводимых на экране, широко используются для диалога между абонентами в процессе передачи информации по каналам СВЯЗИ. -
При вводе текстовой информации в ее состав управляющие символы не попадают, так как для их набора нет соответствующих клавиш. Даже те немногие клавиши, которые ассоциируются с управляющими кодами - Esc, стрелки управления курсором. Tab, перехватываются драйвером. О нажатии таких клавиш программа ввода может узнать с помощью специальной функции опроса буфера клавиатуры (в Бейсике для этой цели используется системная переменная INKEY$). Управляющие символы типа LF и CR, разделяющие строки в текстовых файлах, включаются в состав текста программным путем.
Основную часть алфавита Бейсика составляют отображаемые символы, начинающиеся с кода 32, которые приведены в табл.З и снабжены пояснениями по поводу их употребления. Во всех элементах Бейсик-программ, за исключением комментариев и текстовых констант, употребление русских букв запрещено.
Таблица 3
Код
Символ
Функциональное назначение
32
Пробел
Улучшает восприятие текстовой информации;
33
1
последний символ в именах объектов вещественного типа;
индикатор позиции выводной строки, в которой воспроизводится первый символ текстового значения
34
Ограничитель текстовых констант;
35
#
последний символ в именах объектов вещественного типа с удвоенной точностью;
символ, предшествующий номеру файла;
индикатор числовой позиции в формате выводной строки
36
$
Последний символ в именах объектов текстового типа; первый символ в наименованиях метаоператоров; знак денежной единицы в формате выводной строки
37
%
Последний символ в именах целочисленных объектов;
Первый символ в идентификаторах целочисленных констант (Turbo BASIC)
38
&
Последний символ в именах целочисленных объектов удвоенной длины;
первый символ в обозначениях двоичных, восьмеричных и шестнадцатеричных констант
39
Предшествует комментарию и заменяет служебное слово REM
код
Символ
Функциональное назначение
40
(
Открывающая скобка в индексных, арифметических, логических
или символьных выражениях;
ограничитель списка параметров функции или подпрограммы
41
)
Закрывающая скобка
42
♦
Знак операции умножения числовых операндов;
индикатор замещения незначащих числовых позиций в формате выводной строки
43
+
Знак операции сложения числовых операндов;
знак операции сцепления (конкатенации) символьных операндов
44
•
Разделитель данных или других элементов списка
45
-
Знак операции вычитания числовых операндов; признак смены знака числового выражения
46
Разделитель целой и дробной частей числа;
внутренний символ в имени объекта;
индикатор местоположения точки в формате выводной строки
47
/
Знак операции деления числовых операндов
48
0
Запись числовых констант
Внутренние символы в именах объектов
57
9
58
•
Разделитель операторов в программной строке; признак конца метки оператора
59
Разделитель элементов выводного списка
60
<
Знак операции отношения, проверка на “меньше”
61
Знак операции отношения, проверка на “равно"; знак операции присваивания
62
>
Знак операции отношения, проверка иа “больше”
63
9
Заменяет служебное слово PRINT в операторе вывода
64
@
Коммерческое “эт”, иногда встречается название “алеф”
65
А
Большие буквы латинского алфавита
90
Z
91
[ ' '
Открывающая квадратная скобка
92
\
Знак операции целочисленного деления;
ограничитель символьных полей в формате выводной строки;
разделитель элементов в спецификациях файлов и обозначениях дисковых оглавлений
93
]
Закрывающая квадратная скобка
94
Знак операции возведения в степень;
индикатор позиции порядка в формате выводной строки
95
-
Признак переноса программной строки на экране дисплея в системе Turbo-BASIC;
индикатор отображаемого символа в формате выводной строки
96
•
Код
Символ
Функциональное назначение
97
а
Малые буквы латинского алфавита
122
Z
.123
{
Открывающая фигурная скобка
124
1
125
}
Закрывающая фигурная скобка
126
127
DEL
Признак удаления предшествующего символа
Бейсик не делает различия между большими и малыми латинскими буквами в служебных словах, обозначениях переменных, функций и процедур. В Quick-BASIC, например, сразу после ввода программной строки строчные буквы автоматически заменяются прописными. Такая замена не распространяется на содержимое текстовых констант, в составе которых могут использоваться любые отображаемые символы ASCII.
Серьезные затруднения могут ожидать наших пользователей из-за второй половины кодировочной таблицы, где расположены прописные и строчные русские буквы, символы псевдографики, очень удобные для оформления таблиц, и некоторые специальные знаки. Дело в том, что для “русификации” клавиатур, мониторов и принтеров используются различные кодировочные таблицы. С пятью возможными вариантами таких таблиц можно познакомиться по статье В.Э.Фигурнова, опубликованной в первом выпуске 1990г. советско-польского журнала “Компьютер”.
Разнобой в расположении русских букв приводит к тому, что текст Бейсик-программы, разработанной на одной ПЭВМ, нельзя просто перенести на другую машину. Прочитав дискету на ЭВМ заказчика, вы можете не узнать текст своей собственной программы. Всюду, где были расположены русские буквы и заготовки для рамок таблиц, появилась какая-то абракадабра. Программу можно запустить. Она будет даже правильно считать, и об этом; свидетельствуют ожидаемые числовые результаты тестовых прогонов. Но во что превратились тщательно подобранные кадры диалоговых сценариев и эффектно отработанные тексты подсказок! Ни один заказчик не согласится принять такую работу.
Чтобы установить, с каким вариантом кодировочной таблицы работает ваш компьютер, наберите и исполните следующую программу:
12
10 CLS: PRINT TAB(24); “Таблица ASCII иа вашем компьютере”
20 FOR i - 32 TO 54: LOCATE 1-30,1
30FORJ-1TO 1 + 9*23 STEP 23
40 IF j> 255 THEN 80.
60 PRINT USING" ####”;];
70 PRINT CHR$(j);
80 NEXT j: NEXT!
Попробуйте выдать результаты ее работы на принтер, нажав клавишу Print Screen или заменив операторы PRINT на LPRINT. Здесь вас тоже могут ожидать забавные сюрпризы. Из-за того, что программы русификации дисплея и принтера пользуются различными копировочными таблицами, полученная твердая копия может не совпадать с экранной таблицей. При выполнении операторов LPRINT Бейсик-система выдает принтеру команду на установку шрифта. Поэтому вы можете получить еще и третью таблицу, отличающуюся от двух предыдущих.
Для преодоления трудностей переноса своих программ на ПЭВМ с другой кодировочной таблицей воспользуйтесь одним из следующих советов.
Заведите у себя драйверы русификации ПЭВМ и принтера, которыми пользуется заказчик. Тогда ваши машины станут идентичными, но сделать это лучше до начала разработки. (Выполнить такую рекомендацию удается не всегда, так как знакогенератор на одной из ПЭВМ может оказаться прошитым в ПЗУ. Другим препятствием может быть несовместимость принтеров. Кроме того, смена драйвера чревата тем, что абракадабру начнут выдавать ранее разработанные программы.)
Перенесите тексты исходных Бейсик-программ на ПЭВМ заказчика. По своему листингу замените все тексты русских сообщений и символы оформления таблиц.
Напишите программу перекодировки текстового файла, в которой коды всех символов второй половины вашей таблицы ASCII заменяются кодами из таблицы заказчика. Такого рода программы могут быть написаны на любом языке, в том числе и на Бейсике. Их основу составляет словарь перекодировки, который в нашем случае занимает 128 байт. По числовому коду символа, уменьшенному на 128, программа выбирает содержимое соответствующего байта в словаре и заменяет им старый код символа.
Используйте буквы только латинского алфавита, и тогда ваши программы будут работать на любой ПЭВМ.
Несколько слов о способе набора в тексте программы символов псевдографики и спецзнаков из второй половины кодировочной таблицы. Так как для них нет клавиш с соответствующими обозначениями, то
набор осуществляют по числовому коду. Для этого необходимо левой рукой зажать клавишу Alt и не отпускать, а правой—набрать известный вам числовой код из трех цифр. После этого клавиша Alt отпускается, и на экране возникает желанный символ.
В изложении материала последующих разделов используются квадратные и фигурные скобки при описании синтаксических конструкций языка. Квадратные скобки означают, что находящийся в них объект является необязательным и может быть опущен. Например, в операторе присваивания служебное слово LET, как правило, не пишут:
[LET] A-SIN(X)
В тексте набираемой вами программы никаких квадратных скобок быть не должно. Символы “ [ ]” могут встречаться в комментариях или текстовых константах.
Фигурные скобки свидетельствуют о ситуации, когда из нескольких элементов должен быть выбран только один. Перечисляемые внутри скобок элементы разделяются символом “ I ”. Например, утверждение типа “именем тригонометрической функции NAMETRIG является ATN, COS, SIN или TAN” может быть записано следующим образом:
NAMETRIG-{ATN I COS I SIN I TAN}
Типы данных и форматы их представления
Литеральные константы числового и символьного типов
Константы представляют собой объекты, чьи значения не могут быть изменены в процессе выполнения программы. Эпитет “литеральный”, который чаще применяется в машинно-ориентированных языках (автокод, ассемблер), связывают с константой, значение которой в явном виде указано в тексте программы.
В описываемых версиях литеральные константы принадлежат двум множествам — числовому и символьному. Первое множество представлено четырьмя типами числовых констант — целыми числами нормальной или удвоенной длины, вещественными числами с одинарной или удвоенной точностью. -
Целые числа нормальной длины принадлежат диапазону [-32768, 32767 ] и представляются в ЭВМ двухбайтовыми двоичными числами в дополнительном коде. В программе целочисленные константы этого типа могут быть заданы десятичными числами, запись которых завершается символом % , или числами в других системах счисления - двоичной, восьмеричной или шестнадцатеричной. К последним прибе-
14
тают в случае задания беззнаковых констант, логических шкал или адресов оперативной памяти. Двоичные константы начинаются с символов &В и могут содержать от одной до шестнадцати двоичных цифр. Восьмеричные константы начинаются с комбинации &0 и не должны превосходить своего максимального значения — &O177777. Шестнадцатеричные константы начинаются символами &Н и должны принадлежать диапазону от &Н0 до &HFFFF.
Целые числа удвоенной длины принадлежат диапазону [-2147483648,2147483647] и представляются в ЭВМ четырехбайтовыми двоичными числами в дополнительном коде. Запись целочисленных констант этого типа заканчивается символом &. Указанные константы мотут использоваться только в Quick и Turbo-системах.
Для представления вещественных чисел с одинарной точностью используется четырехбайтовый стандарт американского института инженеров по электротехнике и радиоэлектронике (формат IEEE). Он поддерживается сопроцессорами 8087 Х80287) и похож на формат, известный нам по ЭВМ серии DEC (отечественный эквивалент — СМ/4). В памяти ЭВМ вещественное число такого типа имеет следующий вид:
76543210
Рис.1. Представление вещественного числа в памяти ЭВМ
Здесь s — знак числа (0 — положительное число, 1 — отрицательное); р — смещенный двоичный порядок (р — Р + 127, 0 < — р<255); ш — усеченная двоичная мантисса без старшего двоичного разряда (m - М -1, 1 < -М < 2).
Вещественное число х в формате IEEE представляется выражением. вида:
x-(-l)^s*M»2^P
Смещение порядка обеспечивает возможность работать только с положительными значениями р, что несколько упрощает выполнение арифметических операций с плавающей запятой. Отсутствие старшей единицы в мантиссе, характерное для нормализованного числа, позволяет дополнительно хранить в памяти еще один младший разряд мантиссы, что несколько увеличивает точность представления чисел.
Вещественные константы с одинарной точностью по модулю принадлежат диапазону [1.2 Е-38,3.4 Е+38 ] и могут содержать до 7 значащих цифр. Характерной особенностью в записи вещественных чисел является наличие точки, отделяющей целую часть числа от дробной и/или множителя вида Е+р или Е-р. Иногда запись констант такого типа сопровождают символом"!” (0.3141593Е+1!, 15!).
Для хранения вещественных чисел с удвоенной точностью в системах фирмы Microsoft обычно используются восьмибайтовые поля, которые обличаются от выше описанного короткого формата IEEE только наличием более длинной мантиссы. Это дает возможность записывать константы, содержащие до 16 —17 десятичных значащих цифр и принадлежащие тому же самому диапазону допустимых чисел. Для обозначения такого формата в фирменных руководствах используется термин Microsoft Binary Format (сокращенно — MBF). Однако сопроцессор 8087 (80287) не поддерживает формат MBF. Поэтому в версии Quick-BASIC наряду с 8-байтовым форматом MBF может использоваться более прогрессивный расширенный стандарт IEEE:
63 62 5251Q
sPPPPPPPPPPP mmmmmmmmmmmmmm
Вещественное число х в этом формате представляется в виде:
X- (-l)~s * М * 2ЛР - (-1)^ * (т+1) * 2л(р-1023)
Расширенный формат IEEE поддерживается сопроцессорами и обеспечивает работу с 17 -разрядными десятичными числами, по модулю принадлежащими диапазону [4.19Е-307,1.67Е+308 ].
Запись вещественных констант с удвоенной точностью заканчивается символом #.
Символьные (строковые, текстовые) константы, включаемые в текст программы, обычно заключаются в кавычки. Исключение могут составлять символьные константы, задаваемые в списках операторов DATA, где признаки начала и конца текстового значения выполняют окаймляющие запятые. Максимальная длина текстовой константы ограничена лишь емкостью соответствующей программной строки.
16
В текстовых константах могут использоваться любые отображаемые символы алфавита, которые можно набрать на клавиатуре. Если внутри константы необходимо задать кавычку, то приходится набирать две подряд идущие кавычки, которые во внутреннем представлении константы рассматриваются как один символ.
Числовые и символьные переменные
В отличие от констант переменные представляют такие объекты, значения которых могут изменяться в процессе выполнения программы. Каждая переменная снабжается уникальным именем - идентификатором, содержащим от одного до 40 алфавитно-цифровых символов и начинающимся с буквы. Большие и малые буквы в именах переменных не различаются. В идентификаторах должны использоваться только буквы латинского алфавита. Это важно помнить при наборе программы, так как многие латинские и русские буквы имеют сходные начертания, но в памяти ЭВМ им соответствуют различные коды, и русские символы в именах любой Бейсик-системой будут отвергнуты. В идентификаторах переменных допускается употребление точек. Обычно ими пользуются в тех случаях, когда имя образовано из нескольких слов^например Max.Coord, Min.X.Y, End.of.Text и т.п.
Переменные называются числовыми, если они могут принимать только числовые значения. По способу представления соответствующих значений числовые переменные подразделяются на четыре типа -целочисленные переменные со значениями нормальной (2 байта) или удвоенной (4 байта) длины и вещественные переменные со значениями обычной (4 байта) и удвоенной (8 байт) точности. Четырехбайтовые переменные целого типа допускаются только в Quick- и Turbo-системах.
Значением переменной символьного типа является цепочка любых символов алфавита si s2..., количество которых рассматривается как “длина” переменной. Эта длина может находиться в интервале от нуля ("пустая" переменная) до максимального значения, допустимого системой программирования. Для GW-BASIC максимальная длина равна 255, для систем Quick и Turbo - 32 767. Объясняется это тем, что для хранения k-символьного значения текстовой переменной в GW-системе используются к+3 байта, а в остальных системах—к+4 байта. Один или два байта из числа дополнительных хранят длину символьной переменной, а два оставшихся используются в качестве относительного адреса текущего значения переменной в так называемой “куче”. Куча представляет собой участок оперативной памяти, отведенный для хранения значений всех символьных переменных. Как только
символьной переменной присваивается новое значение, имеющее длину .отличную от предыдущей, оно располагается в куче на свободном месте, а поле с прежним значением освобождается. Указанная технология приводит к тому, что в куче образуется довольно много свободных участков, расположенных не подряд. Поэтому время от времени, содержимое кучи приходится реорганизовывать с целью группировки свободных участков в поле со сплошной адресацией. Такая процедура носит название “уборка мусора” и может производиться по запросу системы или по требованию программы (см. функцию FRE).
Тип числовой или символьной переменной может быть указан либо явно — с помощью специального символа, завершающего имя переменной, либо неявно — по принадлежности первого символа идентификатора заданному диапазону букв.
В качестве конечного символа идентификатора используются знаки % (двухбайтовый целочисленный тип), & (четырехбайтовый целочисленный тип),! (четырехбайтовый вещественный тип), # (восьмибайтовый вещественный тип) или $ (символьный тип).
Неявное объявление типа переменной осуществляется с помощью операторов DEFINT (двухбайтовый целочисленный), DEFLNG (четырехбайтовый целочисленный), DEFSNG (четырехбайтовый вещественный), DEFDBL (восьмибайтовый вещественный) и DEFSTR (символьный тип).
Все эти операторы имеют одинаковый формат:
DEFINT al [а2],Ы [Ь2]....
DEFLNG al [-а2], Ы[-Ь2]....
DEFSNG al [-а2], Ы [-Ь2]....
DEFDBL а1[-а2],Ы[-Ь2]....
DEFSTR al [-а2], Ы [-Ь2]....
Здесь al—буква или диапазон букв (al — а2) латинского алфавита, с которых может начинаться имдлеременной соответствующего типа. Следует отметить, что на переменные, описанные явным способом, действие указанных операторов не распространяется. Поэтому в программе наряду с оператором “DEFSNG C-F” MOiyr существовать и целочисленные переменные с именами COR% , DLINA&. Неявное описание типа распространяется только на те переменные, имена которых не завершаются указанными выше спецсимволами.
Quick-BASIC позволяет объявлять типы переменных и несколько иными способами с привлечением описателей INTEGER (целые,2 байта), LONG (целые,4 байта), SINGLE (вещественные,4 байта), DOUBLE (вещественные,8 байт) и STRING (строковые). Такие возможности используются в операторах COMMON, DIM, REDIM,
18
SHARED, TYPE и будут более подробно рассмотрены в соответствующих разделах.
Перед выполнением программы производится “очистка” всех переменных. Числовым переменным при этом присваиваются нулевые значения. Длина каждой переменной символьного типа при чистке устанавливается также в нуль, таким образом всем текстовым переменным присваивается значение “пусто”.
Именованные константы
Версия Quick-BASIC допускает употребление констант, которые, подобно переменным, снабжаются именами. Объявление именованных констант осуществляется с помощью оператора CONST, имеющего следующий формат:
CONST ncl-el [,nc2-e2 ...]
Здесь пс — идентификатор константы, который строится по тем же правилам, что и имя переменной. Выражение е , определяющее значение константы, может включать литеральные и ранее определенные именованные константы, объединенные знаками операций соответствующего типа. Выражения такого рода принято называть константными.
Turbo-BASIC тоже допускает употребление именованных констант, принимающих целочисленные значения. Имена таких констант начинаются с символа “%”. Для установления соответствия между именем константы и ее значением используется конструкция, напоминающая оператор присваивания:
%N- 255
Преимущество от использования именованной константы заключается в том, что имя константы может быть существенно короче ее значения (CONST PI - 3.14159265#). При многократном употреблении такой константы экономится время набора текста программы. Изменение значения именованной константы связано с перенабором только одного оператора, тогда как в случае использования литеральных констант модификацию пришлось бы выполнять многократно.
Именованная константа может употребляться в любом месте программы, где используется обычная переменная, за исключением левой части оператора присваивания, списка операторов ввода и фактиче-
ских аргументов подпрограммы, соответствующих выходным параметрам.
Массивы
Массивы представляют собой организованный набор однотипных переменных, компактно расположенных в оперативной памяти. Все элементы одного массива снабжаются общим идентификатором, вслед за которым в круглых скобках записывается один или несколько индексов, определяющих местоположение элемента в массиве.
Наиболее просто организованы одномерные массивы, являющиеся Эквивалентами векторов. Все их элементы пронумерованы последовательными натуральными числами, которые и выполняют роль индексов. Минимальное значение индекса устанавливается либо по умолчанию, либо задается явным или неявным образом.
Максимальное значение индекса обычно указывается при об’явле- нии массива. Для необъявленных массивов максимальный индекс принимается равным 10.
Двумерные массивы являются аналогами матриц. Первый индекс элемента двумерного массива определяет номер строки, а второй - номер столбца, на пересечении которых расположен элемент. Строки и столбцы нумеруются либо от единого, установленного заранее минимального значения индекса, либо от граничного значения, заданного одновременно с объявлением массива.
Количество индексов в многомерных массивах, вообще говоря, ограничено (табл. 4). В Turbo- и Quick-системах размеры массива не должны превышать 64 Кбайт. В GW -BASIC массивы и программа должны помещаться в одном сегменте длиной не более 64 Кбайт.
Таблица 4
Характеристика
GW
Turbo
Quick
Максимальное количество индексов
255
8
60
Минимальный индекс
0
любой
" любой
Максимальный индекс
16 387
32767
32767
По умолчанию во всех трех системах минимальным значением индекса считается 0. Для изменения этой границы используется оператор OPTION BASE:
OPTION BASE 0
OPTION BASE 1
Оператор OPTION BASE должен находиться среди первых операто- 20
ров программы до объявления какого-либо массива. В системе GW- BASIC отсчет индексов всегда ведется от нуля, т.е. действие оператора OPTION BASE игнорируется. Система Quick-BASIC позволяет по умолчанию ограничить минимальное значение индекса либо нулем, либо единицей. Входной язык Turbo-BASIC позволяет использовать в качестве минимальной границы любое число из диапазона [0,32767 ]:
OPTION BASE 1990
В системах Quick- и Turbo-BASIC при объявлении конкретного массива наряду с максимальным значением индекса можно указать и его минимальную границу. Оператор DIM, используемый для этой цели, имеет свой формат в каждой из систем:
GW:DIM V (Пшах,12тах,... )
Turbo : DIM [ STATIC ] V ([Ilmin:]Ilmax, [I2min:]I2max,„. )
DIM [ DYNAMIC ] V ([Ilmin:]Ilmax,[I2min:]I2max,...)
Quick : DIM [ SHARED ] V ([Ilmin T0]Ilmax,[I2min ТО]12шах,... ) [AS type]
Значение минимального индекса в Quick-системе может быть и отрицательным.
Атрибуты STATIC или DYNAMIC определяют способ выделения оперативной памяти под массив и вытекающие из этого возможности освобождения занимаемого участка или его использования для других целей. Статическим массивам память выделяется во время компиляции. Такой массив нельзя переопределить или уничтожить. По умолчанию массивы, границы которых заданы константными выражениями, в Turbo-системе считаются статическими. Выделение памяти для хранения динамических массивов осуществляется во время выполнения программы. Динамические массивы можно многократно переопределять и уничтожать. Если в операторе DIM граница массива задана значением переменной, то такой массив считается динамическим. Например :
INPUT “Введите размерность массива TOR”; N
DIM TOR(N)
К динамическим причисляются и все массивы, объявляемые локальными в подпрограммах (см. оператор LOCAL). Система Turbo- BASIC дает пользователю возможность установить свое правило пред-
почтения для выбора динамического или статического способа распределения памяти под массивы. Для этой цели предназначены метаоператоры $STATIC и $DYNAMIC. Аналогичные команды, изменяющие режим работы компилятора, имеются и в системе Quick-BASIC. Один из указанных метаоператоров помещается в начале программы, и тем самым устанавливается соответствующее правило умолчания. Например:
SDYNAMIC
DIMAI50)
Способ распределения памяти под массивы, являющиеся внутренними в подпрограммах или функциях, в Quick-BASIC может задаваться с помощью атрибутов STATIC или DYNAMIC, записываемых в конце заголовка соответствующей процедуры (см. операторы SUB и FUNCTION).
Удаление динамического массива из памяти выполняет оператор ERASE:■
ERASE CENA,TEXT$
Системы GW- и Turbo-BASIC позволяют многократно переопределять размеры динамического массива. Для этого старый массив должен быть предварительно удален (ERASE), после чего его имя можно снова использовать в операторе DIM.
Применение оператора ERASE к статическому массиву приводит к инициализации (сбросу) значений всех его элементов.
В Quick-системе переопределение динамических массивов осуществляется с помощью оператора REDIM даже без их предварительного уничтожения (ERASE):
REDIM [ SHARED ] V([Ilmin TO] Umax,...) [ AS type ]
Атрибут SHARED в операторах DIM и REDIM используется в подпрограммах и внешних функциях для указания массивов общего пользования, доступных двум программным модулям..
Операторы DIM и REDIM позволяют в Quick-системе наряду с размерами массивов объявить и тип его элементов:
DIM АВС(-ЮТО 20) AS SINGLE
Характеристика type может задаваться служебными словами INTEGER, LONG, SINGLE, DOUBLE, STRING, определяющими
один из описанных ранее стандартных форматов. Наряду с этим в Quick-BASIC элементами массива мотут быть переменные типа “запись”, структура которых описывается с помощью операторов TYPE - END TYPE (см. п. 1.2.5).
Составные данные (записи)
При работе с файлами в качестве неделимых единиц обмена информацией выступают записи, составными частями которых являются последовательные поля с данными разных типов. В GW- и Turbo-версиях такого рода записи помещаются в буфер, связанный с файлом прямого доступа. Последовательные поля этого буфера рассматриваются как символьные переменные фиксированной длины, которые описываются в операторе FIELD.
Шаг вперед по сравнению с этими версиями сделан в системе QuickBASIC - 4.0, где появился новый тип переменных—“записи”, структура которых описывается с помощью конструкции TYPE - END TYPE:
TYPE struc
VI AS type)
V2 AS type2
END TYPE
Здесь struc - идентификатор шаблона (структуры) записи, которая состоит из последовательных полей с именами VI, V2,.... Тип данного, который может находиться на поле Vi, описывается либо с помощью атрибутов INTEGER, LONG, SINGLE, DOUBLE, STRING, либо путем ссылки на имя шаблона другой ранее описанной переменной типа “запись”. В последнем случае поле Vi в свою очередь является составным, т. е. само имеет структуру типа “запись”.
Описание символьных полей в записях вСыда сопровождается указанием их длины в байтах:
TYPE book
avtor AS STRING 20
naimenovanie AS STRING 100
izdatelstvo AS STRING 15
god AS INTEGER cena AS SINGLE
END TYPE
Перенос структуры записи, объявленной указанным выше спосо-
бом, на конкретную переменную или массив с именем V осуществляется с помощью операторов COMMON, DIM, REDIM, SHARED или STATIC. В их теле должна присутствовать одна из конструкций вида:
V([indl,...) AS book
V[()]ASbook-
После такого объявления к содержимому соответствующих компонент записи можно обращаться по именам V.avtor, V.naimenovanie, V.izdatelstvo, V.god, V.cena.
Основным назначением переменных типа “запись” является их использование в операторах обмена с файлами прямого доступа:
get #5, к, v
PUT#3, 20.V
Преобразование типов данных
С преобразованием данных из одного формата представления в другой мы сталкиваемся как явно, используя соответствующие стандартные функции, так и неявно, когда тип переменной не совпадает с типом присваиваемого ей значения. По результату своего действия явный и неявный способы преобразования ничем не отличаются друг от друга. Например, два следующих оператора приводят к абсолютно идентичным результатам:
А#—1%
A#-CDBL(1%)
Стандартные функции преобразования числовых и символьных данных можно сгруппировать по следующим пяти разделам.
Первуюгруппу составляют четыре функции, преобразующ е числовой аргумент любого типа к заданному числовому формату. Значениями этих функций являются соответственно короткие 4CINT) или длинные (CLNG) целые числа, вещественные числа с одинарной '-(CSNG) илиудвоеннойЧСОВЕ) точностью. Замене аргумента вещественного типа коротким или длинным целочисленным значением предшествует округление аргумента др ближайшего целого числа. Аналогичное округление производится при переходе от вещественного аргумента с удвоенной точностью к короткому вещественному числу. Если аргумент функции CINT, CLNG или CSNG выходит за пределы допустимых диапазонов для данных соответствующего типа, то во время выполнения программы фиксируется ошибка типа “переполнение”.
Описанные выше преобразования числовых аргументов могут быть использованы для передачи параметров нужного типа подпрограммам или функциям без дополнительного переприсваивания.
Вторая группа преобразований, представленная двумя функциями, связана с прямыми (ASC) или обратными (CHR$) переходами от представления любого символа таблицы ASCII к его числовому коду, принадлежащему диапазону [0, 255 ]. Аргументом функции ASC может быть любое символьное выражение ненулевой длины, однако преобразованию подвергается только его первый знак. Например:
ASCCASC)-65
Попытка применить функцию ASC к пустому аргументу фиксируется как ошибка периода выполнения. Функция CHR$ выполняет преобразование целочисленного аргумента в односимвольное значение :
CHR$(65) - “А”
Функция CHR$ зачастую используется для включения в текстовые выражения любых неотображаемых символов. Например:
PRINTCHR$(7)
KEY 1,"UST 1 - 9999" + CHR$(13)
В первом случае оператор PRINT выдает односимвольную константу со служебным обозначением Bell в таблице ASCII, вывод которой сопровождается кратковременным звуковым сигналом. Во втором случае за функциональной клавишей F1 закрепляется текст директивы вывода программы, завершающийся символом “возврат каретки” (десятичный код — 13, шестнадцатеричный — &H0D). Это позволяет выполнить директиву LIST путем нажатия единственной клавиши.
Третья г р у п п а, в которую также входят две функции, используется для преобразования числовых величин из их машинного представления в символьную строку (STR$) или для обратного перевода (VAL). Аргументом функции STR$ может быть числовое выражение любого типа. Результат преобразования - строка символов, абсолютно идентичная той, которую мы бы увидели на экране дисплея при выводе значения аргумента по оператору PRINT. Обратное преобразование числа из его символьного представления в машинный
формат, соответствующий типу аргумента, осуществляется функцией VAL. Это преобразование начинается с наиболее левого значащего символа и продолжается до тех пор, пока не будет исчерпана строка либо пока не встретится первый нечисловой символ (пробелы при этом игнорируются).
В четвертую группу входят три функции-BIN$(e)jHEX$(e) и*ОСТ$(е), которые осуществляют перевод числового аргумента любого типа в строку с двоичной, восьмеричной или шестнадцатеричной формой эквивалентного значения. Вещественные аргументы при этом округляются до целых. Если округленное значение принадлежит одному из интервалов [-32768, 327671 или [0, 65535], то результат преобразования по длине совпадает с записью коротких констант соответствующего типа, у которых отброшены лидирующие нули:
ВШ$(б5) -“1000001"
НЕХ$(65) — “41"
ОСТ$(65)-“101"..
Если округленное значение аргумента выходит за пределы указанных интервалов, но может быть размещено в целочисленном четырех- байтово!^ формате, то указанные функции выдают результат типа LONG.
Отрицательные аргументы преобразуются в соответствии с их представлением в дополнительном коде. Например:
BIN$(-1) -“1111111111111111"
HEX$(-1)-”FFFF"
ОСТ$(-2) - “177776"
Наиболее многочисленная группа представлена 16 функциями, используемыми для замены числовых данных их символьными “эквивалентами’’при работе с файлами прямого доступа или для перехода от формата MBF к стандарту IEEE. Функции MKI$, MKL$*MKS$ и MKD$ позволяют преобразовать n-байтовое числовое значение аргумента (п—2,4,4,8) в п-байтовый “эквивалент” символьного типа. Фактически при этом переходе никакого преобразования не происходит. К двоичному представлению целого или вещественного числа добавляются 3 или 4 байта, сопровождающие хранение текстовой величины, а само число без какого-либо изменения копируется в область, предназначенную для хранения символьных данных. Полученный таким образом символьный “эквивалент” числа можно переносить с левым или правым прижимом на поля буфера, отведенного для обмена с файлом прямого доступа:
HELD #5, 6 AS pl$, 10 AS p2$, 5 AS p3$, 12 AS p4$
LSET pl$-MKI$(Vl%)
LSET p2$-MKL$ (V2&)
RSET p3$-MKS$ (V3)
RSET p4$-MKD$ (V4#)
PUT #5,K•
Обратный переход от символьных “эквивалентов” числовых данных, считанных в буфер из файла прямого доступа, производится с помощью функций CVI, CVL, CVS и CVD. Их аргументами должны быть символьные строки, содержащие соответственно по 2,4,4 и 8 байт и полученные в результате применения функции MKI$, MKL$, MKS$ hMKD$:
GET#5,N
VI% - СИ (MKI$ (LEFTS (pl$,2)))
V2&-CVL (MKL$ ( LEFTS (p2$,4))) -
V3 - CVS (MKSS (RIGHTS (p3$,4)))
V4#-CVD (MKD$ (RIGHTS (p4$,8)))
Входной язык Turbo-BASIC предоставляет в распоряжение пользователя функции MKMS$ и MKMD$, являющиеся аналогами функций MKS$ и MKD$, с помощью которых производится перевод вещественных значений из числового формата IEEE в символьный “эквивалент” формата MBF. В этих процедурах числовой аргумент уже подвергается содержательному преобразованию, так как стандарты MBF и IEEE отличаются по внутреннему представлению. Обратный переход в стандарт IEEE из символьного “эквивалента” вещественных чисел формата MBF производится с помощью функции CVMS или CVMD.
В Quick-BASIC тоже имеется возможность перехода от числового стандарта IEEE к формату MBF. Функции MKSMBF$ и MKDMBF$ преобразуют в символьный формат MBF соответственно короткие или длинные вещественные числа, представленные в стандарте IEEE. Обратный переход от символьного “эквивалента” формата MBF в числовой стандарт IEEE производится с помощью функции CVSMBF или CVDMBF.
Последние восемь функций позволяют через внешний носитель обмениваться результатами вычислений между программами, разработанными в разных системах. GW-BASIC не может использовать числовые данные формата IEEE, полученные в “чужой” системе.
Стандартные и нестандартные функции
Кроме констант, переменных и более сложных объектов типа записей к числу операндов, над которыми можно выполнять те или иные операции, относятся стандартные и нестандартные функции. По аналогии с математическим определением функцию можно представлять себе как некоторую вычислительную процедуру, на вход которой подается набор допустимых аргументов, а на выходе получается единственный результат - значение числового или символьного типа. Любая функция реализуется с помощью программы, которая либо является постоянной компонентой системы программирования, либо должна быть сконструирована в той или иной форме пользователем. В соответствии с этим все функции подразделяются на системные (стандартные) и пользовательские (нестандартные).
Подобно переменным, каждая функция снабжается уникальным именем, и строится оно по тем же правилам, что и любой идентификатор Бейсика. За стандартными функциями закреплены фиксированные имена, которые нельзя употреблять в качестве идентификаторов других объектов. Полный их перечень приведен в табл.5. Имена нестандартных функций пользователь конструирует сам. В одних случаях (см. оператор DEF FN) имя нестандартной функции должно начинаться с символов FN, после чего может следовать до 38 других алфавитно-цифровых символов, включая и последний символ, явно определяющий тип функции. В системе Quick-BASIC наряду со внутренними функциями (DEF FN) могут использоваться и внешние функции, оформляемые в виде отдельных модулей (см. оператор FUNCTION). Их имена могут начинаться с любых символов.
Количество аргументов в нестандартных функциях обычно ограничивается достаточно большим числом (в Turbo-BASIC, например, до 16 переменных). В качестве формальных параметров внутренних функций пользователя выступают только простые переменные числового или символьного типа. Для внешних функций набор формальных параметров существенно шире. Он может включать имена массивов, структуры типа записей, номера файлов и адреса переменных.
Таблица 5
Имя функции
Наличие в системе
Имя функции
Наличие в системе
GW
Quick
Turbo
GW
Quick
Turbo
ABS
+
+
+
LTRIMS
+
-
ASC
+
+
+
МГО$
+
+
+
ATN
s/d
s,d
d
MKD$ '
+
+
+
BIN$
-
-
+
MKDMBFS
-
+
-
Продолжение
Имя функции
Наличие в системе
Имя функции
Наличие в системе
GW
Quick
Turbo
GW
Quick
Turbo
CDBL
+
4-
4-
MKI$
4-
4-
4-
CEIL,
-
-
4-
MKL$
-
4-
4-
CHR$
+
4-
4-
MKMD$
-
-
4-
CINT
+
4-
4-
MKMS$
-
-
4-
CLNG
-
4-
4-
MKS$
4-
4-
4-
COS
s/d
s,d
d
MKSMBFS
-
4-
-
CSNG
+
4-
4-
OCT$
4-
4-
4-
CVD
*
*
4-
PEEK
4-
4-
4-
CVDMBF
-
4-
-
PEN
4-
4-
4-
CVI
+
4-
4-
PLAY
4-
4-
4-
CVL
-
4-
4-
PMAP
4-
4-
4-
CVMD
-
-
4-
POINT
4-
4-
4-
CVMS
-
-
4-
POS
4-
4-
4-
CVS
*
*
4-
REG
-
-
4-
CVSMBF
-
4-
-
RIGHTS
4-
4-
4-
ENVIRONS
4-
4-
4-
RND
. 4-
4-
4-
EOF
*
4-
4-
RTRIM$
-
4-
-
EXP
s/d
s,d
d
SADD
-
4-
-
EXP10
-
-
d
SCREEN
4-
4-
4-
EXP2
-
-
d
SEEK
-
4-
-
FILEATTR
-
4-
-
SETMEM
-
4-
-
FIX
4-
4-
4-
SGN
4-
4-.
a 4"
ERE
*
4-
4-
SIN
s/d
s,d /
d
HEX$
4-
4-
4-
SPACES
4-
4- "
4-
INP
+
4-
4-
SPC
4-
4-
4-
INPUTS
4-
4-
4-
SQR
s/d
s,d
d
INSTR
4-
4-
4-
STICK
4-
4-
4-
INT
4-
4-
4-
STR$
4-
4-
4-
IOCTL$
-
4-
4-
STRIG
4-
4-
4-
LBOUND
-
4-
4-
STRINGS
4-
4-
4-
LCASES
-
4-
4-
TAB
4-
4-
4-
LEFTS
4-
4-
4-
TAN
s/d
s,d
d
LEN
*
4-
*
UBOUND
-
4-
4-
LOC
4-
4-
4-
UCASE$
-
4-
4-
LOF
4-
4-
4-
USRn
4-
-
-
LOG
s/d
s,d
d
VAL
4-
4-
4-
LOGIC
-
-
d
VARPTR
♦
4-
4-
LOG2
-
-
d
VARPTRS
4-
4-
4-
LPOS
*
4-
4-
VARSEG
4-
4-
Примечания.
s/d—вычисляется одинарной или удвоенной точностью в зависимости от настройки
системы при запуске;
d — вычисляется только с удвоенной точностью;
s,d — точность вычислений зависит от типа аргумента;
* — имеются отклонения в синтаксисе.
Арифметические и логические выражения
Арифметические выражения состоят из операндов числового типа (константы,переменные, функции), объединенных знаками арифметических операций, перечень которых приведен ниже. Круглые скобки в арифметических выражениях используются для управления последовательностью выполнения действий.
Знак операции +
Выполняемое действие
Сложение
-
Вычитание
*
Л \
MOD
Умножение
Деление
Целочисленное деление
Нахождение остатка отделения
Возведение в степень
Результат операции деления (/) всегда является вещественным числом с одинарной или удвоенной точностью. Перед выполнением операций целочисленного деления (\) и нахождения остатка от деления (MOD) оба операнда округляются до ближайшего целого. Результат этих двух операций всегда целочисленный.
За исключением высказанных выше соображений, тип арифметического выражения определяется по типу наиболее “сложного” среди входящих в него операндов. Порядок возрастания “сложности” типов задается довольно естественной цепочкой: целочисленный короткий -♦целочисленный длинный -* вещественный с одинарной точностью -* вещественный с удвоенной точностью. Возведение в целочисленную степень выполняется путем последовательных умножений (х^п * х * х *... * х). Если показатель степени вещественного типа, то значение х^у находится по формуле ЕХР(у * LOG(x)). Поэтому величина х должна быть положительной.
Логические выражения, на базе которых формируются условия в операторах цикла (WHILE, DO — LOOP) и конструкциях типа IF, ELSEIF, образуются из логических операндов, принимающих одно из двух значений—ложь или истина. Элементарные логические операнды представляют собой результат сравнения двух числовых величин:
А>В, А> —В, А<В, А<-В, A-В, АоВ
Сочетание <> обозначает сравнение на неравенство. Значение эле-30
ментарного логического операнда, равное “истине”, в памяти ЭВМ ассоциируется с двухбайтовым целым числом, отличным от нуля. Значение “ложь” воспринимаетсякаккороткоецелое число, равное нулю. Элементарные огические операнды могут объединяться в выражения с помощью логических операций, перечень которых приведен в табл.6.
Таблица 6
Обозначение операции
Результат выполнения операции
х-0 у-0
х-0 у-1
х-1 у-0
х-1 у-1
NOTх
1
1
0
0
хANDу
0
0
0
1
хORу
0
1
1
1
хXORу
0
1
1
0
хEQVу
1
0
0
1
хIMPу
1
1
0
1
Логические операции выполняютсянад каждой паройодноименных двоичных разрядов своих операндов. Поэтому их можно использовать для работы с двухбайтовыми логическими шкалами:
N% AND 8 - 1, если третий разряд в двоичном представлении значения переменной N% равен 1;
N% AND 8 — 0, если указанный бит равеи 0.
Операндами логических операций могут быть и объекты вещественного типа, но перед выполнением соответствующего действия значения операндов округляются до ближайшего целого числа.
Операторы и программные строки
Декларативные и исполняемые операторы
Операторы представляют собой синтаксические конструкции, из которых составляется программа. Как правило, такие конструкции начинаются с одного или двух служебных слов, определяющих характер действия, предписываемого оператором. Действие это может носить как декларативный, так и исполнительный характер.
В первом случае оно адресовано компилятору (интерпретатору) и должно быть обработано до начала выполнения программы. К декла-
ративным действиям относятся операторы объявления типов и структур данных (CONST, DEFDBL, DEFINT, DEFLNG, DEFSNG, DEFSTR, DIM, OPTION BASE, TYPE), задания способов распределения данных в памяти ЭВМ (COMMON, LOCAL, MEMSET, SHARED, STATIC), формирования внутреннего блока данных (DATA), описания нестандартных функций и подпрограмм (DECLARE, DEF FN, DEF SEG, FUNCTION, SUB), указания точек входа в подпрограммы обработки рсобых ситуаций (ON COM ON ERROR, ON KEY, ON PLAY, ON STRIG, ON TIMER, ON PEN), включения комментариев (REM или апостроф).
За исключением Quick-системы, где оператор REM может быть использован для набора псевдооператоров $STATIC, $DYNAMIC или $INCLUDE,itckct комментария компилятором (интерпретатором) игнорируется^ .
На декларативные операторы распространяется довольно естественное правило по поводу их расположения в программе или в процедуре : сначала опиши (объяви), а потом — используй. Поэтому они обычно должны находиться в начале программы (модуля). Указанное правило не относится к комментариям, которые могут встретиться в любом месте программы. '
Некоторое отклонение от этого правила связано и с оператором DIM при объявлении динамических массивов. В этом случае оператор DIM превращается в исполняемый оператор, и описанные выше ограничения на него уже не распространяются.
Исполняемые операторы предписывают действия, результат которых проявится только во время выполнения программы. В этот период декларативные операторы у^е не обрабатываются—они просто обходятся.
Служебное слово, определяющее характер действия операторов, среди программистов принято называть “именем оператора”. Термин этот не очень точно передает смысл, так как соответствует понятию “идентификатор”, которое по отношению к шифру действия вряд ли следовало применять. Идентификатором оператора скорее следовало называть его метку или номер соответствующей программной строки.
Вслед за именем оператора располагается информация, используемая при его обработке. Обычно ее называют “телом оператора”, и завершается оно двоеточием, комментарием или неотображаемым символом “возврат каретки”. Обычно комментарий отделяется от текста оператора только апострофом, и после него может следовать лишь “возврат каретки”. ■
Непосредственные и отложенные действия
Системы GW- и Quick-BASIC позволяют “превратить” ПЭВМ в арифмометр, который выполняет оператор сразу же после его набора. |В GW-системе для этой цели программная строка набирается без номера, и после нажатия клавиши Enter на экране появляется результат., В Quick-системе операторы выполняются немедленно, если они набираются в окне непосредственных вычислений (Immediate Window). Такой режим обработки операторов может быть использован как для организации несложных одноразовых расчетов, для которых нецелесообразно составлять программу, так и для отладки текущей программы, выполнение которой тем или иным способом прервано. С помощью непосредственно выполняемых операторов можно отобразить на экране или изменить значения любых переменных, изменить режим работы дисплея и т.п. j
Текст операторов, непосредственно выполняемых GW-системой, в памяти ЭВМ не сохраняется. Поэтому при повторении какого-либо ранее проведенного вычисления текст программной строки придется набирать заново. ■
Непосредственный режим не распространяется на декларативные операторы. Да и не любой исполняемый оператор может быть выполнен таким образом. К числу таких исключений относятся операторы цикла WHILE — WEND и любые другие блочные конструкции типа SELECT - END SELECT, IF - END IF, для реализации которых пришлось бы набрать несколько программных строк.
Операторы, которые набираются в GW-BASIC с номерами строк или вводятся в Quick- и Turbo-системах в окне редактирования, участвуют в формировании текста исходной программы. Выполнение последней может быть отложено на неопределенно долгий срок, конечно, при условии, что текст набранной программы будет сохранен. Отложенные таким образом действия можно выполнить в любой момент, запустив тем или иным способом вызванный программный файл. Их можно многократно исполнить без повторного перенабора текста программы.
Идентификация программных строк
3333Строки с отложенным выполнением мы будем называть программными. Каждая такая строка может содержать один или несколько операторов, разделяемых двоеточием. Последний оператор в программной строке завершается символом “возврат каретки”, включаемым в состав оператора в момент нажатия клавиши Enter. Особо внимательно надо набирать составные программные строки, содержащие
33
33
2. Ю. Л. Кетков
несколько операторов и включающие комментарии.(Правее комментария нельзя располагать какие-либо другие операторы j Следует воздерживаться от объединения в одной строке декларативных и исполняемых операторов.
В GW-системе любая программная строка начинается с целочисленного номера, принадлежащего диапазону [0, 65529 ]. Нулевой номер строки используется для специальных целей (например, для блокировки перехода на подпрограмму обработки особых ситуаций) и поэтому для нумерации программных строк обычно не используется.
Системы Quick-BASIC и Turbo-BASIC не требуют обязательной нумерации программных строк, хотя “старые" Бейсик-программы обрабатываются в этих системах без каких-либо изменений. Кроме традиционных номеров строк в новых системах допускается применение меток, характерных для развитых алгоритмических языков.
В качестве меток могут выступать любые идентификаторы, содержащие до 40 символов, и целые числа. В строке, которая начинается с метки, может находиться только комментарий. Таким образом, метка идентифицирует программную строку, расположенную следом:
МахДВ:
LET Y - В : REM возможно, максимум - В
055:
IFA>BTHEN Y-A
Print.MaxA.B:'■'
PRINT “А-”; А, “В-”; В, “Мах(А,В)-”; Y
Метка отделяется от оператора двоеточием, и в этом смысле целочисленная метка мало чем отличается от традиционного номера строки. Нужно только представить себе, что программная строка начинается с пустого оператора и имеет продолжение. Двоеточие может следовать как сразу после метки, так и спустя несколько пробелов.
Программная строка может иметь несколько абсолютно равноправных меток, но каждая из них должна располагаться в отдельной строке:
Ml:
М2:
PRINT USING “Максимум - ###.##” ; Y
В связи с появлением меток все операторы передачи управления в системах Quick- и Turbo-BASIC в качестве точек перехода наряду с прежними номерами строк допускают использование меток. Мнемоника символьных меток выгодно отличается от лишенных какого-либо
содержания номеров строк. Конечно, при этом не следует злоупотреблять метками типа Ml, М2, ...,М999.
Максимальная длина программной строки достаточно велика (GW - 255, Turbo - 249, Quick - 255). Однако при наборе строк, длина которых превышает 80 символов, пользователь испытывает неудобства из-за того, что не видит всю строку целиком. Кроме того, длинные строки могут быть обрезаны при выводе на принтер. В Turbo-BASIC имеется возможность осуществить “перенос” программной строки на следующую строку экрана дисплея за счет использования символа “подчерк”.
ОРГАНИЗАЦИЯ ПРОГРАММЫ
Головная программа
По аналогии с другими алгоритмическими языками под головной программой понимают модуль, с которого начинается счет. В ранних версиях Бейсика, в том числе и в GW-системе, программа для решения той или Иной задачи представляет собой единственный модуль, физическим концом которого является оператор END, расположенный в строке с наибольшим номером.
В системах программирования Turbo- и Quick-BASIC наряду с головной программой (Main Program) могут существовать и другие программные модули, оформленные в виде внешних функций и подпрограмм. Такие модули могут компилироваться как совместно с головной программой, так и отдельно от нее. В последнем случае получаются так называемые объектные модули. Их имена в файловой системе MS DOS снабжаются расширением .OBJ. Объектные модули можно подключать к головной программе на стадии ее выполнения и компоновать в библиотеки, которые по своему назначению мало чем отличаются от системных библиотек.
Внешние процедуры имеют свои собственные (локальные) переменные, допускают свою автономную нумерацию строк, и эти обстоятельства развязывают программисту руки. Он вовсе не должен знать, какие имена переменных задействованы в используемых им процедурах в отличие от ранних версий Бейсика, где это обстоятельство приходилось учитывать. Он не должен заботиться о согласовании номеров (меток) строк в головной программе и во внешней процедуре. А раньше приходилось выполнять значительный объем работы по перенастройке используемых им готовых подпрограмм, заимствованных из других задач. Наличие отдельно транслируемых внешних модулей существенно облегчает работу по созданию крупных программных
систем.
Элементы структурного программирования
Мы уже упоминали, что минимальной синтаксической конструкцией, участвующей в построении программы, является оператор. Следующим по сложности элементом конструкции программ является программная строка с необязательным номером (меткой) М, содержащая несколько операторов Oi:
[М:] 01:02: ... :Оп
Характерной особенностью программной строки является то, что начать ее выполнение можно только с самого первого оператора 01, т.е. нельзя извне передать управление внутреннему оператору.
По аналогии с принципами построения программной строки в структурном программировании выделяют типовые блочные конструкции, которые, как правило, состоят из нескольких программных строк, имеют один вход, один выход и реализуют наиболее часто встречающиеся логические структуры — циклы, выбор альтернативных вариантов и т.п.
Как и в случае программной строки, войти в блочную конструкцию извне разрешается только через ее единственный вход. Для современных версий Бейсика (Quick, Turbo) характерно и то обстоятельство, что блок обязательно должен доработать до своего логического конца. Это означает, что в нем могут быть и не выполнены все запрограммированные действия, но возврат из блочной конструкции должен состояться только через ее единственный выход. Внутренние переходы в блоках не запрещены.
2.2.1.Циклы
Цикл представляет собой фрагмент программы, который повторяется либо заданное количество раз, либо до тех пор, пока не будет удовлетворено некоторое условие. Чтобы выделить такой фрагмент, необходимо тем или иным способом задать его начало (заголовок цикла) и указать его конец. Программные строки, расположенные между этими двумя точками, принято называть телом цикла.
Условие повторения цикла может находиться как в заголовке цикла, так и в его конечном операторе.]Досрочный выход из тела цикла на строку, следующую за конечным оператором цикла, осуществляется с помощью оператора EXIT. В ранних версияхБейсика такого оператора не было и для досрочного завершения цикла использовались обычные переходы — условные или безусловные. Они могли передать управление не только на оператор, следующий за концом цикла, но и
в любую точку программы. Такие возвраты не проходят бесследно, так как организация повтора цикла обычно связана со стеком, где хранятся параметры цикла - указатель на начало тела цикла, имя управляющей переменной, ее конечное значение и величина приращения при очередном повторе. Если цикл не завершается нормальным образом, то такого рода информация из стека не удаляется. Это может привести как к исчерпанию выделенного под стек участка памяти, так и к неправильному выполнению последующих циклов. Поэтому мы рекомендуем любой досрочный выход из цикла производить только с помощью оператора EXIT (EXIT FOR, EXIT DO, EXIT LOOP).
К наиболее простым вариантам организации цикла относится повтор тела, при котором по правилу арифметической прогрессии осуществляется изменение значения управляющей переменной (счетчика цикла) V:
V-Vh, V-VH + dV, V-VH + 2*dV, ...
Имя управляющей переменной (V), ее начальное (Vh) и конечное (Vk) значения, а также величина приращения (dV) задаются в заголовке цикла с помощью оператора FOR:
FOR V-VhTO VkSTEP dV
В качестве управляющей переменной может выступать простая переменная любого из числовых типов. Элемент массива в роли счетчика циклов не допустим. Параметры цикла (VH,VK,dV) могут задаваться любыми арифметическими выражениями. Если шаг приращения управляющей переменной равен единице, то конструкцию “STEP 1" в заголовке цикла можно опустить.
В современных версиях компиляторов и интерпретаторов принято проверять условие завершения цикла перед входом в его тело (цикл с предусловием):
¥ > ¥к при d¥ > О
V < ¥к при d¥ < О
Поэтому надо быть готовым к ситуации, что тело цикла никогда не выполнится при задании несовместимых параметров цикла. В этом случае программа продолжит свою работу с оператора, расположенного вслед за оператором конца цикла NEXT:
NEXT Y
Имя управляющей переменной, повторяемое в операторе конца
цикла, обязательно должно совпадать с идентификатором, указанным взаголо ке Все три версии допускают употребление оператора NEXT без указания имени управляющей переменной.
Короткие циклы могут быть организованы даже в пределах одной программной строки:
S-0: FORK-1 ТО 20 :S - S + A(K):NEXT
С помощью операторов WHILE - WEND организуется цикл с предусловием :
WHILE условие
тело цикла
WEND
Работа такого цикла начинается с проверки условия, записанного в заголовке WHILE. Если условие истинно, то начинается выполнение тела цикла, после чего оператор WEND вновь возвращает нас на заголовок цикла WHILE. Если в теле цикла происходят какие-то изменения, влияющие на результат проверки условия, то может наступить момент, когда это условие становится ложным, и управление из WHILE будет передано на оператор, следующий за WEND. В противном случае цикл будет повторяться до тех пор, пока в его теле не сработает один из операторов перехода (GOTO, IF, ON) или досрочного выхода из цикла (EXIT).
Одну из наиболее современных конструкций цикла позволяют создать операторы DO - LOOP:
DO [ WHILE условие I UNTIL условие]
тело цикла
LOOP [ WHILE условие I UNTIL условие]
В таких циклах программист сам может выбрать вариант проверки условия повторения — в начале цикла (предусловие) или в конце (постусловие). А можно воспользоваться и двумя условиями сразу или организовать бесконечно повторяющийся цикл, который можно прервать либо с помощью оператора EXIT LOOP, либо при наступлении какого либо события (прерывание от активного внешнего устройства, истечение заданного временного интервала и т.п.).
Конструкция “WHILE условие” заставляет повторять тело цикла до тех пор, пока условие остается истинным. Сочетание “UNTIL условие” приводит к повтору цикла при ложности условия.
Тело цикла может включать другие циклы, которые принято называть внутренними или вложенными по отношению к внешнему циклу. Это могут быть как однотипные циклы, организуемые парами FOR - NEXT, WHILE - WEND, DO - LOOP, так и смешанные конструкции с любым сочетанием типов циклов и количеством их вложений. Если вложенные циклы имеют одинаковую структуру FOR - NEXT, то допускается завершать два цикла или более одним оператором NEXT:
FOR К-1 ТО 10
FOR J-1 ТО 20
S(K,n— A(K,J)+B(K,J)
NEXTJ.K
Последовательность управляющих переменных при этом задается в порядке вложения циклов.
•2.2.2. Блоки выбора по условию
Блочная конструкция IF — END IF обобщила первоначальный замысел оператора условного перехода IF... THEN . Сначала этот оператор предусматривал проверку элементарного логического условия и при его истинности передавал управление в указанную точку программы :
50 IF А>В THEN 100
Если проверяемое условие оказывалось ложным, то выполнение программы продолжалось с оператора, следующего за IF.
На следующем этапе развития языка появилась возможность задавать в операторе IF и альтернативную точку перехода:
50 IF А>В THEN 100 ELSE 200
' Затем последовало радикальное сближение оператора IF ...THEN ...ELSE с логическим оператором IF из Фортрана, который в случае истинности проверяемого условия допускал использование не только операторов перехода (IF (A.GT.B) GOTO 100), но и многих других операторов. В результате в Бейсике возникла очередная конструкция оператора IF:
. IF условие THEN оператор! ELSE оператор2
Несколько расширились возможности условного оператора IF за счет применения более сложных логических выражений (см. п. 1.4). Однако кульминация этого подхода состояла в том, чтобы разрешить в альтернативных ветвях после служебных слов THEN и ELSE выполнять не только по одному оператору. Оставалось только придумать способ указания начала и конца трупп альтернативных действий, т.е. ввести эквивалент операторных скобок, существующих в других алгоритмических языках (фигурные скобки в “Си”, begin и end в алголоподобных языках и т.п.)‘ Поскольку служебные слота THEN и ELSE сами являются разделителями, то для указания конца второй группы операторов и был введен признак END IF (допускается и слитное написание ENDIF).
В результате появилась блочная конструкция IF - END IF, которая в простейшем случае выглядит следующим образом:
IF условие THEN
Действия, выполняемые при соблюдении условия
(Группа 1)
ELSE
Действия, выполняемые при несоблюдении условия
(Группа 2)
END IF
Выполнение первой группы программных строк, следующих за служебным словом THEN, автоматически завершается переходом на END IF, т.е. выходом из блока. Поэтому пользователю не требуется завершать группу 1 оператором передачи управления на END IF.
Вторая альтернативная ветвь (группа 2) может отсутствовать. При этом признак ее начала—служебное слово ELSE—также опускается. И тогда группа 1 завершается оператором END IF.
Для построения сложных блоков указанного вида, в которых количество разветвлений может быть более двух, используется оператор EUSEIF, обеспечивающий проверку дополнительных условий и выполнение соответствующих действий. Продемонстрируем это на примере квадратного уравнения, без программы решения которого не обходится ни одна книга по Бейсику: ..
PRINT “Решение квадратного уравнения А * Хл2 + В*Х + С - О" Wwod:
INPUT "Введите коэффициенты А,В,С; А,В,С
IFА-О THEN
PRINT “Степень этого уравнения меньше двух. Повторим :”
GOTO Wwod
END IF
D-B*B-4*A*C : E-2*A : DI - SQR(ABS(D))
IF D-OTHEN
PRINT “Имеется два кратных корня:”
PRINT “XI - Х2 -”; -В/Е
ELSEIF D>0 THEN
PRINT “Имеется два вещественных различных корня:”
PRINT “XI -”; (-В + DD/E
PRINT “Х2 -”; (-В - Dl)/E
ELSE л
PRINT “Имеется два комплексных сопряженных корня:”
PRINT “Вещественная часть корня —”; -В/Е PRINT “Мнимая часть корня —”; D1/E END IF
В пределах одного блока IF - END IF может быть использовано любое количество конструкций с дополнительными проверками (ELSEIF).
Выполнение любой из альтернативных групп действий автоматически завершается выходом из блока.
На все выше описанные конструкции типа IF - END IF распространяется общее для блочных структур правило: никаких передач извне на внутренние программные строки.
Включенные в данный раздел сведения о различных модификациях оператора IF и путях его эволюции носят не только характер исторической справки. Все эти форматы могут использоваться в любой из описываемых версий. Однако блочная конструкция IF - END IF в состав входного языка GW BASIC, к сожалению, не попала.
2.2.3. Блоки выбора по ключу
Одним из частных случаев выбора альтернативных решений является вариант проверки на принадлежность значения арифметического или символьного выражения заданному набору значений. Конечн , такую проверку можно было бы реализовать с помощью ранее описанного блока IF - END IF:
IF e-cl THEN
Группа 1 программных строк
ELSEIF e-'c2 THEN
Группа 2 программных строк
ELSEIF e-сЗ THEN
Группа 3 программных строк
END IF
Однако в структурном программировании предпочитают использовать более изящную конструкцию:
SELECT CASE е
CASE cl
Группа 1 программных строк
CASE с2
Группа 2программных строк
CASE ELSE
Группап программных строк
END SELECT
Блоки такого вида принято называть переключателями, а тестируемое выражение е, которое может быть числовым или символьным, - переключающим выражением.
Условия проверки, формируемые с помощью операторов CASE, могут содержать не только одно ключевое значение. В теле оператора CASE может быть задано несколько таких значений, разделенных запятыми. И в качестве ключей могут выступать любые выражения того же типа, что и переключающее выражение:
CASE 5+N, 12, -(K+l)
Второй разновидностью проверяемого условия является проверка на принадлежность значения переключающего выражения некоторому интервалу. Например, проверка на принадлежность значения х интервалу [а,Ь ] может быть реализована с помощью условия:
SELECT CASE х
CASE а ТО b
Наконец, третья модификация проверки значения переключающего выражения состоит в использовании самой обычной операции отно- шения.Например, для выполнения действий, когда тестируемое выражение превышает заданный порог а, условие выбора может выглядеть так:
CASEIS>-a
Связка IS заменяет в данном случае тестируемое выражение.
Оператор CASE ELSE позволяет выполнить группу действий в случае, когда значение переключающего выражения не “совпало” ни с одним из выше указанных ключей.
Необходимо иметь в виду, что условия проверок в блоке SELECT - END SELECT не обязательно должны быть взаимоисключающими. Поэтому если значение переключающего выражения “совпало” с одним из ключей и соответствующие этой ситуации действия были выполнены, то последующие проверки в теле блока не игнорируются. Для того чтобы прервать все последующие проверки и выйти на конец блока, соответствующая группа действий должна заканчиваться оператором EXIT SELECT.
Описание нестандартных функций
Внутренние функции
Нестандартные функции принято называть внутренними или локальными, если описание соответствующей вычислительной процедуры включено в состав того программного модуля, где эта функция используется. '
Различают одностроковые (точнее, однооператорные) имногостро-
ковые внутренние функции. В первом случае формула для вычисления значения функции должна быть представлена выражением арифметического или символьного типа, которое записывается в правой части оператора DEF FN:
DEF FNnn...nt(xl,x2,...)-e.
Идентификатор функции FNnn...nt должен начинаться с символов FN (от FuNction). Этот “пережиток” сохранился от ранних версий Бейсика, но зато он позволяет пользоваться функциями без аргументов, чего нет в других алгоритмических языках. Общее количество символов в обозначении функции, включая FN и концевой признак типа t (t - { % ,!,#,$}), не должно превышать 40.
В круглых скобках после имени функции расположен список формальных параметров - аргументов функции. В Turbo BASIC их количество не должно превышать 16. В качестве формальных параметров можно указывать только идентификаторы простых переменйых. К имени аргумента может добавляться символ - указатель типа. В Quick BASIC наряду с таким способом задания типа формального параметра применяется и другой:
DEF FNsumma% ( XI AS REAL, Х2 AS REAL) - XI + X2
Выражение e, используемое для вычисления значения функции, наряду с именами аргументов может включать имена обычных переменных программного модуля, указатели стандартных и нестандартных функций. Явная (DEF FNfactorial(n) - и * FNfactorial(n-l)) или скрытая (FNA ~* FNB -* FNC -* ... -* FNA) рекурсия в описании функций запрещена.
Очень важно подчеркнуть, что идентификаторы, используемые для обозначения формальных переменных, не имеют никакого отношения к программнымпеременным с теми же именами. В этом легко убедиться, выполнив следующую программу ^
10 DEF FNA(X,Y) - X + Y
20Х-1
30Y-2 .
40 Z-FNA (3.4)
50 PRINT "Х-" ; X, “Y-"; Y, “Z-”; Z
Никаких троек или четверок в программных переменных X и Y мы не обнаружим, хотя в формальные параметры с аналогичными именами такие значения подставлялись.
Если процедура вычисления функции включает проверку различ-
ных условий, то в некоторых ситуациях можно попытаться построить одностроковое определение. Пусть, например:
у (х) - -х , если х < О;
у(х) -хЛ2 , если х> О.
Не так уж и сложно подобрать некоторый множитель g (х), который принимает нулевое значение для отрицательных аргументов и единичное - для положительных. Очевидно, что для конструирования такой единичной “ступеньки” следует воспользоваться функцией SGN, которая тоже имеет форму ступеньки, но немного смещена вниз и имеет вдвое большую амплитуду:
g(x) - (SGN(x) +1)/2
■ Тогда нашу функцию у(х) можно представить в виде двух слагаемых :
у(х) - -х • (1 - g(x)) +g(x) * хЛ2
И соответствующее одностроковое определение функции уже никакого труда не составляет.
Но процедура вычисления функции может оказаться и намного более сложной. И в этой ситуации на помощь приходит возможность создать многостроковое описание, которая предоставляется пользователям Quick- и Turbo-систем. По сути это блочная конструкция, обращение к которой производится неявно в тот момент, когда потребова- ■ лось значение функции. При прямой передаче управления такой блок обходится, как и любой декларативный оператор.
М огостроковая нестандартная функция начинается с заголовка:
DEF FNnn...nt (xl,x2,...)
За ним размещается программа вычисления значения функции, состоящая из обычных операторов Бейсика. Единственная особенность заключается в технике возврата найденного результата. Его надо присвоить простой переменной с таким же именем, как и идентификатор функции. Завершается многостроковое описание нестандартной функции оператором END DEF.
И еще одна особенность - для досрочного выхода из тела функции используется оператор EXIT DEF. Продемонстрируем эти средства на приводившемся выше примере функции у(х):
DEFFNy(x)
IF х<0 THEN FNy--x: EXTTDEF
FNy-x~2 END DEF
Конечно, в данном примере можно было построить и другое описание:
DEFFNytx)
IF х<0 THEN FNy--x ELSE FNy-x~2
END DEF'
Внешние функции
Возможность описать нестандартную функцию в виде внешней процедуры со своими локальными переменными и со своей внутренней идентификацией программных строк имеется только в Quick-BASIC.
В отличие от внутренних функций внешнюю процедуру можно автономно откомпилировать и использовать полученный объектный модуль либо как самостоятельную программную единицу, либо в составе библиотеки. К услугам внешней процедуры-функции может обратиться любая Бейсик-программа, тогда как внутренняя функция доступна лишь тому модулю, где она определена.
Описание внешней функции начинается с заголовка:
FUNCTION паше [(VI [О] [AS typel]
[,(V2[O] [AStype2] ...] [STATIC]
В отличие от внутренних функций идентификатор внешней функции может начинаться с любых символов. Он может содержать до 40 символов, включая концевик, определяющий тип функции.
Заголовок внешней функции может включать описание типов аргументов, среди которых в отличие от внутренних функций могут присутствовать и имена массивов, сопровожд емые пустыми круглыми скобками.
Указатель STATIC, завершающий заголовок, употребляется в тех случаях, когда необходимо сохранить значения локальных переменных между двумя последовательными обращениями к функции. Перед первым обращением к внешней функции все ее локальные переменные сброшены в начальное состояние (нулевые значе i1 ия для числовых переменных и пустые значения - для символьных).
Во всем остальном тело внешней функции мало чем отличается от многостроков внутренней функции Здесь тоже должен присутствовать оператор присваивания, возвращающий результат вычислени . Для досрочного выхода из процедуры используется оператор EXIT
FUNCTION. А завершается тело внешней функции оператором END FUNCTION.
Для внешних функций система Quick BASIC допускает рекурсивные обращения:
FUNCTION Fact# (N%)
IF N% > 1 .THEN
, Fact# - N% * Fact#(N% - 1)
ELSE
Fact#-1
END IF
END FUNCTION
Отметим еще две важные детали, связанные с использованием внешних функций. Во-первых, в программе, использующей внешнюю функцию с именем f, должен присутствовать декларативный оператор:
DECLARE FUNCTION I [ CDECL ] [ ALIAS “namel" ]
. [ ( [BYVAL I SEC] VI [()] [AStypel I ANY]
[,( [BYVAL I SEC] V21[0] [AStypel I ANY] ...])]
Такое объявление позволяет выделить идентификатор f и не путать его с именами других объектов в случае отсутствия у функции аргументов. В связи с тем, что вызываемая функция может быть написана не только на Бейсике, но и на других алгоритмических языках, в операторе присутствуют два межязыковых указателя — CDECL и ALIAS. Первый из них означает, что вызываемая функция придерживается способа передачи аргументов, принятого в системе программирования “Си”. Второй указатель сопровождается заданием дополнительного имени namel, которое может оказаться необходимым для ■ поиска вызываемого модуля среди отдельных файлов с расширением .OBJ или в библиотечном файле.
Дело в том, что в разных системах программирования используются • различные правила идентификации программных единиц. В одних случаях имя модуля может иметь до 40 символов (Бейсик), в других случаях длина идентификатора регулируется ("Си"), Фортран использует шестисимвольные обозначения, а в файловой системе MS DOS имя модуля не может содержать более 8 знаков. Возможность указать дополнительное эквивалентное имя модуля позволяет в какой-то степени согласовать такие разночтения.
Повторение описания типов аргументов, в точности совпадающее с
соответствующим фрагментом заголовка внешней функции, обеспе- цивает возможность проконтролировать правильность обращений по типу и количеству параметров. Контроль за соответствием типов может быть отключен, если вместо описания типа (AS type) стоит указание ANY (любой).
Кроме того, перед каждым параметром может быть задан один из двух указателей BYVAL или SEG. Первый из них указывает на способ передачи соответствующего аргумента по значению (by value). В этом случае значение фактического аргумента при необходимости вычисляется и переносится в ту область памяти внешней процедуры, которая отведена для хранения соответствующего формального параметра. Сочетание указателей ANY и BYVAL недопустимо. Во втором случае (SEG) вместо значения аргумента передается его адрес в виде двухбайтового смещения от начала сегмента данных. Имена массивов передаются только по адресу.
Вторая особенность связана с тем, что обмен данными между внешней функцией и вызывающей программой не ограничивается только механизмом передачи параметров. Функция может иметь доступ к глобальным переменным вызывающего модуля, если они между собой “договорились” о совместном использовании общих переменных. С этой целью в теле функции может находиться оператор SHARED:
SHARED VI [ AS typel ] [, V2 [ AS type2 ] ...]
Здесь имена V1,V2,... — идентификаторы переменных вызывающего модуля, которыми пользуется внешняя функция без их передачи в качестве параметров. Среди совместных переменных, объявляемых по оператору SHARED, могут находиться и массивы. Тогда их идентификаторы в списке сопровождаются пустыми круглыми скобками:
SHARED Alpha О AS INTEGER, Beta O AS STRING
Другой вариант совместного доступа к общему участку памяти реализуется с помощью оператора COMMON. Однако в этом случае оператор COMMON должен появиться не только в теле внешней функции, но и в составе вызывающего модуля. В Quick BASIC этот оператор имеет следующий формат:
COMMON [ SHARED ] [ /name_block/ ]
VI [(indll,...)] [AS typel]
[, V2 [0nd21,...)] [ AS type2],... ]
Указатель SHARED в данной ситуации означает, что переменные (массивы) с именами VI ,V2,.„ доступны для всех процедур модуля.
Идентификатор name_block, заключаемый в косые скобки, используется для обозначения блока общей памяти, в который объявляющий модуль помещает свои переменные (массивы). Отсутствие этого параметра допустимо только в том случае, когда для размещения'общих переменных используется непоименованный блок общей памяти.
Порядок переменных (массивов) в списке оператора COMMON важен, так как именно в этой последовательности объекты размещаются в указанном блоке.
Если два модуля, например, вызывающий модуль и внешняя функция используют один и тот же блок общей памяти, то каждый из них должен содержать по оператору COMMON с указанием имени этого блока. Можно совместно использовать и безымянный блок, но и в этом случае форматы операторов COMMON должны быть согласованы.
Что же касается обозначения общих переменных (массивов), то каждому модулю предоставляется право именовать их по-своему. Это упрощает работу программиста, так как не надо согласовывать имена объектов, используемых при написании программ. Но порядок размещения совместно используемых величин в блоке общей памяти эти программы должны обязательно соблюдать, и соответствие типов данных должно быть обеспечено. В этом и заключается основное различие между операторами COMMON и SHARED.
Описание и использование подпрограмм
Подпрограмма представляет собой встроенную в модуль или автономно оформленную процедуру, к которой можно обратиться из любой точки, приостановив таким образом выполнение основной программы, и после завершения работы процедуры вернуться в точку прерывания для продолжения основной программы.
Для организации работы подпрограмм характерны следующие обстоятельства. Во-первых, при каждом очередном обращении подпрограмме должны быть тем или иным способомпереданы новые исходные данные. Без этого многократное выполнение подпрограммы потерял бы свой смысл. Естественно, что результаты работы процедуры тоже каким-то образом должны быть возвращены адресату.
Во-вторых, любое обращение к подпрограмме отличается от обычного перехода (GOTO, IF) тем, что координаты точки, из которой производится вызов, необходимо запомнить для организации возврата после завершения работы вызванной процедуры. Это напоминает
50
ситуацию с циклами, когда при обработке заголовка приходится запоминать параметры и адрес точки входа в тело цикла. Они понадобятся в тот момент, когда будет обрабатываться последний оператор цикла. И при реализации вложенных циклов, и в случае последовательных обращений из одной подпрограммы в другую для запоминания очередной точки возврата используется стековый механизм. В момент обращения к подпрограмме адрес возврата заносится в стек и хранится там до тех пор, пока не будет выполнен специальный оператор возврата. При этом сделавший свое дело адрес возврата из стека удаляется.
Внутренние подпрограммы
Внутренние или встроенные подпрограммы — одна из наиболее ранних синтаксических конструкций Бейсика, построенная по аналогии с примитивно оформленными машинными подпрограммами. У них отсутствуют четко выраженные границы, характерные для блочных конструкций. Для индикации входных точек во внутренней подпрограмме приходится пользоваться только комментариями. Физический конец внутренней подпрограммы тоже ничем не выделяется. Единственный оператор, по которому можно опознать подпрограмму, — это оператор возврата RETURN. Но и он может располагаться не только в последней программной строке подпрограммы. Например:
1000 REM Масштабирование 1-й строки матрицы
1010J-0'
10201ЕА(1,Ь -0 THEN RETURN ELSE J--1
1030FORK-I+1 ТО N
1040A(I,K) -A(I,K)/A(I,I)
1050 NEXT К
1060 RETURN •
В приведенной процедуре реализуется один из шагов вычисления определителя по схеме Гаусса — деление элементов строк на диагональный элемент. Если деление невозможно, то в переменную J заносится нуль, отождествляемый с логическим значением “ложь”.
Для обращения к внутренним подпрограммам используется оператор GOSUB, в теле которого задается номер начальной программной строки или метка первого оператора подпрограммы. В частности, к приведенной выше процедуре можно обратиться с помощью оператора GOSUB 1010.
Самым большим недостатком внутренних подпрограмм является отсутствие механизма параметров, который применяется даже в час-
■ тном виде подпрограмм—в нестандартных функциях. Поэтому обмен данными с подпрограммой основан на совместном использовании переменных, область действия которых распространяется на весь модуль. Это накладывает на программиста дополнительные заботы по согласованию имен переменных и номеров строк, задействованных во внутренних подпрограммах. Кроме того, перед обращением к подпрограмме пользователь должен позаботиться о присвоении нужных значений входным переменным, а после возврата из подпрограммы — и о спасении результатов работы процедуры. Иначе предыдущие результаты будут “забиты” при повторном обращении к подпрограмме.
В отличие от функций в результате работы подпрограммы вовсе не обязательно что-то сосчитать и возвратить одно или несколько значений. Подпрограмма может, например, осуществить построение на экране некоторого графического объекта с заданными характеристиками, выполнить проверку сходимости итерационного процесса,произвести ввод значений определённых переменных, которые должны удовлетворять условиям задачи и т.п.
Возврат из подпрограммы тоже может быть предусмотрен не только на оператор, следующий за GOSUB. Эта возможность обеспечивается за счет указания в теле оператора RETURN номера или метки программной строки. Например:
Analiz:
dx - xl - х2
dy - yl - у 2
dz - zl - z2
d — sqr(dx*dx + dy*dy + dz*dz)
IF d > le-4 AND Niter < 100
xl - x2: yl - у2: zl - z2
Niter - Niter + 1 : RETURN
ELSEIF Niter > 100 THEN
PRINT “Количество итераций превысило допустимое”
PRINT “Смените начальную точку”
RETURN NewPoint
ELSE.
PRINT “Решение найдено за"; Niter,"итераций"
RETURN NewAlgorithm
END IF
Таким фрагментом проверен сходимости можно воспользоваться при решении некоторой оптимизационной задачи, в которой запрограммировано несколько разных алгоритмов. -
Возможность указать точку возврата в операторе RETURN не следует воспринимать как аналог оператора обычного перехода в заданную точку программы. Дело в том, что выполнение оператора RETURN связано еще и с дополнительной нагрузкой — очисткой строки в отёке возвратов, которая была сформирована оператором GOSUB. Именно это обстоятельство позволяет зафиксировать ошибку, вызванную переходом на подпрограмму с помощью обычных операторов GOTO, IF. В этом случае стек возвратов пуст и выполнение оператора RETURN заканчивается выдачей сообщения об ошибке.
Стековый механизм позволяет легко организовать вложенные обращения из одной подпрограммы в другую, а в системе Quick-BASIC допускаются и рекурсивные обращения:
Factorial:
Nfact - 1 : N% - n GOSUB Factor
RETURN
Factor:
IFN%>1 THEN
Nfact-N% * Nfact N%-N%-1 GOSUB Factor
ELSE
RETURN
Приведенный пример подпрограммы, вычисляющей значение п! , носит только иллюстративный характер. Конечно, вычисление факториала можно реализовать и более эффективным способом.
Внешние подпрограммы
Отсутствие четких правил в оформлении структуры внутренних подпрограмм и механизма передачи параметров, необходимость согласовывать совместно используемые ресурсы (переменные, номера строк), обязательное включение текста внутренней подпрограммы в состав основной программы существенно затрудняют использование таких процедур.
В системах Quick- и Turbo-BASIC эти препятствия удалось устранить за счет подключения внешних подпрограмм, которые могут быть составлены как на Бейсике, так и на других алгоритмических языках. Заголовок внешней подпрограммы на Бейсике оформляется с по-
мощью оператора SUB, который в обеих системах имеет несколько отличающиеся форматы:
Turbo: SUB name [ (VI [О], V2 [О],...]
Quick: SUB name [ (VI [()] [AStypel],
V2 [01 [AS type2],.... ] [STATIC]
Каждая внешняя подпрограмма, подобно функциям, уже имеет индивидуальное имя (паше) и список формальных параметров, среди которых наряду с простыми переменными могут фигурировать имена массивов любой размерности. Для их выделения в списке формальных параметров вслед за идентификатором массива ставятся круглые скобки.
В теле подпрограммы наряду с формальными параметрами могут использоваться свои собственные (локальные) объекты с динамическим или статическим способом размещения в оперативной памяти, а также переменные, совместно используемые (SHARED) вызывающей программой и подпрограммой или расположенные в одноименных блоках общей памяти (COMMON). В общих чертах механизм обмена данными с внешними подпрограммами практически ничем не отличается от аналогичного общения с внешними функциями.
Применение ряда операторов в теле подпрограммы запрещается (DEF FN, FUNCTION, SUB). Однако обращаться к другим внешним функциям и подпрограммам можно без каких-либо ограничений.
Завершает тело подпрограммы оператор END SUB, выход на который автоматически приводит к возврату в вызывающую программу. Оператор RETURN во внешних подпрограммах не используется. Для досрочного выхода из подпрограммы применяют оператор EXIT SUB.
Обращение к внешней подпрограмме осуществляется с помощью оператора CALL:
CALL name [ (W1 [01.W2 [О],...) ]
Здесь W1 ,W2,... — фактические аргументы, последовательность и тип которых должны находиться в соответствии с формальными параметрами VI ,V2,.„
Система Turbo-В ASIC допускает применение параметров, способом передачи которых можно управлять. По умолчанию вместо значений скалярных (одиночных) аргументов в подпрограмму передаются их относительные а; еса в сегменте данных. Такой способ принято называть передачей данных по указателю (по ссылке, по адресу). Массивы всегда передаются только по указателю. Для физического
переноса значения фактического параметра в соответствующую область подпрограммы аргумент заключают в круглые скобки:
CALL АВС (а, (Ь), (с(5)))
Если в роли фактического аргумента выступает переменная и в подпрограмму передается ее значение, то такой параметр может быть только входным, ибо любое его изменение в теле подпрограммы никак не скажется на самой переменной в вызывающей программе. Адрес-то ее мы ведь в подпрограмму не сообщили.
В связи с тем, что в теле внешних подпрограмм (функций) не принято описывать массивы, указанные в числе формальных параметров, входные языки Quick- и Turbo-систем предоставляют внешним процедурам возможность узнать настоящи размеры соответствующего фактического аргумента. Для этого используются функции LBOUND(V,k) nUBOUND(V,k), выдающие соответственно значения нижней и верхней границы индекса по заданному измерению к в массиве с именем V. Способ их применения демонстрирует внешняя подпрограмма, суммирующая элементы двумерного массива:
SUB SumArray (АО AS REALES AS REAL)
N1 - LBOUND(A,1) : Ml - UBOUND(A,1)
N2 - LBOUND(A,2) : М2 - UBOUND(A,2)
S-0
FORI-N1 TO Ml
FORJ-N2 TO М2
S-S + AdJ)
NEXT!
NEXT I
END SUB
Возврат из внешней подпрограммы все!да происходит на оператор, следующий за оператором CALL.
Quick-BASIC допускает возможность обращения к подпрограммам и без оператора CALL. Однако в этом случае имя подпрограммы не может совпадать с именами служебных слов, а в вызывающей программе должен присутствовать декларативный оператор:
DECLARE SUB name [(VI [О] [AS lypel] ,V2[()] [AS 1ype2],...)]
При вызове внешней подпрограммы без служебного слова CALL фактические аргументы в круглые скобки не заключаются.■
Общение с другими системами программирования
Иногда бывает полезно воспользоваться подпрограммами или функциями, составленными на других алгоритмических языках. Однако существует довольно много причин, осложняющих взаимодействие объектных модулей, изготовленных различными системами программирования. ■
Во-первых, могут оказаться несовместимыми внутренние форматы представления внешне однотипных объектов (вспомните форматы IEEE и MBF для вещественных чисел, трех- и четырехбайтовые дескрипторы, связанные с хранением символьных значений, возможность расположить двумерный массив в памяти по строкам или столбцам и Т.П.).
Во-втррых, разные системы программирования используют различные механизмы передачи параметров и способы совместного использования общих переменных. В одних случаях формируются таблицы, содержащие адреса значений фактических параметров, и вызываемым модулям передаются ссылки на эти таблицы и их длины. В других случаях вся информация передается через стек. Да и сами параметры могут передаваться разными способами — по значению, по ссылке (вместо значения передается его адрес).
В-третьих, могут оказаться различными и соглашения о правилах использования регистров, о порядке их запоминания и восстановления, о месте расположения и размерах областей сохранения.
Преодолению такого рода барьеров способствует расширение состава стандартных функций, обеспечивающих преобразование данных из одного формата представления в другой (см. п. 1.2.6) и установление соответствия между идентификаторами объектов и их адресами (VARPTR,VARPTR$,SADD), средства управления памятью (DEF SEG, MEMSET), процедуры обмена с ячейками оперативной памяти по физическим адресам (РОКЕ,РЕЕК) и т.д.
Ниже рассматриваются основные средства, обеспечивающие взаимосвязь между Бейсик-программами и внешними процедурами, реализованными на других алгоритмических языках.
Ранние Бейсик-системы (в том числе и GW BASIC) отводили в оперативной памяти под задачу пользователя всего 64 Кбайта. Объяснялось это принятым тогда способом прямой адресации объектов, который на ЭВМ с 16-разрядными словами не позволял задать адрес более 65535. Однако на IBM PC/XT имеется возможность работать с адресным пространством до 640 Кбайт, а на моделях АТ-286 и АТ-386 объем оперативной памяти может достигать 16 Мбайт.
Чтобы рационально использовать память большого объема, ее делят
56
на сегменты, размер каждого из которых не может превышать 64 Кбайта. Для адресации объектов (команд, операндов), расположенных в любом сегменте, используются две компоненты—база сегмента Ь, эквивалентная (но не равная!) его начальному адресу, и смещение d объекта относительно начала сегмента.
Значение базы b формируется в одном из 16-разрядных управляющих регистров:
CS - регистр сегмента команд;
DS - регистр сегмента данных;
SS - регистр сегмента стековых операндов;
ES - регистр внешнего сегмента;
Величина смещения d может быть указана непосредственно в машинной команде или формироваться за счет прибавления к машинному адресу соответствующего индексного регистра.
Полный 20-разрядный адрес, позволяющий идентифицировать любые данные в пределах до 1 Мбайта, формируется следующим образом:
Address-16 *b+d
Первое слагаемое, представляющее собой настоящий начальный адрес сегмента, равно содержимому регистра соответствующего сегмента, сдвинутому влево на 4 двоичных разряда.
Это небольшое отступление было предпринято для того, чтобы лучше понять смысл некоторых стандартных функций и операторов, используемых в процессе взаимодействия с внешними функциями и подпрограммами..
Оператор DEF SEG позволяет сформировать в одной из служебных ячеек Бейсик-системы начальный адрес сегмента, значение которого влияет на выполнение операторов BLOAD, BSAVE, CALL
ABSOLUTE, DEF USR, POKE и функции PEEK. Он имеет следующий формат:
DEFSEG [-Address]
База сегмента должна принадлежать диапазону [0, 65535 ]. Если операнд не задан, то в соответствующую служебную ячейку заносится значение, предусмотренное системой по умолчанию.
С помощью функции VARSEG(V) можно узнать базовый адрес сегмента, в котором хранится переменная с именем V. Смещение этой
же переменной относительно начала сегмента определяется по значению функции VARPTR(V). Аргументами обеих функций метут быть идентификаторы как символьных, так и числовых переменных или массивов. Результат выдается в виде двухбайтового целого числа, и он может быть передан в качестве параметра в любую внешнюю функцию или подпрограмму.
В Quick-BASIC для определения смещения переменной (массива) символьного типа применяется функция SADD(V$).
В GW-BASIC функции VARPTR(V) и VARPTR$(V) имеют несколько иной смысл. Первая функция наряду с идентификатором переменной допускает в качестве аргумента и номер файла (VARPTR(#5)). В этом случае значением функции является адрес (смещение) блока управления (FCB - File Control Block), выделяемого задаче в'Момент инициализации файла, с указанным номером. Функция VARPTR$(V) выдает в символьном формате трехбайтовый дескриптор переменной V:
123
Тип переменной
Мл. разряды адреса
Ст. разряды адреса
Тип переменной обозначается числовым признаком, принимающим значения 2 (целый), 3 (строка), 4 (вещественный с одинарной точностью) и 8 (вещественный с удвоенной точностью).
Дополнительные средства управления распределением памяти предоставляются функциями FRE (GW, Quick, Turbo), SETMEM (Quick) и оператором MEMSET (Turbo).
Функция FRE, предназначенная для опроса объема свободной памяти, в GW-системе работает несколько не так, как в двух других. Если ее аргументом является идентификатор любой числовой переменной, то она выдает количество свободных байтов, оставшихся в сегменте задачи (полный объем этого сегмента — 64 Кбайта). При аргументе символьного типа функция FRE выдает объем свободного участка памяти в области, выделенной для хранения текстовых значений (в так называемой “куче”). Одновременно запускается и процедура “уборки мусора” в куче. Периодическая реорганизация кучи с целью сборки свободных участков в сплошной массив памяти производится системой каждый раз, когда в куче не находится свободное место под очередной результат символьного типа. Процедура эта довольно длительная. На IBM PC/XT она занимает от одной до полутора минут.
В Quick- и Turbo-системах аргумент функции FRE может принимать одно из четырех следующих значений:
58
FRE (-2) — сообщает объем свободной памяти в стеке;
FRE (-1) —сообщает объем свободной памяти,который может быть использован для размещения числового массива;
FRE (е) — сообщает размер следующего свободного блока в куче (е — произвольное числовое выражение, значение которого отлично от-1 и-2);
FRE (е$)— сообщает размер всех свободных блоков в куче (е$ - произвольное выражение символьного типа).
Система Quick-BASIC предоставляет возможность управлять размером памяти (кучи), отводимой для хранения символьных значений:
K-SETMEM(n) ■ .
Если значение аргумента функции SETMEM отлично от нуля, то на такое количество байтов увеличивается (п>0) или уменьшается (п < 0) объем памяти в дальней куче. Значение функции при этом совпадает с новым объемом кучи. Если п-0, то функция SETMEM выдает текущий объем кучи.
В Turbo-BASIC с помощью оператора “MEMSET EndAddr” можно установить максимальный адрес, ограничивающий ресурсы Turbo-системы. Ячейки памяти с адресами, превышающими значение EndAddr, могут быть выделенывнешним подпрограммам, изготовленным в других системах программирования. Аналогичными средствами располагают GW-интерпретатор и Quick-компилятор. Только задаются такие границы, как значения соответствующих параметров в командной строке.
Связь с ассемблером. Исторически сложилось так, что в Бейсик-си- стемах раньше всего была отработана схема общения с подпрограммами на языке ассемблера. Имеются такие средства и в GW-BASIC, однако они не носят достаточно универсальный характер и потому в дальнейшем не получили распространения. К их числу относятся оператор DEF USRn и функция USRn(x).
Программа на Бейсике может включать до 10 пользовательских подпрограмм (п *"0,1,2,...,9), написанных в машинных кодах. Оператор DEF USR устанавливает связь между подпрограммой с номером п и ее начальным адресом:
150 DEF USR3 - &Н4000
О размещении (загрузке) соответствующей подпрограммы по указанному адресу пользователь должен позаботиться сам. Сделать это можно различными способами. Например, объявить массив необходи- . мого размера и определить его ад рес с помощью функции VARPTR:
20 DIM A(2000)
100 Address - VARPTR(A)
Затем на это место можно загрузить абсолютную программу из дискового файла по оператору BLOAD:
140 BLOAD “Sub3". Address
Абсолютная программа может быть задана и в блоке данных (DATA) как последовательность числовых значений байтов программы. Оттуда их можно извлечь и с помощью оператора РОКЕ записать на выделенное место в памяти:
120 FOR К-Address ТО Address + N
130 READ А% :РОКЕК,А%
140 NEXT К
। Переход на подпрограмму осуществляется с помощью функции USRn(x):
160Y-USR3(X)
При этом подпрограмме передается единственный числовой или символьный аргумент. Числовой аргумент помещается на специальное восьмибайтовое поле FAC (от Floating point Accumulator), расположенное в сегменте данных GW-системы. Адрес FAC сообщается вызванной подпрограмме через регистр ВХ (<ВХ> - FAC + 4).
Тип аргумента заносится в виде числового признака в регистр AL (2 —■ целочисленный тип, 3 — строка, 4 — вещественный тип с одинарной точностью, 8 — вещественный тип с удвоенной точностью). Если аргумент представлен числовым объектом, то его значение расположено в FAC следующим образом:
МЛ. разр.ст.разр.. мл. разр.СТ. разр.р-128МЛ.разр. |ст. разр.р-128МЛ. разр.ст.разр.. мл. разр.СТ. разр.р-128МЛ.разр. |ст. разр.р-128FAC FAC+1 FAC+2 FAC+3 FAC+4 FAC+5 FAC+6 FAC+7FAC FAC+1 FAC+2 FAC+3 FAC+4 FAC+5 FAC+6 FAC+7singlesingledoubledoubleintegerinteger
МЛ. разр.
ст.
разр.
. мл. разр.
СТ. разр.
р-128
МЛ.
разр. |
ст. разр.
р-128
МЛ. разр.
ст.
разр.
. мл. разр.
СТ. разр.
р-128
МЛ.
разр. |
ст. разр.
р-128
FAC FAC+1 FAC+2 FAC+3 FAC+4 FAC+5 FAC+6 FAC+7
FAC FAC+1 FAC+2 FAC+3 FAC+4 FAC+5 FAC+6 FAC+7
single
single
double
double
integer
integer
Вычисляемое подпрограммой арифметическое значение обычно имеет такой же тип, что и аргумент, и оно должно быть занесено в FAC.
Если аргумент X символьного типа, то при входе в подпрограмму регистр DX содержит адрес трехбайтового дескриптора строки (1 байт — длина, 2 байта — адрес строки).
60
Гораздо больший прогресс в GW BASIC был достигнут за счет введения почти современной конструкции оператора CALL:
CALL V [(al,a2,...)]
Здесь V - идентификатор целочисленной переменной, значение которой равно адресу входа в подпрограмму (точнее — смещению относительно начального адреса сегмента команд, установленного ранее с помощью оператора DEF SEG). В качестве фактических параметров вызываемой подпрограмме могут быть переданы значения переменных любого типа или константы. На самом деле подпрограмма получает не сами значения аргументов, а их адреса, расположенные в стеке в обратном порядке. Подпрограмма должна сама извлечь необходимые ей входные данные, организовать отсылку вычисляемых значений выходных параметров и привести стек в состояние, предшествовавшее моменту обращения. Проверка на соответствие и количество фактических и формальных параметров здесь не производится, хотя это обстоятельство может оказаться причиной трудно уловимых ошибок.
В системе Turbo BASIC появился довольно оригинальный способ включения ассемблеровской программы в состав исходной программы:
SUB name_sub INLINE
$INLINE Ы1,Ы2„.. $INUNE Ь21,Ь22,...
END SUB
ИЛИ
SUB name_sub INLINE
$INUNE “name_file”
END SUB
В первом варианте вслед за метаоператором $INUNE расположены байты машинной программы, во втором — задается имя файла с расширением .СОМ, который должен существовать на диске. Количество COM-файлов, участвующих в формировании тела одной подпрограммы типа INLINE, может достигать 16. Допускается и смешанное использование обоих вариантов.
Обращаются к подключенной таким образом подпрограмме с помощью стандартного оператора CALL:
CALLname_sub [(al,a2,...)]
Turbo BASIC предоставляет еще одну возможность обращения к ассемблеровским подпрограммам:
CALL ABSOLUTE address [(11,12,...)]
Здесь вместо имени подпрограммы указывается адрес ее точки входа (address), а в качестве фактических аргументов могут использоваться только целочисленные переменные или константы. Через стек передаются, однако, не сами значения аргументов, а их адреса.
Quick-BASIC предлагает два оператора для вызова ассемблеров- ских подпрограмм:
CALL ABSOLUTE (al,a2,...,l)
CALLS name_sub (al,a2,...)
В первом операторе адрес точки входа в вызываемую подпрограмму задается с помощью смещения i, которое должно быть прибавлено к базовому адресу сегмента команд, установленного по оператору DEF SEG. Добавка символа S к оператору CALL означает, что обмен данными между вызывающей и вызываемой программами осуществляется через стек.
Использование прерываний BIOS. Система прерываний BIOS (Basic Input/ Output System) и тесно связанные с ней встроенные программы, обслуживающие процедуры обмена с различными устройствами, являются компонентами операционной системы MS DOS и по- зволяют°максимально эффективно использовать аппаратные возможности ЭВМ.
Доступ к системе прерываний на языке ассемблера реализуется по машинной команде INT:
INT п
Номер прерывания п, обычно задаваемый в виде шестнадцатеричной константы, соответствует адресу слова в так называемом векторе прерываний (ячейки оперативной памяти с адресами ОН - 1FH). А находится в этом слове адрес точки входа в программу ПЗУ, отвечающую за обработку прерывания с номером п. Так что команда INT выполняет функцию оператора вызова соответствующей процедуры BIOS. Естественно, что при этом запоминается и адрес возврата на команду, следующую за INT.
Для обмена информацией между вызывающей программой и процедурами BIOS, используются двухбайтовые регистры микропроцессора АХ, ВХ,„. или их однобайтовые компоненты (АН — старший байт регистра АХ, AL — младший байт регистра АХ, ВН, BL,...).
Как правило, каждая процедура BIOS, обслуживающая прерывание с заданным номером, выполняет несколько операций. Иногда их называют функциями и внутри каждого прерывания различают по. номерам — 0,1,2,.... Перед выполнением команды INT номер функции
заносится в регистр АН. Каждая функция имеет свой набор входных и выходных параметров, размещаемых на фиксированных регистрах. С этой информацией в первом приближении можно познакомиться, например, в 6-й главе книги Л.Скэнлона “Персональные ЭВМ IBM PC и XT : Программирование на языке ассемблера” (М.: Радио и связь, 1989). Некоторые из функций, связанных с обработкой прерывания ЮН (управление дисплеем в текстовом и графическом режимах), рассматриваются в п. 5.4.5.
Для обращения к функциям BIOS в системе Turbo BASIC предлагаются операторы CALL INTERRUPT, REG и функция REG.
Оператор REG позволяет сформировать входные параметры в служебном массиве, содержимое которого перед обращением к выбранной процедуре переносится в регистры микропроцессора. При работе на ассемблере такого рода участки памяти принято называть областями сохранения. Переход из одной подпрограммы в другую сопровождается запоминанием в области сохранения состояния машинных регистров. После завершения работы вызванной подпрограммы содержимое области сохранения используется для восстановления регистров. Служебный массив, формируемый с помощью оператора REG, работает как бы в противофазе—его элементы загружаются в соответствующие машинные регистры в момент перехода на процедуру BIOS. А по завершению процедуры в них запоминается состояние регистров. Общепринятого идентификатора у служебного массива нет. Обращение к его элементам производится по их индексам — 0,1,2,...,9. В этой последовательности им соответствуют регистры FLAGS, АХ, ВХ, СХ, DX, SI, DI, BP, DSmES.
Для того чтобы сформировать в регистрах АН, AL и ВХ соответственно значения 16, 3 и 5, необходимо выполнить операторы:
REG 1,16*256 + 3
REG 2,5
Первый операнд задает номер элемента служебного массива, выделенного в качестве образа соответствующего регистра. Второй операнд представляет значение элемента массива, которое впоследствии будет занесено в выбранный регистр. Иногда заносимое в регистр значение бывает удобно задавать в виде шестнадцатеричной константы. Предыдущий пример мог бы выглядеть и так:
REG 1.&Н1003
REG 2, &Н5
Состояние тех регистров, эквивалентные области сохранения кото- 63
рых не подвергаются воздействию операторов REG, будет таким же, каким оно было в момент завершения предшествующего обращения к BIOS. Перед выполнением программы всем элементам служебного массива присваиваются нулевые значения.
Физическая пересылка содержимого области сохранения в регистры микропроцессора, осуществляется в момент исполнения оператора CALL, INTERRUPT. Единственным его аргументом является номер п функции BIOS:
CALL INTERRUPT n
После обработки прерывания с номером п содержимое выходных регистров можно опросить с помощью функции REG:
AX-REG(l)
AL-REG(l) AND &HOOFF
AH-REG(l) \ 256
К операциям умножения или целочисленного деления на 256 приходится прибегать в тех случаях, когда нас интересует содержимое старших разрядов соответствующего регистра. Для опроса младшего байта (AL, BL, CL, DL) разумнее всего использовать логическое умножение.
Quick BASIC тоже предоставляет возможность доступа к прерываниям и соответствующим процедурам BIOS с помощью следующих служебных подпрограмм:
CALL INT86OLD (п, INR, OUTR)
CALL INT86XOLD (n, IN_R, OUT_R)
CALL INTERRUPT (n, IN_REC,OUT _REC)
CALLINTERRUPTX (n, IN_REC,OUT_REC)
Здесь n — номер прерывания;
IN_R — массив, содержащий 8 или 10 (в модификации с добавлением символа X - от extended) элементов и представляющий область с входной регистровой информацией;
OUT R — массив с аналогичной структурой, предназначенный для запоминания выходного состояния регистров;
IN_REC — имя переменной типа “запись", содержащей 8 или 10 целочисленных компонент с входной регистровой информацией;
OUT_REC — запись с аналогичной структурой, предназначенная для запоминания состояния регистров на выходе из процедуры обработки прерывания.
Имена входного и выходного массивов (записей) могут, в частности, и совпадать.-•
Индексы элементов в массивах IN_R и OUT_R отсчитываются от
единицы, и их номера соответствуют следующей последовательности регистров:
Г Индекс 12345678910
I РегистрАХВХСХDXBPSIDIFlagsDSAS
Шаблон записи, тип которой приписывается параметрам IN_REC и OUT_REC, может быть описан следующим образом:
TYPE REGS
АХ AS INTEGER
ВХ AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
Flags AS INTEGER
DS AS INTEGER
AS AS INTEGER
END TYPE
DIM IN_RECAS REGS, OUT_REC AS REGS
Рассматривавшийся ранее пример в Quick-BASIC выглядел бы так:
INREC.AX - 16*256 + 3
INREC.BX-5
CALL INTERRUPT (&H10,IN_REC,OUT_REC)
AX = OUT_REC.AX
AL - OUT_REC. AX AND &H00FF
AH - OUT_REC.AX \ 256
Таким образом, единственное отличие в процедурах обращения между Turbo- и Quick-системами заключается в способах формирования и опроса содержимого регистров. Вариант, предлагаемый в Quick-BASIC, очень близок к принятому в системах программирования на базе языка “Си” и кажется нам более рациональным.
Связь с другими языками про раммир ва ия Средства общения с другими системами программирования более всего развиты в QuickBASIC. Он позволяет, например, обратиться из Бейсик-программ к подпрограммам и функциям, написанным на “Си”, Фортране или Паскале.
Ю. Л. Кетков^5
Именно поэтому в операторах объявления внешних функций и подпрограмм здесь появились указатели CDECL и ALIAS:
DECLARE FUNCTION паше [CDECL] [ALIAS “namel"] [(аргументы)]
DECLARE SUB паше [CDECL] [ALIAS "namel"] [(аргументы)]
Смысл этих указателей уже обсуждался в п. 2.3.2. Кроме того, в операторе объявления перед кажды [ формальным параметром может быть задан и способ его передачи вызываемой процедуре — по значению (BYVAL) или по относительному адресу (SEG).
Приведем несколько примеров, заимствованных из руководства фирмы “Microsoft” по межязыковому общению. В первом примере Бейсик-программа обращается к подпрограмме на “Си", не содержащей параметров и не возвращающей значение.
BASIC:С:
DECLARE SUB Pm CDECL ()void Pm ()
{} CALLPm
Во втором примере Бейсик-программа обращается к внешней функции, вычисляющей факториал и написанной на Фортране.
BASIC:FORTRAN:
DECLARE FUNCTION Fact%INTEGER*2 FUNCTION FACT (N)
(BYVAL N AS INTEGER) INTEGER*! N [VALUE]
X% - 3:Y% - 4■INTEGER*! J
PRINT Fact%(X%), Fact%(Y%)FACT-1
ENDDO!J—1,N
.FACT-FACT*J
1 CONTINUE ,RETURN
END
Третий пример демонстрирует вызов подпрограммы, написанной на Фортране. Адресация параметров, передаваемых подпрограмме, в этом примере использует двухбайтовые (короткие, близкие — NEAR) указатели.
DECLARE SUB Maxparam ALIAS “MAXPAR" (A AS INTEGER, В AS INTEGER)X%-3 : Y%-4CALL Maxparam (X%,Y%) PRINT X%,Y%ENDDECLARE SUB Maxparam ALIAS “MAXPAR" (A AS INTEGER, В AS INTEGER)X%-3 : Y%-4CALL Maxparam (X%,Y%) PRINT X%,Y%ENDSUBROUTINE MAXPAR (I,J) INTEGER*! I [NEAR] INTEGER*!! [NEAR] IFI>JTHENJ-IELSEI-JEND IFENDSUBROUTINE MAXPAR (I,J) INTEGER*! I [NEAR] INTEGER*!! [NEAR] IFI>JTHENJ-IELSEI-JEND IFEND
DECLARE SUB Maxparam ALIAS “MAXPAR" (A AS INTEGER, В AS INTEGER)
X%-3 : Y%-4
CALL Maxparam (X%,Y%) PRINT X%,Y%
END
DECLARE SUB Maxparam ALIAS “MAXPAR" (A AS INTEGER, В AS INTEGER)
X%-3 : Y%-4
CALL Maxparam (X%,Y%) PRINT X%,Y%
END
SUBROUTINE MAXPAR (I,J) INTEGER*! I [NEAR] INTEGER*!! [NEAR] IFI>JTHEN
J-I
ELSE
I-J
END IF
END
SUBROUTINE MAXPAR (I,J) INTEGER*! I [NEAR] INTEGER*!! [NEAR] IFI>JTHEN
J-I
ELSE
I-J
END IF
END
BASIC :BASIC :FORTRAN :
BASIC :
BASIC :
Программные файлы
Изначальный ввод текста программ в память ЭВМ связан с большими затратами времени из-за длительности ручного набора на клавиатуре. Набранная программа обычно содержит ошибки как синтаксического, так и алгоритм ческого характера. Придется еще изрядно потрудиться, чтобы довести ее до кондиции. Поэтому маловероятна, что за один сеанс работы с ПЭВМ можно получить качественную программу, и отелось бы максимально упростить процесс ее появления в памяти ЭВМ при повторных сеансах. Это —- первое обстоятельство, вынуждающее нас прибегать к средствам хранения текстов программ на внешних запоминающих устрой ва .
Во-вторых, ранее создававшиеся программы или их фрагменты могут быть повторно использованы прн конструировании новых программ.
Наконец, для того чтобы обмениваться программами, мы так или иначе вынуждены прибегать к услугам системных средств, обеспечивающих хранение и поддержку программных файлов.
.Запоминание программных файлов на диске
Для того чтобы сохранить текст исходной программы нг Бейсике, необходимо с терминала обратиться к соответствующей компоненте той или иной системы программирования. Эти возможности подробно обсуждаются в главах 7 — 9.
Текст программы, сформированной в машинных командах, запоминается на диске с помощью оператора BSAVE:
BSAVE “file_spec”,Address,l
Здесь file spec — полная или сокращенная спецификация дискового файла, записанная в соответствии с правилами MS DOS. Начальный адрес запоминаемой программы задается в виде смещения Address относительно начала сегмента, установленного предшествующим оператором DEF SEG. Длина сохраняемой программы 1 задается в байтах (0<-1 <—65535).
Загрузка дисковых файлов
Кроме средств первоначальной загрузки исходной программы, ко- торымифа полагает каждая Бейсик-система (они подробно обсуждаются в главах 7 — 9), для считывания программного файла : диска в оперативную память можно прибегнуть к операторам LOAD, BLOAD и RUN.
Первый из них можно использовать только в рамках GW-системы:
LOAD *“file_spec” [,R]
Он дает возможность загрузить указанный программный файл и даже передать ему управление для запуска на счет, если задан второй операнд — символ “R”. В последнем случае сохраняются значения всех переменных текущей программы и состояние всех открытых ею файлов. Это обстоятельство обеспечивает передачу информации от вызывающей программы вновь загружаемому файлу.
В Quick- и Turbo-системах загрузка программного файла выполняется оператором RUN:
RUN “fiiespec”
В отличие от оператора LOAD текущая программа и значения ее переменных при этом не сохраняются.
Для загрузки программ, написанных в машинных командах, предназначен оператор BLOAD:
BLOAD “file_spec” [.Address]
Начальный адрес оперативной памяти, начиная с которого располагается считываемая программа, формируется из смещения Address с учетом базового адреса сегмента, установленного предшествующим оператором DEF SEG.
Подключение файлов к текущей программе
В отличие от процедуры загрузки подключение программного файла происходит без уничтожения текста текущей программы. Таким образом, осуществляется объединение нескольких программных модулей или заблаговременно подготовленных заготовок.
В GW-BASIC слияние текущей программы с дисковым файлом осуществляется по оператору MERGE:
MERGE “file_spec”
При этом следует учитывать, что номера программных строк вызываемого файла могут совпадать с номерами строк текущей программы. В таком случае вновь вызываемые строки будут затирать своих предшественников.
Quick-BASIC и Turbo-BASIC для подключения дисковых файлов используют сходные метаоператоры $INCLUDE:
Quick:REM $INCLUDE “file_spec”
Turbo:$INCLUDE “file_spec”
Обычно такие метаоператоры располагаются в самом начале программы. В Turbo-системе подключаемые дисковые файлы иногда снабжают расширением .INC, однако по умолчанию система добавит к неполной спецификации файла стандартное расширение .BAS.
4. Выполнение цепочки программных файлов
В большинстве систем программирования, базирующихся на алгоритмических языках высокого уровня, существует возможность использовать внешние процедуры, вызывая их при каждом обращении из соответствующего участка дисковой памяти и занимая место в оперативной памяти под процедуру только на время ее выполнения. Поскольку в одном и том же участке оперативной памяти моту т последовательно располагаться разные подпрограммы, то принято говорить о наложении одного программного модуля на другой или о программах с так называемой оверлейной структурой.
Некоторую аналогию с этой организацией программ можно усмотреть в возможности увязать в цепочку последовательность Бейсик - программ, выполняющихся друг за другом и передающих совместно используемые данные своему соседу по цепочке. Такой подход позволяет построить крупный программный комплекс, целиком не помещающийся в оперативной памяти.
Вызов следующей по цепочке программы осуществляется с помощью оператора CHAIN:
GW: CHAIN [ MERGE ] “fiie_spec" [, [ N ] [ ALL ] [ .DELETE N1-N2 ]] ]
Quick,Turbo: CHAIN “file_spec”
Служебное слово MERGE означает, что вызываемый файл объединяется (сливается) с текущей программой. При этом имеется возможность предварительно удалить фрагмент текущей программы, начиная со строки с номером N1 и до строки с номером N2 включительно. Параметр ALL означает, что должны быть сохранены значения всех переменных текущей программы, а не только те переменные, которые соседи по цепочке “договорились” разместить в общей памяти (COMMON). Задание номера строки N после спецификации вызываемого файла позволяет передать управление в указанную точку сформированной программы. Если номер N не задан, то в качестве продолжения выбирается оператор, следующий за CHAIN.
Взаимодействие с файловой системой MS DOS
Работа с программными файлами в конечном итоге реализуется с помощью соответствующих компонент операционной системы MS DOS. Поэтому кроме перечисленных выше операторов в состав входного языка Quick- и Turbo-систем дополнительно включен ряд операторов, позволяющих в процессе выполнения Бейсик-программ изменять текущий каталог, выводить оглавления существующих директорий, создавать новые оглавления, переименовывать или уничтожать файлы. Формат этих операторов максимально приближен к структуре одноименных директив операционной системы.
Формат оператораCHDIR path_specFILES [file_mask]KILL file_specKILL file_maskMKDIR path_specNAME oidjname AS new_nameRMDIR path_specФормат оператораCHDIR path_specFILES [file_mask]KILL file_specKILL file_maskMKDIR path_specNAME oidjname AS new_nameRMDIR path_specВыполняемая функция
Формат оператора
CHDIR path_spec
FILES [file_mask]
KILL file_spec
KILL file_mask
MKDIR path_spec
NAME oidjname AS new_name
RMDIR path_spec
Формат оператора
CHDIR path_spec
FILES [file_mask]
KILL file_spec
KILL file_mask
MKDIR path_spec
NAME oidjname AS new_name
RMDIR path_spec
Изменение текущей директории
Вывод имен файлов текущей директории, спецификация которых удовлетворяет заданной маске Удаление указанного файла из текущей директории
Удаление всех файлов текущей директории, спецификации которых удовлетворяют заданной маске
Создание нового оглавления
Переименование файла
Удаление указанного оглавления
В GW-BASIC аналогичные процедуры можно выполнить с помощью
одноименных директив Бейсик-системы.
Взаимосвязь по данным междупрограммными модулями
Способы управления памятью, влияющие на распределение переменных (массивов) и возможность доступа к ним из разных программных модулей, в той или иной мере уже описывались в соответствующих параграфах глав 1 и 2. Цель настоящего параграфа собрать воедино разрозненную информаци и обсудить ее с общих позиций.
Локальные и глобальные переменные
Для ранних Бейсик-систем (в том числе и для GW-BASIC) было характерно использование только глобальных переменных, действие которых распространялось на всю программу, представленную единственным модулем.
С появлением внешних программных единиц разделились и зоны действия переменных. Те переме ные, область влияния которых ограничивается только тем модулем, где они были объявлены, называются локальными. В отличие от них в программах могут использоваться и другие переменные, предназначенные для межмодульного общения.
В различных языках программирования приняты два подхода к введению переменных совместного пользования. В одних системах модуль объявляет некоторые свои переменные (массивы) доступными для других программных единиц. На языке ассемблера, например, для этой цели используется оператор ENTRY, в теле которого перечисляются входные идентификаторы. Другие модули, в которых эти объекты используются с целью обмена информацией, объявляют такие идентификаторы внешними (EXTERN). Характерной особенностью этого подхода является то, что совместно используемые переменные (массивы) имеют одинаковые имена как в модуле владельце, так и в вызываемых процедурах. Это не всегда удобно, так как при подключении к своей программе чужого модуля приходится согласовывать идентификаторы совместно используемых данных.
Второй подход, развивавшийся в рамках Фортрана, базируется на выделении одной или нескольких областей (блоков) общей памяти, расположенных за пределами программной единицы. Два модуля, использующие совместные данные, “договариваются” между собой об идентификаторе общего блока памяти, и каждый из них “просит” систему поместить в эту область общие переменные (массивы). Каждый из них может называть такие объекты по-своему, но порядок расположения общих данных и их типы между партнерами должны быть согласованы. -
В Quick- и Turbo-системах нашли отражение оба подхода. Переменные головной программы, используемые одновременно и во внешней процедуре без их передачи в качестве фактических параметров, носят название разделяемых объектов. Объявляются они только в теле внешней подпрограммы или функции с помощью оператора SHARED:
Turbo: SHARED VI [О], V2 [О],...
Quick': SHARED VI [0] AS typel, V2 [0] AS type2,.„
Для вынесения переменных в общую память используется оператор COMMON, форматы которого в наших системах несколько отличаются :
GW: COMMON VI [О], V2[0] ....
Turbo: COMMON VI [(nl)], V2[(n2)J....
Quick /COMMON [SHARED] [/name_block/J
VI [(indll,...)] [AS typel],
V2[(ind21,...)] [AS type2],...
Общие переменные в GW-системе используются для передачи данных следующей по цепочке программе (см. оператор CHAIN).
В Turbo-BASIC оператором COMMON могут дополнительно пользоваться и внешние подпрограммы. Целое число п, указываемое в круглых скобках после имени массива, задает количество.индексов. Верхнюю и нижнюю границы каждого из них подпрограмма может опросить с помощью функций LBOUND и UBOUND.
Ближе всего к Фортрану находится формат оператора COMMON, реализованный в Quick-BASIC. Если в двух предыдущих системах взаимодействующие программные единицы используют одну-единст- венную область внешней памяти (так называемый непоименованный блок), то входной язык Quick-BASIC предоставляет возможность иметь любое количество общих блоков. Идентификатор общего блока (name_block) может содержать до 40 символов. Дополнительное служебное слово SHARED означает, что общие переменные, указанные в списке оператора COMMON, доступны для всех процедур модуля. Непоименованный блок общей памяти в Quick-системе используется, как и в двух других, для общения программ, вызываемых по цепочке.
Локальные переменные и массивы, доступные только в текущей процедуре или в пределах многостроковой внутренней функции, объявляются в Turbo-BASIC с помощью оператора LOCAL:
LOCAL V1,V2,...
Память под локальные переменные выделяется только на время 72
выполнения процедуры. Поэтому объекты, перечисленные в теле оператора LOCAL, не могут встречаться в операторах SHARED и STATIC.
Статическое и динамическое распределение памяти
В системах Quick- и Turbo-BASIC предусмотрены две возможности для распределения оперативной памяти под локальные переменные и массивы.
В первом случае память выделяется на стадии компиляции и закрепляется за переменными (массивами) на весь период выполнения программы. Такие объекты принято называть статическими. Если статическая переменная принадлежит внешней процедуре, то ее значение сохраняется между двумя последовательными обращениями к процедуре. Этим обстоятельством можно пользоваться для запоминания некоторых промежуточных данных без опасения, что какой-то другой модуль может что-то испортить..
Второй вариант распределения памяти под переменные и массивы заключается в том, что необходимые ресурсы выделяются во время выполнения соответствующего модуля и сразу же освобождаются перед возвратом в вызывающую пре • ^амму. Такой способ носит название динамического. Он позволяет более экономно расходовать оперативную память, особенно в тех случаях, когда речь идет о массивах большого размера. Однако динамическое выделение и освобождение ресурсов памяти связано с дополнительными затратами машинного времени.
В системе Turbo-BASIC приняты следующие соглашения:
под одиночные (скалярные) переменные память выделяется динамически только в тех случаях, когда они описаны с помощью оператора LOCAL;
массивы с переменными границами, массивы, отнесенные к общей памяти (COMMON), и локальные (LOCAL) массивы процедур распределяются только динамически;
по умолчанию под массивы с фиксированными границами память выделяется статически.-
Последнее правило умолчания для массивов может быть изменено, если перед соответствующей процедурой поместить метаоператор $DYNAMIC. Отменить его действие для других процедур можно с помощью метаоператора$8ТАТ1С.
Конкретны" массив, объявляемый с помощью оператора DIM, можно явно описать как статический или динамический, включив $ состав оператора один из указателей STATIC или DYNAMIC:
DIM STATIC A(50)
DIM DYNAMIC В (30)
В Quick-системе no умолчанию все локальные переменные внешней процедуры распределяются динамически. Чтобы перейти к статическому выделению памяти, в заголовке процедуры добавляется указатель STATIC (см. операторы SUB и FUNCTION). Пользователю Quick-системы доступен и метаоператор $STATIC, имеющий тот же смысл, что и в Turbo-системе.
Обе системы допускают явное описание статических переменных в теле подпрограмм и функций:
Turbo: STATIC VI [()] V2[O],...
Quick: ^JATIC Vl[0] [AStypel], V2[0] [AS type2],...
ОРГАНИЗАЦИЯ МАТЕМАТИЧЕСКИХВЫЧИСЛЕНИЙ
Способы формирования и изменения значенийчисловых переменных
Исходные данные, промежуточные и окончательные результаты вычислений составляют тот набор значений, которые приходится размещать и в течение некоторого времени хранить в соответствующих переменных.
Для формирования заранее известных значений в числовых пере - менных обычно прибегают к процедуре ввода нужной информации, которая может быть прочитана из буфера клавиатуры, из файла данных, расположенного на гибком или жестком магнитном диске, из блока данных, предварительно сформированного в оперативной памяти.
‘Если значение переменной должно быть получено в результате вычисления по арифметической формуле, то его запись в обла сть оперативной памяти, выделенную для хранения переменной, производится с помощью оператора присвоения.
Использование внутренних блоков данных
Блок числовых данных можно представить себе как одномерный массив, расположенный в оперативной памяти. Последнее обстоятельство является основанием назвать этот блок внутренним. Запоминание указанного массива ведется в процессе предварительной обработки текста исходной программы до ее запуска на счет. Как только в программе встречается оператор DATA, то все константы, перечисленные в его теле, переносятся в специально отведенную область памяти. Порядок их размещения в блоке данных в точности повторяет порядок их следования в списке оператора DATA:
DATA cl,c2,.„.
Первая константа cl становится первым элементом блока данных, вторая константа с2 — вторым элементом и т.д.
В программе может встретиться не один оператор DATA, и тогда очередная числовая порция заносится в блок данных вслед за предшествующей. Порядок переноса таких порций соответствует последовательности расположения операторов DATA в тексте программы. Сформированный таким образом блок данных может быть использован в качестве поставщика числовых значений переменных арифметического типа во время выполнения программы. Сами же операторы DATA относятся к декларативным, и во время работы программы их обходят. Характерной особенностью блока данных является последовательный доступ к его элементам. В момент запуска программы на счет в cdtro ние готовности приводится числовое значение, которое попало в блок данных первым. Иными словами, это - первая ко станта самого первого оператора DATA. После выборки этого значения доступной гановится следующая константа и т.д.
Для извлечения числовых значений из блока данных предназначен оператор. READ:
READ V1,V2,.„
Он последовательно удовлетворяет переменные всего списка, извлекая очередное доступное значение из блока данных и перемещая его в область памяти, отведенную для хранения переменной. Выполнение этой процедуры при необходимости может сопровождаться преобразованием машинного формата числовой константы к тому виду, который соответствует типу переменной.
Попытка извлечь из блока данных хотя бы еще одно значение после того, как уже была прочитана последняя константа, расценивается как ошибка периода выполнения и приводит к аварийному завершению рограммы
Третьим оператором, который участвует в обслуживании блока данных, является оператор RESTORE:
RESTORE [N]
Без операнда N этот оператор привод т блок данных в первоначальное состояние, при котором очередным доступным значением становится самая первая константа. Если операнд задан, то в GW BASIC им может быть номер программной строки, в которой находится оператор DATA, а в двух других версиях вместо числового номера может быть
76
задана метка аналогичной строки. После выполнения такого оператора RESTORE очередным доступным значением становится первая константа числовой порции указанного оператора DATA.
Оператор RESTORE может быть применен на любой стадии “опустошения” блока данных, даже если мы из блока данных еще ни одного значения и не извлекали.
Ввод данных по запросу программы
Требование на ввод данных с клавиатуры или из файла последовательного доступа реализуется путем включения в программу оператора INPUT:..
INPUT [;] |"texf {;l,}] V1,V2,...
INPUT #n, VI ,V2,„.
Здесь text — произвольный текст, который в случае ввода с клавиатуры выдается на терминал и играет роль подсказки для пользователя;
VI ,V2... — список переменных, которым присваиваются вводимые значения;
п — номер файла с последовательным доступом, из которого должна быть считана очередная порция данных.
В связи с тем, что процедуры обмена с файлами более подробно описываются в главе 5, мы остановимся здесь только на деталях ввода данных с клавиатуры.
Выполнение оператора INPUT начинается с приостанова работы программы. В этот момент на экране дисплея появляется сообщение, заданное параметром text, вслед за которым в этой же строке или в начале следующей возникает вопросительный знак. Позиция, в которой появляется символ “?”, зависит от наличия или отсутствия символа “:” сразу после наименования оператора. Если тело оператора начинается с точки с за ятой, то вопрос появляется в той же строке, что и подсказка text. Если в качестве разделителя, стоящего вслед за параметром text, используется запятая, то выдача вопросительного знака отменяется.
После появления на экране указанного приглашения пользователь должен набрать необходимое количество числовых значений, разделяя их запятыми. Набор последнего числа завершается нажатием клавиши Enter. В системе Turbo-BASIC в качестве разделителя можно использовать и пробел. Если количество данных не соответствует длине списка переменных, то GW- и Quick-системы реагируют одинаково. Они выдают повторное приглашение:
TReado from start
Теперь ввод данных придется начать заново. Эта же ситуация возникнет и в том случае, если произведен набор недопустимой числовой константы (число содержит нечисловые символы, выходит за пределы допустимого диапазона и т.д.).
В Turbo-системе количество вводимых данных может не совпадать с длиной списка переменных. Липшие данные будут проигнорированы, а в случае нехватки числовых данных оставшимся переменным присвоятся нулевые значения.
Изменение значений переменныхпо результатам вычислений
Засылка значения арифметического выражения в область, выделенную для хранения числовой переменной, носит название процедуры присваивания и реализуется с помощью оператора присваивания:
[LET] v-e
Слева от знака равенства указывается идентификатор скалярной переменной или элемента массива, а справа — любое арифметическое выражение. Наименование оператора (LET) можно ие писать, и это - единственный оператор в Бейсике, который может начинаться не со служебного слова.
(Допускается, чтобы типы числовой переменной V и арифметического выражения е не совпадали] В этом случае система осуществляет автоматическое преобразование числового значения из одного формата предст вления в другой. Никаких округлений при этом не происходит. Для того чтобы округлить результат вычислений по общепринятым в математике правилам, можно воспользоваться соответствующей функцией преобразования типов данных — CINT, CLNG, CSNG, CDBL (см. п. 1.2.6),
Кроме оператора присваив ния в Бейсике существует оператор SWAP, позволяющий двум переменным одного типа обменяться своими значен ями;
SWAP VI, V2
Таким образом, один оператор SWAP заменяет три оператора LET, использующих для этой же цели еще и вспомогательную переменную V3;
LET V3-V1
LET VI-V2
LET V2-V3
Turbo-BASIC предлагает еще два оператора, с помощью которых можно увеличить (INCR) или уменьшить (DECR) значение переменной V на заданную величину dV. По умолчанию величина приращения считается равной :
INCR V эквивалентно LETV-V+1
INCR V,dV эквивалентно LETV-V + dV
DECR V эквивалентно LETV-V-1
DECR V.dV эквивалентно LETV-V-dV
Стандартные математические функции
Перечень математических функций, которые можно использовать в качестве операндов арифметических выражений, приведен ниже. В большинстве случаев наименование функции совпадает с ее общепринятым математическим обозначением. Однако некоторые детали нуждаются в комментариях.
ФункцияНазначение
ABS (X)Вычисление модуля 1X1
ATN (X)Вычисление арктангенса arctg(X)
CEIL (X)Нахождение ближайшего целого, превосходящего X
COS (X)Вычислениекос нуса cos(X)
EXP (X)ВычислениеэкспонентыеАХ
ЕХР10 (X)Вычисление экспоненты И^Х
ЕХР2 (X)Вычислениеэкспоненты2АХ
FIX (X)Выделение целой части X
INT (X)Нахожде ие ближайшего целого, не превосходящего X
LOG (X)Вычисление натурального логарифма 1п(Х)
LOGIC (X) Вычисление десятичного логарифма 0| (X) LOG2 (X)Вычисление двоичного логарифма or X
RND [ (X) ] Генерация очередного случайного числа SGN (X)Определение знака X:
SGN(X) --1, если Х< О
SIN (X)SQR (X)TAN (X)SIN (X)SQR (X)TAN (X)SGN(0)-0 8СМ(Х)-+1,еслиХ >0
SIN (X)
SQR (X)
TAN (X)
SIN (X)
SQR (X)
TAN (X)
Выч сление синуса sin (X)
Извлечение квадратного корня из X
Вычисление тангенса if (X)
Первое обстоятельство связано с точностью вычисления зна ения Функции. В GW-BASIC точность устанавливается в м мент запуска системы (см. главу 7) Поэтому все стандартные функции выдают свои
значения либо с одинарной точностью, либо с удвоенной. В Turbo-системе вычисления значений всех функций ведутся с удвоенной точностью, а лишние значащие цифры могут быть отброшены в момент присваивания или вывода. Система Quick-BASIC подстраивает точность вычисления функции под тип аргумента. Если последний имеет удвоенную точность, то с таким же количеством значащих цифр выдается и значение функции.
Аргументом математических функций может быть арифметическое выражение любого числового типа. Для тригонометрических функций типа SIN, COS и TAN аргумент задается в радианах. Результат вычисления обратной тригонометрической функции ATN также выдается в радианах.
Аргумент функций LOG, LOG10 и LOG2 должен быть положительным. Это же относится и к функции SQR, однако квадратный корень из нуля извлечь можно.
Функции CEIL, FIX и INT используются для манипуляций над вещественными аргументами, в результате которых можно выделить целую или дробную части числа, произвести его округление в нужном разряде. Продемонстрируем эти возможности на конкретных примерах : * .
INT(l.l) —1 CEIL (1.1)-2
INT (1.9)-1 CEIL (1.9)-2
INT (-1.1)--2 CEIL (-1.1)--1
INT (-1.9)--2 CEIL (-1.9)--!
INT (1.1+0.5) -1 INT (-1.1+0.5)--1
INT (1.9+ 0.5)-2 INT (-1.9+ 0.5)--2
INT(1.481 * 100 + 0.5) / 100-1.480 INT(-1.481 * 100 + 0.5) / 100--1.480 INT(1.486* 100 + 0.5) /100-1.490 INT(-1.486* 100 + 0.5) / 100--1.490
Функция RND вызывает служебную подпрограмму, генерирующую очередное случайное число из интервала (0,1). Ее алгоритм предусматривает выдачу чисел с равномерным законом распределения и в зависимости от знака аргумента X позволяет:
выдать очередное случайное число (при X > 0);
повторить выдачу предыдущего “случайного” числа (при X = 0);
начать цикл генерации “случайных" чисел заново (при X < 0). Эта функция является уникальной в том смысле, что ее можно употребить и без аргумента:
Y-INT (RND* (К+1))
В этом случае она действует точно так же, как и с положительным аргументом Кстати, приведенный пример демонстрирует возможность получать целые случайные числа из диапазона [О, К ].
Любой запрограммированный алгоритм генерации случайных чисел имеет вполне определенный цикл, после прохождения которого полученный ряд “случайных” чисел повторяется. Обычно в таких программах в качестве стартовых исходных данных используют одну или две константы, и если в алгоритм не вносить никаких изменений, то очередной запуск датчика случайных чисел будет повторять те же самые значения, которые получались и раньше. Таким образом, распечатав один раз эту цепочку или ее начало, в следующий раз мы сможем точно предсказать очередное случайное число.
При отладке программы, использующей датчик случайных чисел, возможность повторить прохождение программы на одном и том же наборе данных полезна. Однако во время эксплуатации такой программы возможность предсказать очередное “случайное” событие вряд ли кого обрадует. Поэтому входной язык предоставляет пользователю средство “возмутить” стартовые константы таким образом, чтобы и само возмущение тоже носило достаточно случайный характер. Достигается это путем включения в программу оператора RANDOMIZE:
RANDOMIZE
RANDOMIZE е%
RANDOMIZE TIMER
В случае отсутствия аргумента система обратится к пользователю с просьбой ввести целое число из диапазона [-32768,32767 ]. Это число, или заданное значение арифметического выражения е% , или показатель таймера используются для перенастройки текущих параметров датчика случайных чисел. После выполнения оператора RANDOMIZE функция RND начинает выдавать числа, которые с гораздо большим основанием можно называть случайными.
Очень интересный пример перенастройки генератора случайных чисел для игровых программ приведен в руководстве по TurboBASIC:
MTIMER
PRINT “Для начала игры нажмите любую клавишу”
WHILE NOT INSTAT: WEND -
RANDOMIZE MTIMER
Первая строка сбрасывает микротаймер Turbo-системы, после чего он начинает отсчет времени до момента нажатия любой клавиши.
Индикатором последнего события служит появление отличного от нуля значения в системной переменной INSTAT. Таким образом, стартовая величина, влияющая на выработку первого случайного значения, зависит от реакции пользователя.
Вывод результатов вычислений
Результаты вычислений, предназначенные для визуального контроля за ходом решения задачи, выдаются на экран дисплея с помощью одного из операторов PRINT или PRINT USING. Если итоговые результаты предназначены для включения в состав отчетной документации, то. для их оформления используются операторы LPRINT или LPRINT USING, осуществляющие вывод данных на принтер.
Выводимая числовая информация может сопровождаться различными пояснительными текстами, которые либо заготавливаются заранее, либо формируются в процессе выполнения программы.
Отображению числовых данных на дисплее могут предшествовать стирание прежнего содержимого экрана и позиционирование курсора. Первая процедура выполняется с помощью оператора CLS. Для перевода курсора в позицию экрана, с которой начнет отображаться выводимая информация, используется оператор LOCATE:
LOCATE [ nr ] [, [ nc ] [,Щ, [ start ] [.stop ] ] ]
Здесь nr — номер строки (от 1 до 25);
nc — номер столбца (от 1 до 80);
I — признак видимости 0-1) или невидимости (Н)) курсора;
start — номер начальной строки в мини-растре знакоместа;
stop — номер конечной строки в мини-растре знакоместа.
Два последних параметра управляют габаритами курсора и его расположением в знакоместе г прямоугольной области экрана, отводимой для размещения одного символа. В зависимости от типа дисплея и установленного режима его работы знакоместо представлено матрицей точек размером 8x8, 8x14 или 8x16.
В GW и Quick BASIC имеется возможность разделить экран на две или три горизонтальные полосы, в одной из которых выводится текстовая информация, а в оставшейся части экрана — графическая. Указание границ текстового экрана осуществляется с помощью оператора VIEW PRINT:
VIEWPRINT rlT0r2
При этом вывод числовых и символьных данных будет происходить в окне, начиная со строки rl и кончая строкой г2.
Вывод числовых данных по стандартному формату
Стандартный формат вывода предполагает, что текущая строка на дисплее или принтере, предназначенная для отображения числовой информации, разделена на зоны длиной по 14 позиций. Всего таких зон шесть, но на последнюю зону остается всего 10 позиций.
Вывод по стандартному формату организуется с помощью оператора PRINT или LPRINT:
PRINT [al{;l,l }а2{;1,1 }...]
LPRINT [al{;l,l }а2{;1,1 }...]
В качестве элементов выводного списка а1,а2,... могут выступать арифметические выражения любого типа, текстовые константы или редактирующие указатели. Каждый элемент выводного списка завершается символом-разделителем, в качестве которого можно использовать запятую, точку с запятой, пробел или один из двух признаков конца оператора — двоеточие или управляющий символ “возврат каретки”.
Во время выполнения оператора PRINT (LPRINT) значениячисло- вых выражений или текстовых констант переносятся в выводную строку. Лажным элементом этого процесса является специальный системный указатель, который “смотрит” на очередную свободную позицию выводной строки и по мере ее заполнения перемещается вправо. Его поведение напоминает перемещения курсора на экране дисплея во время набора строки или пишущего узла принтера во время вывода.
В момент запуска программы выводная строка заполнена пробелами, а указатель смотрит на первую позицию, т.е. на самую левую позицию первой зоны. Если вывод начинается с числового элемента, то начальная позиция рассматривается как знаковая и заполняется пробелом для положительного значения. После переноса отображаемого числа указатель перемещается на ближайшую справа свободную позицию выводной строки. На дальнейшее перемещение указателя влияет символ-разделитель, расположенный вслед за обработанным числовым значением.
Если им оказалась запятая, то указатель переводится в первую позицию следующей зоны выводной строки. Именно отсюда и будет Расположено значение очередного элемента выводного списка. Если правее текущего положения указателя не осталось ни одной зоны, то
83
Заполненная выводная строка отображается на дисплее или принтере. После этого строка чистится, а указатель возвращается в ее начальную позицию.
Если в качестве разделителя была использована точка с запятой или пробел, то после переноса числового значения указатель выводной строки перемещается вправо дополнительно на одну позицию. Таким образом, между двумя смежными значениями на выводе образуется только один пробел. Точка с запятой после текстовой константы к дополнительному сдвигу указателя не приводит.
В случае когда значение очередного элемента списка оператора PRINT (LPRINT) не помещается в оставшейся части строки, текущее содержимое выводной строки отображается на экране дисплея (принтере) , и вывод продолжается с начальной позиции следующей строки. „
Если очередной элемент списка завершается признаком конца оператора, то выводная строка отображается независимо от степени ее заполнения и приводится в свое первоначальное состояние.
Указатель можно переместить в произвольную позицию выводной строки с номером п (0 < п < 81), расположенную справа от текущего положения указателя. Осуществляется это путем включения редактирующей функции ТАВ(п) в качестве элемента выводного списка:
PRINT TAB (5), “X-”; X, TAB (30); “SIN(X)-"; SIN(X)
Знак препинания после функции ТАВ(п) не вызывает никакого дополнительного перемещения указателя и может вообще отсутствовать.
Если элементом выводного списка оказывается другая редактирующая функция SPC(n), то п позиций выводной строки, начиная с текущего положения указателя, заполняются пробелами. В каком- то смысле функции ТАВ (п) и SPC (п) приводят к одинаковому результату, только в первом случае отсчет позиций выводной строки осуществляется в абсолютных единицах, а во втором — в относительных.
Если последний элемент выводного списка завершается запятой, точкой с запятой, функциями SPC или ТАВ, то следующий оператор PRINT (LPRINT) продолжит вывод в той же строке с позиции, в которой находится указатель.
Физически реализация вывода на дисплей или принтер носит несколько иной характер, нежели описанная выше технология переноса данных в выводную строку. Оба эти устройства располагают буферной памятью с принципиально разными схемами управления. Запись информации в буферную память дисплея (видеопамять) сопровождается
84
мгновенным появлением выводимых данных на экране дисплея. В отличие от этого принтер — устройство гораздо более медленное, и выводимая информация сначала накапливается в его буфере, а уж потом из ЭВМ поступит команда на отображение содержимого буфера. Исключая мелкие технические детали, буфер принтера можно рассматривать как физический эквивалент выводной строки. У него действительно есть аналог указателя, позицию которого можно опросить с помощью функции LPOS(n). В GW BASIC аргумент функции носит фиктивный характер, тогда как в двух других системах он задает номер опрашиваемого принтера (п-1,2,3).
Бейсик-системы оперируют с выводной строкой, длина которой по умолчанию равна 80 позициям. С помощью оператора WIDTH длину строки можно изменить.
Для дисплея эта процедура выполняется следующим образом:
WIDTH [nc][,nr]
Здесь пс — количество столбцов, которое может принимать значение 40 или 80;
пг — количество строк, которое в зависимости от типа дисплея может быть равно 25,30,43,50 или 60 (по умолчанию пг - 25).
Уменьшение количества столбцов до 40 сопровождается увеличением ширины символов примерно вдвое, так как физические размеры экрана при этом не меняются.
Для принтера длина выводной строки изменяется одним из следующих операторов:
WIDTH LPRINT, ПС WIDTH “LPTl:”,nc WIDTH “LPT2:”, пс WIDTH “LPT3:", пс
Количество позиций в строке выбирается в зависимости от технических ограничений принтера - ширины бумаги, типа установленного или загруженного шрифта.
Стандартный формат печати числовых данных автоматически учитывает тип и величину значения элемента списка. Во всех трех системах целочисленные значения, принадлежащие соответствующему диапазону, выдаются в формате целых чисел. Для вещественных значений с одинарной и удвоенной точностью формат вывода в каждой из систем имеет свои особенности.
В GW-системе для числовых значений с одинарной точностью действует следующее правило. Если количество значащих цифр, включая
85
лидирующие нули в дробном числе, не превышает семи, то используется формат вывода с фиксированной точкой. В противном случае вещественное число выводится в формате с плавающей точкой:
-b.bbb...E+pp
И в том, и в другом случае количество выводимых значащих цифр не превышает семи (незначащие нули в хвосте числа подавляются). Для вещественных значений с удвоенной точностью, выводимых с фиксированной точкой, количество значащих цифр может достигать , 16. В формате с плавающей точкой указатель порядка “Е” заменяется символом “D”.
Очень похожие правила вывода числовых значений приняты и в Quick-BASIC. Некоторые расхождения в точности выводимых значений объясняются разными способами хранения числовых данных в GW и Quick-системах.
В Turbo-системе вещественные значения с одинарной точностью, принадлежащие диапазону [0.1, 1Е15 ], выводятся в формате с фиксированной точкой и могут содержать до 16 значащих цифр, из которых верными являются только семь. В остальных случаях вещественные ’числа выводятся в формате с плавающей точкой и содержат 16 значащих цифр, из которых доверять можно только первым семи:
-b.bbbbbbbbbbbbbbbE+ppp
Для вещественных чисел удвоенной точности в Turbo-BASIC используются аналогичные форматы, но доверять уже можно 16—17 значащим цифрам.
Следует обратить внимание на один важный нюанс, связанный с выводом текстовой информации, содержащей русские буквы. Так называемая “русификация”дисплея и принтера выполняется разными программно-техническими средствами. Их необходимо задействовать, прежде чем начать сеанс работы с Бейсиком. Особенно важно проследить за принтером, так как его “русификация” иногда выполняется путем программной загрузки шрифта в буферную память, ко. торая стирается при отключении питания.
Потоковый вывод данных
В отличие от описанного выше зонного расположения данных в выводной строке имеется возможность сгруппировать отображаемую информацию в виде потока или списка значений. Два смежных значения в таком списке разделяются запятой, а текстовые величины в
86
дополнение к тому окаймляются кавычками. Завершается выводная строка управляющими символами CR ("возврат каретки") и LF ("новая строка").
Поток данных, состоящий из строк описанной структуры, формируется операторами WRITE:
WRITE al,a2, ...
Элементами выводного списка здесь могут быть любые выражения арифметического или символьного типов.
К выводу потока на экран дисплея прибегают крайне редко. Гораздо чаще операторами WRITE пользуются для вывода данных на внешние запоминающие устройства, откуда их можно извлекать подобно тому, как считываются значения из списка оператора DATA.
Использование нестандартного форматапри выводе результатов вычислении
Зонный формат вывода числовой информации не позволяет получать качественные документы в форме привычных таблиц из-за того, что отображаемы значения прижимаются к левой границе зоны. При этом одноименные разряды данных, расположенных в одной колонке, оказываются смещенными; разброс значений нарушает однообразие в формате представления чисел, отображение слишком большого количества цифр приводит к захвату смежной зоны и искривлению колонок таблицы.
Нестандартный формат вывода, задаваемый пользователем, дает ему возможность самому решать, в каком месте выводной строки разместить то или иное числовое значение, сколько цифр должно быть отведено в целой и дробной частях, следует ли сопровождать отображаемое число знаком плюс и где его расположить, подавлять или не подавлять в выводимом значении лидирующие нули и т.п. С этой целью нестандартная структура выводной строки описывается при помощи шаблона, задаваемого в теле оператора PRINT (LPRINT) USING:
. PRINTUSING {с$ I е$ }; al, а2,...
LPRINTUSING {с$ I е$ }, al, а2,...
Выводная строка при этом представляется как последовательность полей, предназначенных для размещения информации трех типов:
значений числовых выражений, являющихся элементами выводного списка (числовые поля);
значений символьных выражений, являющихся элементами выводного списка (символьные поля);
произвольных текстовых констант, включенных в состав шаблона между описаниями числовых и символьных полей (литеральные поля). -
Как । равило, каждый символ шаблона, заданного значением символьной константы с$ или символьного выражения е$, соответствует одной позиции выводной строки.
Для описания структуры числовых полей в шаблоне применяется следующий набор символов: ""
- ^ + - * $ , _
Знакномера (#) обозначает цифровую позицию, которая в случае необходимости может быть заполнена пробелом, знаком числа, знаком денежной единицы ($) или звездочкой (*).
Точка в описании числового поля задает позицию десятичной точки, отделяющей целую часть числа от дробной. Например, шаблон вида “#####” задает описание поля, отводимого под целочисленное значение, тогда как шаблон “##.###” предусматривает вывод числа с тремя цифрами в дробной части.
Четыре подряд идущих знака возведения в степень (АААА). определяют местоположение порядка числа (Е+рр или D-pp) в случае выбора формата с плавающей точкой. Например:
PRINT USING “###.###АААА”;-12345 “* -12.345Е403
Знак плюс заставляет систему выводить символ “+” у положительного числа вместо заполнения соответствующей позиции пробелом. Знаки плюс или минус могут находиться как в начале описания числового поля, так и в конце. В первом случае знак числа выводится перед старшей значащей цифрой числа или перед десятичной точкой, если число чисто дробное. Во втором случае — в самой правой позиции поля.
Две звездочки, расположенные в начале описания числового поля, приводят к заполнению символом “* ” лидирующих нулей. Обычно же такие нули подавляются пробелами.
Комбинация $$ в начале шаблона числового поля вызывает появление знака денежной единицы перед старшей значащей цифрой числа. Сочетание **$ в первых трех позициях шаблона указывает на необходимость заполнения звездочками лидирующих нулей и вывода знака доллара перед старшей значащей цифрой.
88
Запятая в описании числового поля используется для придания большей наглядности отображаемому значению:
PRINT USING “#,###,###”; 1Е6 -» 1,000,000
Значение арифметического выражения округляется, преобразуется к формату, заданному описанием числового поля, и размещается на соответствующих позициях выводной строки с прижимом к правой границе поля. Это обеспечивает необходимую стройность при выводе табличных документов.
^4ожет оказаться, что количество знаков в выводимом значении превышает число позиций, содержащихся в описании соответствующего числового поля. Тогда в выводной строке резервируется необходимое количество дополнительных позиций и перед отображаемым значением помещается знак процента:
PRINT USING “.##”; 0.999"» %1.00
В качестве описателя текстовно^полей в шаблоне вывода могут использоваться либо цепочка из п пробелов, окаймленная символами “\”, либо односимвольные указатели “!” или “&”.
Описатель вида \ п пробелов \ осуществляет перенос в выводную строку (п+2) начальных символов из текстового значения очередного элемента списка. Если длина отображаемого значения меньше длины символьного поля, то недостающие позиции справазаполняются пробелами.
Восклицательный знак заставит систему перенести в выводную строку только первый символ отображаемого значения.
Амперсанд (&) является указанием о выводе текстового значения элемента выводного списка целиком. Это единственный описатель выводного поля, длина которого не определена. В сочетании с возможностью переполнения числового поля такая ситуация приводит к несоответствию между длинами шаблона и выводной строки.
Все остальные символы алфавита в шаблоне выполняют роль разделителей между описаниями числовых и текстовых полей. Они без всякого изменения переносятся в соответствующие позиции выводной строки. Если в их состав необходимо включить те символы, которые задействованы в описании числовых и текстовых полей, то перед каждым “управляющим” символом в шаблоне помещают знак подчеркивания (_):
PRINTUSING “####_!”; 1990 "* 1990!
Сам знак подчеркивания в выводной строке может появиться, если в шаблоне ему соответствуют два подряд идущих знака подчеркивания. ■
Если тип очередного элемента выводного списка не соответствует описанию поля, то все три системы реагируют на такую ситуацию как на ошибочную.
Количество описаний числовых и символьных полей в шаблоне вывода может не соответствовать количеству элементов выводного списка. Если количество отображаемых данных превышает число описателей, то шаблон вывода повторяется с самого начала. В отличие от Фортрана здесь вывод продолжается в той же самой строке. Поэтому следующие операторы осуществляют вывод данных абсолютно идентично:
PRINTUSING “### ”; 1, 2, 3
PRINT USING “### ### ### ”; 1,2,3
Если длина списка в операторе PRINT USING короче, чем шаблон вывода, то вслед за значением последнего элемента в выводную строку из шаблона переносится очередное литеральное поле. Описатели полей, оставшиеся неиспользованными, при этом игнорируются. Например :
PRINT USING “###.руб ##коп”; 100 “* 100 руб
Turbo-BASIC воспринимает пробел между элементами выводного списка как разделитель, тогда как GW-система пробелы между числовыми данными игнорирует, а Quick-система при наборе таких операторов автоматически заменяет пробел на точку с запятой.
Отметим еще одно расхождение, связанное с реакцией на нулевую длину шаблона вывода. Turbo-система в такой ситуации все равно выдает значения элементов выводного списка, снабжая их предшествующим символом “ % ”. GW- и Quick-BASIC расценивают это событие как ошибочное.
Управление логикой вычислительного процесса
В однопроцессорных ЭВМ с последовательной обработкой команд машинной программы естественным считается выполнение команд в порядке возрастания их адресов. Такой же естественной назовем последовательность выполнения операторов друг за другом в порядке их написания: в пределах программной строки операторы обрабатывают-
90
ся слева направо, а программные строки — сверху вниз (в терминах GW-BASIC — в порядке возрастания номеров строк).
Однако вычислительные процессы и соответствующие им программы, как правило, не укладываются в такую линейную схему—отдельные фрагменты алгоритма приходится циклически повторять, в определенных точках в зависимости от выполнения заданных условий необходимо выбирать ту или иную ветвь вычислений и т.п. В таких ситуациях мы должны нарушить естественную последовательность выполнения операторов и заставить ЭВМ перейти в нужную точку программы.
Операторы, с помощью которых осуществляются такого рода манипуляции, принято называть операторами управления. В их состав входят рассматривавшиеся ранее операторы организации циклов (см. п. 2.2.1), структурные блоки выбора по условию(см. п. 2.2.2) или по ключу (см. п. 2.2.3), операторы обращения к внутренним (см. п. 2.4.1) или внешним подпрограммам (см. п. 2.4.2), многочисленные модификации оператора EXIT, обеспечивающие досрочный выход из различного рода программных конструкций. В п. 2.2.2 описывался оператор условного перехода IF - THEN (IF - THEN - ELSE), который также относится к группе операторов управления.
Кроме упомянутых выше операторов к групп управления относятся оператор останова (STOP), безусловного перехода (GOTO) и переключатели (ON).
Оператор останова прерывает выполнение Бейсик-программы. Если такое прерывание происходит в режиме интерпретации (GW- BASIC) или под управлением интегрированной среды (Turbo- или Quick-BASIC), то на экране дисплея появляется сообщение о причине останова и указание о номере программной строки, в которой это событс е наступило (при отсутствии номера выдается 0). В этот момент открытые файлы задачи и значения всех ее переменных сохраняют свое состояние, что обеспечивает возможность провести некоторые отладочные мероприятия и продолжить выполнение программы. Если оператор STOP встречается в самостоятельно откомпилированном модуле с расширением .EXE, то все файлы задачи закрываются и управление передается операционной системе. ■
Тело оператора безусловного перехода состоит из единственного указателя точки программы, в которую передается управление. Им может быть либо номер программной строки (GW-BASIC), либо ее метка:
GOTO 100
GOTO SumVec
Конструкция под названием “переключатель” представляет собой специальный вид оператора условного перехода или условного обращения к внутренней подпрограмме:
ON е GOTO Т1.Т2Tk
ON е GOSUB Tl,T2,...,Tk
Список точек перехода Т1,Т2,„. состоит из к указателей программных строк. Выбор одной из них осуществляется по значению арифметического выражения е, которое иногда называют переключающим выражением. Как правило, оно является целочисленным и возможные его значения должны принадлежать диапазону [ 1 ,к ]. При е=1 из списка точек перехода выбирается Т1 и по этому адресу передается управление (ON...GOTO) или производится вызов внутренней подпрограммы (ON.".. GOSUB), при е=2 в качестве точки перехода используется метка (номер) Т2 и т.д. После выполнения внутренней подпрограммы возврат осуществляется на оператор, следующий за ON...GOSUB .
Если переключающее выражение имеет вещественный тип, то его значение превращается в целое число путем естественного округления дробнойзасти (1.2-*1,1.5 -*2,1.9 -*2).
Если значение переключающего выражения выходит за пределы интервала [1,к], то оператор ON не изменяет естественную последовательность выполнения программных строк. Он просто игнорируется.
ОБРАБОТКА ТЕКСТОВОЙ ИНФОРМАЦИИ
Символьные константы, переменные и массивы
Основные сведения о символьных объектах и их идентификации уже приводились в п. 1.2, однако они были разбросаны там по нескольким параграфам. Поэтому напомним вкратце необходимую информацию.
Символьные константы, используемые в качестве литеральных констант в тексте исходной программы, представляют собой^последо- вательность произвольных знаков алфавита^окаймляемую двойными кавычками.^ списке операторов DATA текстовая константа может не заключаться в кавычки, если она не содержит запятых или концевых пробелов.
Версия Quick-BASIC допускает употребление именованных констант символьного типа:
CONST DATE1$ - “17 июля 1935 года”
Аналогичного эффекта можно добиться, используя внутренние нестандартные функции без аргументов:
DEF FNMaxX%-639
Идентификаторы текстовых переменных распознаются либо по последнему символу имени (DATE1$), либо по первой букве (DATE2,EVA, QUICK), если эта буква была указана в списке оператора DEFSTR:
DEFSTR D-F, Q
Quick-BASIC позволяет вводить объекты символьного типа с помощью описателя AS STRING, который может встретиться в одном из
декларативных операторов COMMON, DECLARE, DEF, DIM, FUNCTION, SHARED, STATIC, SUB, TYPE, REDIM. Например:
DIM ALPHA (20) AS STRING, BETA AS STRING *40
TYPE NOTEBOOK
name AS STRING *20
phone AS STRING *10
address AS STRING *50
END TYPE
Интересной особенностью оператора DIM (REDIM) является возможность объявления не только символьных массивов, но и скалярных переменных. Указание о длине символьного объекта после описателя AS STRING причисляет его к разряду статических.
Формирование и изменение значений переменныхсимвольного типа
Перед запуском задачи на счет всем переменным символьного типа присваивается значение “пусто”. Для формирования заранее известных значений в символьных переменных используются те же самые приемы, что и для числовых переменных - извлечение соответствующих величин из буфера клавиатуры или из файла данных (операторы INPUT, LINE INPUT), считывание предварительно заготовленных текстовых констант (операторы DATA, READ, RESTORE).
Текстовые значения, формируемые в процессе выполнения программы, можно занести в символьную переменную с помощью обычного (LET) или специального (LSET, RSET) оператора присваивания. Оператором MID$ можно воспользоваться для обновления части символов прежнего значения переменной.
Использование внутреннего блока данных
Внутренний блок данных, формируемый с помощью операторов DATA и представляющий собой потоковый набор значений с последовательным доступом, может содержать среди своих элементов как числовые, так и текстовые константы. На порядок их чередования в блоке данных никакого ограничения не накладывается. Забота о соответствии типов переменной и извлекаемого значения возлагается на программиста. При этом надо учитывать тот факт, что текстовые константы в списке операторов DATA могут не заключаться в кавычки;
Поэтому числовые константы можно рассматривать как последовательность символов и их значения допустимо извлекать в переменные символьного типа:
DATA 123,456
READ а$,в$
или
DATA“123”,"456”
READ А$,В$
Каких-либо других особенностей, связанных с употреблением символьных констант в операторах DATA, по сравнению с обычными числовыми блоками данных нет.
Ввод символьных значений по запросу программы
Ввод символьных данных с клавиатуры может быть реализован по оператору INPUT (см. раздел 3.1.2), если в его списке заданы имена текстовых переменных:
INPUT [;] Г1ехГ{;1,)] V1$,V2$,...
Технология ввода при этом ничем не отличается от процесса набора числовых значений, описанного в п. 3.1.2. Текстовые константы, вводимые по оператору INPUT, можно набирать так же, как и в списке оператора DATA - ^кавычками или без кавычек Л последнем случае символьные значения не мотут содержать пробелов и запятых, рассматриваемых при вводе как разделители.
Вторым оператором, с помощью которого программа может выдать запрос на ввод символьного значения с клавиатуры или из последовательного файла данных, является UNE INPUT:
UNE INPUT [;] ("text";] V$
UNE INPUT #n,V$
Он отличается от оператора INPUT тем, что содержит в своем теле имя единственной переменной V$, в которую вводятся все набираемые символы до появления управляющего кода “возврат каретки”. Среди них мотут быть и пробелы, и запятые.
Оператор UNE INPUT не выдает приглашение ко вводу в виде вопросительного знака, но все остальные атрибуты (точка с запятой в
95
начале, текстовая подсказка) имеют тот же смысл, что и в операторе INPUT.
Ввод данных с клавиатуры по операторам INPUT и LINE INPUT сопровождается отображением поступающих значений на экране дисплея. Имеется возможность осуществить ввод символьных данных и без переноса набираемых кодов в видеопамять, то есть без появления соответствующих знаков на экране. Потребность в таком скрытом вводе может возникнуть при наборе секретной информации (пароли доступа) или в игровых программах, где экран занят изображением какой-то сцены.
Если вводимый текст должен содержать фиксированное (к) число символов, то ввод без их отображения осуществляется с помощью функции INPUTS:
А$ INPUTS (к Г, [#] nf])
Второй необязательный аргумент этой функции задается в том случае, когда запрашиваемые к символов извлекаются из файла с номером nf.
Для ввода символьного значения, соответствующего коду одной нажатой клавиши, без отображения знака на экране можно воспользоваться служебной переменной INKEYS:
10 A$-INKEY$ : IFA$-“" THEN 10
В приведенном примере цикл ввода продолжается до тех пор, пока пользователь не нажмет какую-либо клавишу.
С помощью переменной INKEYS можно опознать не только однобайтовый код любого воспроизводимого символа алфавита, но и двухбайтовые коды, появляющиеся в результате нажатия большинства управляющих клавиш или их сочетаний. Исключение составляют клавиша Print Screen и комбинации Ctrl+Break, Ctrl+NumLock, Ctrl+Alt+Del, Ctrl+Print Screen, коды которых программе недоступны.
При работе с функцией INPUTS и служебной переменной INKEYS следует помнить, что ввод может завершиться и без ожидания ответа пользователя. Дело в том, что^клавиатура снабжена буфером, и если до момента выполнения оператора ввода там находились невостребованные символы, то они будут считаны. Поэтому не следует просто так нажимать клавиши во время выполнения программы, ибо поступающая от них информация запоминается в буфере и может неправильно интерпретироваться последующими операторами ввода,
О состоянии буфера ввода в процессе выполнения программы можно
узнать по служебной переменной INSTAT, значение которой равно О ("ложь") при пустом буфере или -1 ("истина") при наличии в нем хотя бы одного символа. Если буфер клавиатуры не пуст, то находящиеся в нем коды символов извлекаются в порядке их поступления (первым вошел — первым вышел).
Символьные выражения и стандартные процедуры ' •обработки текстовой информации
Изменение значения символьной переменной с помощью операторов LET7READ или INPUT изменяет и ее длину. Под длиной символьного объекта понимают количество символов, содержащихся в его значении.
Опрос длины производится с помощью функции LEN:
10 PRINT А$, LEN (А$)
20 А$-“BASIC” : PRINT А$, LEN (А$)
30 A$-“Turbo-BASIC” : PRINT А$, LEN (А$) RUN
0
BASIC 5
Turbo BASIC 11
Максимальная длина текстовой переменной не может превышать 255 символов в системе GW-BASIC и 32 767 символов в Turbo- и Quick-системах.
Аргументом функции LEN может быть произвольное выражение символьного типа, которое составляется из текстовых операндов, объединяемых знаком операции конкатенации (сцепления):
“Turbo”+ А$
Операция конкатенации сводится к приписыванию значения очередного “слагаемого” в хвост к предыдущей строке.
В качестве операндов символьного выражения наряду с текстовыми константами и переменными метут выступать стандартные или нестандартные функции символьного типа. Довольно большую группу функций такого типа составляют процедуры преобразования числовых данных в символьный формат, описанные в п. 1.2.6.
9797Вторую группу процедур, создающих символьные значения, представляют стандартные функции.
97
97
4* Ю. Л. Кетков
НаименованиефункцииENVIRONS (n), ENVIRONS ("SS...S")’ INPUTS (k[,[#]nf])IOCTLS ([#]nu)LCASES (e$)«LEFTS (e$,n)TRIMS (e$)« MIDS (e$,i[,n]>'RIGHTS (e$,n)RTRIM$ (e$)‘SPACES (n) ' STRINGS (n,cod)» STRINGS (n,e$)UCASES (e$)'VARPTRS (V$)НаименованиефункцииENVIRONS (n), ENVIRONS ("SS...S")’ INPUTS (k[,[#]nf])IOCTLS ([#]nu)LCASES (e$)«LEFTS (e$,n)TRIMS (e$)« MIDS (e$,i[,n]>'RIGHTS (e$,n)RTRIM$ (e$)‘SPACES (n) ' STRINGS (n,cod)» STRINGS (n,e$)UCASES (e$)'VARPTRS (V$)Значениефункции
Наименованиефункции
ENVIRONS (n)
, ENVIRONS ("SS...S")
’ INPUTS (k[,[#]nf])
IOCTLS ([#]nu)
LCASES (e$)
«LEFTS (e$,n)
TRIMS (e$)
« MIDS (e$,i[,n]>
'RIGHTS (e$,n)
RTRIM$ (e$)
‘SPACES (n) ' STRINGS (n,cod)
» STRINGS (n,e$)
UCASES (e$)
'VARPTRS (V$)
Наименованиефункции
ENVIRONS (n)
, ENVIRONS ("SS...S")
’ INPUTS (k[,[#]nf])
IOCTLS ([#]nu)
LCASES (e$)
«LEFTS (e$,n)
TRIMS (e$)
« MIDS (e$,i[,n]>
'RIGHTS (e$,n)
RTRIM$ (e$)
‘SPACES (n) ' STRINGS (n,cod)
» STRINGS (n,e$)
UCASES (e$)
'VARPTRS (V$)
Строка, представляющая значение п-го параметра из таблицы окружения операционной системы MS DOS, установленного по директиве SET или оператору ENVIRON Аналогичная строка, выдаваемая по идентификатору системного параметра
Строка, содержащая к символов, считанных из буфера клавиатуры или из файла с номером nf
Строка с управляющими данными, поступившая от драйвера устройства с номером пи
Строка, полученная в результате замены больших букв значения аргумента на малые
Строка, полученная в результате выделения первых п символов из значения аргумента е$ (левая подстрока)
Строка, полученная из значения аргумента путем удаления лидирующих пробелов (отсечение слева)
Строка, полученная из значения аргумента е$ путем выделения п символов, начиная с i-ro (центральная подстрока). Если аргумент п не задан, то выделяются все символы, начиная с i-ro
Строка, полученная в результате выделения последних п символов из значения аргумента е$ (правая подстрока) Строка, полученная из значения аргумента путем удаления конечных пробелов (отсечение справа)
Строка, состоящая из п пробелов
Строка, состоящая из п одинаковых символов с кодом cod (O<-cod<- 255)
Аналогичная строка, в которой п раз повторяется первый символ значения е$
Строка, полученная в результате замены малых букв значения аргумента на большие
Строка, представляющая адрес переменной V$ в символьном формате, используемом в операторах DRAW и PLAY
Функция MID$, используемая для выделения внутренней подстроки, может применяться и как оператор для замены внутренней подстроки новым значением. В этом случае в качестве первого аргумента может выступать только идентификатор символьной переменной:
А$-“Turbo BASIC”
MID$ (A$,l,5)-“Quick”
Длина заменяемой подстроки при таком присвоении не меняется. Если заменяющее значение имеет меньшую длину, то недостающие
98
символы справа дополняются пробелами. В противном случае используются первые п символов замещающего выражения. ■
Кроме стандартных функций, перечисленных выше и в табл.5, в качестве операндов символьных выражений мотут выступать служебные переменные текстового типа, приведенные ниже. Некоторые из них доступны только для чтения (COMMANDS, ERDEV$, INKEY$), значения других (DATES, TIMES) можно изменить.
Наименование переменнойCOMMANDSDATESERDEVSINKEYSTIMESНаименование переменнойCOMMANDSDATESERDEVSINKEYSTIMESЗначениепеременной
Наименование переменной
COMMANDS
DATES
ERDEVS
INKEYS
TIMES
Наименование переменной
COMMANDS
DATES
ERDEVS
INKEYS
TIMES
Текст командной строки, использованной для запуска программы под управлением MS DOS
Текущая дата в одном из допустимых форматов ("01/31/90", “01/31/1990", "01-31-90" или “01-31-1990")
Идентификатор ошибочно сработавшего устройства
Одно или двухбайтовое значение, соответствующее коду нажатой клавиши
Текущее время в формате ”чч:мм:сс”
Идентификаторы переменных символьного типа метут использоваться в левой части обычного (LET) или специальных операторов присваивания
LSET Vl$-el$
RSET V2$-e2$
■ Переменные Vl$ и V2$ в этом случае представляют символьные поля фиксированной длины, расположенные в буфере обмена с файлом прямого доступа. Специфика присвоения значений таким переменным заключается в том, что оно не изменяет длину переменной и осуществляет перенос нового значения на указанное поле с прижимом к его левой (LSET) или правой (RSET) границе. Если присваиваемое значение имеет меньшую длину, то незадейство- ванные позиции символьного поля заполняются пробелами.
Имена символьных переменных мотут встретиться и в теле оператора SWAP, осуществляющего обмен значениями между двумя переменными :
SWAP А$,В$
Подобно числовым выражениям, символьные значения можно сравнивать между собой:
IF A$-“YES” THEN 200
Операции отношения над текстовыми операндами базируются на посимвольном сравнении их числовых кодов. Поэтому для правильной интерпретации результатов сравнения программист должен знать последовательность расположения сравниваемых символов в таблице ASCII. Например,числовые коды латинских букв возрастают в соответствии с их размещением по алфавиту (ASC ("А") - 65, ASC ГВ") - 66,...). Поэтому буква В “больше”'буквы А, и этот факт может быть использован для сортировки текстовых значений в лексикографическом порядке. К сожалению, расположение русских букв в таблицах ASCII не всегда соответствует их порядку в нашем алфавите, и для сортировки русских слов иногда приходится прибегать к специальным приемам.
Для анализа текстовой информации очень полезна функция INSTR:
N-INSTR ([!,] el$,e2$)
Она обеспечивает поиск вхождения значения е2$ в значение е!$. Этот поиск начинается либо с первой, либо с i-й позиции значения е1$. Если процедура поиска завершена успешно и в тексте е!$ найден‘фрагмент е2$, то значением функции INSTR является номер позиции, начиная с которой обнаружено первое вхождение. Для поиска следующего вхождения можно продвинуть указатель начала поиска и повторно обратиться к функции INSTR. Если анализ вхождения приводит к отрицательному результату, то значение функции INSTR равно нулю.
В качестве примера эффективного использования функции INSTR приведем анализ на допустимость односимвольного ответа пользователя:
100 INPUT “Будете продолжать - У/Д/H/N”; 0ТВЕТ$
110 IF INSTR ("УуДдНнМГ, OTBET$) - 0 THEN 100
Вывод текстовой информации
Символьные объекты (константы, переменные, выражения) могут выступать в качестве элементов выводного списка оператора PRINT. При этом в составе их значений мотут встретиться не только знаки алфавита, но и управляющие символы, а также коды псевдографики. Как правило, для их подключения к символьному значению используется стандартная функция CHR$:
PRINT “Привет !” + CHR$ (7)
Вывод приветствия в данном случае будет сопровождаться кратковременным звуковым сигналом.
Запятая после символьного объекта в теле оператора PRINT вызывает перемещение указателя выводной строки в начало следующей зоны. Точка с запятой, используемая в качестве разделителя после символьного объекта, дополнительного сдвига указателя не вызывает. Очередной элемент выводного списка при этом отображается вплотную к предшествующему значению.
Для вывода символьных данных с использованием оператора PRINT USING формат выводной строки должен включать односимвольные описатели “!” , “&” или n-символьные шаблоны текстовых полей вида “\ \” :
А$- “Quick BASIC"
PRINT USING “!&\ \”;A$.A$,A$
Q Quck BASIC Quick
ВЗАИМОДЕЙСТВИЕ С ФАЙЛАМИИ УСТРОЙСТВАМИ
.5.1. Организация файловых структур
Файлы представляют собой особым образом организованные наборы данных, размещаемые на внешних устройствах и допускающие либо односторонний, либо двусторонний обмен с объектами программы, находящимися в оперативной памяти.
Файлы, расположенные на дисковых запоминающих устройствах, играют роль постоянных или временных хранилищ, к которым могут иметь доступ одна или несколько программ. Для их идентификации используются полные или сокращенные файловые спецификации, принятые в операционной системе:
d:\basic\gwbasic\datel .ххх
gwbasicXdatel .ххх
gwbasicXdatel
datel
Полная спецификация, включающая имя дисковода, идентификаторы корневого и присоединенных оглавлений и собственно имя файла, используется в том случае, когда файл хранится не в текущем оглавлении. Идентификация файлов текущей директории осуществляется по восьмисимвольному имени с возможной добавкой трехсимвольного расширения. В отличие от идентификаторов других объектов имена файлов не мшут содержать точек (точка воспринимается как разделитель имени и расширения), но допускают использование следующих символов:
О []©#*%&_/’-
Файлы, располагаемые на других внешних устройствах, обычно
102
идентифицируют по общепринятым системным именам — LPT1:, LPT2:, LPT3:, СОМ1:, COM2:, KYBD:, SCRN:.
Использование длинных файловых спецификаций в операторах обмена неудобно. Поэтому вместо внешних идентификаторов в этих процедурах применяются условные целочисленные номера, приписываемые файлам в момент их инициализации. В зависимости от ситуации программные номера файлов иногда выделяются предшествующим символом #.
Характерной особенностью любой файловой структуры является разбиение файла на записи — регулярные порции данных, выступающие в процедурах обмена как нечто цельное. При этом различают записи физические и записи логические. Размеры физических записей регулируются операционной системой и выбираются из соображений эффективного функционирования соответствующего внешнего устройства. Размеры логических записей диктуются нуждами программы. Согласование размеров логических и физических записей берет на себя операционная система, используя для этой цели различные буфера и управляющие блоки.
Достаточно наглядное представление о записи дает строка с числовыми и символьными данными, отображаемая на экране дисплея в результате выполнения операторов PRINT или WRITE. [Количество данных в пределах одной записи, форматы их представления и способы разделения соседних компонент зависят от типа файла и используемых процедур обмена.
/Ь точки зрения технологии доступа к содержимому файла различают файлы с последовательной организацией и файлы с прямой идентификацией записей. В первом случае в операции обмена участвует очередная доступная запись подобно тому, как это происходит при считывании из внутреннего блока данных.
В файлах прямого доступа каждая запись снабжается номером, который в сочетании с длиной записи однозначно определяет ее местоположение в файле. Такие файлы могут быть расположены либо на гибком диске, либо на “винчестере”.
В двоичных (BINARY) файлах имеется возможность адресовать каждый байт, что позволяет формировать записи из данных в машинном формате. Такой способ повышает эффективность использования дискового пространства и ускоряет процесс передачи данных.
Инициализация файлов данных
Процедура приведения файла в состояние готовности к обмену носит название инициализации или открытия файла. В процессе ее выполнения устанавливается связь между спецификацией файла и
программным номером, под которым он будет выступать в последующих процедурах обмена, закрепляется системный или программный буфер, используемый для реализации операторов ввода-вывода, формируются начальные значения параметров, расположенных в так называемом блоке управления файлом.
Открывается файл с помощью одной из двух разновидностей оператора OPEN: '
OPEN s_f [FORml] [ACCESS a] [p] AS [#]n [LEN-ri]
OPEN m2, [#]n, s_f [дП
Здесь s_f — полная или укороченная спецификация файла;
ml — служебное слово, задающее режим работы файла и принимающее одно из следующих значений - APPEND, BINARY, INPUT, OUTPUT или RANDOM;
m2 — .односимвольный признак режима работы, задаваемый буквами А (от APPEND)”, В (отBINARY), I (отINPUT), О (от OUTPUT) bR (отRANDOM);
а — служебное слово или сочетание слов, определяющее направление обмена (возможные варианты - READ, WRITE или READ WRITE);
р — признак защиты файла от других пользователей (возможные значения - SHARED, LOCK READ, LOCK WRITE или LOCK READ WRITE);
n — целое число из диапазона [1,255], воспринимаемое как номер файла во всех последующих процедурах обмена;
ri — длина записи, целое число из диапазона [1,32767].
Для файлов с последовательным доступом может быть указан один из трех режимов — вводной (INPUT), выводной (OUTPUT) или с дозаписью (APPEND). Из вводного файла данные можно только читать, и если речь идет о дисковом наборе данных, то он должен быть создан заранее.Точно так же должен существовать и файл, прежнее содержимое которого предполагается пополнять новыми записями (APPEND). Если выводной файл на диске к моменту открытия существует, то его прежнее содержимое будет потеряно. Если такого файла нет, то его создадут.
Файлы прямого доступа открываются с атрибутами RANDOM или BINARY. В первом случае содержимым записи могут быть как текстовые, так и числовые значения, преобразованные из машинного представления в символьный формат. Атрибут BINARY, введенный в версиях Turbo- и Quick-BASIC, означает, что числовые данные хранятся в записях в машинном формате. ■
Параметр, сопровождающий служебное слово ACCESS, характеризует направление обмена — READ (разрешено только чтение), WRITE (разрешена только запись), READ WRITE (разрешены и чтение, и запись). Он используется в языках GW- и Quick-BASIC.
Признак защиты файлов появился в связи с подключением персональных ЭВМ к вычислительным сетям. В сети пользователь одной
ЭВМ имеет возможность доступа к файлам, хранящимся в других ЭВМ. Атрибут SHARED применяется для открытия файлов коллективного пользования. С помощью атрибута LOCK READ можно предусмотреть защиту файла от чтения его содержимого другими пользователями. Атрибут LOCK WRITE запрещает пользователям других ЭВМ модифици записи открываемого файла. Запрет любого обращения извне производится параметром LOCK READ WRITE. Кроме перечисленных средств защиты, распространяемых на все записи файла з GW- и Quick-BASIC имеется возможность установить (LOCK) или отменить (UNLOCK) защиту на конкретную запись с номером N или группу последовательных записей •
LOCK [#]n,N
LOCK [#]n, [N1JTON2
. LOCK [#]n, [N1JTOEND.
UNLOCK [#]n,N
UNLOCK [#]n, [Nl] TO N2
UNLOCK [#]n, [Nl] TO END-
Для файлов типа BINARY указанные выш границы защиты воспринимаются как номера байтов.
Инициализация файлов прямого доступа (RANDOM) помимо открытия файла сопровождается выделением буфера, используемого для временно) хранения записи в оперативной памяти. Структура этого буфера описывается с помощью оператора FIELD:
HELD [#]n, 11 AS Vl$, 12 AS V2$,...
Буфер представляет собой линейный участок оперативной памяти, разделенный на последовательные поля символьного типа. Каждое такое поле имеет фиксированную длину (И, 12,...), измеряемую в байтах, и индивидуальное имя (¥1$, ¥2$,..). Поле предназначено для временного хранения соответствующей компоненты записи. Суммарная длина полей должна совпадать с длиной записи, объявленной в операторе открытия файла или установленной по умолчанию. ■
Quick-BASIC позволяет наряду с буфером, выделяемым по оператору FIELD, использова t переменные типа “запись” (см. операторы TYPE - END TYPE). Последние по существу своему являются обобщением линейной структуры буфера, так как наряду с символьными полями допускают числовые поля любого типа и даже более сложные поля, которые могут быть представлены древовидными структурами.
Для прекращения доступа к файлу и освобождения связанных с ним ресурсов файл закрывают:
CLOSE [#]nl, [,[#]п2,...]
Одним оператором CLOSE можно закрыть несколько файлов с номерами nl, п2,... . После этого освободившиеся номера мотут быть использованы для инициализации других файлов.
Все открытые файлы можно закрыть и по оператору (директиве) RESET. При закрытии выводных файлов содержимое обслуживающих их буферов записывается на соответствующий внешний носитель.
Автоматическое закрытие всех файлов происходит и при выполнении операторов (директив) CLEAR, END, RUN, SYSTEM.
Процедуры обмена с файлами данных
0 б мен с последовательными файлами
При создании файлов с последовательным доступом они открываются как выводные (OUTPUT). Вывод данных осуществляется по одному из следующих операторов.
PRINT *n. el {;I,I }е2 {; 1.1 }...
PRINT. [#]n USING f$; el, е2,...
WRITE #n, el,e2,...
Выводной список оператора PRINT может включать выражения числового и символьного типов, редактирующие функции SPC(n) и ТАВ(п). Структура записи, формируемой оператором PRINT#, очень напоминает то, что бы мы увидели на экране дисплея при выполнении оператора PRINT. С целью экономии дискового пространства в формируемую выводную строку-запись не заносятся лишние пробелы, поэтому употребление функций типа SPC и ТАВ в операторе PRINT # особого смысла не имеет. По этой же причине все разделители элементов выводного списка действуют одинаково.
Оператор PRINT #n USING формирует содержимое записи точно в таком же виде, как это осуществляется при форматном выводе на экцан дисплея.1'
/При выполнении оператора WRITE # числовые элементы выводного списка преобразуются в символьный формат так же, как и в результате действия оператора PRINT, а текстовые элементы переносятся в запись с добавлением окаймляющих кавычек. Дополнительно к этому два смежных значения в записи разделяются запятыми.
Для перечисленных выше операторов характерны следующие обстоятельства:
содержание формируемой записи составляет последовательност значений элементов выводного списка;
106
числовые данные в записи представлены в символьном формате;, два смежных значения разделяются в записи пробелами или запятыми.
Считывание данных из файлов с последовательной организацией осуществляется операторами INPUT, LINE INPUT и функцией INPUTS:
INPUT #n,Vl,V2, ...
UNE INPUT #n, V$
A$ - INPUTS (k, [#]n)
Количество переменных в списке оператора INPUT, их тип и порядок следования должны соответствовать количеству и последовательности типов данных, хранящихся в текущей записи. Однако структуры всех записей файла не обязательно должны быть идентичны. Действует вполне естественный принцип — читай так, как записывал.
Оператор UNE INPUT # считывает содержимое текущей записи целиком, рассматривает его как строку символов и заносит в переменную V$. Функция INPUTS позволяет прочитать к символов из текущей записи.
Контроль за исчерпанием данных можно осуществить по значению функции EOF (п), которая принимает нулевое значение ("ложь"), если в файле еще имеются невостребованные записи, и -1 ("истина"), если из файла была прочитана последняя запись.
Обмен с файлами прямого доступа
Файлы прямого доступа, открываемые с атрибутом RANDOM, располагаются на диске. Каждая запись такого файла имеет номер, и ее содержимое на диске формируется в два этапа.
На первом этапе с помощью операторов LSET и RSET заполняются поля буфера, объявленного по оператору FIELD:
HEID #n, 12 AS А$, 4 AS В$,...
LSET А$-“КетковЮ.Л.”
RSET B$-MKI$ (1935)
Оператор LSET переносит присваиваемое значение на поле буфера с прижимом к левой границе поля, а оператор RSET — с прижимом к правой границе. Числовая информация при этом “преобразуется” в символьный формат с помощью функций MKD$, MKI$, MKL$ или MKS$. На самом деле эти функции никакого преобразования не совершают. Просто они позволяют 2-, 4- или 8-байтовый числовой аргумент
107
соответствующего типа рассматривать как цепочку символов, что дает возможность присвоить такое значение символьной переменной, выполняющей роль поля буфера.
Операторы LSET и RSET отличаются от обычного оператора присваивания LET тем, что они не изменяют длину присваиваемой переменной. Если длина заполняемого поля превышает длину присваиваемого значения, то недостающие позиции справа (LSET) или слева (RSET) заполняются пробелами.
Указатели полей буфера файла прямого доступа нельзя использовать в левой части операторов LET, так как они тогда превращаются в обычные символьные переменные. При этом они будут перенесены в сегмент символьных данных ("кучу") и потеряют связь с буфером файла, j
После заполнения буфера его содержимое можно переписать на диск с помощью оператора PUT:
PUT [#]п ы
В качестве второго параметра выступает номер формируемой записи. •
Извлечение информации из файла прямого доступа также осуществляется в два приема. Сначала содержимое дисковой записи переносится в буфер:
GET [#]п [,г]
■ Затем можно начать обработку каждого поля буфера, рассматривая его как символьное представление числового или текстового значения. Числовая величина извлекается из поля буфера с помощью функции “преобразования” аргумента соответствующего типа CVD, CVI, CVL или CVS:
G2 - CVI (LTRIM$ (В$))
Для извлечения из поля буфера текстовой информации, освобожденной от лидирующих или концевых пробелов, можно воспользоваться функциями LTRIM$ и RTRIM$.
Когда в операторах GET или PUT отсутствует номер записи г, то обмен осуществляется по текущему значению указателя файла. При открытии файла прямого доступа в блоке управления файлом формируется указатель, который “смотрит” на запись с номером 1. После
108
завершения обмена с к-й записью в указатель заносится “адрес” следующей записи. Используя в операторах GET/PUT режим обмена только по указателю, мы превращаем файл прямого доступа в файл с последовательной организацией. .
Версия Quick-BASIC предусматривает расширенный вариант операторов GET и PUT:
GET #n, г, V
PUT #n, r,V
Здесь V — идентификатор переменной типа “запись” (см. операторы TYPE — END TYPE), заменяющей функции описанного выше буфера. Переменная типа запись обладает тем преимуществом, что может включать в качестве своих составляющих числовые поля любого типа, поэтому при таких обменах отпадает нужда в “преобразовании” числовых выражений и их значения хранятся в записи непосредственно в машинном формате.
Операторами GET # и PUT # можно пользоваться и для обмена с файлами прямого доступа, открытыми с атрибутом BINARY. Параметр г в этом случае задает не номер записи, а относительный адрес байта в файле (их отсчет ведется от нуля).
Для обмена символьными данными с двоичными файлами в версии Turbo-BASIC можно использовать еще и операторы GET$, PUT$:
GETS [#]n, 1, v$
PUTS [#]n,e$
Здесь 1 — количество байтов, считываемых в переменную V$, начиная с текущего положения указателя.
С помощью оператора SEEK указатель двоичного файла можно установить на любой байт с заданным номером к (0 <■ к <— 2Л31 -1) :
SEEK [#]п,к
Оператором SEEK можно воспользоваться для позиционирования указателей последовательных файлов (к — номер байта) или файлов типа RANDOM (к — номер записи).
Опрос положения указателя файла осуществляется с помощью функции SEEK(n). Ее значением является относительный адрес текущего байта для файлов типа APPEND, BINARY, INPUT, OUTPUT и номер текущей записи для файлов типа RANDOM.
Взаимодействие с экраном дисплея
Технические характеристики дисплеев
Персональные ЭВМ, совместимые с IBM PC/XT и АТ, комплектуются монохромными (MD — Monochrome Display) или цветными (CD - Color Display, ECD — Enhanced Color Display и т.п.) дисплеями. Среди цветных дисплеев различают композитные и RGB-мониторы.
Связь ЭВМ с дисплеем осуществляет специальная управляющая плата, которую в технической литературе принято называть картой. Карта представляет собой довольно сложное техническое изделие, включающее специализированный видеопроцессор с набором управляющих регистров, собственную оперативную память (видеоЗУ), каналы связи с центральным процессором (адресная шина, шина данных) и выходную шину, по которой видеосигнал передается на монитор.
Общение между центральным процессором и дисплейной картой осуществляется через порты ввода-вывода с помощью машинных команд IN и OUT (в языке BASIC аналогичную роль выполняют процедуры INP и OUT). Обмен с нужным портом позволяет выбрать тот или иной регистр видеопроцессора, записать в него соответствующую информацию или опросить его состояние. Имеетсявозможность и прямого доступа к ячейкам видеоЗУ. Однако управление дисплеем на таком уровне очень трудоемко и требует достаточно высоких профессиональных знаний.
Для обслуживания дисплеев в состав BASIC включено довольно много операторов и функций. Если какая-то дисплейная процедура недостижима средствами алгоритмического языка, то ее можно выполнить с помощью подпрограмм, входящих в состав базовой системы управления вводом-выводом (BIOS — Basic Input/Output System) и “зашитых” в постоянной памяти ЭВМ. Более подробно дисплейные функции BIOS рассматриваются в п. 5.4.5.
Управление черно-белым (монохромным) монитором осуществляется по трем каналам, передающим сигналы горизонтальной и вертикальной синхронизации, а также уровень интенсивности луча.
В RGB-мониторах сигнал цветности передается по трем раздельным ходам, управляющим соответственно лучами красной (R — red), зеленой (G — green) и синей (В — blue) пушек. В наиболее дешевых мониторах это управление носит бинарный характер (1 — пушка соответствующего цвета включена, 0 — отключена). В таких мониторах отображаются 8 основных цветов, нумеруемых в диапазоне от 0 до 7 3 частую к этому добавляется также бинарный сигнал управления по
яркостью (интенсивностью) луча (0 — обычная яркость, 1 — повышенная) , что позволяет довести цветовую гамму до 16 оттенков, приведенных в табл.7. К обозначению таких мониторов иногда добавляют Спте одну букву — RGBI (I — Intensity).
Таблица 7
Код
Нормальная яркость (I - 0)
Повышенная яркость (I -1)
I
R
G
В
Цвет
Код
I
R
G
В
Цвет
0
0
0
0
0
черный
8
1
0
0
0
серый
1
0
0
0
1
синий
9
1
0
0
I
голубой
2
0
0
1
0
зеленый
10
1
0
1
0
ярко-зеленый
3
0
0
1
1
бирюзовый
11
1
0
1
1
ярко-бирюзовый
4
0
1
0
0
красный
12
1
1
0
0
розовый
5
0
1
0
1
фиолетовый
13
1
1
0
1
ярко-фиолетовый
б
0
1
1
0
коричневый
14
1
1
1
0
желтый
7
0
1
1
1
сероватый
15
1
1
1
1
ярко-белый
В профессиональных мониторах используются более сложные системы управления цветностью, обеспечивающие раздельную регулировку интенсивности каждого луча. Например, в дисплеях типа ECD яркость каждой цветовой компоненты имеет 4 уровня, что позволяет расширить цветовую гамму до 64 оттенков. В лучших дисплеях, управляемых картами MCGA или VGA, используются 64 градации по каждому цвету, таким образом общее количество доступных цветов превышает 256 000.
В композитных мониторах вместо раздельного управления цветовыми пушками из контроллера выдается интегральный видеосигнал, в котором интенсивности цветовых компонент тем или иным способом суммируются.
К числу наиболее известных управляющих карт относятся следующие:
MDPA (Monochrom Display and Printer Adapter) — карта, обслуживающая монохромный дисплей (MD) и принтер, обеспечивающая вывод только текстовой информации (25 строк по 80 символов, разрешение 720*350 точек);
CGA (Color Graphic Adapter) — наиболее дешевая плата управления цветным дисплеем с невысоким качеством отображения текстовой и графической информации (максимальное разрешение 640*200 точек);
Hercules—не очень распространенная карта управления одноименным дисплеем с достаточно высокой разрешающей способностью (720*348 точек), но со сравнительно бедной цветовой гаммой (4 цвета);
EGA (Enhanced Color Adapter) — довольно распространенная карта управления монохромными н цветными дисплеями со средним качеством изображения. Комплектуется видеопамятью емкостью в 64, 128 или 256 Кбайт и работает в конфигурации с MD, CD или ECD. Путем установки переключателей может имитировать карту CGA;
MCGA (Multi Color Graphic Array) — карта управления цветными дисплеями с высокой разрешающей способностью (720*350 точек) и многослойной видеопамятью;
VGA (Video Graphic Array) — одна из наиболее современных карт управления профессиональными монохромными и цветными аналоговыми дисплеями с достаточно высоким качеством отображения (640*480 точек). Путем программного переключения обеспечивает моделирование режимов работы карт CGA и EGA.
В настоящее время можно встретить улучшенные варианты перечисленных карт (EGA+, Hercules plus. Super VGA и т.п.), разрешающие способности которых приближаются к заветной цифре 1000* 1000 точек.
При выводе текстовых сообщений или графических объектов из допустимой цветовой гаммы выделяют два или три фиксируемых цвета — цвет переднего плана, цвет фона и цвет рамки. Цветом переднего плана воспроизводятся контуры букв, точки или линии графического объекта, если в соответствующих операторах не задан альтернативный код цветности. Все остальные точки рабочей области экрана окрашиваются цветом фона. В дисплеях под управлением карты CGA имеется возможность выделить рабочую область экрана, обведя ее цветной рамкой.
В некоторых графических режимах работы монитора из-за ограничений на количество разрядов, предназначенных для кодировки цветовых атрибутов каждого элемента изображения (пикселя), разрешается использовать не всю цветовую гамму, а только ограниченное ее подмножество, образующее так называемую палитру. Способы формирования палитры могут быть разными. Так, в карте CGA пользователю предлагаются две фиксированные палитры с номерами 0 и 1, каждая из которых содержит по 4 допустимых цвета (табл. 8).
Таблица 8
Атрибут цвета
Палитра 0
Палитра 1
(номер регистра)
(G-0) '
(G-1)
0(00)
цвет фона
цвет фона
1 (01)
красный (R)
бирюзовый (G+B)
2(10)
зеленый (G)
фиолетовый (R+B)
3(11)
желтый (G-Ш)
белый (R+G+B)
Из табл. 8 видно, что оттенки нулевой палитры образованы путем задания битов красной и зеленой компонент и исключения компоненты синего цвета. В палитре 1 разряды красного и зеленого цветов переставлены местами. Для хранения информации о каждом пикселе в таком режиме достаточно двух битов, что при разрешении экрана в 320x200 точек требует видеоЗУ объемом не менее 16 Кбайт.
Усовершенствованные карты CGA позволяют использовать еще две палитры с номерами 2 (ярко-бирюзовый, ярко-фиолетовый, ярко-белый) иЗ (бирюзовый, фиолетовый, серый).
Атрибут цвета, используемый в графических операторах вместо указания физического кода цвета, определяет номер регистра текущей палитры. Содержимое этого регистра участвует в формировании видеосигнала.
Карта EGA в большинстве графических режимов обеспечивает воспроизведение 16 цветов из возможных 64 цветовых оттенков. Для задания физического номера цвета в EGA требуется уже 6 двоичных разрядов (по 2 бита на интенсивность каждой RGB-компоненты) однако видеоЗУ состоит всего из четырех однобитовых матриц (плоскостей), одноименные разряды которых обеспечивают отображение одного пикселя. В эти четыре разряда в процессе графических построений заносится цветовой атрибут пикселя, определяющий номер регистра палитры, где хранится настоящий код цветности.
Карта VGA тоже построена на базе четырехслойного видеоЗУ. Однако формирование истинного кода цветности реализуется здесь по гораздо более сложному алгоритму. Четырехбитовый код пикселя определяет один из 16 регистров палитры, из которого извлекается шестибитовый код, расширяемый до 8 разрядов путем добавления из регистра выбора цвета. Полученное значение рассматривается как адрес одного из 256 восемнадцатиразрядных регистров DAC (Digital- to-Analog Converter). В этих регистрах программным образом могут быть сформированы шестибитовыс значения интенсивностей каждой RGB-компоненты. Описанная схема позволяет закодировать до 256 К цветовых оттенков и использовать из них одновременно любую из 256 комбинаций. Выбранный 18разрядный код цветности преобразуется в аналоговый сигнал и передается в монитор.
Адреса байтов видеопамяти, расположенные в диапазоне от А0000 до BFFFF, находятся за пределами верхней границы ячеек оперативной памяти (640 Кбайт), доступных задачам в рамках MS DOS. Однако 20-разрядный адрес, формируемый в IBM PC путем сдвига влево на 4 разряда содержимого базового регистра и прибавления 16-разрядного смещения позволяет “дотянуться” и до ячеек видеоЗУ. Учитывая, что структура видеоЗУ и форматы хранения информации о пикселе в
разных картах имеют свою специфику, обмен с видеопамятью лучше проводить через дисплейные функции BIOS (см. п. 5.4.5).
В текстовом режиме экран дисплея представляет собой прямоугольную таблицу из п строк и m столбцов. Каждая клеточка такой таблицы предназначена для отображения одного символа и носит название “знакоместа”. Заполняется знакоместо двухцветными точками в соответствии с прямоугольной двоичной матрицей - мини-растром. Единичные точки мини-растра окрашиваются цветом переднего плана, образуя контур отображаемого знака, а нулевые точки окрашиваются фоновым цветом.
Для хранения информации в текстовом режиме на каждое знакоместо в видеоЗУ цветного монитора любого типа отводится два байта, первый из которых занят кодом ASCII отображаемого символа, а второй хранит цветовые атрибуты в следующем формате:
признакяркостьмерцанияпризнакяркостьмерцания
признакяркость
мерцания
признакяркость
мерцания
В монохромном режиме отображения текстовой информации сведения о символе также занимают два байта. Атрибут цветности для мониторов, управляемых картами CGAh Hercules, имеет следующий формат:
ЕмЕм7654321076543210‘цвет” фона■ ООО‘цвет” фона■ ОООI“цвет" символа000-I“цвет" символа000-не отображаетсяне отображается
Ем
Ем
76543210
76543210
‘цвет” фона■ ООО
‘цвет” фона■ ООО
I
“цвет" символа000-
I
“цвет" символа000-
не отображается
не отображается
подчеркивание обычное отображение инверсное отображениеподчеркивание обычное отображение инверсное отображениепризнакОООяркость001 -
подчеркивание обычное отображение инверсное отображение
подчеркивание обычное отображение инверсное отображение
мерцанияООО111 -
ШООО-
По коду ASCII контроллер дисплея извлекает из таблицы шрифтов, формируемой в памяти с помощью программ BIOS, мини-растр требуемого символа и, используя цветовые атрибуты, производит отображение символа на экране дисплея. В зависимости от разрешающей способности дисплея по горизонтали и вертикали мини-растр символа имеет размеры 8*8,8*14,8*16,9*14 или 9*16 точек.
Информация о содержимом всех знакомест экрана занимает об-ласть видеопамяти, называемую страницей. Если видеоЗУ имеет до-114
статочно большие размеры, то там отводится место под несколько текстовых страниц, обычно от однойдо восьми. Одна из таких страниц, содержимое которой отображается на экране, называется видимой. Среди остальных страниц выделяется еще одна — активная, в память которой заносится информация в результате выполнения операторов вывода. Смена номеров видимой и активной страниц позволяет мгновенно изменять содержимое экрана, что бывает полезно при отображении динамических заставок.
Информация о местоположении курсора для каждой из страниц видеопамяти хранится в фиксированной области MS DOS, начиная с адреса 0040:0050h. Справка о курсоре занимает два байта, в младшем из которых находится номер столбца, а в Старшем — номер строки. В обоих случаях отсчет ведется от нуля.
В текстовом режиме можно варьировать количество строк и столбцов за счет укрупнения пикселей путем объединения двух соседних точек или изменения размеров растра. Так, например, объединяя две смежные точки растра по горизонтали, мы можем уменьшить число символов в строке с 80 до 40. При этом буквы на экране будут выглядеть более жирными. Изменяя размеры растра и мини-растра по вертикали, можно варьировать количество строк (EGA — 25 или 43, VGA — 25,30,43,50 или 60).
В графических режимах программа получает доступ к каждому пикселю экрана, который может быть представлен как одной (1рафика высокого разрешения), так и двумя смежными по горизонтали и/или по вертикали (графика среднего разрешения) точками растра/Адреса- ция пикселей на экране начинается с левого верхнего угла (х-0,уЧ)). В пределах строки растра координата х увеличивается до максимального значения. Перемещение по строкам вниз соответствует увеличению вертикальной координаты у.
Информация о каждом пикселе изображения состоит из трех целочисленных положительных значений — координат (х,у) и кода цветности (номера регистра текущей палитры). Координаты пикселя однозначно определяют адрес информации о цветности в видеопамяти, для задания которой выделяется 1, 2 или 4 бита. Фоновый цвет является общим для всех точек экрана.
Любой графический режим наряду с воспроизведением геометрических объектов позволяет выдавать текстовую информацию.
Установка режима работы монитора производится программным путем с помощью видеосервиса BIOS, вызываемого по прерыванию INT 10h. Предварительно в регистр АН должен быть занесен нулевой код, а в регистр AL — числовой код режима. В BASIC-программах аналогичная процедура может быть выполнена путем вызова систем-
ной программы, моделирующей прерывание (INT86OLD, INT86XOLD,INTERRUPT,INERRUPTX).
Основные режимы работы наиболее распространенных дисплеев приведены в табл. 9. Некоторые из них могут быть установлены по оператору SCREEN.
Таблица 9
Код
Режим
Параметры текста
Размер растра
Число цветов
Число страниц
Адресация страниц
CGA
0,1
Текстовый
40x25,8x8
320x200
16
8
В8000, В8800,-
2,3
— -—
80x25,8x8
640x200
16
4
В8000, В9000,...
4,5
Графический
40x25,8x8
320x200
4
1
В8000
6
— * —
80x25,8x8
640x200
2
1
В8000
EGA
0,1
Текстовый
40x25,8x14
320x350
16/64
8
В8000, В8800,...
2,3
— * —
80x25,8x14
640x350
16/64
8
В8000, В9000,...
4,5
Графический
40x25,8x8
320x200
4/64
1
В8000
6
— “ —
80x25,8x8
640x200
2/64
1
В8000
7
Текстовый
80x25, 9x14
720x350
4
8
В1000, В2000,...
D
Графический
40x25,8x8
320x200
16/64
8
А0000, А2000,...
Е
——
80x25,8*8
640x200
16/64
4
А0000, А4000,...
F
“
80x25,8x14
640x350
4
2
А0000, А8000
10
*
80x25,8x14
640x350
16/64
2
А0000, А8000
VGA
0,1
Текстовый
40x25,9x16
360x400
16/256К
8
В8000, В8800,...
2,3
—“ —
80x25,9x16
720x400
16/256К
8
В8000, В9000,...
4,5
Графический
40x25,8x8■
320x200
4/256К
1
В8000
6
— “ —
80*25,8*8
640x200
2/256К
1
В8000,
7
Текстовый
80x25,9x16 -
720x400
4
8
ВОООО, В1000,...
D
Графический
40x25,8x8
320x200
16/256К
8
А0000,
А2000,...
Е
——
80x25,8x8
640x200
16/256К
4
А0000, А4000,...
Продолжение
VGA
Код
Режим
Параметры текста
Размер растра
Число цветов
Число страниц
Адресация страниц
F
— * —
80*25,8*8
640*200
4
2
А0000, А8000
10
*
80*25,8*14
640*350
16/256К
2
А0000, А8000
11
80*30,8*16
640*480
2/256К
1
А0000
12
80*30,8*16
640*480
16/256К
1
А0000
13
— “ —
40*25,8*8
320*200
256/256К
1
А0000
Установочные процедуры
Режим работы монитора устанавливается оператором SCREEN:
SCREEN [г] [,с[, [ар] [,vp]]]
Здесь г — числовой индекс режима;
с — признак цветности (0 — для цветного и любое ненулевое значение — для монохромного режима отображения);
ар — номер активной страницы;
vp — номер видимой страницы. Ниже приведены характеристики режимов отображения текстовой и графической информации, не совпадающие по величине с аналогичными кодами режимов в BIOS (табл.9).
ИндексХарактеристика
режимарежима
О Текстовый; емкость экрана 40*25,80*25,40*43,40*50, 80*43,80*50; размер символов 8*8 (для EGA и VGA — 8*14,9*14,9*16); 2 атрибута из 16 цветов или 16атрибутовиз 16 цветов для EGA
Графический с разрешением 320x200пикселей; емкость текстового экрана
40*25; 4 цветовых атрибута из 16 цветов с EGA. Поддерживается картами CGA, EGA, VGA и MCGA
Графический с разрешением 640*200пикселей; емкость текстового экрана
80x25; черно-белый или 2 цветовых атрибута из 16 цветов с EGA или VGA. Поддерживается картами CGA, EGA, VGA и MCGA
■ Графический с разрешением 320*200пикселей; емкость текстового экрана
40x25; несколько экранных страниц; 16 цветовых атрибутов из 16 цветов. Поддерживается картами EGA и VGA
Графический с разрешением 640x200пикселей; емкость текстового экрана
80x25; остальные параметры те же, что и в режиме 7
Графический с разрешением 640*350пикселей; емкость текстового экрана
80x25 или 80*43; размер символов 8*8 или 8*14; несколько экранных страниц; 4 атрибута из 16 цветов или 16 атрибуте» из 64 цветов в зависимости от объема видеоЗУ. Поддерживается картами EGA и VGA
Ю Графический, монохромный с параметрами, эквивалентными режиму 9. Доступны 4 атрибута из 9 псевдоцветов. Поддерживается картами EGA и VGA в конфигурации с MD
Графический с разрешением 640x480пикселей; емкость текстового экрана
80x30 или 80*60; размер символов 8*8; 2 атрибута из 256 К цветов. Поддерживается картами VGA и MCGA
Графический, отличающийся от режима 11 только тем, что доступны 256
атрибутов из 256 К цветов. Поддерживается картами VGA и MCGA
Графический с разрешением 320*200пикселей; емкость текстового экрана
40x25; 256 атрибутов из 256 К цветов. Поддерживается картами VGA и MCGA
В связи с тем, что пользователю BASIC-системы, работающему с конкретной конфитурацией (карта + дисплей) довольно сложно извлечь необходимую информацию из представленных выше таблиц, приведем данные для оператора SCREEN в разрезе по оборудованию (табл. 10).
Таблица 10
CGA
Режим
Текст
Цвета
Разрешение
Число страниц
040x2516320x2008
80x2516640x2004
1*40x254320x2001
280x252640x200
EGA
Режим
Дисплей
Текст
Атрибут/Пвет
Разрешение
Страницы/Объем
0MD80x2516/3720x3508
MD80x4316/3720x3504
CD40x2516/16320x2008
CD80x2516/16640x2008
ECD40x2516/64320*3508
ECD40x4316/64320x3508
ECD80x2516/64640x3508
ECD80*4316/64640x3508
140x254/16320x2001/16Кбайт
280x252/16640x2001/16Кбайт
40x2516/16320x2001/32Кбайт
80x2516/16640x2001/64Кбайт
ECD80x254/64640x3501/64Кбайт
ECD80x434/64640x3501/64Кбайт
ECD80x2516/64640x3501/128Кбайт
ECD80x4316/64640x3501/128Кбайт
MD80x254/9640x3501/64Кбайт
MD80x434/9640x3501/64Кбайт
Продолжение
MCGA
Режим |
Текст 1
Атрибут/Цвет
I Разрешение
| Страницы/Обьем
0
40x25
16/-
320x400
8
■ 80x25
16/-
640x400
8
1
40x25
4/-
320x200
1/16Кбайт
2
80x25
2/ —
640x200
1/16Кбайт
11
80x30
2/256К
640x480
1/64Кбайт
80x60
2/256K
640x480
1/64Кбайт
13
40x25
256/256K
320x200
1/64Кбайт
VGA
Режим |
Текст [
Атрибут/Цвет
I Разрешение
1 Страницы/Объем
0
40*25
16/64
360x400
8
40x43
16/64
320x350
8
40x50
16/64
320x400
4
80x25
16/64
720x400
8
80x43
16/64
640x350
4
80x43
16/3
720x350
4
80x50
16/64
640x400
4
80x50
16/3
720x400
4
1
40x25
4/16
320x200
1/16Кбайт
2
80x25
2/16
640*200
1/16 Кбайт
7
40x25
16/16
320*200
1/32 Кбайт
8
80x25
16/16
640*350
1/64 Кбайт
- 9
80x25
16/64
640x350
1/128 Кбайт
80x43
16/64
640x350
1/128 Кбайт
10
80x25
4/9
640x350
1/64 Кбайт
(MD)
80x43
4/9
640x350
1/64 Кбайт
11
80x30
2/256 К
640x480
1/64 Кбайт
80*60
2/256К
640x480
1/64 Кбайт
12
80x30
16/256К
640x480
1/256Кбайт
80x60
16/256 К
640*480
1/256 Кбайт
13
40x25
256/256 К
320x200
1/64 Кбайт
Управление цветностью осуществляется оператором COLOR, который в зависимости от установленного режима работы монитора имеет один из следующих формате®:
. COLOR [fg] [,[bg] [,bord]] для"г-0;
COLOR [bg] [,pal]для i—1;
COLOR [fg] [,bg]для 1-7,8,9,10;
COLOR [fg]для r-11,12,13.
Здесь fg — целое число, определяющее цвет переднего плана (цвет символов или линий);
bg — целое число,определяющее цвет фона;
bord — целое число,определяющее цвет рамки (бордюра), окаймляющего рабочее поле дисплея;
pal — целое число из диапазона [0,255], влияющее на выбор нулевой (pal — четное) или первой (pal — нечетное) цветовой палитры.
Диапазоны допустимых значений цветовых атрибутов fg и bg зависят от установленного режима г, и их границы приведены в табл.11. При выводе текстовой информации цвета символов fg в диапазоне от 0 до 15 соответствуют обычным номерам цветовой гаммы, начиная с 16 и до 31 цвета символов повторяются с добавлением признака мерцания.
Понятие палитры, появившееся в версиях Microsoft BASIC, предшествовавших GW-системе, связано с ограничением на количество цветов, воспроизводимых в тех или иных режимах работы монитора. Сначала BASIC обеспечивал в графическом режиме среднего разрешения работу с двумя фиксированными по составу палитрами с номерами 0 и 1. Внутри каждой из них допустимые цвета имеют свою относительную нумерацию — 0,1,2,3. Именно эти номера выступают в качестве атрибутов цветности в последующих графических операторах.
С появлением дисплеев типа MCGA, EGA и VGA, обладающих гораздо более развитым управлением, возникла возможность оперировать палитрами, состав и последовательность цветов в которых задает пользователь.
Формирование палитры сводится к установлению соответствия между номером регистра палитры (гр) и физическим номером цвета (с) в операторах PALETTE и PALETTE USING:
PALETTE [гр,с]
PALETTE USING А%(1)
Первый оператор засылает код цветности в единственный регистр палитры, тогда как второй — изменяет всю палитру целиком. Происходит это следующим образом. В первый регистр палитры заносится значение первого или i-ro элемента целочисленного массива А%, во второй — следующий элемент массива А % и т.д. Если значение очередного элемента А % (j) равно —1, то содержимое соответствующе регистра палитры не изменяется. Любое другое отрицательное значение элемента А% (j) фиксируется как ошибка периода выполнения программы. Индексы в массиве А % отсчитываются от нуля.
Задание оператора PALETTE без параметров приводитк восстановлению в регистрах палитры их первоначальных значений, устанавливаемых системой по умолчанию.
Индекс режима
Диапазон изменения цветовых атрибутов
fg
1bg
bord
pal
0.
[0,31]
[0,7]
[0,15]
—
1
[0,15]
[0,1]
7,8
[1,15]
[0,15]
9
[0,63]
К установочным операторам следует отнести процедуры разделения экрана на прямоугольные области, в которые осуществляется вывод текстовой (VIEW PRINT) и графической (VIEW SCREEN и WINDOW SCREEN) информации:
VIEW PRINT rl ТО г2
VIEW [[SCREEN] (xl,yl)-(x2,y2) [,cf [,cb]]]
WINDOW [[SCREEN] (Xmin,Ymin)- Xmax,Ymax)
Оператор VIEW PRINT, входящий в состав GW- и Quick-BASIC, отводит под текстовое окно строки экрана, начиная с г! и кончая строкой г2.
Оператор VIEW SCREEN устанавливает на экране прямоугольную область, в которой будет отображаться графическая информация. Местоположение графического окна определяется координатами левого верхнего (xl,yl) и правого нижнего (х2,у2) углов прямоугольника. Задаются они в пикселях и измеряются либо в абсолютной системе координат (в теле оператора VIEW присутствует служебное слово SCREEN), либо в приращениях относительно координат текущей точки. Параметром cf задается цвет заливки области графического окна. Если он отсутствует, то окно сохраняет ранее установленный цвет фона. Параметр cb определяет цвет рамки, которым может быть обведена граница графического окна. Если параметр cb не задан, то рамка не обводится.
Оператор WINDOW используется для задания области вывода графической информации в так называемых математических координатах. В сочетании с физическими габаритами графического окна (VIEW SCREEN) пределы изменения математических (программных) координат обеспечивают проектирование геометрических фигур на экран дисплея. Включение служебного слова SCREEN в текст оператора WINDOW означает, что ось у направлена вниз. В противном случае ось у направлена вверх.
В некотором смысле к группе установочных процедур можно отнести и оператор очистки экрана CLS. Будучи употреблен без параметров, он позволяет очистить содержимое видимой страницы или актив-
121
ного графического окна. В GW- и Quick-BASIC оператор CLS может сопровождаться числовым аргументом п, принимающим значения 0,1 или 2. При п-0 экран дисплея очищается от отображенной на нем текстовой и графической информации. При п-1 производится очистка текстового окна, если оператору CLS предшествовало назначение VIEW PRINT. Если область вывода текстовой информации совпадает со всем экраном, то пробелами заполняются 25 строк. При п-2 чистится весь экран, за исключением 25-й (служебной) строки.
.4.3. Работа с экраном в текстовом режиме
Текстовый режим устанавливается автоматически при запуске задачи на счет или оператором SCREEN 0, если до этого экран работал в графическом режиме:
SCREEN 0 [.[с] [,[ар] [,vp]]]
По умолчанию емкость строки составляет 80 символов. Однако ее можно уменьшить до 40 знаков, применив оператор WIDTH:
WIDTH 40
Отображение числовой или символьной информации осуществляется путем переписи содержимого выводной строки в участок памяти видимой страницы, начиная с позиции, определяемой текущими координатами текстового курсора. Положение последнего фиксируется в системных переменных CSRLIN (номер строки) и POS (номер столбца) . В GW- и Quick-системах номер столбца опрашивается с помощью функции POS(x), аргумент которой является фиктивным.
^осле вывода очередной порции текстовой информации с помощью оператора PRINT или WRITE, выводной список которых завершается запятой или точкой с запятой, курсор перемещается вправо до конца выводимых данных. Если выводной список заканчивался символом CR ("возврат каретки"), то курсор переводится в начальную позицию следующей строки текстового окна. Вывод в последнюю строку текстового окна завершается подъемом содержимого экрана на одну строку вверх, а курсор переводится в левый нижний угол окна.
Изменение текущей позиции текстового курсора и способа его отображения на экране производится оператором LOCATE:
LOCATE [г] [,[С] [,v],[rl] [,г2]1
Здесь параметры г и с задают соответственно номер строки (от 1 до 25) и номер столбца (от 1 до 80), на пересечении которых перемещается курсор. Параметр v задает признак видимости (v-1) или невидимости (v-О) курсора. Два следующие операнда определяют номера верхней (rl) и нижней (г2) строк в мини-растре знакоместа, между которыми находится мерцающая часть курсора. Строки мини-растра нумеруются сверху вниз от 0.
При очистке экрана или текстового окна (оператор CLS) курсор возвращается в первую позицию начальной строки.
Вывод текстовой информации производится с помощью операторов PRINT, PRINT USING или WRITE, действие которых подробно рассматривалось в п. 3.2.1, 3.2.2 и 3.2.3.
С помощью функции SCREEN программа имеет возможность опросить код (аргумент cf“l) или цвет (аргумент cf=O или опущен) символа, расположенного на пересечении i-й строки и j-ro столбца:
N - SCREEN (i,j [,cfl)
Quick BASIC позволяет переписать содержимое одной страницы видеопамяти в другую страницу по оператору PCOPY.
PCOPY pgl, pg2
Первый операнд определяет номер страницы, из которой копируется информация, а второй - номер страницы-получателя.
5.4.4 Работа с экраном в графических режимах
Экран дисплея переводится в графический режим после выполнения оператора SCREEN n (1 < = п < = 13). Выбор номера п режима должен производиться с учетом типа дисплея, требуемого разрешения и желательной цветовой гаммы. Для управления набором допустимых цветов и установки необходимых цветовых атрибутов (цвет линий, цвет фона) можйд воспользоваться операторами COLOR, PALETTE, PALETTE USING, VIEW. -
Для индикации точек дисплея в графическом режиме используется система экранных (физических) координат, начало которой расположено в верхнем левом углу, а ось у направлена вниз. Физические координаты измеряются в целых числах от нуля до максимальных значений (Хшах, Ушах), однозначно определяемых номером графического режима. Каждая точка экрана, представляющая минимальный элемент изображения — пиксель, характеризуется экранными координатами (х,у) и целочисленным кодом цветности.
Геометрические построения могут производиться как на всей рабо-
123
чей области экрана (0 < - х < - Хшах, 0 < - у < - Ymax), так и на любой прямоугольной области меньшего размера (0 < - Xmin < - х < - Хшах, О < - Ymin < - у < - Ymax), называемой графическим окном. По умолчанию графическое окно совпадает с полным экраном, однако его размеры можно уменьшить с помощью одного из операторов:
VIEWSCREEN (Xmin,Ymin)-(Xmax,Ymax) [,cf [,cb]]
VIEW (dXl,dYl)-(dX2,dY2) [,cf [,cb]]
В первом случае границы графического окна задаются в физических (абсолютных) координатах, а во втором—в приращениях относительно положения графического курсора или так называемой текущей точки. При установке графического режима текущая точка помещается в начало координат. В процессе последующих геометрических построений она перемещается в конечную точку очередной воспроизводимой фигуры.
Программные (математические) координаты точек, задающих контуры отображаемых фигур, могут не совпадать по своим пределам с физическими границами графического окна. Приведение математических координат к физическим производится автоматически, если перед выводом графических объектов установить пределы изменения программных координат:
WINDOW [SCREEN] (Xmin,Ymin)-(Xmax,Ymax)
Преобразование координат из математической системы измерения в физическую или наоборот можно выполнить с помощью функции РМАР (е, i). При i-О или i— 1 эта функция переводит в пиксели значение выражения е, представляющее координату х или у в математической системе измерения. При i=2 или i—3 первый аргумент представляет значение координаты х или у в пикселях, преобразуемое в соответствующую математическую координату.
" Первую группу графических построений составляют операторы отображения элементарных геометрических фигур - точек, отрезков прямых или прямоугольников, дуг окружностей или эллипсов. Отдельная точка строится с помощью оператора PSET или PRESET:
PSET [STEP] (х,у) [,с]
PRESET [STEP] (х,у) [,с]
Здесь (х,у) — математические координаты отображаемой точки, измеряемые либо в абсолютной системе координат, либо в приращениях относительно текущей точки. Последний вариант задается служебным словом STEP в теле оператора. Параметр с задает код цветности отображаемой точки. Если ои задан, то действия операторов PSET и PRESET абсолютно идентичны. При отсутствии параметра с оператор PSET окраши-
124
дает точку в цвет переднего плана, a PRESET - в цвет фона. Таким образом PSET строит точку, a PRESET стирает ее. Независимо от способа построения новая точка становится текущей.
Отрезок прямой или прямоугольник, диагональю которого является заданный отрезок, воспроизводится с помощью оператора UNE:
UNE [[STEP] (xl,yl)]-[STEP] (х2,у2) [,[c][B[F]] [.maska]]
Начальная и конечная точки отрезка задаются координатами (xl,yl) и (х2,у2), которые измеряются либо в абсолютных единицах, либо в приращениях (STEP). Если первая точка не задана, то началом отрезка считается текущая точка.
Параметр с определяет код цветности отображаемого отрезка или границы прямоугольника. Если он не задан, то построение ведется цветом переднего плана, установленным ранее по оператору COLOR. Символ В (от box) задается в том случае, если вместо отрезка прямой должен быть построен прямоугольник. Наличие следующей буквы F (orfill) приводит к окраске (заливке) внутренней области прямоугольника.
Последний параметр, задаваемый целочисленной величиной maska, представляет собой 16-разрядную двоичную шкалу, определяющую способ воспроизведения линии. Маска накладывается на фрагмент отрезка “длиной” в 16 пикселей. Длина измеряется либо по приращению dx, либо по приращению dy в зависимости от угла наклона воспроизводимой прямой. Единичным разрядам маски соответствуют видимые пиксели отрезка, нулевым — невидимые. Затем маска переносится на следующий фрагмент отрезка и эта процедура периодически повторяется. Формируя соответствующую маску, можно строить различные штриховые и штрихпунктирные линии. Маска используется и при заливке прямоугольной области, участвуя при окраске очередной горизонтальной линии растра. •
После отображения отрезка (прямоугольника) текущей точкой становится конечная точка (х2,у2).
Полная окружность (эллипс) или любой ее фрагмент воспроизводится с помощью оператора CIRCLE:
CIRCLE [STEP] (x,y),R [,[c] [,[al] [,a2] [,k]]]]
Точка с абсолютными или относительными (STEP) координатами <х,У) задает центр окружности (эллипса). Параметр R определяет Радиус Rx по оси х (прик<1) или Ry по оси у (при к>1). На самом деле
речь идет не о двух радиусах, а о двух полуосях Rx и Ry, которые участвуют в каноническом уравнении эллипса:
хЛ2/ИхЛ2+уЛ2/ИуЛ2 -1
При Rx-Ry эллипс превращается в окружность, а отношение полуосей Kxy-Rx/Ry становится равным 1. Окружность, воспроизводимая на экране дисплея, трансформируется в эллипс не только за счет несовпадения полуосей, но еще и из-за того, что рабочая область экрана имеет вид удлиненного прямоугольника и единичные шаги по осям х и у имеют различную длину. Для построения идеальной окруж- , ности коэффициент “сжатия” полуосей эллипса выбирается следующим образом:
k-(4/3.) * (Nx/Ny)
Здесь Nx и Ny — количество пикселей соответственно по осям х и у. Параметр с задает код цветности, которым воспроизводится контур фигуры. Если он опущен, то контур окрашивается цветом переднего плана.
Построением дуги окружности или эллипса управляют параметры al и а2, которые задают соответственно углы наклона начального и конечного радиусов-векторов сектора. Эти углы измеряются в радианах и могут принимать любые вещественные значения в диапазоне от -2*(пи) до 2*(пи). Углы отсчитываются против часовой стрелки от положительного направления оси х до соответствующего радиус-вектора. На самом деле границы дуги определяются абсолютными значениями углов al и а2. Отрицательное значение угла вызывает дополнительное построение и соответствующего радиус-вектора. Если оба угла отрицательны, то воспроизводится замкнутый круговой или эллиптический сектор. Этим свойством обычно пользуются при построении круговых диаграмм. По умолчанию al-О и а2»2*(пи), что соответствует построению полной окружности (эллипса).
Отображение окружности или эллипса завершается переводом текущей точки в центр (х,у).
Достаточно мощными графическими возможностями располагает оператор DRAW, тело которого содержит символьную строку, представляющую собой последовательность графических команд, например:
DRAW “UIORIODIOLIO"
Команды отделяются друг от друга пробелами. Каждая графическая команда состоит из кода операции, задаваемого, как правило, одной 126
буквой и определяющего характер построения, вслед за которым располагается необходимая числовая информация. В качестве операндов трафических команд можно использовать значения целочисленных переменных. Перечень графических команд приведен ниже.
формат графической
Пояснение
команды
"Un”
Перемещение на n пикселей вверх
“Dn”
Перемещение на п пикселей вниз
“Ln”
Перемещение на п пикселей влево
“Rn”
Перемещение на п пикселей вправо
“En”
Перемещение на п пикселей под углом 45 градусов
“Hn”
Перемещение на п пикселей под углом 135 градусов
“Gn”
Перемещение на п пикселей под углом 225 градусов
“Fn”
Перемещение на п пикселей под углом 315 градусов
“M[{+l-}]x,y”
Перемещение в точку с абсолютными или относительными координатами (х,у)
"Cn”
Установка кода цветности п, которым будут вестись после
дующие построения
“An”
Установка фиксированного угла поворота (п-0,1,2,3) последующих геометрических элементов. Угол в градусах равен п90.
“TAn”
Установка произвольного угла поворота последующих геометрических элементов в градусах
“Sn”
Установка масштабного множителя, увеличивающего или уменьшающего размеры последующих элементов (по умолчанию действует масштаб S32). Пределы изменения масштабного коэффициента от 1 до 255
“Pp,b”
Установка цвета заливки (р) и цвета рамки (Ь)
“V”
Переход на математические координаты
“X”+VARPTR$(A$)
ыполнение графической подпрограммы, закодированной в переменной А$
дуры масштабирования, переноса и поворота составных частей предоставляют пользователю широкие возможности по формированию сложных изображений.
Если в графическом окне построен любой замкнутый контур, то его внутренняя или наружная область может быть окрашена (залита) в заданный цвет или заполнена периодически повторяющимся узором. Выполняются эти процедуры оператором PAINT, который допускает один из двух следующих форматов:
PAINT (х,у), cfill, chord
PAINT (х,у), maskl$, chord [,mask2$]
Здесь (x,y) — координаты любой внутренней или наружной точки, цвет которой отличается от цвета граничных точек;,
cfill — целочисленное выражение, задающее код цветности для всех точек окрашиваемой (заливаемой) области;
chord — целочисленное выражение, задающее код цветности граничных точек;
mask! $ — символьное значение, содержащее от 1 до 64 знаков, образующих заливающий узор;
mask2$ — символьное значение, задающее вторую маску узора, предотвращающую досрочное прекращение заливки..
При заливке области сплошным цветом особых проблем не возникает, за исключением ситуации, когда заливающий цвет (cfill) совпадает с цветом граничных точек (chord). Область при этом окрашивается, но теперь у нее все внутренние (наружные) точки имеют тот же цвет, что и граничные. Поэтому последующая попытка окрасить такую область в любой другой цвет будет игнорироваться.
Заполнение области узором очень напоминает построение штриховых линий с помощью битовой маски. Однако здесь узор имеет пло- щадный характер и строится следующим образом. Байты маски maskl$ разворачиваются в столбец, образуя прямоугольник шириной в 8 бит и высотой от 1 до 64 бит. Затем этот прямоугольник переносится в начало графического окна и начинает последовательно перемещаться вправо, формируя своими разрядами новое содержание атрибутов цветности внутренних или внешних пикселей области. После окраски точек, захваченных сканирующим прямоугольником, шаблонпереме- щается вниз на свою высоту, и узором начинает покрываться следующая полоса.
Вторая маска mask2$ используется в тех случаях, когда узор наносится по области, ранее покрытой другим узором или залитой цветом, который может встретиться в битовой комбинации нового узора. Например, без второй маски нельзя заполнить красно-синими штриховыми горизонтальными линиями область, окрашенную в синий цвет.
Встреча с первым же синим пикселем прервет процедуру заливки. К досрочному завершению оператора PAINT может привести и совпадение двух соседних байтов заливающего узора.
Для желающих поэкспериментировать с масками и познакомиться со способами формирования узоров предлагаем несколько фрагментов, заимствованных из различных источников:
’ Д.Грайс. Графические средства персонального компьютера
PAINT (160,100), “ABCCEF”, 2, “С”
’D.Herbert. Turbo BASIC Instant Reference
CLS: SCREEN 1,0: COLOR I,I
FOR I%-1 TO 8
READ T%
MASK1$ - MASK1$ + CHR$ (T%)
NEXT 1%
FOR I%-I TO 8
READ T%
MASK2$ - MASK2S + CHR$ (T%)
NEXT 1%
LINE (10,10) - STEP(200,I50), 3, В
PAINT STEP (-5,-5), MASK2$, 3
LINE (60,60) - STEP(100,50), 3, В
PAINT STEP (-5,-5), MASK I $, 3, MASK2$
DATA 24,60,90,153,96,36,102,153
DATA 24,36,66,129,129,66,36,24
’V-V-Hari, Murat Tanik & Udo W.Pooch.
* Illustrated Quick BASIC
SCREEN I : CLS
MASKl$-CHR$(120)+CHR$(0)+CHR$(I28)+CHR$(0)+CHR$(129)+CHR$(0)
MASK2$ - CHR$(&H80)+CHR$(&H60)+CHR$(&II30)+CHR$(&H6)+CHR$(&Hl) LINE (40,40) - (300,150)„B
PAINT (50,50), MASK2$
Информация о пикселях, отображаемых в графическом окне, хранится в видеоЗУ, допускающем не только режим записи (вывода новых данных), но и режим чтения. Для реализации процедур опроса графических атрибутов указанного пикселя или текущей точки (графического курсора) используется функция POINT, допускающая две модификации :
COLOR-POINT (х,у)
129129COORD - POINT (n)
129
129
5. Ю. Л КРТИПП
В первом варианте функция POINT выдает атрибут цветности пикселя с заданными координатами. Второй вариант позволяет опросить координату х (п=0,2) или у (п-1,3) текущей точки, которая может быть выдана в пикселях (п-0,1) или в единицах, установленных программой по оператору WINDOW SCREEN (n—2,3).
С помощью функции POINT можно просканировать точки некоторой области экрана и подвергнуть их атрибуты цветности определенным преобразованиям. Например, следующий фрагмент программы осуществляет замену позитивного изображения на экране негативным:
SCREEN 2
FOR 1-0 ТО 199
FOR J-0 TO 639
PSET (I.J), I - POINT (I,J)
NEXT J
NEXT I
Аналогичным способом в цикле можно прочитать и запомнить состояние всех точек некоторой прямоугольной области экрана. Однако процедуры такого рода выполняются очень медленно и связаны с большими затратами памяти, так как на каждый пиксель будет занято не менее 2 байт вместо 1-4 бит.
Гораздо более эффективными являются процедуры обмена с видеопамятью с помощью операторов GET и PUT:
GET [STEP](xI,yl) - [STEP] (х2,у2), A%
PUT [STEP] (x.y), A%' [.mode]
В первом операторе точки (xl,yl) и (х2,у2) задают прямоугольную область, сведения об атрибутах цветности всех ее точек запоминаются в элементах целочисленного массива А %. Процедура чтения соответствующего фрагмента видеоЗУ начинается с левого верхнего угла прямоугольника — пикселя с координатами (xl,yl). Затем извлекается атрибут цветности следующего по строке пикселя - (xl+l,yl) и т.д. Когда набирается полный байт, содержащий сведения о смежных пикселях строки (8,4 или 2 пикселя в зависимости от типа дисплея и установленного режима), его записывают в массив А%. Последний байт сканируемой строки может оказаться неполным, и все его незаполненные биты сбрасываются в нуль. Первым двум элементам массива А % присваиваются соответственно число битов в строке обрабатываемого прямоугольника и число строк.
Длина в байтах массива А %, необходимая для размещения информации об изображении, подсчитывается по формуле:
130
L - 4 + INT (((x2 - xl + 1) * bpp + 7) / 8) * np * (y2 - yl +1)
Здесь bpp — число битов на пиксель в слое видеоЗУ;
Прчисло слоев видеоЗУ.
Параметры bpp и пр зависят от установленного режима работы и размера видеопамяти (см. табл.12).
Таблица 12
Режим
bpp
пр
1
2
1
2
1
1
7.8
1
4
9
1
2 (EGA, 64 Кбайт)
4 (EGA, >64 Кбайт)
10
1
2
. 11
1
1
12
1
4
13
8
1
Сформированный таким способом графический образ прямоугольной области экрана может быть использован для модификации изображения или его запоминания в дисковом файле:
BSAVE "IMAGE1", VARPTR(A% (0)), L
Здесь IMAGE1 —идентификатор дискового файла;
VARPTR(A% (0)) — начальный адрес массива А%;
L — длина массива А % в байтах.
Оператор PUT переносит прямоугольный фрагмент изображения из массива А % в область видеопамяти, начиная с пикселя с координатами (х,у). Третий параметр mode определяет режим взаимодействия вновь заносимых атрибутов цветности с находящимися в видеоЗУ. Задается он одним из пяти служебных слов и принимает следующие значения:
PSET — атрибут цветности из массива А % замещает прежний экранный атрибут пикселя;
PRESET — новый атрибут цветности инвертируется и замещает прежний экранный атрибут пикселя;
XOR — новый атрибут цветности поразрядно складывается с экранным по модулю 2 (логическая операция “исключающее ИЛИ”);
OR — новый атрибут цветности логически складывается с экранным;
AND — новый атрибут цветности логически умножается на экранный.
Для оживления изображения на экране обычно прибегают к следующему приему. Сначала прямоугольный фрагмент запоминается и сразу выдается в ту же область с режимом XOR. При этом все биты цветовых атрибутов становятся равными нулю, что соответствует заливке прямоугольника цветом фона, т.е. стиранию прежнего изображения. Затем повторно выполняется оператор PUT, но уже со смещением точки привязки области. Скорость перемещения “картинки” по экрану можно регулировать путем задержки (пустой цикл, оператор DELAY) между стиранием прежнего изображения и выводом нового. Для увеличения скорости вывода можно включить режим TURBO, если в компьютере имеется возможность повысить тактовую частоту.
Использование функций BIOSдля управления дисплеями
Процесс совершенствования аппаратуры обычно опережает разработку прикладного программного обеспечения. Поэтому некоторые возможности современных дисплеев не обеспечиваются стандартными процедурами Бейсик-систем, особенно если мы имеем дело с их ранними версиями. Однако Turbo- и Quick- BASIC предлагают средства для моделирования машинной команды прерывания (INT), что позволяет обратиться к дисплейному сервису BIOS путем вызова соответствующей процедуры:
Turbo : CALL INTERRUPT nlnt
Quick : CALL INTERRUPT (nlnt, inReg, outReg)
CALL INTERRUPTX (nlnt, inReg, outReg)
CALL INT86OLD (nlnt, inArray, outArray)
CALL INT86OLDX (nlnt, inArray, outArray)
Здесь nlnt — номер прерывания, определяющий класс функций BIOS;
inReg — переменная типа запись, поля которой предназначены для хранения входной информации, переписываемой системой в соответствующие регистры центрального процессора перед обращением к функции BIOS;
outReg — аналогичная переменная, в поля которой система переносит выходную информацию из регистров центрального процессора после выполнения процедуры BIOS;
inArray — целочисленный массив с входной информацией, аналогичной записи inReg;
outArray — целочисленный массив с выходной информацией, аналогичной записи outReg.
Все процедуры BIOS получают входную информацию в виде содержимого тех или иных регистров центрального процессора. Всего таких 132
16-разрядных регистров 10, и они имеют стандартные обозначения - ДХ, ВХ, СХ, DX, BP, SI, DI, Flags, DS и ES. Не вдаваясь в конкретное назначение каждого из них, отметим лишь, что в ряде процедур BIOS раздельно задействованы младшие (к первой букве имени регистра добавляется L - от Low) и старшие (к первой букве имени регистра добавляется Н - от High) разряды регистра. Очевидно, что содержимое полного регистра и его компонент связаны элементарными соотношениями :
AX-256*AH + AL
AL-АХ MOD 256
АН-(АХ-AL) /256
В Turbo-BASIC область памяти, предназначенная для хранения содержимого регистров CPU, считается принадлежностью системы. Компоненты памяти заполняются по оператору REG:
REG riReg, val
Здесь riReg — числовой номер из интервала от 0 до 9, определяющий позицию соответствующего регистра в системном массиве (0 - Flags, 1 - АХ, 2 - ВХ, 3 - СХ, 4 - DX, 5-SI, 6-DI, 7-BP.8-DS, 9-ES);
vat — целочисленное значение, записываемое в выбранный элемент служебного массива.
Заполнение нужных элементов служебного массива должно быть выполнено до обращения к подпрограмме INTERRUPT. После обработки прерывания содержимое всех регистров CPU переносится в тот же служебный массив, и доступ к нужной компоненте организуется с помощью функции REG(nReg).
В Quick-BASIC области с информацией для регистров CPU могут быть разделены и описываются как обычные переменные задачи:
TYPE RegType
АХ AS INTEGER ВХ AS INTEGER CX AS INTEGER DX AS INTEGER BP AS INTEGER SI AS INTEGER DI AS INTEGER Flags AS INTEGER
DS AS INTEGER ES AS INTEGER
END TYPE inReg AS RegType
inReg. AX -1
CALL INTERRUPT (&H10, inReg, inReg)
Единственное отличие подпрограммы INTERRUPTX заключается в том, что она обеспечивает работу с полным набором из 10 регистров, тогда как в процедуре INTERRUPT используются только первые 8. В подпрограммах INT86OLD и INT86XOLD регистровые области описываются как обычные целочисленные массивы (inArray(l)=AX, inArray (2)=ВХ,...):
DIM inArray (1 ТО 10) AS INTEGER
DIM outArray (1 TO 10) AS INTEGER
s
Видеосервис BIOS реализуется с помощью прерывания &10H (более 60 функций и подфункций). Номер функции задается содержимым регистра АН, номер подфункции — содержимым регистра AL или BL. Подробное описание каждой процедуры видеосервиса можно найти в технической документации по видеосервису BIOS. Описание отдельных функций можно встретить в довольно редких пока публикациях по ассемблеру (например: Скэнлон Л. Персональные ЭВМ фирмы IBM PC и XT. Программирование на языке ассемблера.-М.: Радио и связь, 1989). Однако техническая литература практически недоступна нашим пользователям, так как кооперативные поставки зарубежных средств вычислительной техники ведутся, как правило, без всякой документации, а дисплеи на отечественных ПЭВМ типа ЕС1840 и ЕС1841 пока еще находятся на “первобытном” уровне, поэтому автор рассчитывает на снисхождение со стороны любителей Бейсика за включение в настоящий раздел, казалось бы, лишней информации о дисплейных процедурах (табл. 13).
Таблица 13
Номер функции (AH/AL)
Выполняемая операция (реализация средствами BASIC)
Содержимое регистров
0
Дисплейные функции 0-16 Установка режима работы монитора
AL - номер режима (см.
1
(оператор SCREEN, частично) Установка габаритов курсора
табл. 9)
СН - начальная строка
2
(оператор LOCATE)
Установка курсора в заданную позицию
мини-растра
CL — конечная строка минирастра
ВН - иомер страницы (0 для
(оператор LOCATE)
графического режима CGA) DH - строка (от 0) DL - столбец (от 0)
Номер функции (AH/AL)
Выполняемая операция (реализация средствами BASIC)
Содержимое регистров
3
Опрос позиции курсора и его размеров (функция POINT, частично)
ВН - номер страницы Выходная информация DH - номер строки DL-номер столбца СН - начальная строка мини-растра CL - конечная строка мини-растра
4
Опрос состояния светового пера. Не поддерживается картой VGA (функция PEN)
Выходная информация АН -0:1 (триггер СП) DH — номер строки DL-номер столбца СН или СХ - координата х в пикселях
ВХ — координата у в пикселях
5
Установка номера активной страницы (оператор SCREEN)
AL - номер страницы (от 0)
6
Подъем текстовой информации в заданной прямоугольной области.
При AL- 0 происходит очистка окна
AL — число строк, на которое происходит подъем
ВН - атрибут для очищаемых строк
СН — номер строки верхнего левого угла окна
CL - номер столбца верхнего левого угла окна•
DH - номер строки нижнего правого угла окна
DL — номер столбца нижнего правого угла окна
7
Спуск текстовой информации в заданной прямоугольной области.
При AL - 0 происходит очистка окна
См. функцию 6
8
Опрос кода символа и атрибута цветности в позиции курсора. В графическом режиме атрибут смысла не имеет
ВН - номер страницы Выходная информация АН-атрибут.
AL-код ASCII
9
Вывод символа и атрибута в позицию кур-
AL - код ASCII
10
сора с возможностью размножения символа. Позиция курсора не меняется. В графическом режиме три младших бита BL — цвет переднего плана. Если бит 7 в BL установлен в “ Г', то код цветности складывается по операции XOR с цветом фона
BL-атрибут
ВН — номер активной страницы (для текстового режима) СХ - число повторений
Вывод символа подобно функции 9 без изменения атрибута цветности в текстовом режиме
См. функцию 9
Номер функции (AH/AL)
Выполняемая операция (реализация средствами BASIC)
Содержимое регистров
11
Установка параметров текущей палитры дляССА (операторы SCREEN и COLOR)
ВН - 0 для установки цвета рамки или фона
ВН -1 для выбора палитры BL - цвет фона в графическом режиме
BL - цвет рамки в текстовом режиме при ВН - 0
BL - 0:1 (номер палитры при
ВН-1)-
DH- строка
DL - столбец
12
Вывод пикселя заданного цвета в позицию
AL-n*16+с
с заданными координатами. При п-0 новый
(с — цвет 0-15, п — способ
цвет пикселя замещает атрибут цветности в видеоЗУ, при п-8 новый цвет складывается с прежним по XOR (операторы PSET и PRESET)
вывода)
ВН - дисплейная страница DX - строка растра
СХ - столбец растра
13
Опрос цвета пикселя, расположенного в указанной позиции (функция POINT)
ВН - дисплейная страница DX - строка растра СХ ~ столбец растра Выходная информация AL - цвет пикселя
14
Вывод символа в режиме TTY (телетайпа), при котором символы с кодами 07 (звонок), 08 (возврат на символ), ОА (перевод строки) и OD (возврат каретки) не заносятся в вццеоЗУ, а выполняют свои прямые функции. Курсор при выводе отображаемого символа продвигается на одну позицию вправо
AL - код ASCII
ВН - активная страница
(не используется в графическом режиме)
BL- цвет символа (применяется только в графическом режиме)
15
Опрос текущего видеорежима
Выходная информация
AL - номер режима
ВН - число символов в строке
BL — номер активной страницы
16/0
Запись кода цвета в указанный регистр палитры для карт EGA и VGA. По умолчанию в регистре с номером п задан цвет п (оператор PALETTE)
AL- 0 (номер подфункции)
ВН - код цвета (от 0)
BL - номер регистра (отсчет отО)
16/1
Установка цвета в регистре Overscan для EGA и VGA
AL-1 ВН - код цвета
16/2
Запись массива кодов цветности в 16 регистров палитры и в регистр Overscan для EGA и VGA .
(оператор PALETTE USING)
AL-2
ES:DX- указатель на 17-байтовый массив с кодами цветности
16/3
Переключение режимов мерцания и яркости для EGA, VGA. Начальные значения обоих разрядов — 00 (обычная яркость, иет мерцания). Переключение меняет текущий режим на противоположный
AL-3
BL - 0 (инверсия яркости)
BL-1 (инверсия мерцания)
Номер функции (AH/AL)
Выполняемая операция (реализация средствами BASIC)
Содержимое регистров
16/7
Опрос содержимого указанного регистра палитры (только для VGA)
AL-7
BL- номер регистра Выходная информация ВН - содержимое регистра
16/8
Опрос содержимого регистра Overscan (только для VGA)
AL—8
Выходная информация ВН - содержимое регистра
16/9
Считывание содержимого всех регистров палитры и регистра Overscan в указанный массив (только для VGA)
AL—9
ES:DX - указатель на 17-байтовый массив
16/16
Запись кода цветности в регистр DAC с указанным номером (только для VGA)
AL-16
DX - номер регистра (от 0 до 255)
СН - интенсивность зеленого цвета (от 0 до 63)
CL - интенсивность синего цвета (от 0 до 63)
DH — интенсивность красного цвета (от 0 до 63)
16/18
Запись кодов цветности в заданный блок регистров DAC из массива, в котором чередуются интенсивности RGB-компонент (только для VGA)
AL-18
ВХ - номер первого регистра DAC
СХ-количество заполняемых
регистров
ES:DX- указатель на массив с кодами цветности
16/19
Установка цветового режима страниц (BIX)) или выбор (BL-1) страницы (только для VGA)
AL-19
BL-011
ВН -0-4 страницы с 64 цветами
ВН -1 - 16 страниц с 16 цветами
ВН - номер страницы
16/21
Опрос содержимого указанного регистра DAC (только для VGA)
AL-21
ВХ - номер регистра Выходная информация СН - интенсивность зеленого цвета
CL - интенсивность синего цвета
DH - интенсивность красного цвета
16/23
Считывание содержимого блока регистров DAC в указанный массив (только для VGA)
AL-23
ВХ - номер первого регистра DAC
СХ - количество опрашиваемых регистров
ES:DX - указатель на массив- получатель
Номер функции (AH/AL)
Выполняемая операция (реализация средствами BASIC)
Содержимое регистров
16/26
Опрос номера текущей цветовой страницы (только для VGA)
AL-26
Выходная информация ВН - номер страницы BL - цветовой режим
16/27
Суммирование кодов цветности для формирования сигнала в полутоновой шкале: I-0.3xI(R(J))+0.59xI(G(J))+0.11xi(B(J)) Суммирование ведется по всем J для указанной группы регистров. Результат заносится в каждую из RGB-компонент регистра управления цветом (только для VGA)
AL-27
ВХ - номер первого DAC
СХ - количество суммируемых DAC
Дисплейная функция 17 (для карт EGA и VGA)
Номер подфункции (AL)
Выполняемая операция
Содержимое регистров
0
Загрузка шрифта пользователя в область видеопамяти, предназначенную для разме-
BL - номер загружаемого блока видеоЗУ
щения таблицы контуров-символов
ВН - число байтов на образ символа
СХ - число символов в таблице
DX - смещение символов в таблице
ES:BP - указатель на начало таблицы
1
Загрузка из постоянного ЗУ (ROM — Read Only Memory) набора символов для монохромного режима без сброса дисплейного оборудования. Размер символов 8*14
BL - номер загружаемого блока
2
Загрузка из ПЗУ набора символов размером 8*8 с контурами двойной толщины
BL - номер загружаемого блока
3
Установка разрядов в спецификации блока шрифта. Эта функция определяет выбор двух подмножеств символов из четырех возможных по третьему биту атрибута. Разряды О,Гй 4 кода BL задают номер подмножества при нулевом бите в атрибуте, разряды 2,3 и 5'— при единичном бите
BL — устанавливаемый код
4
Загрузка из ПЗУ набора символов размером 8*16
BL - номер загружаемого блока
16
Загрузка шрифта пользователя. Эта процедура напоминает функцию 0, но она должна выполняться сразу вслед за установкой режима при нулевой активной странице
ВН - число байтов иа символ BL - номер загружаемого блока
DX - смещение символа в таблице
ES:BP - указатель на начало таблицы
Номер подфункции (AL)
Выполняемая операция
Содержимое регистров
17
Загрузка из 113 У набора символов размером 8*14 для монохромного режима
BL - номер загружаемого блока
18
Загрузка из ПЗУ набора символов размером 8*8 и контуром двойной толщины
BL- номер загружаемого блока
19
Загрузка из ПЗУ набора символов размером 8*16
BL- номер загружаемого блока
32
Установка указателя на вторую половину кодировочной таблицы пользовательского шрифта с кодами ASCII от 128 до 255
ES:BP - указатель на начало таблицы
33
Установка указателя кодировочной таблицы на пользовательский набор графических символов
BL-1:2:3 для 14, 25или 43 строк на экране
СХ - число байтов на символ ES:BP - указатель на начало таблицы
34
Загрузка из ПЗУ таблицы символов размером 8*14 в графическом режиме
BL - см. подфункцию 33
35
Загрузка из ПЗУ таблицы символов размером 8*8 в графическом режиме
BL — см. подфункцию 33
36
Загрузка из ПЗУ таблицы символов размером 8*16 в графическом режиме
BL- см. подфункцию 33
48
Опрос параметров генератора символов. Результаты выдаются в регистрах СХ (число байтов на символ), DL (число символов в строке дисплея минус 1) и паре ES:BP (адрес соответствующей таблицы)
ВН - 0 — указатель прерывания IFh
ВН -1 — указатель прерывания 43h
ВН -2 — указатель ПЗУ 8*14 ВН - 3 — указатель ПЗУ 8*8
ВН - 4 — указатель ПЗУ 8*8 для символов с кодами от 128 ВН -5 — указатель ПЗУ 9*14 ВН- 6 — указатель ПЗУ 9*16
Дисплейная функция 18
Номер подфункции (BL)
Выполняемая операция
Содержимое регистров
16
Опрос параметров карты EGA или VGA. Комбинация переключателей SW1, SW2, SW3 и SW4 определяет текущую конфигурацию карты
Выходная информация
ВН — 0 — установлен цветной режим
ВН — 1 — установлен чернобелый режим
BL-0 (ОЗУ-64Кбайт)
BL-1 (ОЗУ- 128 Кбайт)
BL-2 (ОЗУ- 192Кбайт)
BL - 3 (ОЗУ - 256 Кбайт) CL - код переключателей
SW1 SW2 SW3
SW4
ЕАМА
CGA
10
0
1
Первичный Вторичный
—
CD, 40 х 25
1 1
1
1
Вторичный Первичный
—
CD, 40 х 25
00
0
1
Первичный Вторичный
—
CD, 80 х 25
01
1
1
Вторичный Первичный
—
CD, 80 х 25
1 1
1
0
Первичный Вторичный
—
ECD, режим эмуляции
1 с
1
1
Вторичный Первичный
—
ECD, режим эмуляции
01
1
0
Первичный Вторичный
—
3
ECD, режим высокого
разрешения
00
1
1
Вторичный Первичный
—
ECD, режим высокого
разрешения
1 с
1
0
Первичный—
MD
Вторичный 40x25
1 1
0
1
Вторичный—
MD
Первичный 40x25
0 с
1
0
Первичный—
MD
Вторичный 80x25
0
0
1
Вторичный—
MD
Первичный 80x25
Карта VGA не имеет физических переключателей. Соответствующая информация об установленном режиме фиксируется в ОЗУ и извлекается с помощью функции BIOS
32 ■
Выбор альтернативной программы печати, позволяющей при нажатии клавиши PrtScr получить копию экрана в режиме 43 строк (для EGA и VGA)
48
Установка числа строк растра текстовых режимов (только для VGA)
AL - 0 (200 строк) AL - 1 (350 строк) AL- 2 (400 строк)
49
Установка или отмена признака блокировки загрузки стандартных значений в регистры палитры при смене режима работы монитора (только для VGA)
AL - 0 (загрузка разрешена) AL-1 (регистры не изменяют ся)
50
Разрешение (AL - 0) или блокировка (AL - 1) доступа к входному видеопорту и буферу декодирования адресов (только для VGA)
AL-011
51
Разрешение (AL - 0) или блокировка (AL - 1) суммирования цветовых компонент для формирования полутонового сигнала (только для VGA)
AL-011
Номер подфункции (BL)
Выполняемая операция
Содержимое регистров
52
Разрешение (AL - 0) или блокировка (AL-1) режима эмуляции курсора (только для VGA)
AL—011
53
Установка ключей дисплея. Результат (AL -18) свидетельствует о правильности задания входной информации. Обращение с AL - 0 или 1 должно предшествовать обращению с AL - 2 или 3 (только для VGA)
AL - 0 (ключ адаптера в “0" — off)
AL - 1 (ключ планарного дисплея в ”1" — on)
AL - 2 (ключ активности дисплея в "0" — off)
AL — 3 (ключ активности дисплея в ”1” — on)
ES:DY - указатель на буфер в 128 байт
54
Разрешение (AL - 0) или блокировка (AL - 1) доступа к выходному видеопорту
AL-011
Дисплейная функция 19
Номер подфункции (AL)
Выполняемая операция (реализация средствами BASIC)
Содержимое регистров
0
Вывод строки символов, начиная с указанной позиции дисплея (только для VGA). После вывода курсор остается в своей начальной позиции (операторы LOCATE, COLOR и PRINT)
ВН - номер страницы
BL - атрибут
СХ - количество символов в строке
DH - строка на экране
DL-столбец
ES:BP - указатель на начало строки
1
Вывод строки символов по такой же информации для EGA и VGA. После вывода курсор перемещается в ближайшую свободную позицию вслед за отображенным текстом (операторы LOCATE, COLOR и PRINT)
См. подфункцию 0
2
Вывод строки символов, в которой каждая позиция экрана представлена двумя байтами — кодом ASCII и атрибутом. После вывода курсор устанавливается на первый отображенный символ (для EGA и VGA)
ВН - номер страницы
СХ - число символов и атрибутов в строке
DH - строка на экране
DL-столбец
ES:BP - указатель на начало строки
3
Процедура, аналогичная функции 2 с позиционированием курсора в конце выводимой строки
См. подфункцию 2
5.5. Взаимодействие с активнымивнешними устройствами
Работа с активными внешними устройствами базируется на аппарате событий и использует механизм прерываний. Идея заключается в том, что в момент возникновения события, который программе заранее не известен, генерируется сигнал прерывания. Работающая программа располагает тремя вариантами поведения. Во-первых, она может проигнорировать возникшее событие, если заранее позаботилась об установке режима блокировки соответствующего сигнала. Во- вторых, программа может запомнить факт появления события, но отложить ("заморозить") его обработку в связи с тем, что занята выполнением более срочных дел. Наконец, работа программы может быть немедленно прервана с целью передачи управления пользовательской или системной подпрограмме обработки неотложного события.
Любая из этих линий поведения программируется с помощью одной из модификаций оператора выбора способа реакции на событие:
тип события ON — разрешение немедленного прерывания в момент возникновения события или перехода на подпрограмму ранее “замороженного” прерывания;
тип события OFF — блокировка реакции на прерывание;
тип события STOP — “замораживание” реакции на прерывание.
Назначение точки входа (метки или номера строки N) в пользовательскую подпрограмму обработки прерывания и установление связи между этой процедурой и типом события выполняются одной из разновидностей оператора ON:
ON тип события GOSUB N
Естественно, что такое назначение должно состояться заблаговременно, и обычно такие операторы помещаются в начало программы. Включение режима слежения за определенным событием означает, что после выполнения каждого оператора программы будет выполняться проверка соответствующего системного признака. Таким образом, возникновение физического сигнала прерывания не прервет текущий оператор и даст ему доработать до конца.
Во время работы подпрограммы может появиться необходимость в отмене или переназначении ранее объявленной процедуры обработки прерывания. Это выполняется повторным назначением с указанием нулевой строки в качестве точки входа, например:
ON KEY GOSUB О
С завершением работы подпрограммы обработки прерывания связана еще одна деталь общего характера. Выход из нее осуществляется либо по безадресному оператору RETURN, либо по оператору RETURN с указанием конкретной точки возврата. В первом случае работа прерванной программы продолжается с той точки, где ее застигло возникшее событие. Во втором случае выход из подпрограммы обработки прерывания происходит в заранее обусловленную точку. Ниже обсуждаются операторы, функции и системные переменные, связанные с обработкой различных событий.
Клавиатура
Операции ввода обычных данных с клавиатуры, выполняемые по запросу программы и сопровождающиеся как отображением набираемой пользователем информации, так и блокировкой эхо-сигнала при наборе специальных сообщений, ранее обсуждались в разделах 3.1.2 и 4.1. Однако клавиатура современного компьютера,, содержащая 101 или 102 клавиши, наряду с отображаемыми и управляющими кодами позволяет работать со специальными — функциональными или программируемыми клавишами.
Специфика функциональных клавиш с обозначениями Fl, F2,... заключается в том, что нажатие любой из них сопровождается выдачей в ЭВМ особого сигнала прерывания. Это событие перехватывается системной программой и может быть использовано для реализации некоторых типовых процедур. Например, в GW-BASIC за каждой из первых десяти функциональных клавиш закреплена определенная строка, воспринимаемая как директива или ее начальный фрагмент. При нажатии такой клавиши закрепленный за ней текст появляется в текущей строке дисплея, и если он завершается управляющим кодом &H0D ("возврат каретки"), соответствующая директива начинает немедленно выполняться.
Запуск GW-системы сопровождается демонстрацией в служебной строке экрана тех текстов, которые по умолчанию закреплены за клавишами F1 — F10. Можно увидеть эти тексты и в более удобном (полном) формате, если выполнить оператор (директиву) KEY LIST. Служебная строка дисплея может быть освобождена системой и передана задаче для использования полного экрана после выполнения оператора KEY OFF. Восстановление статуса служебной строки осуществляется оператором KEY ON.
Рассматриваемые BASIC-системы предоставляют пользователю возможность закрепить за указанной функциональной клавишей новый текст, содержащий не более 15 символов:
KEY п, "новый текст”
Здесь п — номер функциональной клавиши, который может принадлежать диапазону 1-20(GW-BASIC), 1-10или1-12(Turbo-BASIC), [1-10,30,31] (Quick-BASIC). Под номерами 30 и 31 в Quick-системе выступают клавиши Fl 1 иЕ12.
Закрепление за функциональными клавишами часто повторяющихся фрагментов может ускорить процедуру набора данных.
Описанное выше свойство функциональных клавиш следует отнести скорее к разряду пассивных, так как оно не связано с вмешательством человека в процесс работы программы. Однако если функциональная клавиша нажимается во время выполнения программы, то закрепленный за ней текст игнорируется. Вместо этого система имитирует активное событие, характеризуемое номером п нажатой клавиши. Это событие может быть заблаговременно предусмотрено в программе:
KEY (п) { ON I OFF I STOP }
ON KEY (n) GOSUB N
Номер n в этих операторах должен принадлежать диапазону 1-20 (GW), [1-25,28,29] (Turbo) или [1-25,30,31 ] (Quick). В связи с тем, что физическое количество функциональных клавиш обычно не превышает 10 -12, их набор искусственно расширяют путем подключения клавиш управления курсором (n=l 1 - сдвиг вверх, n—12 - сдвиг влево, п=13 - сдвиг вправо, п=14 - сдвиг вниз) и комбинацией двух одновременно нажатых клавиш. Настоящие клавиши F11 и F12 выступают под номерами 28,29 (Turbo) или 30,31 (Quick). Двухсимвольные функциональные “клавиши” с номерами 15-20 (GW) или 15-25 (Quick, Turbo) относятся к разряду определяемых пользователем. Одним из таких символов должен быть управляющий код из числа клавиш CapsLock (код - &Н40), NumLock (код - &Н20), Alt (код - &Н08), Ctrl (код - &Н04), левый Shift (код - &Н01), правый Shift (код - &Н02). В качестве второго символа в паре с первой управляющей клавишей может выступать практически любая другая клавиша по усмотрению пользователя. Объявление функциональной пары с номером п (п >14) выполняется с помощью следующего оператора:
KEY п, CHR$ (HexCode) + CHR$ (ScanCode)
Здесь HexCode — шестнадцатеричный код одной из вышеперечисленных управляющих клавиш, a ScanCode — внутренний код второй клавиши. Некоторое неудобство состоит в том, что скан-коды символов ие совпадают с их кодировкой в таблице ASCII, и приходится иметь дело с еще одной кодировочной таблицей, содержимое которой
144
зависит от типа используемой клавиатуры. Для большинства современных клавиатур внутренняя нумерация клавиш ведется слева направо по рядам (Esc - 1, !/1 - 2, @/2 - 3,... возврат - 14, Tab - 15, Q - 16, W - 17, Е - 18, R - 19,...).
Световое перо
К числу дополнительных устройств, которыми изредка комплектуются персональные ЭВМ, относится световое перо (СП). Оно используется для идентификации знакоместа или пикселя экрана, к которому пользователь подвел кончик пера. На кончике пера находятся миниатюрная линза и светочувствительный элемент, фиксирующий момент времени, в который под пером оказался луч развертки. По разнице между временем фиксации луча и моментом начала развертки контроллер дисплея вычисляет координаты местоположения светового пера.
Рядом с кончиком пера находится микровыключатель, состояние которого можно опросить через аппаратуру контроллера. Нажатие выключателя приводит к активизации пера. Для фиксации точки на экране к ней подводят перо практически вплотную к дисплею и нажимают переключатель.
Опрос состояния светового пера выполняется по прерыванию INT 10h (функция АН=4), к которому можно обратиться как в момент активизации пера (инициатива принадлежит пользователю), так и в любой другой момент времени по инициативе программы. Последняя возможность реализуется функцией PEN (п), перечень значений которой зависит от аргумента (табл. 14).
Таблица 14
п
PEN(n)
Пояснение
0
0
Микровыключатель нажимался хотя бы раз с момента последнего опроса состояния СП
-1
Микровыключатель больше не нажимался
1
Xold
Старая координата х (в пикселях) положения СП в момент его опроса при предшествующей активизации
2
Void
Старая координата у
3
0
В данный момент микровыключатель не нажат
-1
В данный момент микровыключатель нажат
4
Xnew
Новая координата х (в пикселях) текущего положения СП
5
Ynew
Новая координата у
6
Rold
Старый номер строки (от 1 до 24) положения СП в момент его опроса при предшествующей активизации
7
Cold
Старый номер столбца (от 1 до 40 или 80)
8
Rnew
Номер строки текущего положения СП
9
Cnew
Номер столбца текущего положения СП
Для анализа состояния пера в момент его активизации программа должна разрешить реакцию на такое событие (PEN ON) и предусмотреть программу его обработки:
ON PEN GOSUB 1500
Разрешение прерывания со стороны СП замедляет процесс выполнения программы, так как система должна периодически проводить опрос состояния пера. На тех участках работы программы, где статус СП можно проигнорировать, контроль за состоянием пера отключают (PEN OFF) или замораживают (PEN STOP).
В качестве примера работы с СП приведем фрагмент программы, в котором производятся отслеживание положения пера в момент его активизации и фиксация этого места на экране точками красного цвета: *
10 ON PEN GOSUB 1000
20 PEN ON
1000 X-PEN(4) : Y-PEN(5)
1010 PSET (X,Y), 4
1020 RETURN
После вывода очередной “активной” точки программа продолжает свою работу с прерванного места.
Игровые пульты (джойстики)
Игровой порт с адресом 20 lh может обслуживать одновременно два двухкоординатных рычажковых пульта ("джойстики") или четыре однокоординатных игровых устройства (рычажковые или осевые приводы потенциометров, снабженных аналого-цифровыми преобразователями).
Остановимся несколько подробнее на джойстиках в связи с ориентацией на них в рассматриваемых версиях Бейсика. Конструктивно джойстик представляет собой рычаг на подставке, обладающий двумя степенями свободы и приводящий в действие два связанных с ним датчика координат X и Y. На подставке и в верхней части рукоятки джойстика находятся кнопки (клавиши), количество которых зависит от модели. Обычно все кнопки разделяются на две группы, так что нажатие любой кнопки из группы вызывает абсолютно одинаковый эффект. Человек нажимает ту кнопку, которая для него удобнее расположена.
Для того чтобы различать джойстики и их кнопки, используем
146
следующую мнемонику — сами рычаги будем обозначать буквами А или В, а связанные с ними кнопки — через А1 и А2 (первая и вторая кнопки джойстика А), В1 и В2 (кнопки джойстика В).
Игровой порт обеспечивает опрос координат X и Y, пропорциональных отклонению рычага от нейтрального положения, и состояния кнопок любого джойстика. Средствами операционной системы эти процедуры осуществляются путем прерывания INT 15h с входной информацией АН= 84h и DX=O (опрос состояния клавиш) или DX=1 (опрос координат). В Бейсике для управления джойстиками используются функции STICK(n), STRIG(n), а также операторы STRIG ON I OFF I STOP и ON STRIG(n) GOSUB N.
функция STICK(n) в зависимости от аргумента выдает координату джойстиков А (при п=0) и В (при п=2) или X джойстиков А (при п-1) и В (при п=3). Так как конструкции джойстиков достаточно разнообразны и входящие в их состав преобразователи “аналог-код” имеют различное разрешение, то игровой пульт целесообразно протестировать на диапазоны (Xmin, Хшах) и (Ymin, Ymax).
Это поможет выполнить программа, заимствованная из книги Р. Журдена “Справочник программиста IBM PC”, перевод которой готовится в издательстве “Мир”. Единственная хитрость, подмеченная автором этой программы, заключается в том, что получению любой координаты STICK (п) для п-1,2 или 3 обязательно должно предшествовать холостое обращение с нулевым аргументом. Оно обеспечивает сброс прежних показаний координат и выдачу их истинных текущих значений.
110 STRIG ON : ’Разрешили прерывания от нажатия клавиш
120 V-STRIG (0) :’Очистка старых показаний
130 PRINT “Нажми кнопку 1 в крайнем левом положении”
140 Xmin-STICK(0)
150 IF STRIG (0) - 0 THEN 140:’ Повтор до нажатия
155 ’Организуем временную задержку
160 STRIG OFF: FOR N-l TO 1000 : NEXT: STRIG ON
170 PRINT “Нажми кнопку 1 в крайнем правом положении”
180 Xmax-STICK (0)
190 IF STRIG(O) - 0 THEN 180: ’ Повтор до нажатия
200 STRIG OFF: FOR N-l TO 1000: NEXT: STRIG ON
210 PRINT “Нажми кнопку 1 в крайнем верхнем положении”
220 V-STICK(O) : Ymin-STICK(l)
230 IF STRIG (0) - 0 THEN 220: ’ Повтор до нажатия
240 STRIG OFF: FOR N-l TO 1000 : NEXT: STRIG ON
250 PRINT “Нажми кнопку 1 в крайнем нижнем положении"
260 V-STICK(O) : Ymax -STICK(l)
270 IF STRIG (0) - 0 THEN 260: ’ Повтор до нажатия
280 STRIG OFF: ’Запретили отвлекаться
290* ’Вычисляем масштабные коэффициенты Кх и Ку
147
300 Кх - 320 / (Xmax - Xmin)
310 Ку - 200 / (Ymax - Ymin)
320 ’Отслеживаем точку и рисуем траекторию перемещения
330 X-STICK(O) :Y-STICK(1)
340 X-(X-Xmin) *Кх: Y - (Y - Ymin) * Ку
350 PSET (X,Y) : GOTO 330
Таймер и временные прерывания
ПЭВМ типа IBM PC располагают двумя (XT) или тремя (АТ) источниками , связанными с временными измерениями.
Первый из них — тактовый генератор системных часов, импульсы которого, проходя через специальную схему делителя частоты, преобразуются в сигналы отсчета времени. Интервал между двумя такими отсчетами равен 1/18.2 с (в секунде -18,2 импульса, в минуте —1092, в часе — 65520). Появление каждой временной отметки вызывает прерывание, обрабатываемое операционной системой. Обработка заключается в суммировании временных импульсов и записи результата в четырехбайтовый счетчик с адресами &Н46С - &H46F. Обнуление этого счетчика производится в полночь.
Второй источник временных отсчетов представлен программируемой микросхемой — интервальным таймером типа 8253 (XT) или 8254 (АТ). Таймер состоит из трех независимых компонент, которые мы условно будем называть “будильниками”. На входе каждого будильника имеется 16-разрядный регистр с “защелкой”. Защелку можно “открыть” или “закрыть” по сигналам, поступающим в порт управления соответствующего будильника (адреса портов — &Н40,&Н41 и &Н42). Если защелка открыта, то содержимое входного регистра можно обновить путем вывода в соответствующий порт. Как только во входной регистр поступило новое значение, оно переписывается во внутренний регистр, и будильник начинает свою работу. Из содержимого внутреннего регистра с каждым отсчетом времени вычитается по единице. В тот момент, когда содержимое этого регистра становится равным нулю, будильник начинает “звонить” — на его выходной линии меняется потенциал. Затем содержимое регистра-защелки вновь переписывается во внутренний регистр будильника, и процесс повторяется.
Будильник с номером 0 управляет работой системных часов, следующий будильник принимает участие в процедурах регенерации памяти, и, наконец, будильник с номером 2 может использоваться в интересах программы для управления временными процессами и организации звуковых эффектов.-
Последним устройством измерения времени в IBM РС/АТ являются
148
обычные электронные часы — специальная микросхема MCI46818, работающая на собственной батарейке и предоставляющая процессору возможность установить или опросить текущие показания времени и даты.
Для организации временных измерений в распоряжении пользователя имеются системные переменные символьного типа DATE$, Т1МЕ$ и арифметическая переменная TIMER. Первые две из них можно изменять, необходимость в чем возникает при корректировке показаний даты и времени:
DATES -“01/31/91”
DATES-”01/31/1991"
TIMES-“07:45:00"
формат задания текущей даты допускает употребление символа “ - ” в качестве разделителя между месяцем, днем и годом. При установке нового показания времени младшие компоненты (секунды; минуты и секунды) можно не набирать. По умолчанию вместо них будут установлены нулевые значения.
Из показаний системных переменных очень несложно выделить символьные или числовые значения отдельных компонент:
т$-TIMES
Н$-LEFTS (Т$,2) : Н-VAL (Н$) : IF Н> 12 THEN Н-Н-12
M$-MID$ (Т$,4,2) : М-VAL (М$)
S$-RIGHTS (Т$,2) : S-VAL (8$)
В системной переменной TIMER хранится количество секунд, прошедших после полуночи. Содержимое этой переменной можно только прочитать. С ее помощью можно определить время работы той или иной программной процедуры:
ЮТ- TIMER: ’Засекаем время запуска процедуры
20 'Начало хронометрируемой процедуры
200 'Конец процедуры
210 Т —TIMER-Т
220 Н - FIX (Т / 3600) : 'Подсчитываем часы
230Т-Т-Н*3600
240 М - FIX (Т / 60) : 'Подсчитываем минуты
250 S - Т - М * 60 : 'Подсчитываем секунды
260 PRINT Н; “часов”, М; “минут”, 8; “секуид”
Если процедура хронометрирования требует более высокой точности измерения, чем одна секунда, то вместо переменной TIMER можно
воспользоваться подпрограммой опроса содержимого системных часов:
1000 DEFSEG-0
1010 ВО-PEEK (&Н46С) : ’младший байт
1020 Bl - PEEK (&H46D) : ’следующий байт
1030 В2 - PEEK (&Н46Е) : ’старший байт
1040 Т - В2 * 65536 + В1 *256+В0
1050 RETURN
Однако в этом случае надо помнить, что цена единицы времени ("тика") равна 1/18.2 с:
10 GOSUB1000
20 Т1-Т
205 G0SUB 1000
210 Т-Т-Т1
220 H-FIX (Т / 65520) : ’ Подсчитали часы
230 Т-Т-Н*65520
240 М - FIX (Т / 1092) : ’ Подсчитали минуты
250 Т - Т - М * 1092 : ’ Получили остаток в тиках
Значение переменной TIMER можно использовать для перенастройки датчика случайных чисел:
RANDOMIZE TIMER
Пользователи Turbo-системы имеют двусторонний доступ к еще одной системной переменной MTIMER. Она представляет собой обычный счетчик тактовых сигналов, накапливающий сумму с шагом в одну миллисекунду. Установив в нем нулевое значение (MTIMER - 0), спустя некоторое время можно определить длительность прошедшего интервала (DT - MTIMER).
Для организации временной паузы (задержки), например, между динамически сменяющимися кадрами на экране, в Turbo-BASIC используется оператор DELAY. Его единственным аргументом является величина задержки в секундах:
DELAY 5
Интересно, что точно такую же задержку можно организовать и с помощью оператора SOUND:
SOUND 32767,91
На частоте 32 767 Гц динамик компьютера никакого звука не воспроизводит — полоса пропускания не та, да и человеческое ухо не услышит, а время “звучания” (91 - 5*18.2) составит ровно 5 с.
Подпрограммы, срабатывающие по принципу будильника, объявляются с помощью следующих операторов:
10 TIMER ON
20 ON TIMER (n) GOSUB 300
Первый оператор разрешает пользовательскую обработку прерываний от интервального таймера, а второй — устанавливает точку входа в подпрограмму и осуществляет запись в регистр-защелку соответствующего значения будильника. Через каждые и с после выполнения оператора 20 управление будет передаваться подпрограммеобработки сигнала будильника. Такое прерывание можно отменить либо по оператору TIMER OFF, либо путем переназначения точки входа на нулевую строку.
Организация звуковых эффектов
В отличие от бытовых или специализированных компьютеров, снабжаемых программируемыми многоканальными звуковыми генераторами, ПЭВМ типа IBM PC/XT и АТ комплектуются довольно примитивными средствами формирования звуковых сигналов. К встроенному динамику подведены две линии, одна из которых управляется выходом второго канала программируемого таймера 8253/8254, а вторая — первым битом порта 61h (на PC/XT этот порт обслуживает микросхему 8255 управления периферийными устройствами) . На каждой из этих линий программным образом можно сгенерировать электрические сигналы с прямоугольными импульсами заданной частоты и длительности. Изменение переднего и заднего фронтов импульса, а также сглаживание угловых точек позволяют уподобить генерируемые сигналы синусоидальным. Однако регулировка по амплитуде, т.е. по уровню громкости сигнала, здесь отсутствует. Самым простым средством, которое обычно применяется для привлечения внимания пользователя, является генерация кратковременного звукового сигнала с помощью оператора ВЕЕР:
150 PRINT “Вы ошиблись. Повторите” : ВЕЕР : GOTO 60
При его выполнении раздается звук с частотой 400 Гц и длительностью порядка 1/4 с, т.е. примерно такой же эффект, как и при выводе символа с кодом 07.
Оператор SOUND обеспечивает выдачу монотонного звукового сигнала с заданной частотой F от 37 до 32 767 Гц и длительностью звучания Т от 0 до 65 535 тиков:
SOUND F, Т
При Т=0 оператор SOUND блокирует выполнение музыкальных фрагментов, запущенных ранее и не успевших завершиться.
Сигнал, сформированный с помощью оператора SOUND, звучит в так называемом режиме музыки переднего плана. Это означает, что ЭВМ не перейдет к выполнению следующего оператора до тех пор, пока звуковой сигнал не будет отработан.
В отличие от этого Бейсик позволяет формировать и исполнять музыкальную программу на фоне действия других операторов. Для этой цели используется программно организованный музыкальный буфер, размеры которого можно изменить при запуске или перенастройке параметров системы. По умолчанию емкость этого буфера - 256 байт, что позволяет разместить закодированную музыкальную программу, содержащую до 32 нот со всеми необходимыми характеристиками (частота, длительность, темп исполнения).
Музыкальная программа генерируется оператором PLAY по значению символьной строки, представленной в виде текстовой константы или текстового выражения. При этом каждая нота кодируется одной из букв С ("до") ,D ("ре") ,Е ("ми") ,F ("фа") ,G ("соль"), А ("ля") и В ("си"). Знаки “+” или “#”, употребленные вслед за обозначением ноты, соответствуют музыкальному термину “диез” (нота, звучащая на полтона выше). Для включения термина “бемоль” (нота,звучащая на полтона ниже) используется символ “-”. Таким образом, указатели C# или С+ и D-, D# или D+ и Е-, F# или F+ и G-, G# или G+ и А-, A# или А+ и В- соответствуют одноименным черным клавишам октавы.
Выбор октавы в музыкальной программе осуществляется по указанию On, где числовой индекс и, принадлежащий диапазону от 0 до 6, задает номер октавы. Переход к соседней октаве можно указывать символами-">" (увеличение номера октавы на 1) или"<" (уменьшение номера октавы на 1). По умолчанию установлена октава 03, соответствующая первой октаве музыкального инструмента, частоты нот которой имеют следующие значения в герцах:
до (С) - 523.25 соль (G) - 783.99
ре (D) - 587.33ля (А) - 880.00
ми (Е) - 659.26си (В) - 987.77
фа (F) - 698.46
Частоты нот каждой соседней октавы увеличиваются (>) или уменьшаются W вдвое.
Существует и другой способ идентификации клавиш музыкального инструмента в виде Nn, где п — число из диапазона от 0 до 84, задающее (при и > 0) порядковый номер клавиши в семи возможных октавах. Указатель NO соответствует паузе между нотами.
Относительная длительность нот устанавливается командой Ln, где числовой параметр и из диапазона 1-64 задает количество нот, содержащихся в полной (L1) ноте. По умолчанию установлен режим L4. Число, записанное вслед за указателем ноты, определяет ее индивидуальную длительность.
Командами MN (нормальная музыка), ML (музыка legato) и MS (музыка staccato) устанавливаются режимы, в которых фактическая длительность звучания ноты равна соответственно 7/8, 1 и 3/4 от относительной длительности, установленной предшествующей командой Ln. .
Относительные паузы между нотами регулируются командой Рп, где числовая величина п имеет тот же смысл, что и в команде Ln.
Темп исполнения музыкальной программы, определяющий количество четвертных нот в минуте, устанавливается командой Тп (п от 32 до 255). По умолчанию действует режим Т120.
Индивидуальная длительность ноты может быть изменена с помощью одной или нескольких точек, записываемых вслед за обозначением ноты. Каждая точка прибавляет к длительности звучания, заданной командами L и Т, половину временного интервала. Таким образом, ноты “А.” и “А..” звучат соответственно 3/2 и 9/4 от временного интервала, принятого для ноты “А”.
Запись музыкальной программы в буфер осуществляется оператором PLAY:
W$ - “Т180 02 Р2 Р8 L8 G G G L2 Е-”
PLAY W$ + “P24 P8 L8 F F F L2 D”
Если музыкальной программе предшествует команда MF, то содержимое буфера исполняется в режиме музыки переднего плана. Это означает, что программа приостанавливается до тех пор, пока музыкальный буфер не будет опустошен. По умолчанию оператор PLAY исполняет свой фрагмент именно в таком режиме.
В случае когда содержимое буфера формируется с установочной командой МВ, то соответствующий фрагмент исполняется в режиме фоновой музыки. Именно этот режим позволяет программе проконтролировать, сколько нот еще находится в музыкальном буфере. Для
этой цели предназначена функция PLAY (и) с фиктивным аргументом. Ее значением является количество нот буфера, еще не обработанных системной программой воспроизведения звуков. С помощью оператора SOUND F,0 можно произвести досрочную очистку содержимого буфера.
Выполняясь параллельно с фоновой музыкой, программа может прервать свою работу в тот момент, когда в буфере останется заданное количество нот. Для этого необходимо разрешить прерывание, наступающее при переходе звуковоспроизводящего процесса с обработки k-й ноты на (к-1)-ю:
PLAY ON
ON PLAY (к) GOSUB 1200
В качестве числового аргумента музыкальных команд L,O,P и Т могут выступать целочисленные переменные:
10 W$ - "BA#AG#GF#FED#DC#CC#DD#EFF#GG#AA#B"
20 FOR 1% - 1 ТО 10
30 FOR J% -1 TO 6
.40 PLAY “MB L16 T120 O-J%;” + W$
50 NEXT J%
60 NEXT 1%
Одним из мощных средств оператора PLAY является возможность включения в состав музыкальной программы фрагментов, являющихся значениями символьных переменных и выполняющих роль музыкальных подпрограмм. Кроме средств конкатенации, продемонстрированных в ранее приведенных примерах, подключение музыкальной подпрограммы можно реализовать с помощью команды X:
40 PLAY "MBL16T120 O-J%; XW$;”
40 PLAY “MB L16T120O-J%; X”+VARPTR$ (W$)
Первый вариант использования музыкальной команды X характерен для интерпретаторов, второй — для компиляторов.
Использование музыкальных подпрограмм интересно еще и тем, что запрограммированный фрагмент может быть исполнен с различными вариациями управляемых звуковых параметров - в другой октаве, со сменой темпа и т.п.
Доступ к портам и ячейкам оперативной памяти
Термин “порт” уже не раз фигурировал в разделах данной главы, однако попытка расшифровать это понятие еще не предпринималась.
154
Большинство руководств по Бейсик-системам довольно скупо освещает технологию работы с портами, так как эта проблема выходит за рамки обычного программирования прикладных задач.
Порты являются основным средством связи центрального процессора (CPU) с многочисленными микросхемами и контроллерами, которыми напичкана плата компьютера. Обслуживание штатных внешних устройств выполняется средствами операционной системы или системы программирования, поэтому к непосредственной работе с портами рядовые пользователи обычно не прибегают. -
Внешне порты напоминают ячейки оперативной памяти. Так же, как и байты ОП, порты имеют адреса от 0 до 65535, хотя задействованы из них далеко не все. Однако порт с адресом А не имеет никакого отношения к байту оперативной памяти с тем же адресом. Это - два совершенно разных объекта, и запись в один из них никоим образом не влияет на содержимое другого. Доступ к порту осуществляется с помощью машинных команд IN (чтение из порта) и OUT (вывод в порт), тотда как для обращения к байтам памяти используются различные модификации команды MOV.
С каждым внешним устройством обычно связано несколько портов, выполняющих определенные функции на различных стадиях обмена. В одни порты заносятся управляющие признаки и адреса (номера) внутренних регистров обслуживаемой микросхемы. Другие порты используются для обмена данными между CPU и выбранными внутренними регистрами. По содержимому третьих портов операционная система получает информацию о состоянии внешнего устройства, анализирует признаки завершения очередной процедуры обмена, контролирует правильность функционирования оборудования.
Программирование обмена с периферийным устройством на уровне портов инетда называют программированием на физическом уровне. Оно требует профессионального знания большого количества технических деталей, соблюдения жестких временных ограничений и, как правило, ведется на языке ассемблера. Программы, обслуживающие обмен с внешним устройством и оформленные в соответствии с требованиями операционной системы, называются драйверами.
Драйверы на Бейсике практически никто не пишет, однако во всех трех версиях имеется возможность обратиться напрямую к тому или иному порту. Для этой цели предназначены операторы OUT, WAIT и Функция INP. Они позволяют выполнить любые операции по управлению внешними устройствами, которые не предусмотрены в стандартных средствах ввода-вывода. Это может оказаться полезным при
работе с новыми внешними устройствами, не обслуживаемыми Бей- сик-системой.
С помощью функции INP(A) осуществляется считывание однобайтового значения из порта с адресом А. Обычно адрес порта задается в виде шестнадцатеричной константы &Нхххх. Перечень адресов некоторых портов приведен ниже.
Адреса портов
Обслуживаемое устройство
00 — 1F
контроллер прямого доступа к памяти DMA, 8237 (для АТ—первый контроллер DMA)
20 —2F
контроллер прерываний, 8259 (XT)
20 —3F
контроллер прерываний 1 (АТ)
40 —5F
программируемый таймер, 8253/8254
60 —6F в
адаптер интерфейса с периферией, 8255
70 —7F
автономные часы реального времени (АТ)
80 —9F
регистры страниц DMA
АО —BF
контроллер прерываний 2 (АТ)
СО —DF
второй контроллер DMA (АТ)
1F0 — 1F8
контроллер "винчестера" (АТ)
200 —20В
адаптер игровых пультов
278 — 27F
адаптер параллельного принтера (дополнительный)
2F8 — 2FF
адаптер канала связи COM2
320 — 32F
контроллер “винчестера” (XT)
378 — 37F
адаптер параллельного принтера (основной)
ЗВО — 3BF
адаптер параллельного принтера и черно-белого дисплея
3D0—3DF
адаптер цветного графического дисплея
3F0 —3F7
контроллер флоппи-дисков ’
3F8 — 3FF
адаптер канала связи СОМ1
Процедура вывода однобайтового значения и из диапазона от 0 до 255 в порт с адресом А осуществляется оператором OUT А,п.
Оператор WAIT предназначен для приостановки процесса выполнения программы до тех пор, пока в порту с адресом А не появится кодовая комбинация X, удовлетворяющая заданному условию:у
WAIT A, nl [,п2]
Два последних операнда nl и п2, принадлежащие интервалу от 0 до 255, задают условие прекращения задержки:
IF ((X XOR n2) AND nl) - О THEN ожидание
Если операнд п2 не задан, то он по умолчанию считается равным нулю и проверка упрощается:
IF (X AND nl) - 0 THEN ожидание
Конечно, такую задержку можно было бы организовать и без оператора WAIT:
150 Х-INP (А)
160 IF ((XXOR n2) AND nl)-0 THEN 150
Программирование на физическом уровне, как правило, связано с доступом к тем или иным ячейкам памяти ОЗУ / ПЗУ, в которых операционная система хранит информацию, участвующую в обслуживании соответствующего устройства. Для обеспечения такого рода процедур предназначены операторы DEF SEG, РОКЕ и функция РЕЕК.
Мы уже упоминали, что доступ к ячейкам оперативной памяти в IBM PC базируется на использовании 20-разрядных адресов, обеспечивающих идентификацию байтов ОЗУ в диапазоне от 0 до 1 Мбайта. Составляется такой адрес из двух 16-разрядных компонент В и D, условно записываемых в виде B:D.
Компонента В называется базой сегмента и в зависимости от адресуемого типа данных хранится в одном из регистров CS (сегмент команд) , DS (сегмент данных), SS (сегмент стека) или ES (дополнительный сегмент). Сдвиг базового адреса на 4 разряда влево позволяет получить 20-разрядный начальный адрес сегмента.
Вторая компонента D задает смещение адресуемого байта относительно начала сегмента, так что полный физический адрес объекта равен 16 * В + D. Максимально допустимая длина сегмента — 64 Кбайта.
Функция POKE(D) позволяет извлечь содержимое байта, расположенного по относительному адресу D, а оператор “PEEK D,n” осуществляет запись целочисленного значения и (от 0 до 255) по относительному адресу D.
Для правильного формирования полного физического адреса процедурам РОКЕ и РЕЕК должно обязательно предшествовать задание начального базового адреса:
100 ’Фрагмент программы очистки буфера клавиатуры
110 DEF SEG - &Н40 : ’Установили базу сегмента
120 ’Извлекаем указатель головного символа в буфере
130 PBEG -PEEK (&Н1А) : ’Полный адрес равен 0040:001А
140 ’Сбрасываем указатель конечного символа в буфере
150 POKE &Н1С, PBEG : ’Очистка буфера завершена
Оператор DEF SEG, употребленный без параметров, восстанавливает системное значение базы данных.
Компоненты физического адреса любой переменной или массива могут быть опрошены с помощью функций VARSEG, VARPTR или VARPTR$:
100 DEF SEG : ’Восстановили базу системного сегмента данных
ИОВ - VARSEG (А5) : ’База переменной А5
120 D - VARPTR (А5) : ’Смещение переменной А5
130 Bl - VARSEG (С(0)) : ’База массива С
140 ADR$ - VARPTR$ (А5) : ’Адрес А5 в специальном формате
В операторе 140 результат формируется в виде трехбайтовой строки. В первом байте находится признак типа аргумента (2 — целочисленный, 3 — строка, 4 — вещественный, 8 — вещественный с удвоенной точностью). Второй и третий байты содержат соответственно младшие и старшие разряды относительного адреса аргумента. Этот формат соответствует правилам задания адреса операнда команды “X” в операторах DRAW и PLAY.
Полученные таким путем адреса могут быть переданы в качестве входных или выходных параметров процедурам, обслуживающим программные прерывания, или подпрограммам, составленным на других алгоритмических языках.
Работа с каналами связи
Телекоммуникационные возможности IBM PC обеспечиваются одной или двумя микросхемами UART 8250 (Universal Asynchronous Receiver Transmitter), которые носят название последовательных каналов связи СОМ1: и COM2:. Каждая из этих микросхем содержит по 10 однобайтовых программируемых регистров, с помощью которых осуществляется управление обменом информацией между PC и другим устройством — абонентом.
В качестве абонента может выступать принтер с последовательным интерфейсом типа RS 232С, другая ПЭВМ, находящаяся в непосредственной близости, или специальное устройство дальней связи — модем. Последний осуществляет прямое (модуляция) или обратное (демодуляция) преобразование цифрового сигнала, передаваемого по телефонному каналу связи, может накапливать передаваемую порцию данных, контролировать правильность передачи, управлять различными телефонными атрибутами (звонок, номеронабиратель) и т.п. Существует довольно много различных конструкций модемов и схем их взаимодействия с ЭВМ, которые принято называть протоколами связи.
В простейшем случае ЭВМ и пассивный абонент связываются всего тремя линиями, по одной из которых передаются битовые последова-
158
тельности данных, а по другой — управляющие потенциалы. Третья шина выполняет роль общей “земли”. По управляющему проводу высоким или низким потенциалом приемник сообщает о своей готовности принять очередную порцию данных.
Информация, передаваемая по шине данных, представляет собой последовательность кодовых посылок (цифры, символы), окаймляемых специальными сигналами:
<направление передачи данных
о 12...7
стартовый информационные биты контрольный стопо- следующий“бит”битвый стартовый
бит бит
В зависимости от типа передаваемых данных и способа их кодировки количество информационных битов может варьироваться от четырех до восьми.
Контрольный бит дополняет количество единиц в информационных битах до четного (контроль по “чету”) или до нечетного (контроль по “нечету”) числа. Допускаются варианты обмена, когда контрольный разряд может заполняться нулем или единицей, независимо от числа единиц в информационных битах, и даже вообще отсутствовать.
Взаимодействующие абоненты обязательно договариваются между собой о количестве информационных битов, способе заполнения контрольного бита, количестве стоповых битов и скорости передачи данных. Последнее обстоятельство очень важно, так как выделить каждый информационный бит можно только по его длительности, ибо между двумя одинаковыми смежными разрядами никаких разделительных сигналов нет. Скорость передачи данных измеряется в бодах - числе двоичных разрядов, передаваемых в секунду. Для микросхем UART 8250 допустимыми скоростями являются 75, ПО, 150,300, 600, 1200,1800, 2400, 4800 и 9600 бод.
Количество стоповых битов, завершающих посылку информационной единицы данных, может быть равно 1,1.5 или 2. Не надо удивляться значению в “полтора” двоичных разряда, так как здесь имеется в виду временная длительность сигнала, а ее можно делить.
В случае подключения к ЭВМ модема между ними может использоваться одна или две шины данных, а также шесть следующих управляющих линий (рис. 2):
сигнал DTR (Data Terminal Ready) сообщает модему о готовности компьютера к сеансу связи;
сигнал RTS (Request То Send) информирует модем о том, что компьютер ожидает поступления данных;
сигнал DSR (Data Set Ready) сообщает компьютеру о готовности модема к обмену данными;-
сигнал CTS (Clear То Send) сообщает компьютеру о том, что модем готов начать передачу данных;
сигнал DCD (Data Carrier Detect) сообщает компьютеру, что модем связан с другим модемом;
сигнал RI (Ring Indicator) информирует ЭВМ о том, что телефонная линия, к которой подсоединен модем, имеет звонок.
Рис. 2. Схема передачи данных
Взаимодействие компьютера и модема при передаче данных удаленному абоненту развивается по следующей схеме:
ЭВМ выдает сигнал DTR;
установив, что модем включен, компьютер предлагает ему связаться с удаленным абонентом;
после установления связи модем выставляет сигнал DSR;
компьютер выдает сигнал RTS;
после того как модем отвечает сигналом CTS, начинается передача данных абоненту.
В процессе диалога возможны различные ситуации, две из которых мы рассмотрим несколько подробнее. Первая из них связана с ошибкой тайм-аута, свидетельствующей о том, что за установленный интервал времени не поступил ожидаемый сигнал. Второй момент связан с термином “протокол XON/XOFF”. Управляющий сигнал XOFF, имеющий в таблице ASCII код 19, свидетельствует о том, что в приемном пункте обработка данных ведется медленнее и не соответствует скорости их поступления. В такой ситуации передающий пункт должен приостановить поток данных. Второй сигнал XON с кодом 17 сообщает
абоненту, что можно продолжить передачу. Таким образом, обмениваясь сигналами XON / XOFF, абоненты в условиях асинхронной связи могут согласовать свои возможности.
Еще некоторые технические детали следует упомянуть в связи с телекоммуникационными каналами. Для совмещения процессов обработки поступающей информации и диалога с модемом в оперативной памяти ЭВМ за каждым каналом закрепляются приемные и/или передающие буфера. Если процедура обработки затягивается, то, помимо вышеупомянутых сигналов XON / XOFF, можно пойти на увеличение емкости буферов.
Доступ к управляющим регистрам UART 8250 осуществляется через порты с адресами 2F8h - 2FEh (COM2:) и 3F8h - 3FEh (СОМ1:). Программирование на этом уровне требует не только детального знания функций каждого разряда управляющих регистров, системы команд модема, но и понимания логико-временной последовательности событий в процессе взаимодействия абонентов. .
Рассматриваемые версии Бейсика обеспечивают более простой режим общения программы с телекоммуникационными каналами связи, которое протекает по следующей схеме.
Канал связи, например СОМ1:, инициирует так же, как открывают обычные файлы:
OPEN “СОМ1: optlistl optlist2" [ FOR mode ] AS [#]n [ LEN-rl ]
Здесь optlistl — список параметров, определяющих скорость передачи данных и конфигурацию передаваемой порции ([speed] [.[parity] [, [data] [.stop]]]);
optlist2 — список параметров, определяющих другие характеристики процесса обмена;
mode — режим доступа к записям файла, принимающий одно из значений INPUT, OUTPUT или RANDOM;
n — программный номер, под которым канал связи будет выступать в операторах и функциях обмена;
г! — длина записи (по умолчанию -128 байт);
speed — скорость передачи в бодах;
parity — символ, определяющий способ формирования бита контроля (N — нет контроля, Е — контроль по четности, О — контроль по нечетности, S — контрольный бит всегда равен нулю, М — контрольный бит всегда равен единице);
data — количество информационных битов (от 4 до 8);
stop — количество стоповых битов (1 или 2). Для data — 4 или 5 значение stop 2 соответствует полутора стоповым сигналам.
Параметры списка optlist2 разделяются запятыми, их формат приведен ниже.■~
ФорматПояснение
параметра
ASCФайл открывается в режиме ASCII. Символы Tab заменяются пробела
ми. Каждая строка завершается кодом CR. Сочетание Ctrl+Z воспринимается как признак конца файла (EoD. Используется протокол XON/XOFF
BINОткрывается двоичный файл
CD [ш]Устанавливается максимально допустимая задержка сигнала DCD в ш
млс
CS [ш]Аналогичная задержка для сигнала CTS
DS [ш] Аналогичная задержка для сигнала DSR
LFИспользуется при передаче текстового файла на принтер с последова
тельным интерфейсом. Вызывает принудительную вставку управляющего символа LF (Line Feed) после каждого признака конца строки CR (Carriage Return)
OP[m] s Устанавливается максимально допустимая задержка процедуры открытия телекоммуникационного файла
RB [п]Задается длина (п) приемного буфера в байтах (в GW-и Turbo-BASIC
по умолчанию — 256 байт, в Quick-BASIC —512 байт)
RSБлокируется анализ сигнала RTS
ТВ [N]Задается длина передающего буфера
По умолчанию коммуникационный файл открывается как двоичный файл (BIN) со следующими атрибу ами :
speed-300; parity-Е; data -7;
stop - 2 для скоростей 75 и 100 бод;
stop — 1 для всех остальных скоростей;
timeout -1000
Выполнение процедуры OPEN СОМ развивается по следующей схеме :
выделяются буфера и разрешаются сигналы прерывания от UART;
устанавливается высокий потенциал ("1") на линии DTR;
по истечении времени, установленного параметром ОР[ш] или DS [ш ], проверяется ситуация “ошибка тайм-аута”;
если не был задан napaMerpRS, то устанавливается высокий потенциал на шине RTS;
по истечении времени, установленного пара етром ОР[ш] или CD [ш ], проверяется ситуация “ошибка тайм-аута”;
если в указанных проверках ошибка тайм-аута не была обнаружена, то канал связи считается открытым. В противном случае буфера возвращаются системе, прерывания от UART блокируются, сбрасыва-
162
ются потенциалы на управляющих линиях и производится аварийное завершение программы.
В связи с тем, что моменты поступления данных от абонента программе заранее не известны, на помощь приходит аппарат событий и мехяниям обработки прерываний. Операторы COM(n) ON, СОМ(п) OFF и COM(n) STOP соответственно разрешают, блокируют или замораживают прерывания, генерируемые указанным каналом связи в тот момент, когда в приемный буфер поступает очередная порция данных. С помощью оператора ON COM(n) GOSUB ... назначается точка входа в подпрограмму обработки сигналов прерывания.
Для вывода данных через открытый канал используют операторы PRINT #n, PRINT #n USING или WRITE #п, употребление которых ничем не отличается от общения с обычными файлами.
Приемданных, поступающих по каналу связи, можно организовать либо по оператору INPUT #п, либо по функции INPUTS (m,#n). Последняя предоставляет больше удобств, так как мы можем прочитать не всю запись целиком, а только требуемое количество байтов. Размер приемного буфера в 256 байт представляется разумным, так как он позволяет поместить считанное значение в одну текстовую переменную (это ускоряет процедуру ввода).
При обработке вводимых данных из текстового файла могут оказаться полезными функции LOC(n) и LOF (п). Первая из них сообщит, сколько байтов сейчас находится в буфере, и эту информацию можно учесть при вводе:
А$-INPUTS (LOC(1),#1)
Вторая функция сообщает, сколько байтов в буфере свободны. Знание этой величины позволит не переполнить буфер при выводе. Оценить ситуацию появления в приемном буфере сигнала XOFF нам поможет функция INSTR:
IF INSTR (1, А$, CHR$ (19))> 0 THEN...
Для прекращения сеанса связи телекоммуникационный канал закрывают самым обычным образом:
CLOSE #п
В качестве примера познакомьтесь с небольшим фрагментом про-
6*6*163
6*
6*
граммы, которая занимается отображением на экране символов, набираемых на клавиатуре. Однако путь символа к экрану лежит через буфер телекоммуникационного канала. ЭВМ посылает в канал связи информацию, поступающую с клавиатуры, и тут же сама ее принимает:
. 10 OPEN “СОМ1: 9600,0,7" AS #1 : ’Открыли канал
20 ON COM(l) GOSUB 100 :’Назначили точку входа
30 СОМ (1) ON:’Разрешили прерывания
40 ’Прием символа, набираемого на клавиатуре
50 A$-INKEY$:IF А$-”" THEN 50
60 PRINT #1, А$;: ’Вывод символа в канал
70 СОТО 50
100 ’Прием символов из канала и их отображение на экране
110 L, — LOC(l) : IF L<1 THEN RETURN
120 B$-INPUTS (L,#l) : PRINT B$;: RETURN
Управление внешними устройствамина физическом уровне
Дополнительные возможности по управлению устройствами ввода- вывода предоставляют оператор IOCTL и функция IOCTL$ :
IOCTL [#]п, “SS...S”
AS-IOCTLS <[*]п)
Оператор IOCTL обеспечивает передачу цепочки символов “SS...S”, воспринимаемых как последовательность команд, управляющих работой внешнего устройства. Каждая такая команда состоит из кода операции, обозначаемого двух- или трехсимвольным идентификатором, и расположенного вслед за ним необходимого набора данных. Разделителем команд в строке служит точка с запятой. Например, установка количества строк в странице при выводе на принтер может быть реализована следующим образом:
OPEN “LPTL” FOR OUTPUT AS#1
IOCTL #1, “PL64” ’размер страницы-64 строки
С помощью функции IOCTL$ производится опрос управляющих данных, которыми устройство подтверждает правильность обработки поступившей команды, сообщает о причинах аварийной ситуации, выдает значения опрашиваемых параметров. Например, опрос теку-
164
щей ширины строки на принтере можно произвести следующим образом:
IOCTL #1,“GW" 'команда опроса ширины строки
WJDLINE-VAL (IOCTL$(#1)) 'ответ драйвера-принтера
Естественно, что применение таких средств требует детального знакомства с набором команд драйверов соответствующих устройств. Описанные процедуры могут оказаться полезными при подключении к компьютеру новых внешних устройств, не обслуживаемых Бейсик- системой.
6. ОТЛАДКА ПРОГРАММ
Никто не застрахован от ошибок при составлении программ. Одни совершают их в большем количестве, другие - в меньшем. Квалификация пользователя определяется не удельным весом ошибок во вновь написанной программе, а умением быстро их обнаруживать и устранять. Проведению отладочных работ в значительной мере содействуют специальные языковые средства и хорошо разработанные процедуры системного контроля.
Практически все синтаксические ошибки, связанные с нарушением правил написания операторов и выражений, выявляются современными системами программирования на стадии компиляции исходного текста или при анализе программных строк в процессе их набора. Ошибки такого рода мы условимся называть статическими.
В отличие от них существует ряд семантических ошибок динамического характера, выявить которые можно только во время выполнения программы. К ним относятся ошибки в организации работы циклов и подпрограмм, приводящие к недопустимому взаимодействию связанных операторов типа DO — LOOP, FOR — NEXT, GOSUB — RETURN, WHILE — WEND. Просчеты в количестве повторений цикла могут привести к появлению индексных выражений, выходящих за пределы, установленные при описании массивов. Аварийные ситуации могут быть вызваны алгоритмическими ошибками (переполнения в результате выполнения арифметических операций, недопустимые значения аргументов функций и т.п.), нарушениями ряда системных ограничений (превышение допустимых длин строковых значений, емкости буферов и других системных областей памяти, глубины вложенных структур и т.п.), обращениями к несуществующим файлам и директориям, сбоями в работе оборудования.
Контроль за подобного рода динамическими ошибками берет на себя системное окружение периода выполнения программы, которое ин- 166
формирует нас о возникшей ситуации и выдает программные координаты обнаруженной ошибки. Однако первопричину зафиксированного события должен обнаружить сам пользователь. В этом и заключается первый этап процесса отладки программы.
Устранение статических и динамических ошибок еще не означает, что программа решает поставленную задачу. На втором этапе отладки придется убедиться в правильности выбранного алгоритма и его программной реализации.
Выполнение программы в отладочном режиме
Каждая из описываемых систем предоставляет пользователю возможность выполнить отлаживаемую программу или ее любые фрагменты в режиме трассировки. При этом система фиксирует последовательность выполняющихся строк и в том или ином виде выдает их пользователю.
В GW-системе номера программных строк заключаются в квадратные скобки и поступают в окно вывода, перемежаясь с результатами работы программы. Информация о трассировке программы PROG1, приведенной в приложении D, выглядит следующим образом:
[20] [30] [40] [50] [60] [70] [60] [70] [60] [70] [80] .0625
С целью экономии времени и места количество повторений цикла в этом примере было сокращено с 3000 до 3.
В Turbo-системе последовательность выполняющихся строк фиксируется примерно в таком же формате, но выводится в специальное окно с заголовком Trace. Программные строки, у которых отсутствуют номера или метки, в трассировочный список не попадают.
Quick-система в режиме трассировки резко замедляет скорость выполнения программы (примернодо 5 операторов в секунду) и выделяет обрабатываемую строку в листинге программы повышенной яркостью и другим цветом. Это дает возможность визуально проследить за порядком выполнения операторов. Если скорость прокрутки слишком высока по сравнению с реакцией пользователя, то он имеет возможность “простучать” каждый шаг трассировки, просматривая ее историю в прямом или обратном порядке. Для этой цели в режиме Debug предусмотрена процедура History ON. Если она включена, то система запоминает последовательность шагов выполнения программы. Пройтись по этой цепочке без повторного выполнения операторов можно, нажимая клавиши Shift +F10 (движение вперед) или Shift+F8 (движе-
нис назад). Каждое нажатие указанной пары перемещает курсор на очередную строку программы.
Для того чтобы распространить режим трассировки на всю программу, достаточно разместить в ее первой строке оператор TRON или с помощью соответствующих средств управления системой установить режим трассировки. В GW-BASIC это выполняется директивой TRON (достаточно нажать клавишу F7). В Turbo-системе необходимо войти в режим Debug, выбрать процедуру TRACE и нажатием клавиши Enter включить трассировку (ON). В Quick-системе после входа в меню Debug необходимо установить “галочку" в строке Trace ON. Если ее нет, то она появится после нажатия клавиши “Т”.
Если режим трассировки необходимо задействовать только на отдельных участках отлаживаемой программы, то первым оператором контролируемого фрагмента должен быть оператор TRON, а последним - TROFF.
Системы Turbo-BASIC и Quick-BASIC предусматривают возможность пошагового выполнения программы.
В Turbo-системе под шагом программы понимают одну или несколько программных строк, начинающихся с номера строки или метки. Инициация очередного шага осуществляется здесь нажатием пары клавиш Alt+FlO. Если при этом включен режим трассировки, то выполнение очередного шага сопровождается появлением метки (номера) в окне Trace. Отказ от пошаговой прокрутки и переход к автоматическому продолжению работы программы происходит после нажатия клавиш Alt+ F9.
В Quick-системе под шагом программы понимают каждую программную строку независимо от наличия у нее номера или метки. Выполнение очередного шага происходит после нажатия клавиши F8 или F10. Если очередная строка содержит обращение к внешней процедуре, то нажатие клавиши F8 распространяет пошаговый режим и на вызываемую процедуру. Нажатие клавиши F10 приводит к выполнению очередного шага с автоматической прокруткой вызываемой подпрограммы.
Система Quick-BASIC располагает еще двумя отладочными средствами, позволяющими приостановить выполнение программы. Первое из них — останов на одной из помеченных программных строк. Такие точки останова (breakpoint) фиксируются путем нажатия клавиши F9. Помеченной считается строка, в которой в этот момент находился курсор. Отмена точки останова производится повторным нажатием клавиши F9. Имеется возможность отменить сразу все набранные остановы.
Второе отладочное средство - останов при выполнении заданного условия (watchpoint). Условия останова набираются в режиме Debug и умеют вид обычных операций отношения (А—О, N > 1000). Как только такое условие становится истинным, работа программы прекращается, и пользователь может увидеть оператор, при выполнении которого произошло ожидаемое событие.
Системная реакция на программные прерывания
Прерывания, возникающие в процессе выполнения программы, обрабатываются описываемыми системами практически одинаково. В системных переменных ERR и ERL запоминаются соответственно числовой код зафиксированной ошибки и номер (метка) строки, выполнение которой вызвало прерывание. На экран дисплея выдаются координаты прерванной строки и текст сообщения, поясняющий характер обнаруженной ошибки. После этого выполнение Бейсик-программы аварийно завершается и пользователю предоставляется возможность исправить ошибку.
Описываемые системы используют одинаковую нумерацию и идентичный состав сообщений о динамических ошибках. Небольшие отклонения можно заметить лишь в том, что некоторые из сообщений в той или иной системе заменены “пустыми” текстами типа “Unprintable error” (GW- и Quick-BASIC) и “Undefined error” (TurboBASIC). Полный перечень сообщений с краткими их комментариями приведен ниже.
Код и текст сообщения
Причины ошибки
1. NEXT without FOR
Оператор NEXT встретился до оператора FOR или в nape FOR — NEXT употреблены имена разных переменных
2. Syntax error
Обнаружена синтаксическая ошибка в строке с указанным номером
3. RETURN without GOSUB
Выполнению оператора RETURN не предшествовало обращение к подпрограмме
4. Out of DATA
При выполнении оператора READ были исчерпаны данные
5. Illegal function call
Неправильное обращение к функции, вызванное ошибочными значениями или недопустимым типом аргу-
6. Overflow
ментов
В результате выполнения арифметической операции получено число, выходящее за максимально допустимые пределы
7. Out of memoryПрограмма слишком велика, содержит недопустимо много вложенных циклов или подпрограмм, использует очень громоздкие арифметические выражения8. Undefined line numberВ программе отсутствует строка, номер которой указан в операторе перехода9. Subscript out of rangeЗначение индексного выражения выходит за обьявлен- , ные пределы10. Duplicate DefinitionПовторное определение массива. Эта же ошибка фиксируется и в случае появления оператора DIM после установления размерности массива по умолчанию (10, 10x10)Division by zeroIllegal directДеление на нульПопытка использовать запрещенный оператор в режиме непосредственных вычислений13. Type mismatchиНесоответствие допустимого и использованного типов данных (строковое значение вместо числового или наоборот)Out of string spaceString too longИсчерпана область хранения символьных переменных Длина строки превышает максимально допустимое значение7. Out of memoryПрограмма слишком велика, содержит недопустимо много вложенных циклов или подпрограмм, использует очень громоздкие арифметические выражения8. Undefined line numberВ программе отсутствует строка, номер которой указан в операторе перехода9. Subscript out of rangeЗначение индексного выражения выходит за обьявлен- , ные пределы10. Duplicate DefinitionПовторное определение массива. Эта же ошибка фиксируется и в случае появления оператора DIM после установления размерности массива по умолчанию (10, 10x10)Division by zeroIllegal directДеление на нульПопытка использовать запрещенный оператор в режиме непосредственных вычислений13. Type mismatchиНесоответствие допустимого и использованного типов данных (строковое значение вместо числового или наоборот)Out of string spaceString too longИсчерпана область хранения символьных переменных Длина строки превышает максимально допустимое значение16. String formula too complex17. Can't continue16. String formula too complex17. Can't continueUndefined user functionNo RESUMERESUME without errorMissing operandLine buffer overflowDevice TimeoutDevice Fault ‘FOR without NEXTOut of PaperWHILE without WENDWEND without WHILEDuplicate labelSubroutine not definedArgument-count mismatchArray not definedUndefined user functionNo RESUMERESUME without errorMissing operandLine buffer overflowDevice TimeoutDevice Fault ‘FOR without NEXTOut of PaperWHILE without WENDWEND without WHILEDuplicate labelSubroutine not definedArgument-count mismatchArray not definedСимвольное выражение слишком сложно
7. Out of memory
Программа слишком велика, содержит недопустимо много вложенных циклов или подпрограмм, использует очень громоздкие арифметические выражения
8. Undefined line number
В программе отсутствует строка, номер которой указан в операторе перехода
9. Subscript out of range
Значение индексного выражения выходит за обьявлен- , ные пределы
10. Duplicate Definition
Повторное определение массива. Эта же ошибка фиксируется и в случае появления оператора DIM после установления размерности массива по умолчанию (10, 10x10)
Division by zero
Illegal direct
Деление на нуль
Попытка использовать запрещенный оператор в режиме непосредственных вычислений
13. Type mismatch
и
Несоответствие допустимого и использованного типов данных (строковое значение вместо числового или наоборот)
Out of string space
String too long
Исчерпана область хранения символьных переменных Длина строки превышает максимально допустимое значение
7. Out of memory
Программа слишком велика, содержит недопустимо много вложенных циклов или подпрограмм, использует очень громоздкие арифметические выражения
8. Undefined line number
В программе отсутствует строка, номер которой указан в операторе перехода
9. Subscript out of range
Значение индексного выражения выходит за обьявлен- , ные пределы
10. Duplicate Definition
Повторное определение массива. Эта же ошибка фиксируется и в случае появления оператора DIM после установления размерности массива по умолчанию (10, 10x10)
Division by zero
Illegal direct
Деление на нуль
Попытка использовать запрещенный оператор в режиме непосредственных вычислений
13. Type mismatch
и
Несоответствие допустимого и использованного типов данных (строковое значение вместо числового или наоборот)
Out of string space
String too long
Исчерпана область хранения символьных переменных Длина строки превышает максимально допустимое значение
16. String formula too complex
17. Can't continue
16. String formula too complex
17. Can't continue
Undefined user function
No RESUME
RESUME without error
Missing operand
Line buffer overflow
Device Timeout
Device Fault ‘
FOR without NEXT
Out of Paper
WHILE without WEND
WEND without WHILE
Duplicate label
Subroutine not defined
Argument-count mismatch
Array not defined
Undefined user function
No RESUME
RESUME without error
Missing operand
Line buffer overflow
Device Timeout
Device Fault ‘
FOR without NEXT
Out of Paper
WHILE without WEND
WEND without WHILE
Duplicate label
Subroutine not defined
Argument-count mismatch
Array not defined
Продолжение программы невозможно. Например, после внесения изменений программу нельзя продолжить по директиве CONT
Использован оператор USRn (X) без описания функции (DEF USRn) или употреблена функция, не объявленная в виде процедуры FUNCTION
Подпрограмма обработки ошибочных ситуаций не содержит оператора RESUME
Оператор RESUME использован не в рамках подпрограммы обработки ошибочных ситуаций
Пропущен операнд
При вводе превышена максимально допустимая длина строки
За предусмотренный интервал времени от устройства ввода-вывода не поступил ожидаемый сигнал Ошибка в работе принтера или интерфейсной карты Для оператора FOR не обнаружен соответствующий ему оператор NEXT
В принтере не заправлена бумага
Ошибка в оформлении цикла WHILE — WEND (отсутствует конец цикла)
Ошибка в оформлении цикла WHILE — WEND (отсутствует начало цикла)
Дублирование меток
Подпрограмма не определена
Несоответствие количества аргументов
Массив не определен
CASE ELSE expectedVariable requiredHELD OverflowInternal errorBad file numberFile not foundBad file modeCASE ELSE expectedVariable requiredHELD OverflowInternal errorBad file numberFile not foundBad file modeFile already openFIELD statement activeDevice I/O ErrorFile already existsBad record lengthDisk fullInput past end fileBad record numberBad file nameDirect statement in fileToo many filesDevice unavailableCommunication buffer overflowPermission DeniedDisk not ReadyDisk Media ErrorAdvanced FeatureRename across disksPath/File Access errorPath not foundFile already openFIELD statement activeDevice I/O ErrorFile already existsBad record lengthDisk fullInput past end fileBad record numberBad file nameDirect statement in fileToo many filesDevice unavailableCommunication buffer overflowPermission DeniedDisk not ReadyDisk Media ErrorAdvanced FeatureRename across disksPath/File Access errorPath not foundОтсутствует выбор CASE ELSE.
CASE ELSE expected
Variable required
HELD Overflow
Internal error
Bad file number
File not found
Bad file mode
CASE ELSE expected
Variable required
HELD Overflow
Internal error
Bad file number
File not found
Bad file mode
File already open
FIELD statement active
Device I/O Error
File already exists
Bad record length
Disk full
Input past end file
Bad record number
Bad file name
Direct statement in file
Too many files
Device unavailable
Communication buffer overflow
Permission Denied
Disk not Ready
Disk Media Error
Advanced Feature
Rename across disks
Path/File Access error
Path not found
File already open
FIELD statement active
Device I/O Error
File already exists
Bad record length
Disk full
Input past end file
Bad record number
Bad file name
Direct statement in file
Too many files
Device unavailable
Communication buffer overflow
Permission Denied
Disk not Ready
Disk Media Error
Advanced Feature
Rename across disks
Path/File Access error
Path not found
В этой конструкции допустимо употребление только имени переменной
Длина записи в файле прямого доступа превышает размеры буфера, отведенного по оператору HELD Внутренняя ошибка системы
Попытка обращения к файлу, который не был открыт.
Попытка открыть файл С недопустимым номером
На диске не найден файл с указанным именем. Возможна ошибка в задании имени
Недопустимый файловый режим. Возможно неправильное употребление операторов обмена (PUT или GET для последовательных файлов, LOAD для файла прямого доступа) или задание недопустимого режима в операторе OPEN
Попытка удалить открытый файл или открыть его повторно
Ошибка оборудования
Попытка присвоить файлу нмя уже существующего файла
Недопустимая длина записи
На диске нет свободного места
Попытка прочитать данные из файла, который уже исчерпан
Недопустимый номер записи
Ошибка в задании имени файла
При загрузке программного файла (LOAD) GW-система обнаружила строку без номера
Слишком много файлов, в оглавлении нет места для нового файла
Устройство недоступно (ие включено или не переведено в режим On-line)
Переполнен буфер телекоммуникационного канала
Попытка обращения к защищенным данным (запись на дискету с заклеенной прорезью, обращение к файлу с защищенными записями и т.п.)
Дискета не вставлена или дисковод не приведен в состояние готовности
Разрушен участок с носителем информации на диске Использована конструкция, еще не реализованная в рамках данной версии
В попытке переименовать файл указано, что новый файл должен быть расположен на другом диске. Такая процедура запрещена
Неверно задана спецификация файла
Не найдено оглавление
Индивидуальная обработкапрограммных прерываний
В состав пользовательской программы может быть включена подпрограмма, осуществляющая нестандартную обработку программных прерываний. Точка входа в такую подпрограмму объявляется с помощью следующего оператора:
ON ERROR GOTO N
Если значение N отлично от нуля, то стандартная реакция системы на программные прерывания блокируется. Теперь при возникновении любой особой ситуации во время выполнения программы управление будет передано указанной подпрограмме. Для анализа типа события и локализации места ошибки можно воспользоваться значениями системных переменных, перечень которых приведен ниже. (Если во время работы подпрограммы обработки ошибок снова возникнет особая ситуация, то задача снимается.)
НаименованиепеременнойERADRERDEVERDEV$ERLERREXTERRНаименованиепеременнойERADRERDEVERDEV$ERLERREXTERRЗначение переменной
Наименованиепеременной
ERADR
ERDEV
ERDEV$
ERL
ERR
EXTERR
Наименованиепеременной
ERADR
ERDEV
ERDEV$
ERL
ERR
EXTERR
Адрес команды, при выполнении которой была обнаружена ошибка. Turbo-система в режиме Debug позволяет опознать оператор исходной программы, соответствующий ошибочной команде
Код ошибки, обнаруженной при работе с внешним устройством
Идентификатор устройства, при работе которого была обнаружена ошибка
Номер строки исходной программы, при выполнении которой возникла особая ситуация
Код программной ошибки (см. п. 6.2)
Массив, используемый в GW-системе и содержащий четыре элемента, в которых находится расширенная информация об ошибке
Возврат из подпрограммы обработки ошибочной ситуации осуществляется с помощью оператора RESUME. Будучи употреблен без аргумента или с нулевым аргументом, он передает управление оператору, при выполнении которого возникла ошибочная ситуация. Это дает возможность повторить действие, если ошибка носит случайный характер.
Для обхода ошибочного оператора используется модификация
RESUME NEXT. Возможен и вариант возврата на строку с заданным номером или меткой:
RESUME 150
Программное прерывание не всегда означает ошибку в работе алгоритма. Некоторые ситуации типа исчерпания данных могут быть заранее запланированы:
10 ON ERROR GOTO 1000
20READ А,В,С
250 GOTO 20
1000 IF ERR - 4 THEN RESUME 260
1010 PRINT “ERR-”; ERR, “ERL-”; ERL
1020 RESUME NEXT
Отладке программы обработки ошибочных ситуаций может оказать содействие оператор ERROR п. Он моделирует возникновение ошибки с кодом и (0 < - п < - 255).
Выполнение оператора ON ERROR GOTO 0 восстанавливает с^- темный режим контроля за программными прерываниями.
1. ОСНОВНЫЕ ПРИЕМЫ РАБОТЫВ СРЕДЕ GW-BASIC
Название системы происходит от сокращения фразы Gee Whiz BASIC, которую довольно трудно перевести на русский язык. Первое слово имеет несколько значений — «лошадка», «вот это да!», «ого!», Поэтому иногда систему GW называют надежной лошадкой. Второе слово, являющееся синонимом whizz, переводится как , «чудо», .«прелесть», «здорово», «молодец», . . . . Будем считать, что сочетание «чудо-Бейсик» не очень противоречит замысловатому GW.
GW-BASIC представляет собой завершающий этап в развитии семейства MS-BASIC, BASIC-T, BASIC-D и BASIC-A — первых про- - граммных продуктов фирмы Microsoft Corporation, появившихся в составе операционных систем MS DOS и PC DOS.
Известно довольно много версий GW-BASIC, появившихся в ре- ■ зультате совместных усилий фирм Microsoft и Commodore на ПЭВМ типа PC-10, PC-20, PC-30, Microsoft и Apple Computer на ПЭВМ типа Macintosh. В этой главе приводятся сведения о версии 3.23, функционирующей под управлением MS DOS - 3.30.
В отличие от более современных систем компилирующего типа (Quick-BASIC — 4.0, Turbo-BASIC — 1.1) GW-BASIC базируется на интерпретации. Любая Бейсик-программа может исполняться только в среде GW-системы и интерпретируется заново при каждом очередном запуске. В последнее время в литературе появилось сообщение разработке GW-компилятора.
GW-интерпретатор версии 3.23 является программным продуктом фирмы Microsoft Corporation и состоит из единственного модуля gwbasic.exe, занимающего на диске 80 608 байт.
Вызов и настройка интерпретатора
Старт GW-системы сопровождается запуском ее единственного модуля, для настройки которого в команд ой строке задается набор необходимых параметров:
> gwbasic [ nameprog ] [ < input ] [ [ > ] > output ] [/c: n] [/d]
[Zf: n] [Zi] [/m: [nl] [,n2]] [Zs: n]
Здесь nameprog — имя Бейсик-программы, которая автоматически загружается в память после вызова интерпретатора и иачинает выполняться. Имя программы может быть задано как полной спецификацией файла (диск.корневое оглавление, вложенные оглавления, имя файла), так и именем файла без указания расширения .BAS, если нужный текст находится в текущей директории;
< input — назначение устройства ввода, в качестве которого по умолчанию выступает клавиатура (KYBD:);
[>]>output — назначение устройства (файла) вывода, в качестве которого по умолчанию выступает экран дисплея (SCRN:). Наличие двух подрад идущих символов «»* означает, что файл вывода открывается для дозаписи с сохранением ранее находившейся в нем информации;
/с: п — установка максимального размера буферов, обслуживающих обмен по телекоммуникационным каналам связи (СОМ1: и/или COM2:). По умолчанию емкость буфера вывода равна 128 байт, а емкость принимающего буфера — 256 байт. Нулевое значение п отменяет поддержку работы с каналами связи;
Zd — признак установки режима вычисления значений математических функций (ATN, COS, EXP, LOG, SIN, SQR, TAN) с удвоенной точностью;
Zf: n — установка максимального количества n одновременно открытых файлов. Каждый открываемый файл требует для своего обслуживания 194 байта памяти под так называемый блок управления (FCB - File Control Block) и 128 байт под буфер для обмена данными. По умолчанию система ограничивает количество одновременно открытых файлов числом 3;
/1 — признак статического распределения памяти под области FCB и буфера обмена;
/ш: nl [,п2] — установка максимального адреса ячейки оперативной памяти (nl) и максимального размера блока (п2), используемых системой. Указанные ограничения необходимы в тех случаях, когда используются ассемблеровские подпрограммы и занимаемые ими области не должны пересекаться с системой.
Все числовые параметры, изменяющие размеры соответствующих системных областей, задаются десятичными, восьмеричными или шестнадцатеричными константами. Порядок задания управляющих параметров — произвольный. Однако имена вызываемого программного файла и файлов ввода-вывода располагаются в начале командной строки.
Директивы управления системой GW-BASIC
Помимо директив (операторов), используемых для работы с файловой подсистемой MS DOS и описанных в п. 2.5.5, система GW-BASIC
"располагает специфическим набором директив, полный перечень которых приведен ниже в п. 7.2.1.
С целью ускорения набора наиболее употребительных директив их полный или частичный текст закреплен за функциональными клавишами :
Fl : LISTF2 : RUN + CHR$(13)F3 : LOAD"F4 : SAVE"F5:CONT + CHR$(13)Fl : LISTF2 : RUN + CHR$(13)F3 : LOAD"F4 : SAVE"F5:CONT + CHR$(13)F6 : ,"LPT1:" + CHR$(13)
Fl : LIST
F2 : RUN + CHR$(13)
F3 : LOAD"
F4 : SAVE"
F5:CONT + CHR$(13)
Fl : LIST
F2 : RUN + CHR$(13)
F3 : LOAD"
F4 : SAVE"
F5:CONT + CHR$(13)
F7 : TRON + CHR$(13)
F8 : TROFF + CHR$(13)
F9 : KEY
F10: SCREEN 0,0,0,+CHR$( 13)
Ввод новой программы
Ввод новой программы начинается с директивы NEW, которая производит очистку оперативной памяти от предшествующей программы и ее переменных.
Время набора можно сократить, воспользовавшись директивой AUTO, которая устанавливает режим автоматической нумерации вводимых строк. Первый ее аргумент определяет новый начальный номер (N) или воспринимает в качестве точки отсчета номер только что введенной строки (.). По умолчанию начальный номер принимается равным 10. Второй аргумент (dN) задает шаг нумерации строк. При его отсутствии шаг принимается равным 10 или устанавливается по значению dN, употребленному в ранее набранной директиве AUTO. Последний вариант имеет место, если первый аргумент завершается запятой, a dN — отсутствует.
Отмена режима автоматической нумерации строк происходит после нажатия клавиш Ctrl+Break (Ctrl+S).
Длина программной (логической) строки в системе GW-BASIC может доходить до 255 символов. При наборе длинной строки, содержащей более 80 символов, курсор автоматически переходит в начало следующей экранной строки. Набор строки завершается нажатием клавиши Enter.
Во время набора текущей строки можно исправить замеченные пользователем ошибки. Для этого применяются клавиши перемещения курсора Delete, Backspace, Insert.
Одной из наиболее распространенных ошибок начинающих пользователей является исправление, удаление или замена фрагментов ранее набранной программы без нажатия клавиши Enter. При такого рода коррекциях курсор следует обязательно перевести в конец исправляемой строки, после чего необходимо нажать клавишу Enter. В
176
противном случае исправление останется только на экране, а в программный файл не попадет.
Вообще говоря, для исправления строки с номером N или только что набранной строки лучше воспользоваться директивой EDIT и средствами экранного редактора, описанными в п. 7.2.3.
Удаление ненужных или ошибочно набранных строк может быть выполнено двумя способами. Одиночную строку проще удалить, набрав ее номер и нажав клавишу Enter, т.е. введя пустую программную строку. Для удаления фрагмента, начинающегося строкой с номером N1 и заканчивающегося строкой с номером N2, естественно воспользоваться директивой DELETE.
Формат директивы
Назначение
AUTO [N] [,[dN]]
AUTO . [,[dN]]
CONT
DELETE [Nl] [-N2]
DELETE Nl-
EDITN EDIT.
KEY i,"ss...s“
Установка режима автоматической нумерации строк
Продолжение выполнения прерванной программы
Удаление строк текущей программы
Удаление программы, начиная со строки N1
Переход в режим редактирования указанной или текущей строки
Закрепление текста ss. ..$ за функциональной клавишей Fi-
KEY LIST
Вывод на экран полных текстов, закрепленных за всеми функциональными клавишами
UST [Nl] [-N2] [."file"]
LIST [N1-] [,"file"[
LLIST [Nl] [-N2]
LLIST [N1-]
LOAD «file» [,R]
MERGE «file»
Вывод фрагмента текущей программы на экран или в указанный файл
Вывод фрагмента текущей программы на принтер
Загрузка программного файла
Слияние указанного программного файла с текущей программой
NEW
Удаление текущей программы из памяти и очистка значений всех переменных
RENUM [Nnew], [Noid] [,dN]
RUN [N] [Ji]
RUN «file» [,R]
SAVE «file» [,A]
SAVE «file» [,P]
Перенумерация строк текущей программы
Выполнение текущей программы
Запоминание текущей программы в формате ASCII Запоминание текущей программы в защищенном формате
SYSTEM TROFF TRON
Возврат из GW-системы в MS DOS Отключение режима трассировки Включение режима трассировки
Запоминание и загрузка программных файло
Чтобы сохранить текущую программу на винчестере или дискете, надо нажать клавишу F4, после чего в командной строке появится начало директивы SAVE. Затем необходимо набрать полную или укороченную спецификацию программного файла, закрыть кавычку и нажать клавишу Enter:
SAVE "d:\basic\gwbasic\progl"
SAVE "progl"
Имя файла можно и не заключать в кавычки. В директиве SAVE может присутствовать еще один аргумент - буква А или Р. В первом случае текст программы запоминается в формате ASCII, что позволяет его в дальнейшем редактировать и распечатывать. Несмотря на то, что формат ASCII предполагает хранение программы в виде обычного текстового файла, GW-система все-таки его модифиц рует, заменяя служебные слова одно- или двухсимвольными комбинациями. Поэтому такой текст нельзя отредактировать, например, средствами Нортон-редактора или передать на исполнение другим Бейсик-системам. Так что обрабатывать текст программы можно только в среде GW-системы. Во втором случае (Р) для хранения программы используется специальный защищенный формат. После этого программу можно только выполнить, но редактировать или распечатывать ее нельзя. Этот вариант может быть использован при передаче своих разработок другим лицам или организациям : целью сохранения в тайне текста исходной программы. Абсолютную защиту это, естественно, не обеспечивает, так как знание внутреннего представления защищенного файла позволяет восстановить его текст.
Дисковые программные файлы загружаются в память с помощью директив LOAD или RUN:
LOAD "progl" [,R] ..
RUN "progl" [,R]
Директива LOAD без параметра R перед загрузкой осуществляет очистку памяти от предыдущей программы и ее переменных и только после этого считывает указанный программный файл. Затем загруженную программу можно редактировать, распечатывать и выполнять.
В сочетании с параметром R директива LOAD напоминает оператор CHAIN. Перед вызовом новой программы из памяти удаляются все 178
строки предшествующей программы, но значения всех ее пере енных и состояние открытых файлов сохраняются. Это обеспечивает возможность передачи данных между программами. Файл, загруженный с параметром R, начинает немедленно исполняться.
Директива RUN в сочетании с именем файла действует, подобно оператору LOAD, и единственное отличие состоит только в том, что загружаемый файл в любом случае начинает исполняться.
' К тексту текущей программы можно присоединить содержимое любого дискового файла с помощью директивы MERGE. При такой загрузке строки текущей программы из памяти не удаляются, но если во вновь вызываемой программе имеются строки с совпадающими номерами, то они замещают прежние операторы.
Редактирование текущей программы
Для внесения изменений в текст текущей программы его необходимо предварительно вывести на экран дисплея с помощью директивы LIST. Корректуру в текст можно вносить, используя примитивные средства вставки (удаления) в сочетании с клавишами перемещения курсора. Однако большего эффекта можно достичь с помощью клавишных функций экранного редактора GW-системы. Полный их перечень приведен в табл. 15.
Если объем вносимых изменений достаточно велик и в программе появилось большое количество вставленных строк, то текст программы можно улучшить путем перенумерации строк с помощью директивы RENUM:
RENUM [Nnew] , [Nold] [,dN]
Строке текущей программы с номером Nold присваивается номер Nnew. Все последующие строкиперенумеруются с шагом dN. По умолчанию перенумерация начинается с самой первой строки, а в качестве параметров Nnew и dN принимается 10.
Процедура перенумерации заменяет не только номера строк программы, но и производит соответствующие исправления в операторах, ссылавшихся на прежние номера. Это относится к операторам условного и безусловного перехода, восстановления блока данных (RESTORE) и возврата из подпрограмм (RETURN, RESUME) с указанием номеров строк, к системной переменной ERL.
Таблица 15
Перемещения по тексту
Комбинация клавиш
Направление перемещения курсора
М , Ctrl+] О ,Ctrl+\ Ctrl + M , Ctrl+B Ctrl + 0 ,Ctrl+F Ноше , Ctrl+K End , Ctrl+N H ,Ctrl+6 П , Ctrl+- Ctrl+Enter, Ctrl+J Tab
На «дАу »«зицию в<ев«
На «дАу »«зицию в»рав«
В Аача<« *редыдущег« с<«ва и<и чис<а
В Аача<« с<едующег« с«ва и<и чис<а
В левый верхний угол экрана
В конец текущей логической строки
На «дАу стр«”у вверх
На «дАу стр«”у вАиз
В начало следующей экранной строки
В ближайшую справа позицию, номер которой кратен 8
pi
Удаление
Комбинация клавиш
Назначение
Bcsp , Ctrl+H Ctrl+Bcsp, Dei Ctri+End, Ctrl+E
Ctrl+Г , Esc
Удаление символа слева от курсора
Удаление символа над курсором
Удаление части логической строки от позиции курсора до конца строки
Удаление текущей логической строки целиком
Вставка
Комбинация клавиш
Выполняемая функция
Ins , Ctrl+R
Включение или отключение режима вставки
Прочие операции
Комбинация клавиш
Назначение
. Ctrl+Break
Crtl+M , Enter Ctrl+G
Ctrl+Ноше , Ctrl+L
Ctri+NumLock, Ctri+S
Ctri+PrtSc
Shift+PrtSc
Устанавливает режим ввода и отменяет автоматическую нумерацию строк
Вводит текущую строку до позиции курсора
Генерирует кратковременный звуковой сигнал
Чистит экран и перемещает курсор в левый верхний угол
Останавливает программу. Для продолжения нажать любую клавишу
Включает или отключает режим, при котором информация, выдаваемая на экран дисплея, одновременно печатается на принтере
Выводит содержимое экрана на принтер
Выполнение и прерывание программы
Запуск текущей программы производится нажатием клавиши F2, т.е. путем выполнения директивы RUN без параметров. При этом
интерпретация начинается со строки с наименьшим номером. Директиву RUN с указанием входной точки приходится набирать:
. RUN 150 [,R]
Параметр R, как и при загрузке новой программы, позволяет сохранить значения всех переменных и состояние открытых файлов.
Прервать выполняющуюся программу можно, нажав клавиши Ctrl+ Break (Ctrl+S). После этого работу программы можно продолжить с помощью директивы CONT, если в текст текущей программы с момента останова не вносилось каких-либо изменений. Останов программы, в частности, используют для просмотра значений переменных.
Для получения дополнительной информации о ходе выполнения текущей программы можно воспользоваться директивами TRON и TROFF, выполнение которых осуществляется нажатием единственной клавиши F7 или F8. При включении режима трассировки накапливаются и выдаются номера исполняющихся строк, по последовательности которых можно судить о правильности или ошибочности в запрограммированной логике алгоритма. Режим трассировки отменяется директивами TROFF и NEW.
8. ОСНОВНЫЕ ПРИЕМЫ РАБОТЫВ СРЕДЕ TURBO-BASIC
Turbp-BASIC представляет собой компактную интегрированную систему программирования, обеспечивающую ввод, редактирова ие, хранение, исполнение и отладку программ в довольно комфортных для пользователя условиях. Разработана она фирмой Borland International (США), основанной в 1984 г. и получившей широкую известность благодаря самой дешевой (49 долларов 95 центов) и сверхскоростной системе программирования Turbo Pascal. Не менее популярны н другие программные изделия этой фирмы — Turbo С, Turbo Assembler (TASM), Turbo Prolog, отладчик программ Turbo Debugger (TD), изящный решатель задач Eureka и др.
Работы: с Бейсиком в этой фирме были начаты в 1985 г. Первая промышленная версия известна под порядковым номером 1.0. В начале 1987 г. появилась следующая модификация системы с номером 1.1. Среди последующих реализаций известны версии 1.5 и 2.0. Последняя из них распространяется под названием Power BASIC. К сожалению, автор не располагал возможностью с ней поработать.
В отличие от GW-BASIC продукция фирмы Borland снабжается достаточно информативной системой подсказок, доступной пользователю на любом этапе его работы и вызываемой нажатием клавиши F1 (Help).
В состав версии 1.1 входят шесть основных файлов, перечень которых приведен ниже.
НазначениеНазначениеНаименованиефайла
Назначение
Назначение
READMEREADME.COMТВ.ЕХЕTBINST.COMREADMEREADME.COMТВ.ЕХЕTBINST.COMТекстовый файл с кратким описанием состава версии и особенностей входного языка
README
README.COM
ТВ.ЕХЕ
TBINST.COM
README
README.COM
ТВ.ЕХЕ
TBINST.COM
Программа распечатки файла README
Основной модуль системы Turbo-BASIC
Программа настройки основного модуля
TBCONFIG.TBTBCONFIG.TBTBHELPTBTBHELPTBФайл конфшурации, в котором хранятся параметры, управляющие работой системы
TBCONFIG.TB
TBCONFIG.TB
TBHELPTB
TBHELPTB
Файл с информацией справочного характера, отображаемой по запросам пользователя
К Turbo-системе прилагается довольно большой набор демонстрационных и обслуживающих программ. Среди них небольшие программные файлы на Бейсике и несколько более крупных программных комплексов, представленных головными модулями и совокупностью подключаемых к ним файлов с расширением .INC. Наиболее интересной новинкой по сравнению с версией 1.0 является комплекс программ, демонстрирующих возможности использования меню в прикладных программах и поддержки работы с окнами. С текстами головного модуля TBDEMO30.BAS и подключаемых файлов TBMENU.INC и TBWINDOW.INC мы рекомендуем познакомиться в первую очередь. В работе этого комплекса задействована группа подпрограмм, составленных на языке ассемблера и заранее протрансли- рованных для их непосредственного использования в составе подпрограмм типа SUB INLINE.
Главное и вспомогательное меню. Системные окна
Запуск основного файла ТВ.ЕХЕ сопровождается появлением на экране главного меню и фирменной заставки с указанием индекса и года издания версии. Главное меню представлено фиксированной строкой в верхней части экрана, содержащей наименования восьми основных режимов, и информацион ой строкой в нижней части экрана. Содержимое последне" меняется в зависимости от выбранного режима работы.
Основные режимы Turbo-системы перечислены на экране в следующем порядке:
File Edit Run Compile Options Setup Window Debug
В последующих разделах мы детально познакомимся с каждым из них, а пока ограничимся лишь краткой информацией.
Режим File предназначен для реализации файловых процедур, обеспечивающих сохранение на диске текущей программы и загрузку ранее подготовленных программных файлов. Кроме своих основных Функций, этот режим обеспечивает просмотр оглавлений дисковых
файлов, кратковременный или окончательный переход из Turbo-системы в MS DOS.
В режиме Edit выполняются все процедуры, связанные с набором и редактированием текущей программы.
Запуск текущей программы осуществляется в режиме Run, в отличие от которого режим Compile дополнительно позволяет изготовить и сохранить модуль требуемого образца.
Режим Options обеспечивает установку параметров, управляющих процессами компиляции и выполнения программы. Изменение ряда системных параметров производится и в режиме Setup, который позволяет запомнить конфигурацию системы в стандартном (TBCONFIG.TB) или пользовательском файле и восстановить ее при повторных сеансах.
Параметры системных окон, их количество и взаимное расположение на экране устанавливаются в режиме Window.
Режим Debug управляет процессом отладки программы.
Выбор одного из основных режимов производится с помощью клавиш горизонтального перемещения курсора. При этом по верхней строке главного меню передвигается окрашенный прямоугольник. Для входа в выбранный режим необходимо нажать клавишу Enter, после чего в ряде случаев появляется вспомогательное меню в виде столбца возможных процедур. Вход в нужный режим главного меню можно осуществить и путем одновременного нажатия двух клавиш — Alt и первого символа наименования режима. Обычно этот символ в строке главного меню окрашен другим цветом. Для возврата в главное меню необходимо нажать клавишу Esc.
Перемещение прямоугольника выбора по вспомогательному меню производится клавишами вертикального перемещения курсора или нажатием символа, выделенного в процедуре другим цветом. Вход в некоторые процедуры вспомогательного меню может сопровождаться появлением дополнительных меню следующего уровня. Новое меню частично заслоняет меню предыдущего уровня и тоже содержит несколько выбираемых строк. В некоторых ситуациях на экране одновременно может находиться до четырех таких меню-заставок.
Строки вспомогательных меню предназначены для выполнения различных операций или изменения значений системных параметров. Иногда значение модифицируемого параметра находится непосредственно в строке меню, в других случаях оно набирается в специально появляющейся прямоугольной области. Различают несколько типов системных параметров.
В одних ситуациях параметры представляются строковыми значе-
ниями, задающими наименования файлов, оглавлений и т.п. Для их установки система выделяет прямоугольную область, в которой может быть выдано предшествующее значение параметра. Необходимо очень внимательно отнестись к набору нового значения, если оно может быть получено путем незначительной коррекции старого текста. Первой клавишей, которую вы должны нажать, может быть только клавиша горизонтального перемещениякурсора. При этом пропадает контрастный фон предыдущего значения, оно сохраняется в окне и готово к внесению любых изменений. Нажатие любой другой клавиши приведет к очистке наборного окна, и вам придется набирать значение нового параметра целиком.
Второй тип параметров может принимать только два значения, соответствующих включению (ON) или отключению (OFF) определенного признака. Изменение состояния таких параметров осуществляется повторными нажатиями клавиши Enter, каждое из которых изменяет значение параметра на противоположное.
В состав третьей группы входят числовые параметры, задающие размеры различных буферов и стеков.
Последнюю группу составляют параметры, определяющие цветовые атрибуты различных системных компонент. Модификация таких параметров может доставить пользователям большое наслаждение, так как их значения выбираются по красиво оформленному табличному образцу. Клеточки такой таблицы окрашены в разные цвета, на фоне которых отображены цветные крестики. Предлагаемые сочетания могут удовлетворить любой вкус. Выбор нужной клеточки осуществляется клавишами горизонтального и вертикального перемещения курсора. Одновременно с этим на экране демонстрируются результаты вашего выбора. Если они вам понравились, то для фиксации значений соответствующих параметров на время сеанса надо нажать клавишу Esc.
Область экрана, не занятая главным меню, может быть использована для последовательного или одновременного отображения информации одного из четырех типов:
текст текущей программы (окно Edit);
результаты выполнения текущей программы (окно Run);
тексты системных сообщений (окно Message);
результаты выполнения программы в отладочном режиме (окно Trace).
Каждое из перечисленных окон обведено прямоугольной рамкой, в разрыве верхней линии которой находится заголовок окна. Одно из окон считается активным и выделяется тем, что его рамка обведена
двойной линией. Размеры окон и их взаимное расположение на экране можно менять.
Для предоставления активному окну всей площади экрана необходимо нажать клавишу F5 (Zoom). Повторное нажатие клавиши F5 восстанавливает прежний размер активного окна.
Активизация очередного окна, необходимая для просмотра его содержимого или выполнения каких-либо других операций, производится нажатием клавиши F6 (Next).
Информация о действиях, закрепленных за функциональными клавишами, находится в нижней строке экрана. В затруднительных случаях полезно прибегнуть к услугам встроенного подсказчика, вызываемого нажатием клавиши Fl (Help). В режиме подсказки вы можете перемещениями курсора подвести прямоугольник выбора к отмеченному термину и нажать клавишу Enter. Иногда подсказка занимает несколько кадров, и тогда в правом нижнем /глу кадра выделено сочетание «go on...*. Подведите к нему прямоугольник выбора и продолжайте просмотр. Выход из режима подсказки происходит после нажатия клавиши Esc.
8.*2. Ввод и редактирование новой программы
Набор новой программы начинается с выбора файловой процедуры New. Ее исполнение приводит к очистке соответствующих областей оперативной памяти и переходу в режим редактирования. Для начала желательно нажать клавишу F5, расширив окно редактирования до полного экрана.
Вновь набираемой программе система присваивает стандартное имя NONAME.BAS, которое можно будет заменить в момент записи текущей программы на диск (см. файловые процедуры Save и Write to...).
Ввод новой программы производится естественным образом путем набора ее строк на клавиатуре. Набор каждой строки завершается нажатием клавиши Enter.
В любой момент вы можете переместить курсор по ранее набранному тексту и произвести в нем необходимые исправления — встав ть недостающие символы, удалить или заменить ненужные. Все эти операции производятся с помощью встроенного редактора текстовой информации, обеспечивающего манипуляции с отдельными символами, словами, строками и выделенными фрагментами текста (блоками). Он позволяет включить в состав набираемой программы текстовый фрагмент, хранящийся в дисковом файле, произвести распечатку программы или любого ее фрагмента. Перечень команд редактора приведен в
табл.16. Его состав несколько полнее, чем справка по функциям редактора, выдаваемая по запросу Help.
Табл ица 16
Перемещения по тексту
Комбинация клавиш
Направление перемещения курсора
М , Ctrl+S 0 ,CtrHD Tab, Ctrl+I
На «диб си>в«< в<ев«
На «диб си>в«< в»рав«
На фиксированное количество позиций вправо
Ctrl+M, Ctrl+A Ctrl+O, Ctrl+F Home , Ctrl+Q+S End , Ctrl+Q+D H , Ctri+E П , Ctrl+X Ctrl+Enter, Ctrl+J Ctrl+Home, Ctrl+Q+E Ctrl+End , Ctrl+Q+X PgUp . Ctrl+R PgDn , CtrH-C Ctrl+PgUp, Ctrl+Q+R Ctrl+PgDn, Ctrl+Q+C CtrH-Q+B Ctrl+Q+K Ctrl+Q+fl Ctrl+Q+1 Ctrl+Q+2
Ctrl+Q+3
Ctrl+Q+P
На «д4« с<«в« в<ев«
На «д6« с<«в« в»рав«
В начало текущей строки
В конец текущей строки
На «дбу стр«"у вверх
На «дбу стр«"у вбиз
В начало следующей строки
В начальную позицию текущего экрана
В конечную позицию текущего экрана На страницу вверх
На страницу вниз
В начальную позицию программы
В конечную позицию программы
В начало выделенного блока
В конец выделенного блока
В отмеченную позицию с номером 0
В отмеченную позицию с номером 1
В отмеченную позицию с номером 2
В отмеченную позицию с номером 3
В предыдущую отмеченную позицию
Команды выделения
Комбинация клавши
Назначение
F7 , Ctrl+K+B
F8 , Ctrl+K+K Ctrl+K+H
Фиксация начальной позиции блока
Фиксация конечной позиции блока Включение или отмена индикации выделенного блока
Ctrl+K+T
Ctrl+K+0
Ctrl+K+1
Ctrl+K+2
Ctrl+K+3
Выделение слова над курсором 'Фиксация позиции с меткой 0
Фиксация позиции с меткой 1
Фиксация позиции с меткой 2
фиксация позиции с меткой 3
Команды удаления
Комбинация клавиш
Назначение
Del , Ctrl+G Bcsp , Ctrl+H Ctrl+T Ctrl+Q+Y
Удаление символа над курсором
Удаление символа слева от курсора
Удаление слова справа от курсора
Удаление части строки справа от курсора
Ctrl+Y
Ctrl+K+Y
Удаление текущей строки целиком
Удаление выделенного блока
Команды вставки
Комбинация клавиш
Назначение
Ins , Ctrl+V
Enter, Ctji+N
Переключение режима вставки Вставка строки, начиная с позиции курсора
Ctrl+K+C
Копирование выделенного блока на новое место, начиная с позиции курсора
Ctrl+K+V
Перенос выделенного блока на новое место, начиная с позиции курсора
Ctrl+K+R
Вставка блока — содержимого указанного файла
Команды вывода
Комбинация клавиш
Назначение
Ctrl+K+W
Запись выделенного блока в дисковый файл
Ctrl+K+P
Печать выделенного блока
Команды поиска и замены
Комбинация клавиш
Назначение
Ctrl+Q+F
Поиск строки, содержащей заданный контекст
Ctrl+Q+A
Поиск строки, содержащей заданный кон текст, и замена его новым текстом
Ctrl+L
Повторение предыдущей операции поиска или замены
Прочие команды
Комбинация клавиш
Назначение
Ctrl+0+T
Включение или отключение режима табуляции
Crtl+0+I
Переключение режима автоматического отступа
Ctrl+O+L
Отмена изменений в текущей строке (откат на один шаг назад)
Поясним некоторые процедуры редактирования для читателей, не «меющих достаточного опыта работы с текстовыми процессорами. \ Довольно много неприятных ощущений пользователь испытывает из-за того, что он нажал не ту клавишу, выполнил ту или иную операцию, не поместив курсор в нужную позицию, не обратил внимание на текущее состояние режима вставки. Для ликвидации последствий новички обычно пытаются набрать подпорченный текст заново. Делать этого не следует, так как имеются возможности восстановить ситуацию более простыми средствами.
Один из наиболее частых сбоев в редактировании заключается в несвоевременном нажатии клавиши Enter. Если курсор находился при этом под одним из набранных символов, то вся правая часть текущей строки, начиная с позиции курсора, переходит в начало следующей строки. Ситуацию можно восстановить следующим образом. Возвратите курсор на предыдущую строку, переведите его в конец разорванной строки (клавиша End) и нажмите клавишу Del. Последнюю, возможно, придется нажать несколько раз, чтобы соединить разорванные части..
Во время редактирования внимательно следите за информационной строкой в верхней части экрана. Кроме указания номера текущей строки (Line nnn) и позиции курсора (Col mm) там отображаются или не отображаются слова Insert, Indent и Tab Fill.
Режим вставки включается или отключается при повторных нажатиях клавиши Ins. Если режим вставки включен, т.е. вы видите слово Insert, то набор новых символов сопровождается сдвигом оставшейся части строки вправо. Если режим вставки отключен, то содержимое хвостовой части строки не сдвигается. Вместо этого вновь набираемые символы заменяют предыдущий текст.
Указатель Indent связан с режимом автоматического отступа. Если вы набрали строку, первый значащий символ которой расположен, например, в 10-й позиции, то после нажатия клавиши Enter курсор переводится в ту же позицию следующей строки. Можно даже заметить такую картину: курсор появляется в первой позиции следующей строки и, как мячик, отскакивает от левой границы экрана. Если режим автоматического отступа отключен, то курсор переводится в начальную позицию новой строки.
Режим Tab Fill сигнализирует о включении механизма использования табуляторного пропуска. В этом режиме каждое нажатие клавиши Tab перемещает курсор на 8 позиций вправо. Несмотря на то что пропущенные позиции на экране заполнены пробелами, в тексте запоминаемой строки вместо каждых восьми пробелов находится управляющий код &Н09. Это позволяет более компактно использовать память при наличии внутренних пробелов. Если режим табуляции отключен, то клавиша Tab игнорируется, и для организации пропусков
в строке придется действовать клавишами пробела и горизонтальн го перемещения курсора.
Очень удобен механизм работы с блоками, если в вашей программе встречаются повторяющиеся или похожие фрагменты текста. В таком случае надо выделить соответствующий участок программы и повторить его, установив предварительно курсор в нужную позицию. При фиксации конца блока курсор должен находиться правее последнего символа. Последовательность фиксации границ блока может быть произвольной. Это избавляет пользователя от лишних перемещений курсора. Блок, состоящий из одного слова, не требует указани двух границ — достаточно того, чтобы курсор находился под любым символом слова или был расположен правее его.
Довольно часто при выделении блока вместо клавиши Ctrl нажимается клавиша Shift. В результате в текст попадают ненужные символы. Их следует удалить двумя нажатиями клавиши Backspace и повторить индикацию границы блока заново.
Процедуры записи выделенного блока на диск или вставки дискового файла в текст текущей программы сопровождаются запросом имени файла. Запрос появляется в выделенном прямоугольнике в левой верхней части экрана. Курсор уже находится в начале прямоугольника, и остается только набрать полную или сокращенную спецификацию файла. Если вызываемый файл находится в текущем оглавлении, то набирается только его имя. Расширение .BAS можно не набирать, так как система сделает такую добавку сама. При записи блока новый файл заводится автоматически. Ранее находившийся на диске файл с таким же именем сохраняется с расширением .ВАК, если вы позаботились об установке такого режима в своей версии Turbo-системы.
Для быстрого перемещения курсора в фиксированные места программы можно воспользоваться процедурой маркировки позиций (Ctrl+K+i). Одновременно может существовать до четырех таких точек.
К другим средствам быстрого перемещения по тексту программы относятся процедуры контекстного поиска. Если вы набрали команду поиска, то система последовательно запрашивает два параметра: образец для поиска и режим поиска. Образец (контекст) набирается в появляющемся прямоугольнике и может содержать любые символы алфавита, включая и пробелы между словами. Последние рассматриваются как обычные символы, и их количество может повлиять на результаты поиска (цепочки «СОТО*, «СО ТО» и «СО ТО» считаются различными).
Режим поиска задается в виде одной или нескольких комбинаций следующих возможностей:
В — поиск назад (область поиска начинается с начала программы и завершается текущей позицией курсора);
G — глобальный поиск (область поиска — вся программ );
N — замена без запроса (в ал тернативном варианте система находит заменяемый образ и запрашивает разрешение у пользователя);
U — при поиске считать эквивалентными большие и малые буквы;
W — поисковый образ является словом (в программе должна быть найдена указанная комбинация символе , не являющаяся частью другого слова);
и — целое число, задающее номер вхождения поискового образа.
'8.3. Файловые процедуры
Вход в режим File вызывает на экран меню, содержащее девять файловых процедур:•
Load
— загрузка текущей программы с диска;
New
— подготовка ко вводу новой программы;
Save F2
— запоминание текущей программы;
Write to...
— запоминание текущей программы;
Main file...
— фиксация имени головной программы;
Directory
— просмотр текущего оглавления;
Chahge dir
— изменение текущего оглавления;
OS shell
— переход в MS DOS с возвратом;
Quit
— завершение сеанса работы с Turbo-системой.
Выбор нужной файловой процедуры производится с помощью вертикальных перемещений курсора или набора выделенной буквы (на схеме такие буквы подчеркнуты). '
' Загрузка текущей программы из дискового файла начинается с появления на экране приглашения, предлагающего пользователю ввести имя загружаемого файла или маски для отбора файлов: .
Load File Name
*.BAS
Загружаемый файл может находиться в текущем оглавлении, и тогда набирается только его имя. В противном случае вводимая спецификация должна содержать все компоненты дискового маршрута. Набор имени (спецификации) завершается нажатием клавиши Enter, после чего файл появляется на экране, и система переходит в режим редактирования.
Если в окне ввода набрана маска для отбора файлов, то после нажатия клавиши Enter на экран выводится таблица с именами всех файлов, удовлетворяющих заданному условию. При этом индикатор выбора (цветной прямоугольник), установленный на первом файле таблицы, может перемещаться как в вертикальном, так и в горизонтальном направлениях клавишами управления курсором. Если таблица целиком не помещается на экране, то «листание» ее страниц в прямом или обратном направлении производят с помощью клавиш PgUp и PgDn. После установки индикатора поиска в требуемую позицию необходимо нажать клавишу Enter, что приведет к загрузке отмеченного файла.,
Процедура New удаляет текст текущей программы (если таковая присутствует в памяти), производит очистку соответствующих областей и переводит систему в режим редактирования.
Для запоминания текста текущей программы меню предлагает две процедуры — Save (ее можно запустить нажатием клавиши F2) и Write to. Первая процедура используется для записи текущей программы под ее первоначальным именем. Однако если таковым является стандартный идентификатор NONAME.BAS, то перед записью пользователю предоставляется возможность переименовать программу:
Rename NONAME —
Процедура Write to... предлагает переименовать программу в любом случае, каким бы ни было ее текущее имя:
।New NAME
Фиксация имени головной программы обычно производится при конструировании достаточно сложных программ. В этом случае в окно редактирования приходится вызывать многочисленные компоненты, 192
не являющиеся самостоятельными программными файлами. Как правило, их подключают к головной программе по метаоператору ^INCLUDE. Если имя текущей программы не совпадает с именем юловной программы, то запуску компилятора предшествует приглашение сохранить текущий текст. Транслироваться же будет головная программа, которая при необходимости автоматически вызывается в память.
Процедура просмотра текущего оглавления начинается с приглашения ввести маску отбора файлов :
Enter Mask
Процесс просмотра файлов отличается от аналогичной процедуры в режиме Load только тем, что помеченный файл в память не вызывается. По всей вероятности, это — недоработка версии 1.1, так как в системах Turbo С и Turbo Pascal аналогичная процедура считывает выбранный файл в память.
Окно ввода, приглашающее пользователя изменить наименование текущего оглавления, выглядит следующим образом:
New Directory —
D:\BASIC\BASH
При входе в процедуру Change dir в окне ввода находится спецификация текущего оглавления. Ее можно подкорректировать или изменить полностью. В первом случае перед набором изменений необходимо нажать клавишу горизонтального перемещения курсора (это обеспечит сохранность содержимого окна). Во втором случае набор любого отображаемого символа на клавиатуре чистит содержимое окна.
В состав файловых операций включены две несколько чужеродные процедуры, обеспечивающие переход из Turbo-системы в MS DOS При входе в процедуру OS shell текущее состояние Turbo-системы запоминается, что обеспечивает возможность возврата в прерванную точку после выполнения директивы EXIT. Такой временный переход в среду MS DOS позволяет выполнять наиболее употребительные директивы операционной системы, запускать самостоятельные ЕХЕ- или COM-файлы, а также командные файлы с расширением .ВАТ, заканчивающиеся директивой EXIT. Можно усмотреть полную аналогию между процедурой OS shell и оператором SHELL в Бейсик-про-
граммах.
Процедура Quit выполняет работу по завершению сеанса связи с Turbo-системой. Если текущая Бейсик-программа при этом не была сохранена, то перед возвратом в MS DOS пользователю предоставляется возможность записать ее текст на диск:
—Verify ——
\PRIMER1.BAS not saved, Save ? (Y/N)
Положительный ответ (Y) позволит сохранить окончательную версию вашей программы. Действия, аналогичные процедуре Quit, осуществляются и при нажатии пары клавиш Alt+X.
Управление компилятором
Основной набор параметров, управляющих работой компилятора, устанавливается в режиме Options. Вспомогательное меню этого режима и связанные с ним меню двух уровней представлены на рис. 3.
Рис.З. Взаимодействие меню в режиме Options
Компилятор может преобразовать текущую программу в файл одного из трех следующих типов :
файл одноразового пользования, расположенный в оперативной
памяти и выполняемый под управлением Turbo-системы (Compile to Memory). Как правило, этот вариант устанавливается в процессе отладки программы;
самостоятельный ЕХЕ-файл многоразового пользования, запоминаемый на диске и выполняемый под управлением MS DOS (Compile to EXE file);
файл, запоминаемый на диске с расширением .ТВС и выполняемый в составе цепочки программ (Compile to Chain file). К такому файлу не подключаются библиотечные подпрограммы, поэтому он не может выполняться самостоятельно.
Следующие пять бинарных признаков определяют необходимость подключения тех или иных системных компонент, повышающих эффективность и (или) надежность изготавливаемой программы. Признак «8087 required» сообщает компилятору, что в конфигурацию ПЭВМ входит математический сопроцессор 8087(80287), и им необходимо воспользоваться для более эффективной организации вычислений значений элементарных функций и выполнения арифметических операций с плавающей запятой. В противном случае указанные действия будут выполняться подпрограммами на центральном процессоре (такой режим принято называть эмуляцией сопроцессора), что сильно замедляет скорость работы программы и увеличивает ее объем. Признак «Keyboard break ON» обеспечивает возможность прерывания режима выполнения пользовательской программы путем одновременного нажатия двух клавиш Ctrl+Break.
Включение признака Bounds заставляет компилятор генерировать дополнительные команды, предшествующие каждому обращению к значениям элементов массива. Эти команды обеспечивают проверку индексов на их принадлежность объявленным границам во время выполнения программы. Указанные действия распространяются только на вычисляемые индексные выражения. Проверка индексов, представленных константами, осуществляется на стадии компиляции и производится независимо от установки признака Bounds.
Проверка переполнения, подключаемая компилятором при установке признака «Overflow ON», обеспечивает не только выдачу соответствующего сообщения во время работы пользовательской программы, но и гарантирует правильность вычислений.
Установка признака Stack test в состояние ON вынуждает компилятор подключать проверки на переполнение стека,который используется во время выполнения пользовательской программы для временного хранения результатов промежуточных вычислений, параметров вложенных процедур и т.п. По умолчанию под стек выделяется 1024 байта, однако этого может оказаться недостаточно для некоторых про-
грамм. Неконтролируемое переполнение стека приводит к порче смежных полей памяти и в конечном итоге к неправильному функционированию программы. Если подключенный вами контроль зафиксирует переполнение стека, то его размеры можно увеличить с помощью метаоператора $STACK или путем изменения системного параметра процедурой Metastatements.
Любые средства контроля, подключаемые к пользовательской программе, замедляют скорость ее выполнения. Они необходимы на стадии отладки, но впоследствии от некоторых из них можно отказаться. Процедура Parameter line позволяет набрать параметры командной строки, к которой программа пользователя во время своего выполнения имеет доступ с помощью функции COMMANDS.
Последняя строка меню предоставляет возможность изменить размеры следующих полей и буферов, обслуживающих процесс выполнения пользовательской программы:
стек задачи (по умолчанию длина стека 1024 байта);
музыкальный буфер (по умолчанию емкость буфера 256 байт, что позволяет разместить в нем фрагмент музыкальной программы, содержащей до 32 нот);
буфера коммуникационных каналов связи СОМ1: и COM2: (емкость каждого буфера по умолчанию 256 байт).
К числу параметров, влияющих на работу компилятора, относятся списки дисковых оглавлений, устанавливаемые в режиме Setup с помощью процедуры Directories. В их состав входят три группы оглавлений :
■ • оглавления модулей с расширением .INC, подключаемых к головной программе по псевдооператорам $INCLUDE (Include directories);
дисковое оглавление, в которое заносится модуль, изготовленный компилятором (Executable directory);
системное оглавление (Turbo directory), из которого извлекаются файл конфигурации системы TBCONFIG.TB и тексты кадров подсказки (TBHELP.TB).
Последовательность оглавлений подключаемых файлов определяет порядок просмотра соответствующих директорий. И если в разных оглавлениях окажутся файлы с одинаковыми именами, то Turbo-система выберет файл из первой по порядку директории. Учитывая это, программист может указать более полную спецификацию, исключающую двусмысленность при поиске нужного файла.
В Turbo-системе имеется возможность повлиять на работу компилятора с помощью специальных управляющих строк, содержащих так
196
называемые метаоператоры. Метаоператоры начинаются с символа *$». Ниже приведен их полный перечень.
Формат метаоперагора
Выполняемое действие
$COMi п
Устанавливает размер приемного буфера i-ro телекоммуникационного канала 0-1 : 2) в пбайтов. По умолчанию емкость буфера — 256 байт
$DYNAM1C
Устанавливает режим, при котором все последующие массивы по умолчанию считаются динамическими
$EVENT (ON 1 OFF}
Подключает (ON) или отключает (OFF) механизм управления событиями
$1F const ... операторы
[$ELSE
... операторы J
$ENDIF
Условное подключение или обход группы операторов в процессе компиляции. В качестве проверяемого условия может выступать литеральная или именованная константа const. Если const-O, то условие считается невыполненным. В условных группах операторов допускаются вложенные условия. Максимальная глубина вложения — 256
$INCLUDE file_spec
Включает в текст компилируемой программы указанный файл. Текст текущей программы при этом не изменяется, но вместо строки с метаоператором начинает транслироваться текст вставки
$1NL1NE (список байтов]:
(fiiespecj
$SEGMENT
Включает текст машинной программы в тело подпрограммы тина SUB...INLINE
Объявляет новый программный сегмент. Используется в ситуации, когда компилятор выдает сообщение о том, что объ ем программы превышает 64 Кбайта
$SOUND n
Устанавливает размер музыкального буфера. По умолчанию емкость буфера — 256 байт, что позволяет поместить в него информацию о 32 цотах. Новый размер должен быть кратен 8 и не превышать 32 Кбайт
$STACK n
Устанавливает размер стека, выделяемого программе во время ее выполнения. По умолчанию размер стека — 1024 байта. Максимальный размер — 32 Кбайта. Величина п должна быть кратна 1 б
$STAT1C
Устанавливает режим, при котором все последующие массивы по умолчанию считаются статическими
Выполнение, компиляцияи отладка текущей программы
Первые пуски новой программы должны проводиться в режиме Run или в режиме Compile с созданием временного модуля в оперативной памяти (по умолчанию устанавливается именно этот режим). Не забудьте подключить максимум возможных проверок и запомнить текст
197
текущей программы перед запуском. Обратите особое внимание на последний совет, так как неверно работающая программа может привести к зависанию операционной системы. После вынужденной перезагрузки MS DOS текст вашей программы в оперативной памяти будет уничтожен. Система автоматически сохранит текст текущей программы перед ее запуском, если в процедуре Miscellaneous (режим Setup) вы установите признак «Auto save edit ON».
Прерывание зациклившейся или неверно работающей программы осуществляется одновременным нажатием клавиш Ctrl+Break, если такой способ управления был предусмотрен процедурой Keyboard break (режим Options).
Для отладки можно воспользоваться операторами TRON/TROFF, заранее включенными в текст вашей программы, или установить режим глобальной трассировки с помощью процедуры TRACE. Последний можно включать и отключать, не входя в режим Debug. Для этой цели достаточно нажать комбинацию клавиш Alt+F9. Повторное нажатие этой пары переключает режим трассировки на противоположный (ON О OFF О ON О OFF...).
В режиме трассировки окно Trace фиксирует номера и метки выполняющихся строк, имена вызываемых подпрограмм и функций. По этой информации вы можете проконтролировать логику работы программы.
Turbo-система предоставляет пользователю возможность пошагового выполнения текущей программы. Выполнение очередного шага инициируется нажатием клавиш Alt+FlO. Заканчивается шаг очередной строкой программы, снабженной меткой или номером.
■ Вторая процедура режима Debug связана с поиском ошибок в EXE- и ТВС-файлах. Поскольку они выполняются под управлением операционной системы, то обычных сообщений об ошибках с идентификацией соответствующей строки Бейсик-программы вы уже не получите. Вместо этого мы узнаем только адрес команды (содержимое регистра PC), при выполнении которой была обнаружена ошибка. Чтобы определить соответствующую точку в исходной программе, необходимо войти в процедуру Run-time error и ввести адрес команды:
,— Enter PC
ЕI
Затем необходимо повторить компиляцию, и система сообщит, на какой оператор программы приходится введенный адрес.
Управление окнами
Назначение системных окон Edit, Run, Message и Trace описано в п. 8.1. В момент запуска Turbo-системы все окна «открыты», т.е. видны на экране, и Одно из них — окно редактирования — объявлено активным. Для изменения количества открытых окон и их взаимного расположения на экране вы должны войти в режим Window. Появляющееся при этом меню содержит восемь следующих процедур:
Процедура Open открывает окно, выбираемое в меню следующего уровня. Открывать окна, уже представленные на экране, великого смысла не имеет. Попытки такого рода системой игнорируются. После входа в процедуру Close каждое нажатие клавиши Enter удаляет с экрана очередное окно.
С помощью процедуры Next можно совершить обход видимых окон, присваивая им по очереди статус активного окна путем нажатия клавиши Enter. Аналогичное переключение происходит и при нажатии клавиши F6.
Операция Goto переводит курсор в активное окно, предоставляя пользователю возможность более детально рассмотреть содержимое окна или выполнить там какие-либо действия. Такой же переход происходит и при нажатии клавиши F7 (в режиме редактирования за этой клавишей закреплена другая функция).
Процедура Tile по-братски делит поверхность экрана между открытыми окнами. Если открыто два или три окна, то рабочая область делится на горизонтальные полосы равной ширины. Полный набор окон делит экран на четыре равных прямоугольника. В отличие от такого расположения окон, когда они полностью видны на экране, имеется возможность (процедура Stack) выстроить их друг за другом.
На первом плане находится активное окно, полное содержимое которого мы видим. От остальных окон видны только их заголовки.
С помощью клавиш управления курсором активное окно можно переместить в любую часть экрана. При перемещении активного окна возникают ситуации, когда оно затеняет содержимое других окон, создавая иллюзию, что остальные окна находятся от пользователя дальше.
Наиболее информативным окнам с текстом текущей программы (Edit) и результатами ее выполнения (Run) может быть предоставлена вся рабочая область экрана. Переключение размера активного окна осуществляется процедурой Zoom. В других режимах для этой цели используется клавиша F5.
3 8.7. Модификация цветовых атрибутов
Многочисленные меню, окна и другие экранные области используют цветовые атрибуты для того, чтобы выделить отдельные свои компоненты. Если вам не нравится цветовая гамма, предлагаемая системой, то окраску любой компоненты можно изменить в режиме Setup. Управление цветом осуществляет процедура Colors, взаимосвязь которой с меню последующих уровней представлена на рис.4. Ниже приведена расшифровка наименований всех компонент, участвующих в процедурах раскрашивания.
Для модификации интересующей вас компоненты необходимо перейти в меню самого последнего уровня, установить прямоугольник выбора на соответствующее наименование и нажать клавишу Enter. На экране появится прямоугольная таблица всевозможных сочетаний фоновых оттенков с цветами символов. Выделенная клетка таблицы соответствует текущей ситуации. Вы можете переместить выделенный квадратик в любую позицию таблицы и сразу же увидеть на экране компоненту с новой цветовой комбинацией. Для фиксации этих атрибутов на время сеанса никаких дополнительных действий предпринимать не надо — достаточно нажать клавишу Esc и выйти в меню предыдущего уровня. Если вам захочется работать с установленными атрибутами и в последующих сеансах, то перед выходом из Turbo-системы необходимо запомнить текущую конфигурацию с помощью процедуры Save Options/Windows/Setup.
При выборе новых цветовых атрибутов всегда имеется возможность вернуться к первоначальной гамме, устанавливаемой системой по умолчанию. Для этой цели в каждом из меню нижнего уровня предусмотрена строка Restore default. Войдите в нее и нажмите клавишу Enter.
Рис. 4. Взаимодействие меню в процедуре Colors
201
НаименованиекомпонентыBorderError messageFirst letterHighlighted textKeywordsLock keysMarked blockNormal textSelection barSelected keywordStatus line *TitleНаименованиекомпонентыBorderError messageFirst letterHighlighted textKeywordsLock keysMarked blockNormal textSelection barSelected keywordStatus line *Title
Наименованиекомпоненты
Border
Error message
First letter
Highlighted text
Keywords
Lock keys
Marked block
Normal text
Selection bar
Selected keyword
Status line *
Title
Наименованиекомпоненты
Border
Error message
First letter
Highlighted text
Keywords
Lock keys
Marked block
Normal text
Selection bar
Selected keyword
Status line *
Title
Пояснение
Рамка, окаймляющая меню, окно или область ввода параметров. Воспроизводится символами псевдографики
Текст сообщения об ошибке
Первая буква, выделяемая особым цветом в наименованиях режимов и процедур
Текст, выделяемый повышенной яркостью
Ключевые слова, используемые в системе подсказки для выбора соответствующего кадра
Обозначения функциональных клавиш, за которыми закреплены управляющие функции
Фрагмент текста текущей программы, выделенный указаниями начальной и конечной позиций блока
Обычный текст, используемый для воспроизведения текущей программы, наименований процедур в меню, результатов вычислений и т.п.
Прямоугольник выбора, перемещаемый по строкам меню
Прямоугольник выбора, перемещаемый по ключевым словам в кадрах подсказки
Строка, отображающая текущее состояние в том иди ином режиме работы
Заголовок окна, меню или системной области
Запоминание и восстановлениеконфигурации системы
Начальная установка параметров системы, влияющих на работу Turbo-системы, осуществляется программой TBINST.COM. В режиме диалога она запрашивает у пользователя необходимые данные и формирует файл конфигурации системы TBCONFIG.TB .
В дальнейшей работе можно произвести установку новых значений параметров, которые пользователь посчитает более удобными. Режим Setup позволяет запомнить новую, конфигурацию в том же файле TBCONFIG.TB или в каком-либо другом. Это позволяет разным пользователям хранить свои собственные конфигурации и загружать их в начале сеанса работы. Наверняка такой возможностью воспользуются программисты-дальтоники.
Автоматическая загрузка конфигурации из файла TBCONFIG.TB происходит при запуске Turbo-системы. Для перезагрузки новой конфигурации необходимо войти в режим Setup и выполнить процедуру 202
Load Options/Windows/Setup. После нажатия клавиши Enter система предлагает набрать имя файла с новой конфигурацией:
Config File
♦.ТВ «
Запоминание конфигурации после модификации системных параметров осуществляется процедурой Save Options/Windows/Setup, выполнению которой предшествует запрос имени файла:
Config File TBCONFIG.TB
Если вы не захотите воспользоваться именем системного файла, то необходимо набрать полную спецификацию или имя другого файла с расширением .ТВ.
Среди возможностей режима Setup имеются еще две установочные операции, вызываемые процедурой Miscellaneous:
Auto save edit ON : OFF
Backup source files ON : OFF
Первая из них включает или отключает режим автоматического запоминания отредактированной программы перед ее запуском. Вторая операция включает или отключает режим сохранения предыдущей дисковой версии текущей программы, осуществляемый при запоминании новой версии.
9. ОСНОВНЫЕ ПРИЕМЫ РАБОТЫВ СРЕДЕ QUICK BASIC
Система программирования Quick-BASIC, v. 4.0 представлена двумя компонентами. Первую из них составляет интегрированный вариант но гланс с основным модулем QB.EXE, обеспечивающий диалоговое взаимодействие с пользователем на любых этапах обработки программ и обладающий развитой иерархической системой меню и подсказок. Bj-орая компонента включает набор самостоятельных ЕХЕ- процедур, осуществляющих выполнение BASIC-программ в традиционной для пакетного режима последовательности: компиляция - редактирование связей - загрузка и исполнение. Каждый из этих этапов реализуется под управлением MS DOS с поочередным запуском той или иной процедуры, снабжаемой соответствующим набором управляющих параметров. Работу QB-систсмы по схеме пакетного варианта обеспечивают компилятор ВС.ЕХЕ, компоновщик объектных модулей (редактор связей) LINK.EXE и библиотекарь LIB.EXE.
Общей для обеих компонент QB-систсмы является возможность использования библиотек с расширениями .QLB и .LIB.
Выбор пакетной схемы может быть обусловлен рядом причин. Среди них:
возможность создания больших программ, размеры которых превышают ограничения диалоговой схемы;
возможность получения модулей, удовлетворяющих по структуре требованиям отладчика CodeView;
желание получить листинг компиляции или использовать специальные условия, нс обеспечиваемые в диалоговом режиме;
необходимость обработки текстов программ, созданных с помощью других редакторов.
Наименованиемодуля
Выполняемая функция
ВС.ЕХЕ
BCOM40.L1B
BQLB40LIB
BRUN40.EXE
BRUN40.LIB
FIXSllIFr.COM
Компиляция в пакетном режиме
Библиотека периода выполнения
Библиотека поддержки периода выполнения
Поддержка периода выполнения
Альтернативная библиотека периода выполнения
Согласование BIOS и QB-редактора при работе с расширенной клавиатурой
LIB EXE
LINK.EXE
Обслуживание библиотек
Компоновка объектных модулей (редактирование связей)
MOUSE.COM
NOCOM OBJ
Драйвер мыши Отключение режимаиспользования общих
(COMMON) блоков памяти
NOEM.OBJ
Выполнение операций с плавающей занятой через сопроцессор 8087(80287) — отмена эмуляции сопроцессора
QB.EXE
QB.IILP
QB.INI
QB.LIB
QB.PIF
QB.QLB
QBI1ERC COM
SETUP BAT
SETUP1.BAT
Диалоговая обработка BASIC-программ Тексты для оказания помощи пользователю Файл для настройки QB-системы Библиотека для работы с прерываниями DOS Системный файл
Библиотека для работы с прерываниями DOS Работа с дисплеями типа Hercules
Настройка QB-системы 11асгройка QB-системы
Работа под управлением интегрированнойQB-системы
Командная строка по запуску интегрированного варианта QB-системы имеет вид:
... > qb[.cxc] [/pl /р2 ...]
Здесь pi — набор параметров, определяющих значения некоторых системных переменных и влияющих на работу QB-системы. Полный их перечень приведен ниже. При отсутствии управляющих параметров регулируемые характеристики принимаются равными соответствующим значениям, заданным во время настройки системы.
Формат управляющеговоздействия/run имя/ь/в/h/с:п/1 имя/mbf -/ahФормат управляющеговоздействия/run имя/ь/в/h/с:п/1 имя/mbf -/ah/cmd *ss...»/cmd *ss...»
Формат управляющеговоздействия
/run имя
/ь
/в
/h
/с:п
/1 имя
/mbf -
/ah
Формат управляющеговоздействия
/run имя
/ь
/в
/h
/с:п
/1 имя
/mbf -
/ah
/cmd *ss...»
/cmd *ss...»
Назначение
Загрузка и выполнение BASIC-программы с указанным именем
Настройка цветного монитора на работу в черно-белом режиме
Настройка монитора на работу в графическом режиме
Установка параметров монитора для максимально допустимого разрешения (для CGA — 25 строк по 80 символов в строке, для EGA — 43 х 80)
Установка длины буфера, обслуживающего телекоммуникационные каналы связи (и < 32767). По умолчанию емкость буфера — 512 байт
Загрузка Quick-библиотеки с указанным именем
Переход на работу с двоичным форматом фирмы Microsoft для вещественных данных вместо формата IEEE
Установка режима, при котором динамически распределяется память под. массивы записей и строки фиксированной длины. Числовые данные могут занимать память более 64 Кбайт
Задание строки, содержимое которой задача пользователя может прочитать или изменить с помощью функции или оператора COMMANDSS
На рис.5 приведен формат главного меню, появляющегося на экране после запуска QB-системы. Верхняя и нижняя строки являются служебными. Остальная часть экрана разделена на два окна. Большая его часть (строки 2 — 20) используется в качестве основной области при диалоге с пользователем. Строки 23 — 24 образуют так называемое окно непосредственных вычислений (Immediate Window), в котором можно набирать немедленно исполняемую программу.
File Edit View Search Run Debug CallsFl-Help
<Untitled>
<Immediate>
QuickBASIC 4.0 Copyright (C) MicrosoftCorp.1982—1987
Рис. 5. Начальная заставка QB-системы
Верхняя строка экрана содержит заголовки семи основных режимов работы:
File — режим файловых процедур;
Edit — режим набора или корректировки текущей программы;
View — режим просмотра программы или ее компонент;
Search — режим контекстного поиска и замены;
Run — режим компиляции и выполнения текущей программы;
Debug — режим отладки текущей программы;
Calls — режим позиционирования курсора на операторе модуля или процедуры, который подлежит исполнению.
Заголовок, выделенный особым цветом, является текущим, и для его активизации - входа в режим - необходимо нажать клавишу Enter. Выход из активного режима обычно производится путем нажатия клавиши Esc. Переходы от одного заголовка режима к другому осуществляются клавишами горизонтального перемещения курсора.
В правом углу верхней строки светится напоминание о том, что нажатие функциональной клавиши F1 поможет пользователю разобраться в сложившейся ситуации.
Нижняя служебная строка содержит информацию об основной функции текущего режима. В ее правом углу находится счетчик, показывающий четырехзначный номер текущей строки и трехзначный номер столбца, определяющие местоположение курсора в текущей программе или подпрограмме.
При входе в .любой из режимов главного меню под его заголовком на экране появляется меню первого уровня, содержащее определенное количество строк - функций. Выбор той или иной функции осуществляется либо с помощью клавиш вертикального перемещения курсора, либо путем набора символа, отмеченного в названии каждой функции особым цветом. Выбранная функция подсвечивается прямоугольником, цвет фона которого отличен от остальных строк меню. Переход к исполнению выбранной функции производится путем нажатия клавиши Enter.
Для большинства функций должна быть задана дополнительная информация, запрашиваемая у пользователя в диалрговом режиме. С этой целью в центре экрана появляется меню-заставка второго уровня, временно закрывающая часть основного окна. Вход в заставку происходит либо автоматически, либо после нажатия клавиши Tab. В первом случае в одной из выделенных прямоугольных областей появляется мерцающий курсор, и пользователь должен набрать значение запрашиваемого параметра. Во втором случае заставка содержит несколько процедур, заключенных в прямоугольники с одинарной границей. После нажатия клавиши Tab один из прямоугольников становится активным — его граница очерчена уже двойной линией. Переход к следующей процедуре заставки происходит после очередного нажатия клавиши Tab. Обход процедур в обратном направлении осуществляется одновременным нажатием клавиш Shift+Tab.
Некоторые заставки-меню содержат вертикальный набор опера-
ций, каждая из которых начинается с круглых открывающей и закрывающей скобок. Точка внутри скобок является признаком выбора операции. Ее передвижение по меню-заставке производится с помощью клавиш вертикального перемещения курсора. Исполнение выбранной операции начинается после нажатия клавиши Enter.
Файловые процедуры
При входе в режим File на экране появляется меню первого уровня, представленное на рис.6 и обеспечивающее выполнение 12 функций. Функция New Program используется при наборе новой программы. Ее выполнение сводится к очистке оперативной памяти от текущих программных модулей, удалению всех ранее заведенных переменных и переводу системы в режим редактирования. При этом курсор перемещается^ начальную строку окна редактирования.
Функция Open Program ... применяется для очистки оперативной памяти и вызова программы, хранящейся на диске. Вход в эту функцию сопровождается появлением заставки с запросом на ввод имени вызываемого файла (рис.7). В ответ на это приглашение пользователь может набрать как полную спецификацию требуемого файла (диск:\ имя ка^алогаХ..Димя файла), так и ограничиться предложенным ему расширением (*.bas). В первом случае указанный дисковый файл заменит текущую программу сразу после того, как пользователь нажмет клавишу Enter. Во втором случае после нажатия клавиши Enter на заставке отображаются имена всех файлов текущего оглавления с заданным расширением. Выбор одного из них осуществляется с помощью клавиш перемещения курсора, вслед за нажатием которых по оглавлению двигается выделенный прямоугольник. Вызов отмеченного файла происходит после нажатия клавиши Enter. После вызова новой программы система переводится в режим редактирования. Функция Merge... используется для слияния (объединения) текущей программы с вновь вызываемым файлом. Заставка и выбор загружаемой программы идентичны выше описанной схеме.
Три следующие функции предназначены для запоминания на диске текущей головной программы под текущим именем (Save), новым именем (Save As ...) или головной программы со всеми присоединенными к ней модулями (Save All). QB-система позволяет создавать файлы с расширениями .МАК, которые включают текст головной программы и список имен всех присоединенных к ней модулей. При загрузке таких файлов автоматически загружаются и все присоединенные модули. Заставка, возникающая при выборе одной из процедур сохранения (рис.8), дает возможность пользователю набрать или изменить имя запоминаемой программы и выбрать один из двух возмож-
ных форматов хранения. Первый из них (Fast Load and Save) обеспечивает более компактное хранение текста программы на диске, что экономит внешнюю память и ускоряет процедуру загрузки. Второй формат (Text) обеспечивает запоминание программы в виде обычного текстового файла, что делает его доступным для других систем программирования.
Рис.6. Меню файловых процедур
File
Edit View Search Run Debug Calls
File Name
*.bas
D:\BASIC\QBAS40
Область для отображения именвыбранных файлов
ОК:
Cancel
8. Ю Л. Кетков
Рис.7. Меию-заставка для процедур Open и Merge209
File
Edit View Search Run Debug Calis
File Name
*.bas
D:\BASIC\QBAS40
Format
(*) Quick BASIC — Fast Load and Save () Text—Readable by Other Programs
OK: | | Cancel
Рис.8. Меню-заставка для процедур Save,Save As....Save All
Заставка,появляющаяся при выборе процедуры создания файла (рис.9), обеспечивает пользователю возможность указать имя создаваемого файла и его тип. По типам различают программные модули (Module), файлы, подключаемые по оператору $INCLUDE (Include), и текстовые документы (Document).
File
Edit View Search Run Debug Calls
File Name
—Create as
OK:OK:CancelCancel(*) Module
OK:
OK:
Cancel
Cancel
( ) Include
( ) Document
Рис.9. Меню-заставка для процедуры Create
Две следующие процедуры используются для подключения (Load File...) файла к текущей программе или удаления модуля, уже ставшего ненужным или загруженного, по недоразумению (Unload File...). Заставка первой процедуры (рис. 10) запрашивает у пользователя имя файла или маску расширения, а также его тип.
Процедура Print позволяет выдать на принтер выделенный текст (Selected Text), содержимое активного окна (Active Window), текущий программный модуль (Current Module) или все модули (All Modules). Выбор одной из перечисленных возможностей осуществляется с помощью заставки, приведенной на рис.11.
210
File | Edit View Search Run Debug Calls
File Name*.bas
D:\BAS1C\QBAS4O
Load as (*) Module () Include О Dokument
Имя головной программы
Область для отображения имен файлов с заданнымрасширением
OK: ICancel
Рис.10. Меню-заставка для процедуры Load Hie...
File | Edit View Search Run Debug Calls
( ) Selected Text ( ) Active Window (*) Current Module
() All Modules
I OK:Cancel
Рис.11. Меню-заставка для процедуры Print
Две следующие процедуры к работе с файлами никакого отношения не имеют. Процедура DOS Shell позволяет временно выйти из QB-окружения и выполнить любую последовательность команд операционной системы. После набора директивы EXIT управление вновь передается QB-системе, состояние которой соответствует моменту перехода к интерпретатору команд DOS Shell.
Процедура Exit используется для завершения сеанса работы с QB- системой. Если все текущие модули были предварительно сохранены, то возврат из QB-системы происходит автоматически. В противном случае пользователю предоставляется возможность запомнить свои программы.
Средства редактирования
Режим редактирования обеспечивает набор и модификацию текста 8»211
текущей головной программы или любой ее компоненты - подпрограммы, внешней функции. Основное меню QB-редактора (рис. 12) включает информацию о способах выполнения основных процедур—отказ от предыдущего шага редактирования и восстановление только что исправленной строки (Undo), удаление выделенного фрагмента программы с запоминанием его в специальном буфере (Cut), перепись фрагмента из буфера в указанное место программы (Paste), очистка текущего активного окна (Clear).
File Edit I View Search Run Debug Calls
Undo Alt+Backspace Cut Shift+Del Copy Ctrl+Ins Paste Shift+Ins Clear Del
New SubNew Function ...
Syntax Checking
Рис. 12. Основное меню режима редактирования
Две следующие строки основного меню помогают пользователю оформить набор новой подпрограммы (New Sub...) или функции (New Function...). После набора имени соответствующей программной единицы QB-редактор автоматически формирует на экране начальную и конечную строки (SUB имя - END SUB или FUNCTION имя — END FUNCTION) и открывает активное окно для набора модуля.
Последняя строка обеспечивает возможность подключения синтаксического анализатора, контролирующего правильность набора операторов в процессе их ввода. Перед строкой Syntax Checking при последовательном нажатии клавиши Enter то возникает, то пропадает галочка, напоминающая знак квадратного корня. Наличие галочки свидетельствует о включении режима контроля.
Как правило, функции по редактированию текста программы выполняются с помощью клавишных операций, характерных для многих текстовых процессоров. В связи с тем, что набор клавишных операций QB-системы несколько отличается от соответствующих (итераций ТВ- системы, ниже приведен их полный перечень.
Комбинация клавиш.*- ,Ctrl+S-» ,Ctrl+D Ctri+ ♦'.Ctrl+A Ctrl+-*,Ctrl+F Home, Ctrl+Q+S End , Ctrl+Уfl)I, Ctrl+E, Ctri+X Ctrl+Enter,Ctrl+J PgUp ,Ctrl+R PgDn ,Ctri+C Ctrl+Q+E Ctrl+Q+X Ctrl+PgUp Ctrl+PgDn Ctrl+Home,Ctrl+Q+R Ctrl+End ,Ctrl+Q+C Ctrl+Q+n Ctrl+WCtrl+Z Tab Shift+TabКомбинация клавиш.*- ,Ctrl+S-» ,Ctrl+D Ctri+ ♦'.Ctrl+A Ctrl+-*,Ctrl+F Home, Ctrl+Q+S End , Ctrl+Уfl)I, Ctrl+E, Ctri+X Ctrl+Enter,Ctrl+J PgUp ,Ctrl+R PgDn ,Ctri+C Ctrl+Q+E Ctrl+Q+X Ctrl+PgUp Ctrl+PgDn Ctrl+Home,Ctrl+Q+R Ctrl+End ,Ctrl+Q+C Ctrl+Q+n Ctrl+WCtrl+Z Tab Shift+TabКомбинация клавишShift+«- Shift+^ Shift+: Shift*: Shlft+Ctrl+*~ Shift+Ctrl+-* Shift+PgUp Shift+PgDn Shift+Ctri+Home Shift+Ctri+EndКомбинация клавишCtri+YCtrl*Q+YBcsp, Ctrl+HКомбинация клавишShift+«- Shift+^ Shift+: Shift*: Shlft+Ctrl+*~ Shift+Ctrl+-* Shift+PgUp Shift+PgDn Shift+Ctri+Home Shift+Ctri+EndКомбинация клавишCtri+YCtrl*Q+YBcsp, Ctrl+H
Комбинация клавиш.
*- ,Ctrl+S
-» ,Ctrl+D Ctri+ ♦'.Ctrl+A Ctrl+-*,Ctrl+F Home, Ctrl+Q+S End , Ctrl+Уfl)
I, Ctrl+E
, Ctri+X Ctrl+Enter,Ctrl+J PgUp ,Ctrl+R PgDn ,Ctri+C Ctrl+Q+E Ctrl+Q+X Ctrl+PgUp Ctrl+PgDn Ctrl+Home,Ctrl+Q+R Ctrl+End ,Ctrl+Q+C Ctrl+Q+n Ctrl+W
Ctrl+Z Tab Shift+Tab
Комбинация клавиш.
*- ,Ctrl+S
-» ,Ctrl+D Ctri+ ♦'.Ctrl+A Ctrl+-*,Ctrl+F Home, Ctrl+Q+S End , Ctrl+Уfl)
I, Ctrl+E
, Ctri+X Ctrl+Enter,Ctrl+J PgUp ,Ctrl+R PgDn ,Ctri+C Ctrl+Q+E Ctrl+Q+X Ctrl+PgUp Ctrl+PgDn Ctrl+Home,Ctrl+Q+R Ctrl+End ,Ctrl+Q+C Ctrl+Q+n Ctrl+W
Ctrl+Z Tab Shift+Tab
Комбинация клавиш
Shift+«- Shift+^ Shift+: Shift*: Shlft+Ctrl+*~ Shift+Ctrl+-* Shift+PgUp Shift+PgDn Shift+Ctri+Home Shift+Ctri+End
Комбинация клавиш
Ctri+Y
Ctrl*Q+Y
Bcsp, Ctrl+H
Комбинация клавиш
Shift+«- Shift+^ Shift+: Shift*: Shlft+Ctrl+*~ Shift+Ctrl+-* Shift+PgUp Shift+PgDn Shift+Ctri+Home Shift+Ctri+End
Комбинация клавиш
Ctri+Y
Ctrl*Q+Y
Bcsp, Ctrl+H
Перемещения по тексту
Направление перемещения курсора
На один символ влево
На один символ вправо
На одно слово влево
На одно слово вправо
В начало текущей строки
В конец текущей строки
На одну строку вверх
На одну строку вниз
В начало следующей строки
На страницу вверх
На страницу вниз
На первую строку окна
На последнюю строку окна
Влево на одно окно
Вправо на одно окно
В начало модуля (процедуры)
В конец модуля (процедуры)
В позицию маркера с номером п (0 < - п < - 3)
Подъем текста на одну строку вверх без перемещения курсора
Спуск текста на одну строку вниз без перемещения курсора
В ближайшую справа позицию, номер которой кратен 8
В очередную отмеченную строку
Выделение фрагмента
Границы выделяемого фрагмента
Символ, расположенный слева от курсора
Символ, расположенный справа от курсора
Строка над курсором
Текущая строка
Слово, расположенное слева от курсора
Слово, расположенное справа от курсора
Верхняя часть экрана
Нижняя часть экрана
От начала модуля (процедуры) до текущей строки
От текущей строки до конца модуля (процедуры)
Удаление фрагмента
Назначение
Удаление текущей строки с запоминанием ее содержимого в специально отведенном буфере (clipboard)
Удаление части строки от позиции курсора до конца строки с запоминанием в буфере
Удаление символа слева от курсора
Продолжение
Del , Ctrl+G Clrl+TDelShift+DelDel , Ctrl+G Clrl+TDelShift+DelУдаление символа над курсором
Del , Ctrl+G Clrl+T
Del
Shift+Del
Del , Ctrl+G Clrl+T
Del
Shift+Del
Удаление слова справа от курсора
Удаление выделенного фрагмента без его запоминания в буфере
То же, с запоминанием удаляемого фрагмента
В ставка фрагментов
Комбинация клавиш
Выполняемая функция
Ins , Clrl+V Ctrl+Ins
Включение или отключение режима вставки
Копирование выделенного текста в точку, определяемую позицией курсора, с одновременным запоминанием фрагмента в буфере
Shift+Ins
End+Enter
Home+Ctrf+N
Вставка текста из буфера
Повторение строки, расположенной ниже
Повторение строки расположенной выше
Прочие операции
Комбинация клавишCtrl+K+nCrtl+P&Clrl+@Комбинация клавишCtrl+K+nCrtl+P&Clrl+@Назначение
Комбинация клавиш
Ctrl+K+n
Crtl+P&Clrl+@
Комбинация клавиш
Ctrl+K+n
Crtl+P&Clrl+@
Маркировка позиции (О<—п< —3)
Вставка в текст кода, соответствующего комбинации клавиш Ог1+@
Процедуры просмотра
Режим просмотра тесно примыкает к средствам редактирования. Его основное меню (рис.13) предлагает шесть функций по просмотру текста программы и результатов ее работы, а также две сервисные процедуры по изменению конфигурации просмотровых окон и цветовых атрибутов.
Процедура SUBs... отображает на экране список имен всех компонент текущей программы, включая загруженные модули и подключаемые файлы. С помощью клавиш перемещения курсора пользователю предоставляется возможность выбрать среди них любую компоненту для ее последующего редактирования. Переход к просмотру и редактированию следующей программной единицы осуществляется с помощью процедуры Next SUB. Интересной особенностью режима просмотра и редактирования является возможность расщепления жрана дисплея на два окна. Последовательное применение функции Split приводит к появлению на экране то одного активного окна, то двух окон. ' .
Рис.13. Меню-заставка режима View
Функция Next Statement отображает очередной оператор программы, подлежащий выполнению.Для просмотра результатов работы программы используется функция Output Screen.
Функции Include File и Included Linies позволяют либо просматривать и редактировать (Include File), либо только просматривать (Included Linies) содержимое подключенных файлов.
С помощью процедуры Options... пользователь имеет возможность изменить цветовые атрибуты тех или иных компонент QB-системы. Выбор цвета осуществляется либо путем перемещения курсора, либо путем набора первой буквы названия нужного оттенка. Переход к установке новой цветовой окраски другой компоненты системы осуществляется нажатием клавиши Tab или Shift+Tab.
4. Контекстный поиск
Контекстный поиск, обеспечиваемый режимом Search, позволяет найти нужный фрагмент в большой программе и при необходимости осуществить замену найденного фрагмента новым. Основное меню режима поиска п иведено на рис.14. Три первые функции вызывают появление одинаковой заставки (рис. 15). Эта заставка предлагает пользователю набрать цепочку символов поискового образа, определить область поиска (активное окно, текущий модуль, текст всей программы) и установить режим поиска (различать ли большие и малые буквы - Match Upper/Lowercase, ограничиться ли простым вхождением поискового образа или искать отдельное слово—Whole Word).
Рис. 14. Основное меню в режиме поискаРис. 14. Основное меню в режиме поиска
Рис. 14. Основное меню в режиме поиска
Рис. 14. Основное меню в режиме поиска
File Edit View I Search Run Debug Calls
Find What:Find What:Окно для набора поискового образа
Find What:
Find What:
[ ] Match Upper/Lowercase [] Whole Word[ ] Match Upper/Lowercase [] Whole Word Search () 1 .Active Window (*) 2.Current Module () 3.A11 Modules
[ ] Match Upper/Lowercase [] Whole Word
[ ] Match Upper/Lowercase [] Whole Word
OK:OK:Cancel
OK:
OK:
Рис.15. Меню-заставка для набора режимов поиска
Продолжение поиска очередного вхождения заданного контекста осуществляется нажатием клавиши F3.
Процедура контекстной замены (Change...) сопровождается меню, очень похожим на заставку поиска. Дополнительный параметр - текст замены - здесь набирается в прямоугольнике с указателем Change to:. В процессе выполнения этой процедуры имеется возможность ограни- 'читься либо заменой первого вхождения поискового образа (Find and Verify) либо модифицировать все фрагменты, найденные в указанной области (Chan ge All).
Процедура Label позволяет быстро найти строку с заданной меткой.
Выполнение программы
Основное меню с процедурами запуска программы приведено на рис. 16. Включенные в него функции обеспечивают запуск (Start) или повторный запуск (Restart) модуля, полученного компилятором в оперативной памяти, а также продолжение выполнения прерванной программы (Continue).
Рнс.16. Основное меню для режима выполнения программы
Процедура Modify COMMANDS позволяет изменить содержимое командной строки, значение которой доступно задаче (см. функцию и оператор COMMANDS).
С помощью процедуры Make EXE file... можно изготовить самостоятельный модуль, который записывается на диск и может быть выполнен под управлением MS DOS вне окружения QB-системы. Процедура Make Library... позволяет включить результаты трансляции в состав библиотечного файла с расширением .LIB.
Процедура Set Main Module используется для указания имени головного модуля.
Организация непосредственных вычислений
В GW-BASIC программные строки, набираемые без номеров, выполняются немедленно. Аналогичный режим предусмотрен и в QuickBASIC.
Для проведения непосредственных вычислений предназначено окно Immediate. Программные строки, набираемые в этом окне, исполняются сразу же после нажатия клавиши Enter. В окне одновременно может находиться несколько программных строк, однако выполняется та из них, в которой находится курсор. Обрабатываемая строка имеет достаточно большую емкость (256 символов), и в ней может располагаться несколько операторов, разделяемых двоеточиями. Тексты обработанных строк в окне сохраняются. К любой из них можно подвести курсор и выполнить повторно.
Переход в режим непосредственных вычислений, сопровождаемый появлением курсора в окне Immediate, осуществляетсянажатием клавиши F6. Если вас не устраивают первоначальные размеры окна, то его можно последовательно (за каждый такт на одну строку) увеличивать (Alt +) или уменьшать (Alt -) путем многократного нажатия
указанной пары клавиш. При таких манипуляциях максимальный размер окна непосредственных вычислений достигает 10 строк. Для того чтобы довести его размеры до полного экрана, необходимо нажать пару клавиш Ctrl+F10. Повторное их нажатие восстанавливает первоначальную конфигурацию окна.
При наборе программы в окне Immediate можно пользоваться всеми средствами QB-редактора, за исключением процедур обмена с файлами. Используя клавиши управления курсором, можно набрать несколько программных строк без их исполнения. Однако при очередном нажатии клавиши Enter выполнится только одна из них.
В немедленно исполняемой строке запрещено употребление следующих операторов:
COMMON
DEF
OPTION
TYPE
CONST
DIM
SHARED
$DYNAMIC
DATA
FUNCTION
STATIC
$INCLUDE
DECLARE
IF — ENDIF
SUB
$STATIC
С помощью режима непосредственных вычислений можно апробировать отдельные фрагменты программы.
В частности, по оператору CALL можно обратиться к внешней процедуре и проверить правильность ее работы. Эта процедура должна быть предварительно протранслирована и записана в Quick-библиотеку (процедура Make Library в Run-меню). Перед ее проверкой QB-систему необходимо загрузить вместе с библиотекой, содержащей тестируемый модуль.
Вы можете прервать выполняющуюся программу (Ctrl+Break или условный останов), изменить значения нужных переменных и продолжить работу программы, нажав клавишу F5.
Из окна Immediate можно сгенерировать сигнал программного прерывания (оператор ERROR п) с тем, чтобы проверить работу своей подпрограммы обработки ошибочной ситуации (ON ERROR...).
Выход из режима непосредственных вычислений осуществляется повторным нажатием клавиши F6.
Отладочные процедуры
Режим Debug, основное меню которого приведено на рис. 17, включает три группы процедур, облегчающих процесс поиска ошибок. К первой из них относятся так называемые условия останова программы (Watchpoint). Это самые обычные логические выражения, которые используются в операторах IF, DO, LOOP, WHILE. В тот момент, когда
заданное условие становится истинным, система прерывает выполнение программы. Таких условий может быть несколько. К ним можно добавлять новые (Add Watch), их можно просматривать (Watchpoint), удалять по одному (Delete Watch) или все сразу (Delete AU Watch).
Вторую группу составляют процедуры установки или удаления так называемых точек останова, соответствующих моментам выхода работающей программы на тот или иной помеченный оператор. Текущая строка программы считается отмеченной, если однократно нажать клавишу F9. Повторное нажатие F9 отменяет указанный признак. С помощью процедуры Clear All Breakpoints можно отменить все ранее набранные точки останова.
Третью отладочную возможность предоставляет режим трассировки (Trace ON/OFF), который включается или отключается последо вательными нажатиями клавиши Enter. При включенном режиме трассировки (Trace ON) выполнение программы происходит с замедленной скоростью и подсвечиванием каждого выполняемого оператора. Используя режим HISTORY ON, можно проследить последовательность программных шагов в прямом или обратном направлении.
Рис.17. Основное меню отладочных процедурРис.17. Основное меню отладочных процедур
Рис.17. Основное меню отладочных процедур
Рис.17. Основное меню отладочных процедур
Номер клавишиF4Shift+F5F5Номер клавишиF4Shift+F5F5
Номер клавиши
F4
Shift+F5
F5
Номер клавиши
F4
Shift+F5
F5
Далее приведен полный перечень клавишных операций, используемых в процессе отладки.
Выполняемая функция
Переход с просмотра окна вывода на просмотр листинга программы и обратно
Выполнение программы с самого начала
Продолжение выполнения программы с текущей строки
F7
Продолжение выполнения программы со строки, в которой находится курсор
F8
Выполнение очередной программной строки в пошаговом режиме, включая трассировку внешней процедуры
F10
Выполнение очередной программной строки в пошаговом режиме без трассировки внешней процедуры
Shift+F8
Просмотр очередного шага трассировки в обратном направлении
Shift+F10
Просмотр очередного шага трассировки в прямом направлении
Автономная компиляция Бейсик-программы
Автономный компилятор ВС.ЕХЕ позволяет реализовать раздельную трансляцию отдельных компонент большого программного комплекса. К его услугам можно прибегнуть и в том случае, когда исходная Бейсик-программа слишком велика для совместного размещения в оперативной памяти с QB-системой.
Запуск компилятора осуществляется под управлением MS DOS с помощью командной строки следующего вида:
... > be file.BAS [, [file.OBJ] [.llstfile] ] [option] [;]
Здесь file.BAS — имя файла, в котором находится текст Бейсик-программы (исходный модуль);
file.OBJ — имя файла, в который заносится продукт компиляции (объектный модуль);
list_file — имя файла, в который заносится документ трансляции (листинг); option — список параметров, управляющих процессом компиляции (см. ниже).
Результатом трансляции исходной программы является объектный модуль, представляющий собой программу на языке машинных команд, в которой не определены адреса внешних объектов. Такой модуль снабжается таблицей входных и внешних указателей, позволяющих на стадии сборки (редактирования связей) скомпоновать программу из нескольких объектных модулей и установить соответствие между совместно используемыми объектами.
Если файл для размещения объектного модуля не указан, то компилятор сам заведет файл, имя которого совпадает с наименованием исходного модуля, но имеет расширение .OBJ.
Документ трансляции, формируемый в процессе работы компилятора, может включать текст операторов исходной программы и соответствующие им фрагменты программы на ассемблере, таблицу распределения в памяти и употребления в программе идентификаторов
220
переменных, сообщения об ошибках и т.п. Его можно распечатать на принтере, если в качестве list_file назначить стандартное устройство PRN. Если имя файла для листинга не указано, то информацию о ходе трансляции вы не получите.
Формат параметраВоздействие на компилятор
/аСформировать листинг объектного модуля с указанием со
ответствия ассемблерного кода каждому оператору исходной программы■
/ahРазрешить динамические массивы записей, строки фикси
рованной длины и числовые данные, занимающие более 64 Кбайт
/с:пУстановить новую длину (п байтов) для буферов телеком
муникационных каналов связи (по умолчанию компилятор ВС.ЕХЕ выделяет под каждый буфер по 256 байт)
/dСгенерировать отладочный код и разрешить прерывание по
иажатию клавиш Ctrl+Break
/еРазрешить пользовательскую обработку ошибочных ситуа
ций и выделить все вхождения операторов ON ERROR и RESUME
/mbfИспользовать формат MBF для представления веществен
ных чисел. Функции CVD,CVS,MKD$ и MKS$ заменить соответственно на CVDMBF, CVSMBF, MKDMBF$ и MKSMBF$
/оЗаменить библиотеку BRUN40.UB на ВСОМ40.1ДВ. Ис
пользуется при компиляции больших программ
/гРасполагать в памяти двумерные массивы по строкам. Ис
пользуется для связи с другими системами программирования, где принят такой способ хранения массивов
/$Заносить текстовые константы непосредственно в объект
ный файл, не создавая специальную символьную таблицу. Используется в том случае, когда в программе встречается много текстовых констант
/уРазрешить прерывания, обрабатываемые с помощью поль
зовательских подпрограмм (операторы ON «событие» GOSUBN)
/wТо же самое, что и /у, но с дополнительной проверкой на
появление указанных событий после выполнения очередного оператора
/хПредупреждает, что программа содержит операторы
ON ERROR и RESUME
/zdГенерировать объектный файл с указателями на номера
строк в исходной программе. Используется в случае отладки модуля с помощью отладчика SYMDEB (Microsoft Symbolic Debugger)
/ziГенерировать объектный код в соответствии с требованиями
отладчика CodeView:
Редактирование связей
Преобразование объектных модулей в выполняемый файл заключается в сборке всех объектных модулей, задействованных в рамках решаемой задачи, и установлении соответствия между совместно используемыми объектами — переменными, массивами, точками входа в подпрограммы и функции. Процесс удовлетворения внешних связей выполняется редактором связей — модулем LINK.EXE (Microsoft Overlay Linker). Объектные модули, участвующие в сборке, могут находиться как в отдельных файлах с расширением .OBJ, так и входить в состав библиотек — файлов с расширением .LIB.
Запуск редактора связей осуществляется командной строкой вида:
...>USlK fiie.OBJ.fiie.EXE.mapfiie.lib options;
Здесь fiie.OBJ — имя объектного файла, полученного в результате компиляции головной Бейсик-программы, или конкатенация (сумма) объектных файлов, участвующих в сборке и не входящих в состав библиотечных файлов;
fiie.EXE — имя файла, в который помещается готовая к выполнению машинная программа;
mapfile — имя файла, в который заносится-карта (таблица) распределения памяти;
lib — список библиотечных файлов, в которых находятся используемые объектные модули;
options — список параметров, управляющих процессом сборки (приводится ниже).
ФорматВоздействие на редактор связей
параметра
/ЬПодавление выдачи сообщения в том случае, когда редактор
не может найти библиотеку или объектный файл
/соГенерация программы в соответствии с требованиями отлад
чика CodeView. Объектный модуль должен был транслироваться с указанием /а
/срЗафиксировать объем памяти (единица измерения — па
раграф — имеет емкость 16 байт), необходимый дла загрузки программы. При запуске программы этот объем контролируется
/doУстановить последовательность сегментов в соответствии с
общепринятым стандартом Microsoft для языков высокого уровня
/dsЗагрузить все данные, начиная с конечного адреса в сегмен
те данных
/еЗаменить цепочки повторяющихся байтов более компакт
ными кодами. Такая замена ускорит процедуру загрузки программы и уменьшит ее объем на диске
/heВывести список параметров, управляющих работой редак
тора связей (help)
Продолжение
/1Отобразить информацию о ходе редактирования '
/иВключить в карту памяти таблицу соответствия номеров
строк Бейсик-программы и адресов машинной программы
/шСоздать карту памяти
/nodИгнорировать библиотеки. Используется для блокировки
загрузки нежелательных системных библиотек
/поеУдовлетворить внешние связи в первую очередь за счет от
дельных файлов, включенных в состав Hie OBJ, и только после этого продолжить поиск внешних объектов в библио
,теках
/по!Различать большие и малые буквы
/рас:пГруппировать соседние сегменты команд с тем, чтобы они
пользовались общим адресом сегмента. Параметр п указы-
•вает размер группы (по умолчанию эта величина принима
ется равной 65 530)
/райСделать паузу перед записью сформированного ЕХЕ-файла
надиск
/qОсуществлять поиск объектных модулей в Quick-библиоте
ке. Может поддерживать BQLB40.LIB в качестве одной из библиотек
/se:nУправляет количеством сегментов, которое редактор выде
ляет программе. По умолчанию используется до 128 сегментов, максимальное количество — 1024
/st:nУстанавливает размер стека задачи (0 < п < 65 536). По
умолчанию под стек отводится 2 Кбайта
. Обслуживание библиотек
Quick-BASIC предоставляет возможность использования стандартных библиотечных файлов с расширениями .LIB и специальных библиотек, создаваемых под управлением QB-системы. Имена последних снабжаются расширением .QLB . К объектным модулям, расположенным в QLB-библиотеке, могут обращаться программы, создаваемые и выполняемые под управлением интегрированной QB-системы. Для этого при загрузке QB-системы необходимо указать параметр /L и задать имя загружаемой QLB-библиотеки.
Запись нового объектного модуля в QLB-библиотеку производится по процедуре Make Library из Run-меню.
Если в результате работы интегрированной QB-системы или ВС- компилятора создается самостоятельный ЕХЕ-модуль, то он может обращаться к объектным модулям, хранящимся в LIB-библиотеках. Обслуживание библио тек такого рода, характерных для систем программирования фирмы Microsoft на базе алгоритмических языков
223
FORTRAN, PASCAL, ASSEMBLER, С, выполняется автономным библиотекарем LIB.EXE. Его запуск осуществляется командной строкой вида ...>LIB in_iib [/p:n] [commands], [Iist_file] [,out_iib] [;]
Здесь in_lib — имя библиотечного файла, содержимое которого рассматривается как входная информация для библиотекаря;
/р:п — необязательное указание о размере страницы для библиотекаря, влияющее на скорость его работы. Значением п должна быть степень двойки в диапазоне от 16 до 32 768, задающая количество параграфов (блоков по 16 байт) в буфере обмена;
commands — список процедур, выполняемых над содержимым входной библиотеки (перечислены ниже);
Iist_fiie — имя файла, в который заносится протокол работы (имена модулей и таблица входных меток);
out_iib — имя файла, в который заносится содержимое модифицированной библиотеки in_lib.
Если имя новой библиотеки out_lib совпадает с именем in_lib, то содержимое исходной библиотеки сохраняется в файле с расширением .ВАК.
ФорматВыполняемая функция
команды +fi!e.OBJДобавить объектный файл к содержимому исходной библиоте
ки
-fiie.OBJУдалить объектный файл из исходной библиотеки
+fi!e.LIBДобавить содержимое указанной библиотеки к исходной биб
лиотеке
-file 1 .OBJ+fiie2.OBJ Заменить объектный файл fiiel на файл file2
*fiie.OBJПеренести указанный модуль в новую библиотеку без его уда
ления из старой
-*fi!e.OBJПеренести указанный модуль с удалением его из исходной биб
лиотеки
Имеется возможность вводить параметры командной строки по запросу библиотекаря, запущенного без параметров. Если приходится задавать достаточно много файлов, не помещающихся в командной строке, то в качестве признака продолжения используется символ «&».
Литература
Bodetuan Н. MS-BASIC, GW-BASIC. — Sybex Ratgeber, 1987. - 520 s.
.Bomanns H.-J. Das grosse Buch zu GW -BASIC / PC-BASIC. — Dusseldorf: Data Becker, 1987.— 370 s.
Daubach G. BASIC A, GW BASIC, BASIC 86 ( Fur 16 bit-PC unter MS DOS, PC DOS und CP/M-86). — IWT.,1986.— 320s.
Ellis W. Structured programming using Turbo BASIC. An introduction. — N.Y.: Acad.Press, 1988. — 300 p.
Ewbank K. James M. Using Turbo BASIC. — N.Y.: Wiley, 1987. — 250 p.
Hari V.V.,Tanik M.,Pooch U.W. lilustrated Quick BASIC. — Wcrdware Publishing Inc., 1989. —425 p.
Hartwig O. MS- und GW-BASIC. Tips & Tools. — Sybex, 1987. — 220 s
Hergert D. Introduction to Turbo BASIC. — Sybex Prompter Series. Singapore : Tech Publ., 1988. —523 p.
Hergert D. Turbo BASIC Instant Reference. — Sybex Prompter Series. Singapore: Tech Publ., 1988.— 393 p.
Kebschull G. Das Quick BASIC Handbuch. — Sybex, 1987. — 320 p.
ILKebschull G. Das Turbo BASIC Buch. — Sybex, 1987. — 350 p.
Knecht K. Advanced Quick BASIC. — Ldn.: Scott,Foresman, 1989. — 452 p.
Shammas N.C. The New BASIC’s : Programming Techniques and Library Development. — Redwood City, CA: M & T Publishing, 1987.
Shammas N.C. Quick BASIC : Programming Techniques and Library Development. — Redwood : M & T Books, 1988. — 266 p.
Shammas N.C. Turbo BASIC : Programming Techniques and Library Development. — Redwood : M & T Books, 1987.
ПРИЛОЖЕНИЯ
Приложение А
Указатель операторов
Наименование оператора
Наличие в системе
Указатель разделов
GW
Quick
Turbo
BEER
+ *
+
+
5.5.5
BLOAD
+
+
+
2.4.3,23.2
BSAVE
+
+
+
23.1,5.4.4
CALL
G
Q
T
2.4.2,2.4.3
CALL ABSOLUTE '
-
Q
T
2.4.3
CALLINT86...
-
+
-
2.4.3,5.43
CALL INTERRUPT
-
Q
T
2.4.3,5.43
CALLS s
-
+
-
2.4.3
CASE
-
+
+
2.2.3
CHAIN
G
+
+
2.5.4
CHDIR
+
+
+
2.5.5
CIRCLE
+
+
+
5.4.4
CLEAR
G
Q
T
5.2
CLOSE *
+
+
+
5.2
CLS
+
+
T
5.4.2
COLOR
+
+
+
5.4.2
COM (n)
+
+
+
5.5.7
COMMON
+
Q
+
2.3.2, 2.6.1
CONST
-
+
-
1.2.3
DATA
+
-h
+
3.1.1, 4.2.1
DECLARE
-
+
-
2.3.2,2.4.3 ’
DECR
-
-
+
3.1
DEFFN
G
Q
T
2.3.1
DEFSEC
+
+
+
2.4.3,5.5.6
DEFUSR
+
-
-
2.4.3
DEFDBL
+
+
+
1.2.2
DEFINT
+
+
+
1.2.2
DEFLNG
+
*
1.2.2
DEFSNG
+ ’
+
+
1.2.2
DEFSTR
+
+
+
1.2.2, 4.1
DELAY
-
-
+
5.5.4
DIM'
G
Q
T
1.2.4, 2.6.2, 4.1
DO
-
+
+
2.2.1
DRAW
+
+
+
5.4.4
ELSE
G
+
+
2.2.2
Наименование оператора
Наличие в системе
Указатель разделов
GW
Quick
Turbo
ELSEIF
-
+
+
2.2.2
END
+
+
+
2.1
END DEF
-
+
+
2.3.1
END FUNCTION
-
+
-
2.3.2
END IF
-
+
+
2.2.2
END SELECT
-
+
+
2.2.3
END SUB
-
+
+
2.4.2
END TYPE
-
+
-
1.2.5
ENDIF
-
+
+
2.2.2
ENVIRON
+
+
+
ERASE
+
+
+
1.2.4
ERROR
+
+
+
6.3
EXIT DEF
-
+
+
2.3.1
EXIT DO
-
+
-
2.3.2
EXIT FOR
-
*
+
2.2.1
EXIT FUNCTION
-
+
-
2.3.2
EXIT IF
-
+
+
3.3
EXIT LOOP
-
-
+
2.2.1
EXIT SELECT
-
+
+
2.2.3
EXIT SUB
-
*
+
2.4.2
FIELD
+
+
+
5.2,5.3.2
FILES
-
+
+
2.53
FOR
+
+
+
2.2.1
FUNCTION
-
+
-
2.3.2
GETO
+
+
+
5.4.4
GET#
+
Q
+
5.3.2
GET$
-
-
4-
5.3.2
GOSUB
G
+
+
2.4.1
GOTO
G
+
+
3.3
IF —GOTO
G
+
+
IF —THEN
+
+
+
2.2.2
IF —ENDIF
-
+
+
2.2.2
1NCR
-
-
+
3.1
INPUT
+
+
+
3.1.2,4.2.2
INPUT#
+
+
+
3.1.2,5.3.1
IOCTL
+
+
+
5.5.8
KEYn,...
G
Q
T
5.5.1
KEY LIST
+
-F
+
5.5.1
KEYON/OFF
+
+
+
5.5.1
Наименование оператора
Наличие в системе
Указатель разделов
GW
Quick
Turbo
KEY (n) ON/OFF/STOP
G
Q
T
5.5.1
KILL
+
+
4
2.5.5
LET
+
+
4
3.1.3
LINE
+
+
4
5.4.4
UNE INPUT
+
+
+
4.2.2 ■
UNE INPUT#
+
4-
4
5.3.1
LOAD
+
-
-
2.5.2
LOCAL
-
-
4
2.6.1
LOCATE
4
4
4
3.2,5.4.3
LOCK
+
4
-
5.2
LOOP
-
4
4
2.2.1
LPRINT [USING]
+
4
4
3.2.1,3.2.3
LSET
+
4
4
4.2.3,5.3.2
MEMSET
-
-
4
2.4.3
MERGE
+
-
-
2.5.4
MID$
+
4
+
4.2.3
MKDIR
-
4
4
2.5.5
NAME
-
4
+
2.5.5
NEXT
+
4
4-
Z2.1
ON COM(n)
+
4
+
5.5.7
ON ERROR
+
4
+
6.3
ON KEY (n)
+
+
+
5.5.1
ON PEN
+
4
+
5.5.2
ONPLAY(n)
+
4
4-
5.5.5
ON STRIG(n)
+
4
4-
5.5.3
ONTIMER(n)
+
4
4-
5.5.4
ONeGOSUB
G
4
4-
3.3
ON e GOTO
G
4
+
3.3
OPEN
G
Q
T
5.2.5.5.7
OPTION BASE
+
4
T
1.2.4
OUT
+
4
4-
5.5.6
PAINT
+
+
+
5.4.4
PALETTE [USING]
+
4
+
5.4.2
PCOPY
-
4
-
5.4.3
PEN ON/OFF/STOP
+
4
4-
5.5.2
PLAY
+
4
+
5.5.5
PLAY ON/OFF/STOP
+
4
4-
5.5.5
POKE
+
4
4-
5.5.6
PRESET
+
4
4-
5.4.4
Наименование оператора
Наличие в системе
Указатель разделов
GW
Quick
Turbo
PRINT [USING]
+
+
4
3.2.1, 3.2.3
PRINT# [USING]
+
+
4
5.3.1
PSET
+
+
4
5.4.4
PUTO
+
+
4
5.4.4
PUT#
+
Q
4
5.3.2
PUTS
-
-
4
5.3.2
RANDOMIZE
+
4
4
3.1.4
READ
+
+
4
3.1.1, 4.2.1
REDIM
-
4
-
1.2.4
REG
-
-
4-
5.4.5
REM
4-
Q
4-
2.5.3
RESET
G
+
4-
5.2
RESTORE
G
4
4-
3.1.1
RESUME
+
4
4-
б.З
RETURN
G
+
4-
2.4.1
RMDIR
-
4
4-
2.5.5
RSET
+
4
4-
4.2.3, 5.3.2
RUN
G
4
4-
2.5.2
SCREEN
+
4
4-
5.4.2, 5.4.3
SEEK
-
4
4-
5.3.2
SELECT CASE
-
4
4-
2.2.3
SHARED
-
Q
T
2.3.2, 2.6.1
SHELL
+
4
4-
SOUND
+
4
4-
5.5.5
STATIC
-
Q
T
2.6.2
STOP
+
+
4-
3.3
STRIG(n) ON/OFF/STOP
4-
4
4-
5.5.3
SUB
-
Q
T
2.4.2, 2.4.3
SUB INLINE
-
-
4-
2.4.3
SWAP
+
4
4-
3.1.3, 4.2.3
SYSTEM
+
4
4-
5.2
TIMER ON/OFF/STOP
+
4
4-
5.5.4
TROFF
+
4
4-
6.1
TRON
+
+
4-
6.1
TYPE
-
+
1.2.5
UNLOCK
+
+
5.2
VIEW [SCREEN]
4-
4
4-
5.4.2, 5.4.4
VIEW PRINT
4-
4
3.2,5.4.2
WAIT
+
+
4-
5.5.6
Продолжение
Наименование оператора
Наличие в системе
Указатель разделов
GW
Quick
Turbo
WEND
+
+
+
2.2.1
WHILE
+
+
+
2.2.1
WIDTH
+
+
+
3.2.1,5.4.3
WINDOW
+
+
+
5.4.2,5.4.4
WRITE
+
+
+
3.2.2
WRITE#
+
+
+
5.3.1
Примечание. G,Q,T — в формате оператора имеются синтаксические особенности, характерные для соответствующей системы программирования.
Наименование функции
Наличие в системе
Указатель разделов
GW
Quick
Turbo
ABS
+
+
+
3.1.4
ASC
+
+
+
1.2.6
ATN
+
+
+
3.1.4
BINS
-
-
+
1.2.6
CDBL
+
+
+
1.2.6
CEIL
-
+
3.1.4
CHRS
+
+
+
1.2.6
CINT
+
+
+
1.2.6
CLNG
-
+
+
1.2.6
COS
+
+
+
3.1.4
CSNG
+
+
+
1.2.6
CVD
+
+
+
1.2.6.
CVDMBF
-
+
1.2.6
CVI
+
+
+
1.2.6
CVL
.-
+
+
1.2.6
CVMD
-
-
+
1.2.6
CVMS
-
+
1.2.6
CVS
+
+
+
1.2.6
CVSMBF
-
+
1.2.6
ENVIRONS
+
+
+
4.2.3
EOF
G
+
+
5.3.1
EXP
+
+
+
3.1.4
EXP10
-
+
3.1.4
EXP2
-
-
+
3.1.4
FILEATTR
-
+
MX
+
+
+
3.1.4
FRE
G
+
+
2.4.3
HEX$
+
+
+
1.2.6
INP
+
+
+
5.5.6
INPUTS
+
+
+
4.2.2,4.2.3
INSTR
+
+
+
4.2.3
INT
+
+
+
3.1.4
IOCTLS
-
+
+
4.2.3,5.5.8
LBOUND
-
+
+
2.4.2
LCASES
-
+
+
4.2.3
LEFTS
+
+
+
4.2.3
LEN
G
Q
T
4.2.3
Наименование функции
Наличие в системе
Указатель разделов
GW
Quick
Turbo
LOC
'+
+
4-
5.5.7
LOF
+
+
4-
5.5.7
LOG
+
+
4-
3.1.4
LOGIC
-
-
4-
3.1.4
LOG2
-
-
4-
3.1.4
LPOS
G
+
4-
3.2.1
LTRIM$
-
+
-
4.2.3
MID$
+
+
4-
4.2.3
MKD$
+
+
4-
1.2.6
MKOMBFS
-
+
-
1.2.6
MKI$
+
+
4-
1.2.6
MKL$ э
-
+
4-
1.2.6
MKMD$
-
-
+
1.2.6
MKMSS
-
-
4-
1.2.6
MKS$
+
+
4-
1.2.6
MKSMBFS
-
+
-
1.2.6
OCT$
+
+
4-
1.2.6
PEEK
+
+
4-
5.5.6
PEN
+
+
4-
5.5.2
PLAY
+
+
4-
5.5.5
PMAP
+
+
4-
5.4.4
POINT
+
4-
4-
5.4.4
POS
+
+
4-
5.4.3
REG
-
-
4-
5.4.5
RIGHTS
+
+
4-
4.2.3
RND
+
+
4-
3.1.4
RTRIM$
-
+
-
4.2.3
SADO
-
+
-
2.4.3
SCREEN
+
+
4-
5.4.3
SEEK
-
+
-
5.3.2
SETMEM
-
+
-
2.4.3
SGN
+
+
4-
3.1.4
SIN
+
+
+
3.1.4
SPACES
G
+
+
4.2.3
SPC
+
+
4-
3.2.1
SQR
+
+
+
3.1.4
STICK
+
+
4-
5.5.3
STR$
+
+
4-
1.2.6
STRIG
+
+
4-
5.5.3
Наименование функции
Наличие в системе
Указатель разделов
GW
Quick
Turbo
STRINGS
G
+
+
4.2.3
ТАВ
+
+
+
32.1
TAN
+
+
+
3.1.4
UBOUND
-
4-
+
2.4.2
UCASES
-
+
+
4.2.3
USRn
+
-
-
2.4.3
VAL
+
+■
+
1.2.6
VARPTR
G
+
+
2.4.3
VARPTRS
+
+
+
2.4.3, 4.2.3
VARSEG
-
4-
+
2.4.3
Примечание. G,Q,T— в формате или в алгоритме функции имеются особенности,
характерные для соответствующей системы программирования.
Указатель системных переменных
Наименование переменной
Наличие в системе
Указатель разделов
GW
Quick
Turbo
COMMANDS
+
+
+
4.2.3
CSRUN
Ч-
+
+
5.4.3
DATES
+
+
+
4.2.3,5.5.4
ENDMEM
-
-
+
ERADR
-
-
+
6.3
ERDEV
+
+
+
6.3
ERDEVS
+
+
—+
4.2.3,6.3
ERL
+
+
+
6.2,6.3
ERR "
+
+
+
6.2.6.3
EXTERR
*
-
-
6.3
FREEFILE
-
+
-
INKEYS
+
+
+
4.2.1
INSTAT
-
-
+
3.1.4,4.2.1
MTIMER
-
+
3.1.4,5.5.4
POS *
G
Q
+
5.4.3
TIMES
+
+
+
4.2.3,5.5.4
TIMER
+
+
+
5.5.4
Примечание. GW- BASIC и Quick-BASIC вместо переменной POS используют фун- кциюРО8(х) с фиктивным аргументом.
Набор тестовых программ для анализа быстродействия Бейсик-систем
10 ’PROG1 —тест целочисленной арифметики
20 T-TIMER
30 Х%-0
40 Y% —9
50 FOR 1% -1 ТО 3000
60 Х% - Х% + (Y% * Y% - Y%> \ Y%
70 NEXT 1%
80 PRINT TIMER —T
10 ' PROG2 — тест вещественной арифметики
20 T-TIMER
30 XI-0
40 Y! —9.9
50 FOR I%-1 TO 20000
60 Xi-X! + (Y!*V-Yi)/Yi
70 NEXT 1%
80 PRINT TIMER —T
10 ’ PROG3 — тест стандартных функций
20 T-TIMER
30 Xi—О
40 Yi—9.9
50 FOR 1% -1 TO 5000
60 X! -X! + SIN (ATN (COS (LOG (Y!))))
70 NEXT 1%
80 PRINT TIMER—T
10 ’ PROG4 — тест вывода в текстовом режиме
20 T-TIMER
30 FOR I%-1 ТО 1000
40 PRINT «1234567890QWERTYUIOP».I%
50 NEXT 1%
60 PRINT TIMER —T
10 ’ PROGS — тест вывода в графическом режиме
20 SCREEN 2
30 Т-TIMER
40 FOR 1% - 1 ТО 100
50 FOR J% -1 TO 100
60 PSET(I%,J%)
70 NEXT J%
80 NEXT 1%
90 PRINT TIMER —T
10 ’ PROG6 — тест файловых процедур
20 Т—TIMER4
30 OPEN «TEST.DAT» FOR RANDOM AS #1 LEN-20
40 FIELD *1,20 AS A$
50 FOR I%—1 to 1000
60 A$ -" 1234567890QWERTYUIOP"
70 PUT *1,1%
80 NEXT 1%
90 CLOSE #1
100 KILL «TEST.DAT»
110 PRINT TIMER —T
10 ’PROG7 — тест определения накладных расходов
20 Т*-TIMER
30 FOR 1% “ 1 ТО 20000 ’ число можно менять
40 NEXTI%
50 PR NT TIMER — T*
СОДЕРЖАНИЕ
Введение3
.ЭЛЕМЕНТЫ ВХОДНОГО ЯЗЫКА9
.Алфавит языка и специфика использования символов9
Типы данных и форматы их представления14
Литеральные константы числового и символьного типов14
Числовые и символьные переменные17
Именованные константы19
Массивы,19
Составные данные (записи)23
Преобразование типов данных26
Стандартные и нестандартные функции28
Арифметические и логические выражения30
Операторы и программные строки31
.Декларативные и исполняемые операторы 31
Непосредственные и отложенные действия33
Идентификация программных строк33
. ОРГАНИЗАЦИЯ ПРОГРАММЫ36
Головная программа36
Элементы структурного программирования37
Циклы37
Блоки выбора по условию40
Блоки выбора по ключу42
Описание нестандартных функций44
нутренние функции44
нешние функции47
Описание и использование подпрограмм50
2.4.1.Внутренние подпрограммы51
2.4.2.Внешние подпрограммы53
2.4.3.Общение с другими системами программирования56
Программные файлы67
.Запоминание программных файлов на диске67
агрузка дисковых файлов 68
одключение файлов к текущей программе 69
ыполнение цепочки программных файлов69
аимодействие с файловой системой MS DOS 70
2.6.Взаимосвязь по данным между программными модулями71
.Локальные и глобальные переменные71
.Статическое и динамическое распределение памяти73
З.ОРГАНИЗАЦИЯ МАТЕМАТИЧЕСКИХ ВЫЧИСЛЕНИЙ75
.Способы формирования и изменения значений числовых переменных75
.Использование внутренних блоков данных 75
.Ввод данных по запросу программы 77
ЗЛ.З.Изменениезначений переменных по результатам вычислений78
.Стандартные математические функции79
ывод результатов вычислений82
.Вывод числовых данных по стандартному формату83
Потоковый вывод данных86
Использование нестандартного формата при выводе результатов вычислений87
З.З.Управление логикой вычислительного процесса90
4.ОБРАБОТКА ТЕКСТОВОЙ ИНФОРМАЦИИ93
Символьные константы, переменные и массивы93
4-2.Формирование и изменение значений переменных символьного типа94
.Использование внутреннего блока данных 94
.Ввод символьных значений по запросу программы95
.Символьные выражения и стандартные процедуры обработки текстовой информации 97
4-З.Вывод текстовой информации-.100
5-ВЗАИМОДЕЙСТВИЕ С ФАЙЛАМИ И УСТРОЙСТВАМИ102
Организацияфайловыхструктур102
Инициализация файлов данных"103
Процедуры обмена с файлами данных106
5-3.1 .Обмен с последовательными файлами106
Обмен с файлами прямого доступа107
5-4-Взаимодействиес экраном дисплея110
Технические характеристики дисплеевПО
Установочные процедуры117
Работас экраном в текстовом режиме 122
Работа с экраном в графических режимах123
Использование функций BIOS для управления дисплеями132
имодействие с активными внешними устройствами142
Клавиатура143
Световоелеро -• 145
Игровые пульты (джойстики)146
5-5.4.Таймер и временные прерывания148
5-5.5.Организация звуковых эффектов 151
Доступкпортамиячейкамонеративнойпамяти154
5-5.7.Работа с каналами связи 158
5.5.8.Управлениевнешиимиустройстваминафизическомуровне164
6.ОТЛАДКА ПРОГРАММ166
Выполнение программы в отладочном режиме167
Системная реакция на программные прерывания169
Индивидуальная обработка программных прерываний172
7.ОСНОВНЫЕ ПРИЕМЫ РАБОТЫ В СРЕДЕ GW-BASIC174
Вызови настройка интерпретатора175
Директивы управления системой GW-BASIC175
7.2.1.Ввод новой программы176
7.2.2.3апоминание и загрузка программных файлов178
7.2.3-Редактирование текущей программы".179
7.2.4.Выполнение и прерывание программы180
.ОСНОВНЫЕ ПРИЕМЫ РАБОТЫ В ФЕДЕ TURBO-BASIC182
.Главноеивспомогательноеменю.Системныеокна183
.Ввод и редактирование новой программы186
.Файловые процедуры 191
.Управление компилятором194
.Выполнение, компиляция и отладка текущей программы197
.Управление окнами199
7 .Модификация цветовых атрибутов200
Запоминание и восстановление конфигурации системы202
.ОСНОВНЫЕ ПРИЕМЫ РАБОТЫ В ФЕДЕ QUICK-BASIC204
.Работа под управлением интегрированной QB-системы205
Файловые процедуры208
-2-Средства редактирования 211
Процедуры просмотра214
Контекстный поиск 215
Выполнение программы 216
Организация непосредственных вычислений 217
Отладочные процедуры 218
Автономная компиляция Бейсик-программ220
Редактирование связей 222
Обслуживание библиотек223
Литература225
ПРИЛОЖЕНИЯ226
Приложение А. Указатель операторов226
Приложение В. Указатель функций231
Приложение С. Указатель системных переменных234
Приложение D. Набор тестовых программ для анализа быстродействия Бейсик-систем235