/
Author: Зельднер Г.А.
Tags: компьютерные технологии вычислительная техника микропроцессоры программирование языки программирования язык программирования basic
ISBN: 5-87484-059-1
Year: 1996
Text
ПРОГРАММИРУЕМ НА ЯЗЫКЕ
Quick BASIC 4.5
Учебное пособие по курсам "Основы программирования",
"Информатика и вычислительная техника"
Григорий ЗЕЛЬДНЕР
Программируем
на языке
QuickBASIC 4.5
Учебное пособие по курсам
"Информатика и вычислительная техника",
"Основы программирования"
Москва
ABF
1996
ББК 32.97
350
УДК 681.322-181.4.004.14
ЗЕЛЬДНЕР Григорий Алексеевич
350 Программируем на языке QuickBASIC 4.5
B-е издание, исправленное и дополненное)
М. ABF, 1996. — 432 с: ил.
ISBN 5-87484-059-1
Книга посвящена языку QuickBASIC 4.5 — наи-
более популярному средству для обучения основам
программирования в учебных заведениях России.
Этот язык стал стандартом de facto для всех ком-
пиляторов языка BASIC. Набор управляющих опера-
торов и конструкций языка QuickBASIC поддержи-
вают самые современные языки программирования
компании Microsoft: Visual BASIC for Windows и
Visual BASIC for Application.
В легкой и непринужденной манере в книге рас-
сказывается о среде программирования QuickBASIC,
приводится описание всех операторов и функций
языка, дается понятие о том, что такое хороший
стиль программирования и как стать поклонником
языка BASIC.
Помимо преподавателей и учащихся, она будет
полезна начинающим и опытным программистам, ра-
ботающим с языком BASIC.
324О40Ш00^05О им
0Ш4@3) - 96
ISBN 5—87484—059—1 © Григорий Зельднер, 1996
Обложка Виктора Монетова
Содержание
BASIC — НАДЕЖДА И ОПОРА 15
gwbasic — первое поколение языка 17
QuickBASIC — второе поколение языка 17
Visual BASIC — третье поколение языка 20
О ЧЕМ ЖЕ ЭТА КНИГА ? 21
1. СРЕДА ПРОГРАММИРОВАНИЯ 23
Программы и компьютеры 23
Интерпретатор + Компилятор = QuickBASIC 27
Начинаем работу... или что нужно для начала 28
Знакомимся со средой программирования 32
Как нам обустроить QuickBASIC (*) 47
Драйвер русских букв 47
Программы-оболочки 49
Переключатель Задач 50
2. ОСНОВЫ ЯЗЫКА BASIC 53
АЛФАВИТ ЯЗЫКА 53
ТИПЫ ДАННЫХ 55
Данные и их типы 55
Числовые типы данных 55
Символьные типы данных 56
Пользовательские типы данных (записи) 56
Константы 57
Неименованные константы 57
Именованные константы 58
Переменные 60
Имена переменных 60
Переменные числового типа 61
Переменные символьного типа 64
Переменные пользовательского типа данных 65
Переменные-массивы 67
Большие динамические массивы (*) 69
Выражения и операции 71
Арифметические операции 72
Возведение в степень (Л) 72
Присвоение знака числу (-) 72
Умножение и деление (*, /) 73
Целочисленное деление (\) 73
Нахождение остатка (MOD) 73
Сложение и вычитание (+,-) 73
Порядок вычисления выражений 74
Переполнение и деление на ноль 75
Операции отношения: 75
Логические операции 77
Функциональные операции 79
Строковые операции 80
Конкатенация (сложение) строк 80
Сравнение строк 80
Операторы передачи управления 81
Операторы цикла 81
FOR...NEXT 81
DO...LOOP 82
WHILE...WEND 82
Условные операторы 82
IF...THEN...ELSE 83
SELECT... END SELECT 83
Избегайте устаревших конструкций 83
Как получить код нажатой клавиши: 84
Как выйти из цикла по условию: 84
Как избежать синдрома "ёжика в тумане" 86
Как правильно "разветвиться" 87
ВВОД И ВЫВОД ЗНАЧЕНИЙ 88
Ввод значений 88
INPUT 89
LINE INPUT 90
INPUTS 90
Вывод значений 91
PRINT 91
PRINT USING 92
LPRINT и LPRINT USING 92
LOCATE 93
Почему BASIC не выговаривает русскую букву "р" 95
Модульное программирование (*) 96
Функция DEFFN 97
Процедура FUNCTION 98
Процедура SUB 99
Рекурсия 100
Границы использования переменных и констант 100
Глобальные переменные и константы 101
4
Локальные переменные и константы 101
Совместно используемые переменные 102
Переменные в функции DEF FN 102
Параметры в процедурах SUB и FUNCTION 103
Использование включаемых (INCLUDE) файлов 104
Построение многомодульной программы 106
Исходный текст на языке BASIC 106
Построение Quick-библиотеки 118
3. ОПЕРАТОРЫ ОПИСАНИЯ 121
CONST 121
DEFTnn : 122
DIM 123
REDIM 125
LBOUND 127
UBOUND 128
TYPE 128
OPTION BASE 129
COMMON 129
Использование именованного блока COMMON 131
COMMON и .EXE файлы 132
DATA 133
READ 133
RESTORE 134
4. ОПЕРАТОРЫ ПЕРЕДАЧИ УПРАВЛЕНИЯ 137
Операторы цикла 137
FOR...NEXT 137
WHILE... WEND 141
DO...LOOP 144
Проверка выражения в начале цикла: 144
Проверка выражения в конце цикла: 146
Условные операторы 149
IF...THEN...ELSE 149
Блочная форма 149
Линейная форма 150
Логика работы при блочной и линейной форме 150
SELECT...END SELECT 151
Подпрограммы 155
GOSUB...RETURN 155
Функции 156
DEFFN 156
Линейная форма 156
Блочная форма 156
Логика работы при блочной и линейной форме 157
5
Процедуры (*) 158
FUNCTION 158
Рекурсивные процедуры FUNCTION 159
SUB 160
Передача параметров в процедуры SUB и FUNCTION (*) 161
FUNCTION или SUB — проблема выбора (*) 163
Другие управляющие операторы 166
END 166
EXIT 167
STOP 168
SYSTEM 168
5. ВВОД-ВЫВОД НА ВНЕШНИЕ УСТРОЙСТВА 171
Клавиатура 171
INPUT 171
LINE INPUT 173
INPUTS 173
INKEYS 174
Экран 175
PRINT 175
PRINT USING 176
Форматы для вывода символьных значений 177
Форматы для вывода числовых значений 177
WRITE 179
LOCATE 180
CSRLIN 181
POS 181
SPC 182
TAB 182
WIDTH 183
Файлы 184
OPEN 184
CLOSE 187
RESET 187
GET 188
PUT 190
INPUT # 191
LINE INPUT* 192
INPUTS 193
PRINT #, PRINT # USING 194
WRITE 195
BSAVE 196
BLOAD 198
EOF 199
LOF 200
FIELD 200
LSET, RSET 203
D
FILEATTR 204
FREEFILE 205
IOCTL 206
IOCTLS 206
LOC 207
LOCK..UNLOCK 207
SEEK 209
SEEK 210
Принтер 212
LPOS 212
LPRINT, LPRINT USING 212
Порты 213
INP 213
OUT 214
OPEN COM ' 214
STICK 218
STRIG 219
WAIT 220
6. ГРАФИКА И ЗВУК 221
Графика 221
CLS 221
COLOR 222
Номера экранных цветов 223
Описание экранных режимов 223
PALETTE, PALETTE USING 225
PCOPY 227
SCREEN (функция) 228
SCREEN (оператор) 228
VIEW PRINT ; 229
VIEW 229
WINDOW 230
CIRCLE 231
LINE 233
PRESET 235
PSET 235
DRAW 236
Команды движения относительно текущей точки: 236
Команды установки угла, цвета и масштаба 237
Вызов подкоманды: 238
PAINT 238
GET 241
PUT 242
POINT 244
PMAP 246
3-Х МЕРНЫЕ ОБЪЕКТЫ В ТЕКСТОВОМ РЕЖИМЕ 247
7
Объемные кнопки 247
Рамки и тени 249
Поля для ввода данных 251
Библиотеки для работы с изображениями (*) 253
PCX Programmer's ToolKit 253
VEGX for QuickBASIC 255
Звук и музыка 257
BEEP 257
PLAY 257
Команды октавы и тона 257
Команды длительности и темпа 258
Переключения звучания на основное или фоновое 259
Вызов подкоманды: 259
SOUND 264
Работа с оцифрованным звуком (*) 266
QB SoundBlaster ToolKit 267
7. ПРОЧИЕ ОПЕРАТОРЫ ЯЗЫКА 269
SLEEP 269
REM 269
SWAP 271
ERASE 272
CLEAR 273
8. ВСТРОЕННЫЕ МАТЕМАТИЧЕСКИЕ ФУНКЦИИ
И ФУНКЦИИ ОБРАБОТНИ ДАННЫХ 275
Математические функции 275
ABS 275
ЕХР 276
LOG 277
MOD 277
SGN 277
SQR 277
ATTM 279
COS 279
SIN 280
TAN 281
Секанс и другие 282
RANDOMIZE 283
RND 284
Функции обработки числовых и символьных данных 286
Функции округления 286
FIX 286
INT 286
Преобразование типов данных 287
CINT 287
CLNG 287
CSNG 287
CDBL 288
CHR$ 288
ASC 289
Упаковка данных 290
CVI, CVL, CVS ,CVD 290
MKI$, MKLS, MKSS, MKDS 290
Функции обработки символьных строк 293
LCASES 293
UCASES 293
LTRIM$ 294
RTRIMS 295
SPACES 295
STRINGS 296
INSTR 297
LEFTS 298
RIGHTS 299
MIDS (функция) 299
MIDS (оператор) 300
HEXS 301
OCTS 301
STRS 302
LEN : 302
9. ДОСТУП К АБСОЛЮТНЫМ АДРЕСАМ (*) ..305
DEFSEG 305
PEEK 305
POKE 306
SADD 306
SETMEM 307
VARPTR и VARSEG 307
VARPTRS 308
Доступ к клавишам-переключателям и модификаторам 309
10. ОТСЛЕЖИВАНИЕ СОБЫТИЙ, ОБРАБОТКА
ОШИБОК И ТРАССИРОВКА (*) 313
Отслеживание событий 313
ONCOM(n) 313
СОМ(п) 313
ONKEY(n) 314
KEY 316
9
KEY(n) 318
ON PEN 319
PEN ON, PEN OFF, PEN STOP 319
ON PLAY(n) 320
PLAY 320
PLAY ON, PLAY OFF, PLAY STOP 321
ONSTRIG(n) 322
ONTlMER(n) 322
TIMER ON, TIMER OFF, TIMER STOP 322
ONUEVENT 323
UEVENT ON, UEVENT OFF, UEVENT STOP 325
Обработка ошибок и трассировка 325
ON ERROR 325
ERDEVh ERDEVS 327
ERLmERR 328
ERROR 328
RESUME 328
TRONhTROFF 329
11. СВЯЗЬ С DOS (*) 331
Передача управления другой программе 331
CHAIN 331
SHELL 332
RUN 333
Работа с датой и временем 335
DATES (функция) 335
DATES (оператор) 335
TIMES (функция) 336
TIMES (оператор) 336
TIMER 337
Работа с файловой системой 338
CHDIR 338
MKDIR 339
RMDIR 339
FILES 340
KILL 341
NAME 341
Работа с окружением DOS 342
COMMANDS 342
ENVIRON 343
ENVIRONS 344
12. РАСШИРЕНИЕ ВОЗМОЖНОСТЕЙ
QuickBASIC 4.5(*) 345
ю
Работа с системными прерываниями в QuickBASIC 345
Ввод малой русской буквы "р" 348
Прокрутка текстового экрана.' 349
Интерфейс с драйвером мыши 353
Функция 0: Текущее состояние драйвера мыши 354
Функция 1: Включить курсор мыши 354
Функция 2: Погасить курсор мыши 354
Функция 3.: Прочитать координаты курсора и статус кнопок...355
Функция 4: Установить координаты курсора мыши 355
Функция 5: Прочитать статус нажатой кнопки 356
Функция 6: Прочитать статус отпущенной кнопки 357
Функция 7: Ограничить горизонтальное перемещение курсора. 357
Функция 8: Ограничить вертикальное перемещение курсора.. 358
ПРИЛОЖЕНИЯ 359
ПРИЛОЖЕНИЕ 1. Описание Главного Меню
QuickBASIC 4.5 359
МЕНЮ FILE (ФАЙЛЫ) 359
NEW PROGRAM (Новая программа) 360
OPEN PROGRAM (Открыть программу) 360
MERGE (Объединение) 361
SAVE (Запись) 361
SAVE AS (Записать как...) 362
SAVE ALL (Записать все) 362
CREATE FILE (Создать файл ) 362
FILE LOAD (Загрузить файл) 363
FILE UNLOAD (Выгрузить файл) 364
PRINT (Печать) 364
DOS SHELL (Временный выход в DOS) 364
EXIT (Выход) 365
МЕНЮ EDIT (РЕДАКТИРОВАНИЕ) ...365
UNDO (Отменить) 366
CUT (Вырезать) 366
COPY (Копировать) 367
PASTE (Вставить через буфер) 367
CLEAR (Очистить) 368
NEW SUB (Новая процедура SUB) 368
NEW FUNCTION (Новая процедура SUB) 368
МЕНЮ VIEW (ПРОСМОТР) 369
SUBs (Процедуры) 369
NEXT SUB (Следующая процедура) 370
SPLIT (Разделение) 370
NEXT STATEMENT (Следующий оператор) 370
OUTPUT SCREEN (Выходной экран) 371
INCLUDED FILE (Включенный файл) 371
INCLUDED LINES (Включенные строки) 372
11
МЕНЮ SEARCH (ПОИСК) 372
FIND (Поиск) 372
SELECTED TEXT (Выделенный текст) 373
REPEAT LAST FIND (Повторить последний поиск) 373
CHANGE (Замена) 374
LABEL (Метка) 374
МЕНЮ RUN (ЗАПУСК) 375
START (Запуск) 375
RESTART (Перезапуск) 376
CONTINUE (Продолжить) 376
MODIFY COMMANDS (Изменить переменную COMMANDS) 376
MAKE EXE FILE (Сделать EXE файл) 377
MAKE LIBRARY (Сделать библиотеку) 377
SET MAIN MODULE (Установить главный модуль) 378
МЕНЮ DEBUG (ОТЛАДКА) 378
ADD WATCH (Добавить наблюдение) 379
INSTANT WATCH (Установить наблюдение) 380
WATCHPOINT (Точка наблюдения) 380
DELETE WATCH (Стереть наблюдение) 381
TRACE ON (Включить трассировку) 382
HISTORY ON (История включена) 382
TOGGLE BREAKPOINT (Точка прерывания) 382
CLEAR ALL BREAKPOINTS (Стереть все точки прерывания).... 383
BREAK ON ERRORS (Обрыв на ошибках) 383
SET NEXT STATEMENT (Установить следующий оператор) 384
МЕНЮ CALLS (ВЫЗОВЫ) 384
МЕНЮ OPTIONS (ОПЦИИ) 384
DISPLAY (Экран) 385
SET PATHS (Установить пути) 385
RIGHT MOUSE (Правая кнопка мыши) 386
SYNTAX CHECKING (Проверка синтаксиса) 386
FULL MENUS (Режим полного меню) 387
МЕНЮ HELP (ПОМОЩЬ) 387
HELP INDEX (Индекс помощи) 388
HELP TABLE of CONTENTS
(Таблица содержания файлов помощи) 388
HELP TOPIC (Описание) 389
HELP on HELP (Справка о помощи) 389
ПРИЛОЖЕНИЕ 2. Запуск, редактирование
И ОТЛАДКА ПРОГРАММЫ 389
Ключи запуска среды QB из командной строки DOS 389
Клавиши редактирования 390
Клавиши прокрутки текста 391
Клавиши выбора текста 391
Вставка, копирование и стирание текста 392
Клавиши просмотра 392
Клавиши поиска 393
12 Клавиши запуска и отладки 393
Клавиши помощи 393
ПРИЛОЖЕНИЕ 3. КОДЫ ОШИБОК 394
ПРИЛОЖЕНИЕ 4. Ограничения QuickBASIC 396
Имена, символьные строки и числа 396
Массивы 396
Процедуры и файлы 397
Редактирование 397
ПРИЛОЖЕНИЕ 5. ASCII-коды, Скан-коды 398
ASCII-коды 398
Символы псевдографики для рисования рамок и таблиц 400
Скан-коды клавиатуры 401
ПРИЛОЖЕНИЕ 6. Типы дисплеев и экранные режимы ... 402
Описание экранных режимов SCREEN 402
SCREEN 0 402
SCREEN 1 402
SCREEN 2 403
SCREEN 3 403
SCREEN 4 403
SCREEN 7 403
SCREEN 8 403
SCREEN 9 404
SCREEN 10 404
SCREEN 11 404
SCREEN 12 404
SCREEN 13 405
ПРИЛОЖЕНИЕ 7. Словарь зарезервированных слов 405
ПРИЛОЖЕНИЕ 8. Метакоманды 414
Метакоманды SSTATIC и SDYNAMIC 415
Метакоманда SINCLUDE 415
ПРИЛОЖЕНИЕ 9 416
Что почитать о языке BASIC 416
Журнал "Монитор" 416
Журнал "Мир ПК" 416
Журнал "Компьютер Пресс" 419
Журнал "Персональные программы" 420
Газета "СофтМаркет" 421
Книги издательства "ABF" 422
ИНДЕКС 423
13
BASIC — надежда и опора
"BASIC-программисты — люди меченые, путем насилия или
подкупа нас можно заставить работать на другом языке,
но думать-то мы все равно будем на BASIC..."
С. Г. Зиновьев
Название языка программирования BASIC — это первые
буквы английских слов Beginner's All-purpose Symbolic Instruction
Code (Всецелевой язык программирования для начинающих).
Впрочем, автор предпочитает другой перевод этого названия —
на английском языке слово "basic" -^ означает основной, базо-
вый. Недаром нашумевший триллер последних лет называется
Basic Instinct.
Созданный в начале 1960-х годов двумя профессорами Дарт-
мунского университета Джоном Кенеми и Томасом Куртцом,
BASIC превратился в современный язык высокого уровня, про-
должая оставаться простым и доступным для всех пользовате-
лей — от любителей до профессионалов. По словам президента
фирмы Microsoft Билла Гейтса, BASIC переживет все другие язы-
ки программирования. И жизнь подтверждает это утверждение.
Сегодня BASIC — нет тот, что был еще 10 лет назад. Это по-
стоянно развивающийся язык, снабженный всем необходимым
для профессиональной разработки программ: поддержка модуль-
ного и структурного программирования, эффективная среда раз-
работки, создание исполняемых модулей, мощные средства от-
ладки, встроенный HELP, дополнительные библиотеки процедур
различного назначения — от пользовательского интерфейса до
управления базами данных.
При этом BASIC сохранил свою привлекательность для на-
чинающих и непрофессиональных программистов, прежде всего,
за счет более простой технологии работы в среде интерпретатора
и наличия большого числа операторов высокого уровня (графика,
обработка строковых переменных, работа с аппаратурой и пр.).
BASIC — признанный лидер по скорости разработки и отладки
программ. Это качество особенно требуется в тех многочислен-
ных областях прикладных разработок, в которых знание предмет-
ной области является зачастую более важным, чем высокая ква-
лификация программиста.
Поколение
интерпретаторов
GWBASIC
BASICA
Поколение
QuickBASIC
QBASIC
QuickBASIC 2.0, ЯО, 40,45
BASIC Compiler &0
Microsoft BASIC PDS 7.0,7Л.
Поколение
Visual BASIC
Visual BASIC for DOS 10
Visual BASIC for Windows
lo, 2.0, ao, 40,5.o
На сегодняшний день BASIC — самый распространенный
язык программирования для IBM PC. По данным журнала PC
World свыше 70% программистов владеют тем или иным из диа-
лектов BASIC. Но в чем же причина пренебрежительного отноше-
ния к языку BASIC в среде так называемых "профессиональных"
программистов? Дело в том, что в современной практике програм-
мирования язык непосредственно связан со своим процессором
(интерпретатором или компилятором), обрабатывающим его Так,
например, тяжеловесность и громоздкость Turbo BASIC относится
не к самому языку BASIC, а к его программной реализации фир-
мой Borland, а ошеломляющий успех QuickBASIC следует отнести
к интегрированной Quick-среде, появление которой привело к ре-
волюционному перевороту в технике разработке программ.
Разумеется, фирма Microsoft является не единственным разработ-
чиком систем BASIC Существуют также версии GFA, True, Power, Z
и некоторые другие, но они не получили столь широкое распростра-
нение — отношение объема продажи языков BASIC фирмы Microsoft
к реализациями BASIC остальных фирм составляет 12:1.
Позволю себе кратко остановиться на трех поколениях языка
BASIC фирмы Microsoft:
16
этот язык занял достаточно прочные позиции среди средств раз-
работки серьезных прикладных систем. Фактически на сегод-
няшний день QB стал стандартом de facto для языка BASIC.
Первые версии QB появились в 1985 году, последняя, 4.5 —
была создана в 1988. С точки зрения функциональных возможно-
стей QB 4.5 практически идентичен предыдущей версии 4.0
A987 г.), но имеет более удобную среду программирования —
мощный HELP и возможность управлению опциями среды
(цвета, имена директорий и пр.).
В QuickBASIC в достаточно полной мере реализованы идеи
структурного и модульного программирования, возможности ис-
пользования процедур и функций. Наряду с созданием механизма
применения двоичных библиотек, а следовательно и готовых про-
граммных модулей, в том числе, написанных на других языках, это
обеспечило создание достаточно больших программных систем.
Внешне непохожий на традиционный BASIC, QB в очень
высокой степени обеспечивает совместимость на уровне исходно-
го кода с предыдущими версиями (GW, BASICA, Turbo).
Специфика технологии программирования с среде QB опре-
деляется наличием в ней двух трансляторов — интерпретатора и
компилятора. Основу интегрированной среды, в которой выпол-
няется основной объем разработки и отладки программы, состав-
ляет Интеллектуальный редактор и интерпретатор компилирую-
щего типа (ИКТ). ИКТ — это новый тип интерпретатора, кото-
рый производит предварительные "компиляцию и компоновку"
программы в специальный псевдокод, а затем уже ее выполне-
ние. При завершении отладки программы пользователь может со-
здать исполняемый ЕХЕ-модуль с помощью настоящего компи-
лятора и компоновщика программ.
Именно использование интерпретатора определяет высокую
производительность на этапе отладки программы. Запуск про-
граммы на выполнение после исправления ее исходного текста
происходит практически мгновенно. Проблемы тяжелого зависа-
ния программы, после которого требуется перегрузка компьюте-
ра, почти неизвестна пользователям QB.
Что касается эффективности разработки программ (основные
критерии — время разработки и возможность создания сложных
комплексов), то QB имеет явные преимущества по сравнению с
другими реализациями BASIC. Это относится к средствам отлад-
ки, межязыкового общения, технологии конструирования про-
грамм и пр. А ведь это и является основным достоинством
BASIC-программирования. Кроме того, необходимо иметь в виду,
что повышение эффективности конечного кода программы се-
годня определяется не столько встроенными возможностями
18
языковой системы, сколько использованием дополнительных
специализированных инструментальных средств (то, что обозна-
чается термином "Add-on Products").
В QB практически отсутствует возможности по эффективной
адаптации программ к конкретной конфигурации компьюте-
ра — тип процессора, наличие/отсутствие сопроцессора, мо-
дель памяти и пр. Эти вопросы решаются в его более поздних
системах MS BASIC — PDS, Visual.
Безусловно QB 4.5 в значительной степени сохраняет свою
актуальность как средство обучения и-разработки программ на
компьютерах класса АТ286 и ниже, которых в России еще дос-
таточно много. Простая и компактная, по сравнению с совре-
менными пакетами-монстрами, Quick-система может быть ре-
комендована в качестве первого этапа работы для всех, кто
начинает осваивать работу с семейством Microsoft BASIC.
Косвенным признанием сохранившейся популярности систе-
мы является и то, что несмотря на появление PDS и Visual-
систем фирма Microsoft продолжает коммерческую реализацию
QB 4,5 (мировая цена — 99$).
Начиная с версии MS-DOS 5.0, вместо устаревшего GW-
BASIC фирма Microsoft стала поставлять систему QBASIC, кото-
рая представляет собой усеченный вариант QuickBASIC без ком-
пилятора и некоторых возможностей модульного программиро-
вания. Ее русифицированный вариант входит в состав соответ-
ствующей локализованной версии MSDOS 5.0 и 6.x.
QBASIC, конечно, может вполне использоваться для обуче-
ния и написания небольших программок, но не для сколь-нибудь
серьезной работы. И дело здесь не только в невозможности со-
здавать исполняемые модули. В версии QBASIC программа может
состоять только из одного модуля (отсутствует операция LOAD) и
следовательно нельзя загружать и использовать ранее созданные
модули. А на разработке по принципу "напиши по-новой всю
программу от начала до конца" далеко, конечно, не уедешь.
В 1989 году появилась Microsoft Basic Professional Develop-
ment System (система для профессиональной разработки) версии
7.0 , а на следующий год ее сменила версия 7.1, коммерческую
реализацию которой фирма Microsoft ведет до сих пор. В печати
мелькали самые разнообразные сокращенные названия — Basic
Compiler, Microsoft Basic, Professional Basic, QuickBASIC Extended.
Сегодня ее называют Microsoft BASIC или просто PDS. Говоря о
PDS 7.1, необходимо упомянуть также о версии Microsoft Basic
6.0 (иногда для нее используется термин Basic Compiler 6.0), ко-
торая являлась некоторым тупиковым развитием среды версии
4.0, хотя там и были реализованы некоторые идеи, получившие
19
свое законченное воплощение в Basic PDS 7.1. PDS является
дальнейшим логическим развитием QB 4.5 и в этом плане назва-
ние QuickBASIC Extended (расширенный) вполне оправдано.
Краткая характеристика Basic PDS, по сравнению с QB 4.5,
заключается в следующем: он позволяет создавать более мощные
программные комплексы и расширить круг решаемых задач за
счет использования дополнительных возможностей процессора и
оперативной памяти, новых средств разработки программ, встро-
енной системы управления большими базами данных, а также
повышения эффективности программного кода (объем памяти,
быстродействие). Кроме новых возможностей, в PDS исправлены
ряд ошибок QB, в частности, нет проблем с вводом прописной
русской буквы "р".
Visual BASIC — третье поколение
языка
Первая версия новой системы Visual BASIC (VB) появилась в
1991 году под лозунгом "теперь и начинающие программисты мо-
гут свободно работать в Windows". Действительно, с точки зрения
языка VB 1.0 даже не полностью поддерживал стандарт QB 4.5, в
нем не было многих дополнительных возможностей PDS 7.1. Но
не это было "изюминкой" продукта. Главное — реализация прин-
ципиально новой логики программирования, причем в тогда еще
довольно экзотической системе Windows. Другой базовой идеей
VB/Win являлась возможность использования средств системы
Windows в форме обращения к ее собственным функциям.
Версия VB/Win 1.0 напоминала скорее действующий макет бу-
дущей среды разработки. И действительно, система "мужала" до-
вольно быстро, усиливаясь за счет как развития среды программи-
рования, так и включения профессиональных элементов языка и
проблемно-ориентированных средств. Уже в 1992 году была выпу-
щена версия 2.0, а летом 1993 — 3.0. К 1995 году была готова вер-
сия 4.0, а в конце 1996 ожидается следующая, 5-я. В 1992 году была
также подготовлена система VB for DOS версии 1.0. В настоящее
время фирма Microsoft поддерживает и развивает Visual BASIC, как
одну из своих основных систем программирования, рассчитанную
для массового и профессионального использования.
Появление VB однозначно связано с популяризацией идей
событийно-управляемого и визуального программирования в сре-
де Windows. В связи с этим прежде всего необходимо отметить,
20
что эти методы программирования не являются достоянием толь-
ко системы Windows. Наиболее простым примером этого факта
является создание VB для DOS. Другое дело то, что в Windows,
более мощной графической среде, эти методы получили возмож-
ность более яркой реализации.
Что касается визуального программирования, то это доста-
точно логичное развитие среды программирования, в которую
включены эффективные средства разработки пользователем диа-
логового интерфейса. Его суть хорошо отражена в рекламе —"те-
перь вы можете создать программу, не написав ни строки кода"
(используя термины — "нарисовать", "передвинуть" и пр.).
Оценивая в целом новые идеи программирования, заложенные
в VB, необходимо отметить, что они касаются в основном проблемы
диалогового интерфейса — проблемы важной, но далеко не един-
ственной при разработке программ. Причем надо иметь в виду, что
по мере роста сложности программы основной объем работы пере-
мещается именно в направлении создания ее прикладной начинки.
Что касается самого языка, то VB является развитием
QuickBASIC, в значительной степени (VB/DOS — полностью)
обеспечивая совместимость "снизу-вверх". Более того, несмотря на
появление новых операторов, в принципе это тот же вариант язы-
ка программирования, с его некоторыми принципиальными огра-
ничениями. Это в первую очередь касается того, что он по-
прежнему остается процедурным, но не объектно-ориентирован-
ным языком. Появление термина OBJECT (объект) в VB в данном
случае вносит некоторую путаницу в представления пользователей,
т.к. в здесь речь идет лишь о элементах управления диалогового
интерфейса (достаточно узком классе общего понятия "объект").
Но что же требуется от программиста, имеющего навык работы
с предыдущими версиями BASIC фирмы Microsoft для полноценно-
го использования новых возможностей, предоставляемых версией
Visual? Ни много ни мало — изучить новый язык. Именно новый,
поскольку объектные конструкции Visual интерфейса мало похожи
на "человеческий язык", столь милый сердцу приверженцев BASIC,
а более напоминают "инопланетные" конструкции С или Pascal.
О чем же эта книга ?
Речь в ней пойдет о системе программирования Quick-BASIC
версии 4.5 (в дальнейшем просто BASIC), выпущенной в свет в
1988 году, вы можете спросить, стоит ли работать на версии
восьмилетней давности? Да, несомненно стоит. Начните хотя бы
21
потому, что овладев этой системой, вы без труда освоите более
сложные версии — от Microsoft BASIC Professional Development
System 7.1 (Система Microsoft BASIC для профессиональной раз-
работки — тема следующей книги1) до Visual BASIC for Windows
5.0 (визуальный BASIC для Windows — впрочем автор отнюдь не
является поклонником всяческих "форточек", предпочитая ус-
пешно работать в старой доброй DOS). Все реализации BASIC
фирмы Microsoft имеют сходный интерфейс, набор команд и, что
самое главное, исходные тексты Ваших программ могут быть лег-
ко перенесены в другие реализации BASIC фирмы Microsoft.
Сила языка BASIC заключается в том, что любую мысль
можно просто и ясно изложить, используя встроенные средства
программирования, а если их недостаточно — из BASIC всегда
можно обратиться к прерываниям DOS или подключить библио-
теку на ассемблере или на другом языке. Все это будет описано в
книге в соответствующих главах. Начните работать с языком
BASIC — и вы не откажитесь от него никогда.
Глава первая "Среда программирования" вводит вас в увлека-
тельный мир языка QuickBASIC.
Вторая глава "Основы языка" дает общее представление о
BASIC как языке программирования.
Главы с 3 по 11 подробно рассказывают о операторах, функ-
циях и структурах языка, сгруппированных по функциональным
группам.
Глава 12 посвящена работе с прерываниями DOS, расширя-
ющих стандартные средства QuickBASIC.
В приложениях подробно рассказано о клавишах запуска,
редактирования, отладки программы, ограничениях QuickBASIC,
кодах ошибок, другой литературе, посвященной языку BASIC.
Книга составлена таким образом, что может быть использо-
вана и как учебник по языку BASIC для начинающих, и как
справочник для более опытных пользователей. Те разделы, кото-
рые можно опустить при первом чтении книги, помечены симво-
лом (*) — это значит, что к ним можно вернуться позднее.
Автор выражает свою признательность координатору ассоци-
ации пользователей Microsoft BASIC Андрею Александровичу
Колесову за ряд ценных замечаний по содержанию рукописи
этой книги, а также за любезное разрешение воспользоваться
материалами по истории развития языка BASIC.
1 "Microsoft BASIC Professional Development System 7.1", M. ABF, 400 с
"Библиотеки языка BASIC", M. ABF, 400 с.
22
СРЕДА
ПРОГРАММИРОВАНИЯ
"BASIC — это питон, пожирающий все на своём пути. BASIC
только что закончил "переваривать" язык PASCAL со всеми его уп-
равляющими структурами. После небольшой паузы и нескольких
отрыжек он будет в состоянии "слопать" PROLOG, так что скоро
мы увидим варианты языка BASIC со встроенным механизмом до-
казательства теорем методом резолюций ..."
Р. Форсайт
Программы и компьютеры...
Любое электронное устройство, построенное человеком, вы-
полняет одну общую функцию — преобразование информации в
том или ином виде. Но до изобретения персонального компьютера
каждое устройство выполняло только одну, изначально заложен-
ную в нем функцию. Разговаривая по телефону, вы могли только
мечтать увидеть лицо собеседника, смотря телевизор — иметь воз-
можность получить фотографию понравившейся "звезды", а слу-
шая магнитофонную запись — составить собственную программу
из понравившихся песен.
Напротив, персональные компьютеры — это устройство для
универсальной обработки информации — достаточно только напи-
сать точную инструкцию (последовательность) тех действий, кото-
рые нам нужны. Словесное описание таких действий называется
алгоритмом, а сама последовательность действий носит название
программы. Совокупность программ — программное обеспечение.
Существует несколько категорий программ, границы между
которыми достаточно условны, но принято выделять три боль-
шие группы программного обеспечения:
• Системные программы — выполняют вспомогательную роль: уп-
равление ресурсами компьютера, передача команд на перифе-
рийные устройства, сервисное обслуживание, например копиро-
вание файлов, создание резервных копий, проверку работоспо-
собности компьютера в целом или отдельных его частей.
• Прикладные программы — это те, с которыми пользователь
сталкивается каждый день — программы редактирования тек-
стов, графические редакторы для подготовки иллюстраций,
бухгалтерские программы для ведения хозяйственного учета и
многие другие. Это самый многочисленный класс программ-
ного обеспечения.
• Системы программирования — наиболее интересный класс
программного обеспечения. Ведь именно с помощью систем
программирования создаются новые программы. Об одной из
таких программ — QuickBASIC 4.5 рассказывается в этой
книге. При наличии десятков тысяч прикладных программ,
каждый из нас сталкивался с ситуацией, когда существующие
программы его не удовлетворяют, или делают что-то недоста-
точно быстро или неэффективно. В этой ситуации един-
ственный выход — написание собственной программы.
Программы дт персональных компьютеров
Системные
программы
I
Прикладные
программы
Системы
программирования
24
...Давным-давно, когда DOS 3.20 еще была новинкой, a IBM
и Microsoft были друзьями, автору попался электронный вариант
книги Р. Джордейна "Справочник программиста IBM PC". Она
занимала на диске более 500 КВ и сразу же возник вопрос: как ее
распечатать. Это сейчас есть "русский народный текстовый про-
цессор "Лексикон" имени Е. Веселова" , запросто решающий эти
проблемы, а в те времена он еще только завоевывал заслуженную
славу. Сложность заключалась в том, что имелась рулонная бума-
га, и надо было распечатать текст так, чтобы сгибы листов были
пропущены. Под рукой у автора имелся только горячо любимый
BASIC (тогда еще QuickBASIC 4.0). Данная программа приведена
ниже. Она печатает 63 строки на странице, а затем — 8 пустых
строк. С косметическими изменениями, под названием
"Форматель" она благополучно дожила до наших дней.
1 все переменные целые
DEFINT A-Z
1 определяем константы:
'число строк на странице = 63, пустых строк = 8
CONST LinesOnP'age = 63, BlankLines = 8
'определяем Счетчик страниц
Count = 1
'устанавливаем черный цвет символов на бирюзовом
'фоне и очищаем экран
COLOR 0, 3: CLS
1 выводим на экран список всех файлов с расширением
'"bas", после этого выводим на экран пустую строку
FILES "*.bas": PRINT
'Вводим имя файла и выводим на экран пустую строку
1 а также напоминание о начале печати и ждем
1 нажатия любой клавиши
INPUT "Введите, имя файла "; Filename$: PRINT
PRINT "Установите сгиб у печатающей головки принтера..."
DO: LOOP WHILE INKEY$ = "": PRINT
1 открываем файл для считывания
OPEN Filename$ FOR INPUT AS #1
'начинаем бесконечный цикл DO-LOOP. Выход из него по
'наступлению конца файла
DO
FOR i = 1 ТО LinesOnPage
'проверяем не наступил ли конец файла,
'и если наступил, то уходим отсюда
IF EOF(l) THEN EXIT DO
'считываем строку из файла и выводим на
25
"печать оператором LPRINT
LINE INPUT #1, line$: LPRINT line$
NEXT i
FOR i = 1 TO BlankLines
1 печатаем заданное количество пустых строк
1 чтобы пропустить сгиб листа
LPRINT
NEXT i
LOOP
'очистим экран, закроем файл и закончим программу
CLOSE #1: CLS : END
Таких примеров можно привести множество. "Невозможно
объять необъятное", и поэтому всегда возникают ситуации, когда
готовые программы не обеспечивают тех возможностей, без кото-
рых их эксплуатация бессмысленна.
Еще один пример. До "полной и окончательной победы"
альтернативной кодировки символов, в которой русским буквам
соответствуют символы с кодами 128-175 и 224-241, существовала
так называемая основная кодировка ГОСТ (русские буквы 176-
241), в которой на месте символов псевдографики были русские
буквы. Для экрана можно было подобрать подходящий русифи-
катор, но что делать, если надо распечатать текст, набранный в
альтернативной кодировке на принтере, в котором "зашита" ос-
новная кодировка7 Конечно, написать маленькую программу!
1 все переменные целые
DEFINT A-Z
'открываем файл с текстом
OPEN "ascil.doc" FOR INPUT AS #1
'читаем строки из этого файла, пока он не кончится
WHILE NOT EOF(l)
LINE INPUT #1, AlterLine$
1 определяем длину этой строки
AlterLen = LEN(AlterLme$)
1 открываем цикл и проверяем каждый символ в строке
'при необходимости перекодируем и присваиваем
'переменной OsnLme$
OsnLine$ = ""
FOR i = 1 ТО AlterLen
Symbol = ASC (MID$ (AlterLme$, i, 1))
SELECT CASE Symbol
CASE 128 TO 17 5 'это символы от А до п
OsnLme$ = OsnLme$ + CHR$ (Symbol + 48)
CASE 176 TO 223 'это символы псевдографики
26
OsnLme$ - OsnLme$ + " "
CASE ELSE 'иначе перекодирование не нужно
OsnLme$ = OsnLine$ + CHR$ (Symbol)
END SELECT
NEXT l
'печатаем строку символов
LPRINT OsnLme$
WEND
1 закрываем файл, очищаем экран и заканчиваем программу
CLOSE #1: CLS : END
А если любопытный читатель, прочитав эту книгу, возьмется
за написание собственной программы — автор будет считать
свою задачу выполненной.
Интерпретатор + Компилятор =
QuickBASIC
Чтобы компьютер мог понять написанную программу, она
должна быть переведена в так называемые машинные коды —
язык, понятный самому процессору (впрочем некоторые про-
граммисты могут читать машинные коды так же легко, как про-
граммы на BASIC). Этот процесс перевода называется трансляци-
ей. Существует два различный подхода к трансляции — интер-
претация и компиляция.
Языки программирования интерпретирующего типа при ис-
полнении программы за один проход переводят в машинные ко-
ды одну строку программы. Понятно, что при большом размере
программы процесс исполнения готовой программы занимает до-
вольно много времени. В тоже время при разработке программ
режим интерпретации очень удобен — любое внесенное измене-
ние сразу же переводится в машинные коды и исполняется.
Языки компилирующего типа, напротив, сначала переводят
весь текст программы в машинные коды, а уже затем полученный
файл может быть запущен на выполнение. Понятно, что отком-
пилированная программа выполняется гораздо быстрее (в 5-10
раз), но при наличии ошибок редактирование, компилирование,
исправление ошибок на этапе компиляции, опять редактирова-
ние, и так до тех пор, пока все ошибки не будут устранены, за-
нимает очень много времени при разработке программ.
Интерпретатор можно сравнить с синхронным переводчиком
(транслятором) — вы слышите перевод сразу же, а компилятор —
27
с переводчиком, скажем, художественной литературы, — вы чи-
таете книгу сразу на понятном языке, что более удобно, чем пе-
реводить книгу строка за строкой.
Что же мы имеем в результате? И интерпретатор и компи-
лятор имеют и свои достоинства и недостатки. Но теперь у
нас есть QuickBASIC — уникальная среда программирования,
сочетающая в себе достоинства и интерпретатора и компиля-
тора одновременно!
В нем содержатся два транслятора. При подготовке програм-
мы интерпретатор компилирующего типа (ИКТ) выполняет каж-
дую команду почти также быстро, как если бы программа была
скомпилирована. Дело в том, что при вводе текста Ваша про-
грамма переводится в псевдокод сразу же, как только вы перево-
дите курсор на другую строку, и к тому времени, как вы собирае-
тесь запустить программу на выполнение — она уже готова для
работы. Законченные программы могут быть скомпилированы в
автономные .ЕХЕ программы либо внутри Quick-BASIC, либо из
отдельного компилятора, управляемой из командной строки
DOS.
Начинаем работу... или что нужно для начала
Пакет QuickBASIC записан на 5 дискетах по 360 КВ. Для ус-
тановки его на жесткий диск необходимо запустить программу
SETUP.EXE, которая находится на первом диске под названием
"Setup/Microsoft QB Express"
Для своей установки Microsoft QuickBASIC милосердно тре-
бует всего 1.8 М на жестком диске, что навевает тоску по тем
славным временам, когда фирма Microsoft оправдывала лозунг:
I Не Microsoft, а маленькие программы по-русски! |
Представьте себе: Следующая версия языка — Microsoft
BASIC PDS 7.1 требует для своей установки 14 MB, а последняя
версия — Visual BASIC for Windows 5.0 "изволит откушать" как
минимум 60 Mb от Вашего диска, да еще потребует процессор
Pentium с тактовой частотой не ниже 133 для нормальной работы.
Ах "форточки", "форточки"...
28
Microsoft (R) QuickBASIC 4.50 Setup Progran
Copyright (C) Microsoft Corp 1988. fill rights reserved.
Setup uill install QuickBASIC on your systen by
» Copying progran files
¦ Setting display options
¦ Copying needed systen files
Note: QuickBASIC requires up to 1.8 Megabytes on your hard disk.
If you need to free up sone disk space before proceeding, exit nou.
When you're
ready
Use UP and DOUN arrou keys to highlight your choice, then press ENTER,
or Just type the letter that appears to the right of your selection.
Программа установки запишет следующие файлы:
EXAMPLES\
ADVR_EX\
qb. exe
qb.ini
qb.plf
qb.bi
qb.qlb
qb.lib
be.exe
Директория, где находятся файлы с примерами,
иллюстрирующие возможности Quick-BASIC
Директория, где находятся файлы для системы
оперативной подсказки
Среда для разработки программ Microsoft
QuickBASIC (QB)
Файл конфигурации среды
Файл для запуска QB из под "Windows"
Включаемый файл для работы с системными
вызовами DOS
Quick-библиотека, содержащая процедуры под-
держки системных вызовов DOS в среде QB
Библиотека для компиляции программ, содер-
жащих системные вызовы DOS
Компилятор BASIC Compiler, вызываемый ко-
мандой "Маке ЕХЕ Н1е"(Сделать ЕХЕ Файл),
может также запускаться из командной строки
DOS
29
lib.exe
link.exe
brun45.lib
bcom45.lib
bqlb45.1ib
brun45.exe
noem.obj
smallerr.obj
qb45qck.hlp
qb45ener.hlp
qb45advr.hlp
demol.bas
demo2.bas
Программа Microsoft Library Manager служит
для создания библиотек (.LIB), необходимых
исполняемым файлам
Компоновщик Microsoft Overlay Linker служит
для создания исполнимых файлов и Quick-
библиотек (QLB)
Библиотека времени выполнения для создания
исполняемых файлов. Файлы, созданные с ис-
пользованием этой библиотеки требуют для
своей работы BRUN45.EXE (EXE requiring
BRUN45.EXE)
Альтернативная библиотека времени выполне-
ния для создания исполняемых файлов. Файлы,
созданные с использованием этой библиотеки
не требуют BRUN45.EXE для своей работы.
(Stand-Alone EXE file)
Библиотека с процедурами поддержки, исполь-
зуемых при создании Quick-библиотек
Библиотека для работы исполняемых файлов,
откомпилированных с опцией "EXE requiring
BRUN45.EXE" (EXE
(NO EMulation) При компоновке программ с этим
объектным файлом из получаемого исполнимого
файла удаляется эмуляция математического сопро-
цессора, поэтому полученная программа будет ра-
ботать только на машине с сопроцессором, но зато
уменьшается размер исполнимого файла
Файл для компоновки программ, которые не тре-
буют детальных сообщений при ошибках выпол-
нения, что сокращает размер исполнимого файла
Файлы оперативной подсказки
Файлы оперативной подсказки
Файлы оперативной подсказки
Демонстрационная программа звуковых эффек-
тов, написанная для BASICA
Та же программа, написанная для QuickBASIC 2.0
30
demo3.bas
remline.bas
torus.bas
sortdemo.bas
qcards.bas
qcards.dat
mouse.com
Она же, но для QuickBASIC 4.0 (и выше)
Программа на QuickBASIC, которая удаляет не-
нужную нумерацию строк из программ на BASICA
(в QuickBASIC нумерация строк НЕ нужна)
Графическая демонстрационная программа, ис-
пользующая переопределение цветовой палитры
Программа, иллюстрирующая различные алго-
ритмы сортировки
Служебный файл обучающей системы
Служебный файл обучающей системы
Драйвер "мыши" Microsoft Mouse
После окончания установки QuickBASIC вы можете запус-
тить довольно милую обучающую программу LEARN.COM, ко-
торая находится на первом диске "Setup/Microsoft QB Express"
1_[
> Press PgDn to continue.
QuickBASIC Express поможет получить первое представление
о работе в среде QB, расскажет о порядке запуска QB, покажет
основные компоненты среды, научит загружать, редактировать, и
выполнять программу, сохранять результаты работы.
31
Знакомимся со средой программирования
Для запуска среды программирования QuickBASIC 4.5 перей-
дем в директорию C:\QB45 и запустим файл QB.EXE. Нашему
взору предстанет картинка, подобная той, что изображена на ри-
сунке ниже.
Среда QB может работать в двух режимах:
Режим сокращенного меню — (о нем, в частности, рассказыва-
ет обучающая программа), который больше подходит для бег-
лого знакомства со средой, так как в нем опущены многие
важные пункты меню, такие как работа с модулями, с quick-
библиотеками, урезано меню "DEBUG" (ОТЛАДКА) и т. д.;
Режим полного меню — о котором повествует эта книга. Когда
этот режим включен, то в меню "OPTION" (ОПЦИИ) в пун-
кте "Full Мепи"(Полное меню) стоит точка " • " Для включе-
ния режима полного меню нажмите комбинацию клавиш
32
{ALT-O, F}. Для этого нажмите клавишу {ALT}, затем, не от-
пуская ее, клавишу с буквой {О} (здесь и далее при работе с
меню подразумевается нажатие клавиш с латинскими буква-
ми). Отпустите обе клавиши и нажмите клавишу с буквой {F}.
1. Строка Главного Меню. Имена означают соответствующее
меню. Чтобы войти в нужное меню нажмите клавишу {ALT} и
соответствующую букву меню или подведите курсор "мыши"
и нажмите правую кнопку;
2. Курсор. Он показывает, в каком месте будет напечатан следу-
ющий вводимый символ. Может выглядеть как мигающий
символ подчеркивания "_" (режим вставки — вновь вводимые
символы раздвигают уже напечатанные) или как мигающий
прямоугольник " " (режим замещения — вновь вводимые сим-
волы затирают уже напечатанные);
3. Рабочее окно. Именно в рабочем окне вводится и отлаживает-
ся текст программы. При разработке большой программы
иногда может оказаться полезным работать с двумя частями
программы одновременно. Нажмите {ALT-V, Р} (меню
"VIEW" (ПРОСМОТР), пункт "Split" (Разделение) и рабочее
окно разделится на два, в каждом из которых можно работать
со своей частью программы. Для перехода между разделен-
ными окнами и окном для немедленного выполнения служат
клавиши {F6} и {SHIFT-F6};
4. Строка заголовка. Содержит имя файла (или процедуры), ко-
торый находится в рабочем окне. Чтобы сменить процедуру
или модуль нажмите клавишу {F2}.
5. Курсор манипулятора "мышь". Показывает экранную позицию
"мыши". С помощью мыши также можно работать с меню.
Чтобы открыть меню, подведите курсор мыши к нужному
пункту Главного меню и нажмите правую кнопку мыши. При
работе с текстом программы нажатие левой кнопки "мыши"
вызывает контекстную подсказку на тот оператор BASIC, на
который указывает "мышиный" курсор (впрочем, гораздо
удобнее нажать клавишу {F1}).
6. Указатель увеличения. Распахивает рабочее окно на весь эк-
ран. Предназначен только для работы с "мышью" и практи-
ческого значения не имеет.
7. Указатель прокрутки. Показывает относительное место курсо-
ра в модуле или процедуре. Если текст модуля или процедуры
достаточно длинный, то указатель прокрутки можно переме-
33
щать "мышью". Смысл этого перемещения примерно такой,
какой бывает, когда открываешь толстую книгу "на глазок" —
указатель прокрутки выполняет роль большого пальца. Под-
ведите "мышиный" курсор к указателю прокрутки, нажмите
правую кнопку "мыши", и, не отпуская ее, перемещайте кур-
сор по линейке прокрутки вверх или вниз. Аналогичные кла-
виатурные команды гораздо приятнее — можно просто не-
сколько раз нажать клавишу {PGDN} или {PGUP}. А для пе-
рехода в начало текста модуля или процедуры — {CTRL-
HOME}, в конец - {CTRL-END})
8. Линейки прокрутки. Предназначены для передвижения указа-
теля прокрутки;
9. Окно для немедленного выполнения (Immediate). Для входа в
него нажмите клавишу {F6}. Операторы BASIC сразу выпол-
няются после нажатия клавиши {ENTER}. Очень удобно ис-
пользовать при отладке: оборвав выполнение программы,
можно изменить значение какой-либо переменной, и пустить
программу дальше, либо проверить правильность выполнения
небольшого участка кода. Это идеальное место для экспери-
ментов с цветом или музыкой — введите в окне Immediate
следующий фрагмент и нажмите {ENTER} — "тоска по нос-
тальгии" сразу охватит вас:
PLAY Mtl20o218g4.p8g>c4<g.ab4e.ea4g.fg4c."
PLAY "cd4d.ef4f.g7a4b.>cd2"
Вы заинтересовались? Тогда продолжение:
PLAY "<g>e4d.cd4<g.g>c4<b.ab4e.ea4g.fg4c.c>c4<b.ag2"
10. Строка контекстных подсказок. Показывает текущие значения
функциональных клавиш.
11. Индикаторы нажатия специальных клавиш: AQ — Появляется,
когда вводится последовательность команд редактора
WordStar. AK — Появляется, когда устанавливается маркер
места. ЛР — Появляется, когда вводятся специальные управ-
ляющие символы.
12. Индикаторы нажатия клавиш-переключателей: С — Появляет-
ся, когда нажата клавиша CAPSLOCK. N — Появляется, ког-
да нажата клавиша NUMLOCK.
13. Счетчик строк и столбцов. Показывает текущую позицию кур-
сора в активном окне.
34
При работе со средой QB можно использовать "мышь". Что-
бы указать пункт меню, можно подвести к нему курсор "мыши"
и нажать правую кнопку. Но удобнее использовать клавиатуру.
Нажатие клавиши {ALT} и первой буквы меню вызывает его от-
крытие, а для перемещения по диалоговым окнам (например при
загрузке файла или при его сохранении служат клавиши {TAB}
(движение вперед) и {SHIFT}{TAB} (движение назад).
Для наиболее часто используемых операций можно исполь-
зовать клавиатурные сокращения:
{ALT-F, S}
{ALT-F, Ц
{ALT-F, U}
{ALT-F, X}
{ALT-R, X}
{F1}
{F2}
{F4}
{SHIFT-F5}
{CTRL-BREAK}
{F5}
{SHIFT-F9}
{F9}
Сохранение файла программы; осуществляет
выбор пункта "Save"Canncb) из меню "FILE"
(ФАЙЛЫ);
Загрузка файла или документа; осуществляет
выбор пункта "Load File "(Загрузить Файл) из
меню "FILE" (ФАЙЛЫ);
Выгрузка файла или документа; осуществляет
выбор пункта "File Unload"(Выгрузить файл)
из меню "FILE" (ФАЙЛЫ);
Выход из среды QB; осуществляет выбор пун-
кта "ЕхН"(Выход) из меню "FILE"^AKJIbI);
Сделать исполнимый файл; осуществляет Вы-
бор пункта "Маке ЕХЕ РИе"(Сделать ЕХЕ
Файл) из меню "RUN"CAnyCK)
Получение помощи;
Вызвать список процедур и функций;
Посмотреть на результат работы программы;
Запуск программы на выполнение;
Прервать выполнение программы;
Продолжить выполнение после остановки
Установить/снять точку наблюдения;
Поставить/убрать точку прерывания
35
Кратко перечислю назначение пунктов меню:
МЕНЮ FILE (ФАЙЛЫ) — используется для создания новой
программы, загрузки и сохранения программ или частей про-
грамм, печати файлов или частей файлов, использования команд
DOS, выхода из среды QB;
МЕНЮ EDIT (РЕДАКТИРОВАНИЕ) - используется для
стирания, копирования или передвижения текста программы,
отмены последних изменений, создания новой процедуры (SUB)
и функции (FUNCTION);
МЕНЮ VIEW (ПРОСМОТР) — используется для просмотра
процедур (SUB) и функций (FUNCTION), включаемых (INC-
LUDE) файлов, экрана программы;
МЕНЮ SEARCH (ПОИСК) — предназначен для поиска или
замены названий переменных, меток или фрагментов исходного
текста в активном окне, в текущем модуле или во всех загружен-
ных модулях;
МЕНЮ RUN (ЗАПУСК) — используется для исполнения
загруженной программы, продолжения выполнения прерванной
программы, очистки переменных в памяти перед выполнением,
создания исполняемого (.ЕХЕ) файла, определения главного мо-
дуля в многомодульной программе.
МЕНЮ DEBUG (ОТЛАДКА) - используется для отладки
программы путем открытия окон наблюдения, которые показы-
вают, как переменные изменяются при работе программы, уста-
новки точек прерывания, которые прерывают выполнение про-
граммы для того, чтобы вы смогли просмотреть значения пере-
менных. Сам термин "debug" в дословном переводе означает
"обезжучивание". Он пришел со времен ламповых ЭВМ, когда
инженеры не могли отладить программы из-за того, что какой-то
таракан забрался в шкаф с электронной начинкой машины и
замкнул выводы одной из радиоламп.
МЕНЮ CALLs (ВЫЗОВЫ) — меню CALLs показывает после-
довательность вызова процедур из других процедур (стек вложенных
процедур). Если программа не использует вызовы процедур из дру-
гих процедур, то в меню CALLs выводится только имя главного мо-
дуля программы и имя текущей вызываемой процедуры.
МЕНЮ OPTIONS (ОПЦИИ) — используется для: настройки
цветов экрана, установки путей для поиска служебных файлов,
переопределения правой кнопки мыши, Включения/выключения
36
режимов Full Menus (Полное Меню) и Syntax Checking (Проверка
Синтаксиса)
МЕНЮ HELP (ПОМОЩЬ) — Используется для получения
справки по ключевым словам языка BASIC, информации по язы-
жу программирования QuickBASIC, контекстно-зависимой помо-
щи, основанной на месторасположении курсора, дополнительных
инструкций по получению помощи.
Более подробно о каждом из пунктов меню рассказано в
Приложении 1 "Описание Главного Меню QuickBASIC 4.5".
На примере простой программы познакомимся с работой
среды QB. Встроенный редактор среды QB обладает всеми ос-
новными свойствами редактора текстов, а кроме того, является
Интеллектуальным редактором, так как проверяет синтаксис
каждой строки текста, после того, как вы ее введете. Если син-
таксис верен, то строка переводится в псевдокод сразу же, в про-
тивном случае появляется описание возникшей ошибки. Редак-
тор также переводит все ключевые слова в заглавные буквы и ис-
правляет некоторые ошибки и опечатки. Например, если при
вводе строковой константы в операторе PRINT была пропущена
вторая кавычка, то редактор автоматически ее поставит. Введем
следующий текст. Регистр букв, в котором набирается программа,
значения не имеет. После каждой строки нажимайте клавишу
{ENTER}.
CLS
LOCATE 20, 1
PRINT "Добро пожаловать в QuickBASIC 4.5 !"
В первой строке производится очистка экрана оператором
CLS (сокращение от слов CLEAR SCREEN — очистить экран).
Во второй строке — курсор устанавливается на 20 строку, 1
столбец (от слова LOCATE — разместить. В текстовом режиме
экран делится на 25 строк, а каждая строка на 80 столбцов).
В третьей строке происходит вывод на экран сообщения
"Добро пожаловать в QuickBASIC 4.5". (от слова PRINT — напе-
чатать). Обратите внимание, что оператор PRINT производит вы-
вод только на экран. Чтобы вывести это сообщение на принтер
замените PRINT на LPRINT.
Запустим программу на выполнение. Это можно сделать:
1. При помощи линейки главного меню. Для этого нажмите
клавишу {ALT-R}. Будет выделено меню "RUN" (ЗАПУСК).
37
С помощью клавиши {DOWN} подведите выделенную строку
к пункту "Start" и нажмите {ENTER}.
2. При помощи клавиатурных сокращений. Для этого нажмите
комбинацию клавиш {SHIFT-F5}.
В результате выполнения этой простой программы в нижней
части экрана будет напечатано:
Добро пожаловать в QuickBASIC 4.5!
Press any key to continue
С первым сообщением все понятно — в третьей строке про-
граммы было сказано напечатать это сообщение. Второе сообще-
ние выводит среда QB. Оно означает "Нажмите любую кнопку
для продолжения. Нажмем пробел — на экране снова верну-
лась наша программа. Можно продолжать работу над текстом.
Чтобы снова посмотреть на экран программы, можно нажать {F4}
1 По этому поводу хорошо сказал Брайан Ливингстон в своей книге "Секреты
Windows 3 1" — "...Я конечно понимаю, что есть такие люди, которые не найдут
'любую' кнопку ('any key'), когда на экран будет выведено сообщение типа 'Press any
key to continue' (Нажмите любую кнопку для продолжения), или вообще, поняв фразу
буквально, нажмут действительно 'любую' кнопку (имеется ввиду кнопка питания,
перезагрузки или вообще кнопка стоящего рядом телефона) "
38
или выбрать пункт "Output Screen"(Выходной экран) из меню
"VIEW'(nPOCMOTP).
Теперь эту программу нужно сохранить. Выберем пункт
"Save" (Запись) из меню FILE (ФАЙЛ). Вообще, надо взять себе
за правило регулярно записывать программу на диск. Рекоменду-
ется это делать при каждом запуске программы. При каких-либо
сбоях в работе программы, ее исходный текст будет сохранен. Не
забывайте также по окончании работы сохранять копию Вашей
программы на дискете. Как говорит в таких случаях Peter Norton
"BACKUP OFTEN!" (чаще делайте резервные копии).
Для ускорения работы можно нажать комбинацию клавиш
{ALT-F, S}. К счастью, на все часто используемые операции в
BASIC предусмотрены "быстрые клавиши". И в дальнейшем,
описывая действия с линейкой главного меню, автор будет опи-
раться именно на них.
Надо сказать, что по моему глубокому убеждению, использо-
вание мыши в любых текстовых программах является явным из-
лишеством. Все, что необходимо для работы, можно гораздо быс-
трее сделать с клавиатуры. Другое дело — графические "форто-
чки" типа "Windows", которые сами по себе работают настолько
медленно, что в них уже безразлично, чем пользоваться: мышью
или клавиатурой. И вообще — "на иконки надо в церкви смот-
реть, а не на дисплее".
39
Но вернемся к нашему любимому языку BASIC. Мы не при-
своили имя нашей программе, поэтом сейчас самое время это
сделать. На экране появится окно, для ввода имени файла и
формата, в котором его можно сохранить:
Программу в среде QB можно записать в двух различных
форматах:
1. В виде двоичного файла ("QuickBASIC — fast load and save"—
формат QuickBASIC для быстрой загрузки и записи)
2. В виде текстового файла ("Text — readable by other program"—
текстовый формат, понимаемый другими программами)
Автор настоятельно рекомендует сохранять программы в виде
текстовых файлов — это облегчает поиск нужных модулей, упростит
компиляцию программы, а главное, программы, записанные виде в
текстовых файлов можно безболезненно перенести в другие версии
BASIC — от PDS до Visual, хотя, впрочем, программы записанные в
виде двоичных файлов в QuickBASIC 4.5 свободно можно загрузить
в Microsoft BASIC PDS 7.1 (но не наоборот).
Ведите имя файла: TEST (расширение .BAS вводить не обя-
зательно, QB добавит его сам. Нажмите клавишу {TAB}. Курсор
переместится к списку доступных дисков. Нажмите клавишу
{TAB} еще раз, и используя клавиши {UP} и {DOWN}, установите
точку напротив формата Text — readable by other program. Для
подтверждения записи нажмите клавишу {ENTER}.
40
Программа сохранена. Ее название TEST.BAS появилось ни-
же линейки главного меню, где раньше было написано "Untitled"
(без названия).
Покинем гостеприимную среду QB. Для этого нажмем {ALT-
F, X}. Посмотрим, как можно загрузить в среду QB уже готовую
программу. Это можно сделать также двумя способами:
1. Запустим среду QB из командой строки DOS, введя команду
QB.EXE. Загрузим программу TEST.BAS. Для этого введем
команду {ALT-F, L}. Появится окно для загрузки файла, по-
казанное на рисунке.
Нужная нам программа уже есть в списке файлов, поэтому
нажмем клавишу {TAB}. Курсор переместился к списку файлов.
Нажмем клавишу {DOWN} и подведем выделенную строку к
имени TEST.BAS. Осталось нажать клавишу {ENTER}, и про-
грамма загружена.
2. При запуске среды QB можно явно указать имя файла
(расширение также необязательно), например:
С:\QB45>qb test
Если вы пользуетесь программной-оболочкой Volcov
Commander (Copyright (С) Всеволод В. Волков 1994) или Norton
41
Commander (Copyright (С) 1986 to 1993, Symantec Inc.), то добавь-
те в файл vc.ext (nc.ext) строку:
BAS: c:\qb45\qb.exe !.!
Теперь достаточно подвести выделенную строку к имени
программы на BASIC и нажать {ENTER}. Вообще для каждой бо-
лее-менее крупной программной разработки рекомендуется вы-
делять собственный каталог (или директорию — кому как больше
нравится, смысл все равно один), чтобы не путать файлы Ваших
программ со служебными файлам QuickBASIC. Достаточно удоб-
но использовать такую особенность оболочки Volkov Commander
как задание выполнения нескольких команд на одно файловое
расширение. Это может оказаться полезным, например, при
трансляции программы в исполнимый файл (когда вы выбираете
пункт "Make EXE File" (Сделать EXE файл) из меню "RUN"
(ЗАПУСК). Построение ЕХЕ-файла происходит в два этапа. Сна-
чала компилятор ВС.ЕХЕ строит объектный файл (.OBJ), в кото-
ром каждый оператор BASIC заменяется на соответствующий ма-
шинный код, но при этом остаются внешние ссылки, которые затем
компоновщик LINK.EXE замещает исполнимым кодом из соот-
ветствующей библиотеки. После окончания процесса трансляции
объектные файлы уже не нужны. Можно сделать так, чтобы сразу
уничтожать объектные файлы (.OBJ):
BAS: c:\qb45\qb.exe !.!
del *.obj
Как я уже упоминал, Интеллектуальный редактор среды QB
осуществляет синтаксический контроль вводимого текста. Если
строка написана правильно, то после того, как вы перевели кур-
сор на следующую строку, все ключевые слова BASIC будут на-
писаны заглавными буквами, операторы отделены друг от друга.
Это позволяет сразу понять, есть ли в строке ошибки.
Например, вы набираете текст (эта маленькая программка
выводит ASCII-коды1 символов от 32 то 255).
for 1 = 32 to 255:pnnt chr$ (i) ; :next i
После перевода курсора на следующую строку, или при за-
пуске этой программы строка примет вид:
FOR 1 = 32 ТО 255: PRINT CHR$(i); : NEXT l
1 О кодах символах будет подробнее рассказано в следующей главе
42
Если же допущена ошибка с точки зрения синтаксиса языка
BASIC, то будет высвечено диалоговое окно с описанием воз-
никшей ошибки, а курсор установится на место предполагаемой
ошибки. Так, в следующем примере пропущено ключевое слово
THEN в конструкции IF ... THEN.
Если ошибка понятна без разъяснений, можно нажать
{ENTER}. При необходимости уточнений нажмите {TAB} и выбе-
рите пункт "Help" (Помощь)
Кроме синтаксической поддержки редактор QB поддержива-
ет работу с блоками текста. Это бывает полезно, например, при
копировании участков программы между различными модулями
или процедурами.
Для выделения блоков текста используются клавиши:
{SHIFT}+{LEFT}
или {RIGHT}
{SHIFT}+{UP}
или {DOWN}
Будет выделен строчный фрагмент. Для
этого нажмите клавишу {SHIFT}, и, не от-
пуская ее, клавишу-стрелку.
Для выделения прямоугольного фрагмента.
Заметьте, что строки могут входить в фраг-
мент только целиком.
43
Клавиши для работы с выделенным фрагментом:
{DEL}
{SHIFT-DEL}
{CTRL-INS}
{SHIFT-INS}
Стереть выделенный фрагмент "навсегда"
Стереть, но запомнить в буфере (Clipboard);
Запомнить в буфере, не стирая;
Вставить как текст из буфера.
Текст, запомненный в буфере можно вставить в другое место
программы неограниченное число раз.
К числу несомненных достоинств среды QB относится и сис-
тема оперативной подсказки. Чтобы вы не делали, нажав клави-
шу {F1}, всегда можно получить исчерпывающее объяснение. Но
можно и самому найти нужный раздел — нажмите {ALT-H, С}
для входа в Главное меню оперативной подсказки:
Здесь можно получить помощь по всем разделам BASIC. Для
этого подведите курсор к названию нужной темы и нажмите
{ENTER}. Для получения помощи по всем ключевым словам
BASIC нажмите {ALT-H, I}. Если вы подведете курсор к наиме-
нованию функции или процедуры и нажмете {F1}, то получите
параметры вызова, к имени переменной — ее тип, в каком месте
программы она используется. Но самым важным свойством опе-
44
ративной подсказки считается возможность получения помощи
по всем ключевым словам BASIC непосредственно из программы.
Просто подведите курсор к нужному слову и нажмите {F1}. При-
мер подсказки на оператор PRINT приведен на рисунке.
Можно уточнить синтаксис оператора, уточнить детали ис-
пользования, и даже, посмотрев пример, скопировать его в Вашу
программу и модифицировать под собственные нужды.
Вернемся к нашей программе TEST.BAS. Ее можно запустить на
выполнение только из среды QB. Но что делать, если вы хотите запус-
кать вашу программу вне QB? QuickBASIC предоставляет такую воз-
можность. Нужно сделать исполняемый (.ЕХЕ) файл, который сможет
работать непосредственно из командной строки DOS. Загрузите
TEST.BAS в среду QB, как показано выше, и нажмите {ALT-R, X}.
Исполнимые файлы, оттранслированные из среды QB могут
быть двух типов:
• "EXE requiring BRUN45.EXE" — .ЕХЕ-файлы, требующие для
своей работы присутствия BRUN45.EXE, специальной биб-
лиотеки времени выполнения;
• "Stand-Alone EXE File" — автономные .ЕХЕ-файлы, не тре-
бующие для своей работы BRUN45.EXE. Файлы получаются
больше по размерам, чем в первом случае, но обладают луч-
шей переносимостью — чтобы программа работала, ей не
нужны никакие внешние библиотеки.
45
Автор рекомендует пользоваться именно вторым способом
(Stand-alone EXE File), так как автономные .ЕХЕ-файлы не толь-
ко удобнее переносить, но и работают они значительно быст-
рее — ведь программы требующие BRUN45.EXE постоянно об-
ращаются к ней, что сильно замедляет выполнение программы, а
что касается увеличения размеров, то уменьшить его помогают
программы-упаковщики типа LZEXE или PKLITE.
Нажмите два раза клавишу {TAB}, клавишей {DOWN} подве-
дите точку к строке "Stand-Alone EXE File" и нажмите {ENTER}.
После окончания процесса компиляции вы опять вернетесь в
среду QB. Выйдете из нее ({ALT-F, X}). Полученный файл
TEST.EXE можно запускать из командной строки DOS:
C:\QB45>test
Добро пожаловать в QuickBAASIC!
C:\QB45>
Как нам обустроить QuickBASIC (*)
Драйвер русских букв
Первое, что необходимо сделать, после установки
QuickBASIC — установить подходящий драйвер русских букв для
того, чтобы вы могли иметь возможность вводить и видеть на эк-
ране русские буквы.
Выбор подходящего драйвера производите с учетом того, какого
рода задачи вы предполагаете решать с помощью QuickBASIC:
1. Если вы работаете, как и автор этих строк, преимуще-
ственно в текстовом режиме экрана, и не используете графику
высокого разрешения (SCREEN 11 — 640x480x2 цвета и
SCREEN 12 — 640x480x16 цветов), то я могу порекомендовать
очень хороший драйвер:
EN_DRV.COM (v.1.6 (с) 1990 Е. Свиридов)
У него очень красивые округлые экранные шрифты (боль-
шинство снимков экрана в этой книге сделаны при загруженных
шрифтах драйвера EN_DRV) — 8 х 8 и 8 х 14. Переключение
производится при помощи клавиши {правый CTRL}. Раскладка
клавиатурная — стандартная, не меняется.
2. Если вам необходима графика высокого разрешения и
возможность менять раскладку клавиатуры ~ воспользуйтесь
драйвером:
KEYRUS.COM (v8.0_betal6 (с) 1989-1994 Д.Гуртяк)
Этот драйвер обладает уникальными возможностями на-
стройки — можно изменить экранные шрифты1, раскладку кла-
виатуры, изменить цвет рамки, клавишу переключения — и еще
бог знает сколько параметров — нужных и не очень. Причем все
установки записываются в тело самого драйвера, не требуя до-
полнительных файлов.
1 Что я первым делом и сделал, записав в него раскладку и экранные шриф-
ты моего любимого EN_DRV
47
Раскладка клавиатуры может вам пригодится, если вы хотите
иметь возможность вводить русскую букву "р" стандартными
средствами языка' (INPUT, LINE INPUT, INPUTS, INKEY$).
Для изменения раскладки необходимо проделать следующее:
1. Выгрузить раскладку в файл _keys.kbd (предположим, что
файл keyrus.com находится на диске С: в директории UTILS)
С:\UTILS>keyrus /files
2. При помощи редактора клавиатурных раскладок krkeyb.exe
отредактировать файл _keys.kbd как показано на рисунке:
3. Сохраните сделанные изменения в теле драйвера:
С:\UTILS>keyrus /keys=_keys.kbd /save
Чтобы иметь возможность работать с русскими буквами во
всех экранных режимах, необходимо включить поддержку трех
экранных шрифтов:
8x8 (SCREEN I, SCREEN 2, SCREEN 7, SCREEN 8, SCREEN 13);
8x14 (SCREEN 9, SCREEN 10);
8x16 (SCREEN 11, SCREEN 12).
C:\UTILS>keyrus /8x8=on /8xl4=on /8xl6=on /ALL /save
1 Эта проблема подробно обсуждается в главе второй "ОСНОВЫ ЯЗЫКА
BASIC" в разделе "Почему BASIC не выговаривает русскую букву "р"
48
Поставьте здесь
английскую букву "р"
вместо русской р"
Программы-оболочки
Редко кто пользуется для ввода команд непосредственно ко-
мандной строкой DOS — обычно для этой целей используют од-
ну из трех программ-оболочек, получивших наиболее широкое
хождение в ех-СССР:
Название
Volcov
Commander
Norton
Commander
Norton
Commander
Номер
версии
4.00
Share-
ware
3.0
4.0
Copyright
(C) 1991-1995
В.Волков, Киев
(С) 1986, 88, 89, Peter
Norton Computing
(C) 1986 to 1993,
Symantec Inc.
Физичес
кий раз-
мер , Кб
63
136
207
Требуется
памяти,
Кб
91
174
224
При работе в среде QB часто возникает необходимость вос-
пользоваться программой-оболочкой: например, если надо найти
какой-нибудь модуль или скопировать файл и т. д. Запустить
внешнюю программу из среды можно следующим образом:
1. Выбрать пункт "DOS Shell" (Временный выход в DOS) из
меню "FILE" (ФАЙЛЫ) и ввести имя нужной программы. QB
выдаст сообщение о том, что для возврата нужно ввести команду
EXIT, и запустит копию командного процессора COMMAND.
СОМ. Введите имя программы-оболочки в командной строке
DOS:
Type EXIT to return to QuickBASIC
Novell DOS 7
Copyright (c) 1976, 1993 Novell, Inc.
All rights reserved.
C:\QB45>vc
2. В окне для немедленного выполнения Immediate введите
команду SHELL с параметром — именем программы:
SHELL "vc"
49
Для возврата в среду QB достаточно выйти из программы-
оболочки.
При запуске оболочки необходимо учитывать очень важный
момент — они запускаются поверх 278 Kb модуля QB.EXE и ис-
пользуют только ту память, которую BASIC может им выделить
после собственной загрузки, загрузки программы пользователя и
резервирования памяти под переменные и массивы программы —
примерно 150-200 Kb.
Какую оболочку предпочесть? Я пользуюсь Volcov
Commander (VC). Она требует всего 90 Kb свободной оператив-
ной памяти, и ее удается запустить, даже если загружена доволь-
но большая программа. Кроме того, VC позволяет выполнять ко-
пирование и перемещение как каталогов, так и файлов, имеет
менеджер резидентных программ (с возможностью их выгрузки),
позволяет подставлять в командную строку выделенные файлы и
работать с ними, имеет встроенный редактор1, ограниченный
только объемом свободной оперативной памяти, и многие другие
возможности — и все это в .СОМ-файле размером 63 Kb!
Можно пользоваться и NC 3. Все-таки старина третий
Norton — это живая классика. Правда ему может и не хватить
памяти, особенно если загружена большая программа.
Что касается NC 4 — то здесь ситуация однозначная. Четвер-
тый "Петя" так "разжирел, что не вызывается из-под BASIC
ни под каким видом, даже если вы и не загрузили в среду ни
строчки кода.
Переключатель Задач
Очень часто возможностей временного выхода в DOS оказы-
вается недостаточно — бывает очень удобно держать несколько
задач одновременно в памяти и оперативно переключаться между
ними. Например, иметь возможность нажатием одной клавиши
переключатся, скажем, между средой QB, текстовым редактором
и программой-оболочкой.
1 А не внешний, как в NC 4, редактор, который к тому же и не умеет редак-
тировать файлы, превышающие 64 Kb.
2 Злые языки утверждают, что это, а также многочисленные ошибки NC 4,
связанные с обработкой архивов, работой со вложенными каталогами и др свя-
заны с тем, что Автор Norton Commander Джон Соча покинул Peter Norton
Computing, когда та была поглощена корпорацией Symantec, и четвертого Нор-
тона делали уже совсем другие люди ...
50
Робкие попытки сделать это были предприняты компанией
Microsoft в MS DOS 5.0 и 6.0. Я говорю о оболочке DOS SHELL.
Однако ее неуклюжий Windows-подобный интерфейс отпугнул
большинство пользователей (естественно, Norton — forever...).
Но решение проблемы есть. Речь идет об операционных сис-
темах DR DOS 6.00 компании Digital Research и ее следующей
версии, вышедшей под маркой Novell: Novell DOS 7.00.
Наряду с такими преимуществами, как защита от несанкци-
онированного доступа к компьютеру, каталогам и файлам, утили-
ты настройки системных параметров, гипертектекстовый спра-
вочник, в эти операционные системы включена возможность ра-
боты с несколькоми задачами — Переключатель Задач:
В чем же его преимущество по сравнению с другими подоб-
ными системами?
1. Он позволяет переключать задачи непосредственно из коман-
дной строки DOS: {CTRL-1}1 — переключаемся на первую
задачу; {CTRL-2} — на вторую и так далее.
2. Список загруженных задач вызывается нажатием комбинации
клавиш {CTRL-ESC}. При этом для организации новой зада-
чи достаточно нажать клавишу {INS}, а для удаления —
{DEL}. И все! Это вам не бесконечная возня с .INI-файлами
и не подбор установок в .PIF-файлах "методом научного ты-
ка" в Windows. При этом Переключатель Задач занимает
всего 960 байт для каждой загруженной задачи и полностью
использует преимущества расширенной памяти.
3. Novell DOS 7 пошла еще дальше — Переключатель Задач мо-
жет обеспечивать еще и Многозадачность — при этом не-
сколько DOS-задач могут выполняться параллельно. Так как
этот механизм встроен в ядро операционной системы, то все
переключения выполняются быстро, четко и без сбоев.
Обычно хватает возможностей только Переключателя За-
дач — ведь Многозадачность снижает скорость работы программ,
в то время как Переключатель нет, — в каждый момент времени
выполняется только одна активная задача, а остальные мирно
ждут своей очереди на диске или в расширенной памяти.
Я пишу эту книгу в текстовом процессоре "Лексикон" вер-
сии 1.4. Для отладки приведенных примеров переключаюсь в
QuickBASIC 4.5, а для манипуляций с файлами использую Volkov
Commander 4.00. При загруженном Переключателе Задач каждо-
му приложению доступно 623 Kb оперативной памяти. На рисун-
1 Цифры набираются на цифровой клавиатуре
51
ке приведено главное Меню Переключателя Задач Novell DOS
7.00, вызванное нажатием {CTRL-ESQ прямо из QuickBASIC:
Это сгисок активных задач
0В - активная задача
Это главное меню
переключателя задач
Некоторые эстетствующие товарищи могли бы указать автору
на существование Отца Виндоуса с его иконами1, который тоже
может выступать в качестве Переключателя Задач, и даже пы-
таться изобразить Многозадачность. Теоретически да, может,
но... Дело в том, что при запуске DOS-программ Windows только
эмулирует DOS, причем делает это из рук вон плохо. При запус-
ке маломальски сложной программы (а среда QB.EXE без сомне-
ния таковой является) в любой момент времени может возник-
нуть такое вот сообщение...
В переводе на нормаль-
ный человеческий язык это
означает примерно следую-
щее: "А я тут не при чем, это
натворила все она, плохая
программа QuickBASIC 4.5...".
А виновата именно Windows.
Ее громоздкий графический
интерфейс отнимает львиную долю ресурсов процессора. Практи-
чески она работает сама на себя, а прикладным программам доста-
ются "крохи с барского стола". Разве можно себе представить, рабо-
тая в родной и привычной DOS, чтобы такая благовоспитанная
программа, как QB.EXE так "тявкала" на своего хозяина — да ни-
когда в жизни! Причем как нарочно, Windows выкидывает бедный
BASIC обязательно перед сохранением программы на диске, а после
такого сообщения от нее остаются только воспоминания и обида за
бесцельно потраченное время...
This application has violated system integrity
due to an invalid general protection fault and
will be terminated.
Quit all applications, quit Windows, and then
restart your computer.
52
1 Windows & icons
ОСНОВЫ ЯЗЫКА BASIC
Алфавит языка
Основной единицей хранения данных в компьютере является
бит. Бит — это термин, являющийся сокращением от английских
слов binary digit — bit (двоичная цифра — бит). Он может прини-
мать только два значения "О" или " ("включен" или "вык-
лючен"). 8 бит принято называть байтом1. В байте содержится 8
бит, т. е. 8 нулей или единиц, 8 положений "включено" или
"выключено". С помощью математических расчетов легко опреде-
лить, что если у нас имеется 8 каких-нибудь единиц (бит), и каждая
из них может принять значение 0 или 1, то чисто возможных ком-
бинаций в одном байте составит 28, т. е. 256 (от 0 до 255).
В восьми двоичных разрядах умещается 256 целых чисел, что
вполне достаточно для того, чтобы дать уникальное 8-битовое обо-
значение каждой заглавной и строчной букве двух алфавитов, циф-
рам, знакам препинания, служебным символам. Эта таблица полу-
чила названия ASCII-таблица2 (American Standard Coding for
Information Interchange — Американский Стандартный Код для Об-
мена Информацией). Первая половина этой таблицы (стандартная
ASCII-таблица — символы с кодами 0 - 127), стандартизирована, а
вторая половина (расширенная ASCII-таблица) уникальна для каж-
дой страны. У нас вторую половину таблицы описывает Альтерна-
тивная кодировка, в которой русские буквы представлены кодами
128-175 и 223-241. Разрыв в диапазоне представления русских букв,
1 210 байт или 1024 байта — килобайт, Kb
220 байт или 1048576 байт - мегабайт, Mb
2 См. Приложение 5
связан с тем, что на этом месте находятся символы псевдографики,
используемые для рисования рамок и таблиц.
Существует и такая единица информации, как слово. Слово со-
ставляется из 16 бит, т. е. из 2 байт. 16-разрядным словом можно
представить:
• целые числа без знака от 0 до 65535;
• целые числа со знаком от -32768 до 32767.
Вообще говоря, представление чисел — это внутреннее, глу-
боко "интимное" дело самого BASIC, автор упоминает об этом
только потому, что эти числа будут часто встречаться дальше —
они "круглые" для BASIC. Например:
• Длина строки в редакторе QB ограничена 255 символами A байт);
• Целые числа (INTEGER) могут лежать в диапазоне от -32768
до 32767 B байта);
• Размер массива не может превышать 64 Kb F5535 байт —
слово).
Рассмотрим подробнее, какие символы из таблицы ASCII
можно использовать в программах. Набор символов языка Quick-
BASIC 4.5 состоит из следующих символов:
• Все прописные (A-Z) строчные (a-z) буквы латинского алфавита;
• Цифры @-9), а также буквы (A-F) или (a-f) для представле-
ния шестнадцатеричных1 чисел;
• Знаки:
+
-
*
/
плюс
минус
умножение
деление
=
<
>
Л
равно
меньше
больше
возведение в степень
1 В то время, как в привычной нам десятичной счисления каждая последую-
щая цифра больше предыдущей в 10 раз, в шестнадцатеричных числах каждая
последующая цифра больше в 16 раз. У десятичных чисел первая позиция соот-
ветствует единицам, вторая — десяткам, третья — сотням. У шестнадцатеричных
числе первая позиция соответствует единицами, вторая — 16, третья 256 и т. д.
Это означает, что когда в позиции единиц расположение цифра 9, то прибавле-
ние единицы не приводит к переносу в следующий разряд, как это было бы в
случает десятичных чисел. Но как записать десятичное число 10 одной цифрой?
Ответ состоит в том, что шестнадцатеричные цифры используют первые 6 букв
латинского алфавита в качестве дополнительных цифровых символов. Перечис-
ление шестнадцатеричных чисел продолжается так: ... 8, 9, А, В, С, D, E, F, 10
,11 ... 19, 1А, 1В и т. д. В BASIC шестнадцатеричные числа начинаются с симво-
лов "&Н". Например число 255 можно записать как &HFF.
54
Разделители:
)
запятая
точка
двоеточие
точка с запятой
»
(
)
апостроф
открывающая скобка
закрывающая скобка
подчеркивание
Символы объявления типа данных:
%
&
I
#
$
целые;
длинные
обычной
двойной
целые;
точности;
точности;
символьные.
Типы данных
Данные и их типы
Каждая переменная в языке QuickBASIC имеет тип. Тип оп-
ределяет, какие данные хранятся в этой переменной. Существует
две основных категории данных: числовые и символьные. Каждая
категория включает в себя элементарные типы данных, о которых
рассказано ниже.
Числовые типы данных
Числовые данные представляют собой числа. Они бывают
следующих типов: целые, длинные целые, обычной точности,
двойной точности:
Целые (INTEGER) — занимают в памяти 2 байта и исполь-
зуются для значений в диапазоне от -32768 до +32768.
55
Длинные целые (LONG) — 4 байта. Используются для зна-
чений в диапазоне от -2,147,483,648 до +2,147,483,647. Они ис-
пользуются в тех случаях, когда необходимы операции с целочис-
ленными переменными, выходящими за рамки диапазона целых
чисел в представлении BASIC.
Обычной точности (SINGLE) — 4 байта. Используется для
значений в диапазоне от -3.402823Е+38 до -1.40129Е-45 для от-
рицательных значений и от +1.40129Е-45 до -3.402823Е+38 для
положительных значений.
Двойной точности (DOUBLE) — 8 байт. Используется для
значений в диапазоне от 1.797693134862316Е+308 до -4.94965Е-
324 для отрицательных значений и от 4.94965Е-324 до
1.797693134862316Е+ЗО8 для положительных значений. Обычно
применяется для точных математических вычислений, не допус-
кающих потерю значности.
Символьные типы данных
Строка переменной длины (STRING)— это последователь-
ность длиной до 32567 символов из таблицы ASCII. В памяти она
занимает столько байт, какова ее длина + 4 байта на описатель.
Строка фиксированной длины (STRING * num) — символьная
строка длинною num байт. В памяти такая строка занимает num байт.
Пользовательские типы данных (записи)
Если данные, которые вы используете в программе, необхо-
димо сгруппировать по какому-либо признаку, то для этого очень
удобно использовать пользовательский тип данных (записи). Он
составляется из простых типов данных (числовых и символьных),
описанных выше.
Например, нам необходимо ввести табельный номер работ-
ника, его фамилию и тарифную ставку.
'Определим пользовательский тип данных Record
'с помощью оператора TYPE
TYPE Record
TabNomer AS INTEGER
Family AS STRING * 15
Stavka AS DOUBLE
END TYPE
56
'Присваиваем переменной Rabotnik пользовательский тип
'данных Record
DIM Rabotnik AS Record
'Последовательно вводим значение каждого элемента записи
INPUT "Введите табельный номер"; Rabotnik.TabNomer
INPUT "Введите фамилию работника"; Rabotnik.Family
INPUT "Введите тарифную ставку"; Rabotnik.Stavka
Пользовательский тип данных занимает в памяти столько байт,
сколько занимают в сумме каждый из составляющих его элементов.
Для нашего примера запись Rabotnik включает целое число B бай-
та), строку фиксированной длины A5 байт) и число удвоенной точ-
ности (8 байт). Таким образом она имеет размер 25 байт.
Типы данных, определяемые пользователем, могут включать
любые типы стандартных данных, кроме строк переменной дли-
ны и массивов1.
Константы
Константами называются заранее предопределенные значе-
ния, которые не меняются в процессе работы программы. В каче-
стве примера можно привести число PI, основание натурального
логарифма, год Вашего рождения и т. д. Константы удобно ис-
пользовать для тех величин в Вашей программе, которые не
предполагается изменять — число строк, выводимых на экран,
значения функциональных клавиш, и т. д.
В языке QuickBASIC имеются 2 типа констант — неимено-
ванные и именованные.
Неименованные константы
Они бывают символьные и числовые, и используются в
программе в тех случаях, когда их значение заранее известно и не
подлежит изменению.
Символьные константы — это последовательность до 32767 ал-
фавитно-числовых символов (за исключением кавычек (") и симво-
лов перевода каретки и пропуска строки (CR — ASCII 13 и LF —
ASCII 10). Они обязательно должны заключаться в кавычки:
'В пользовательский тип данных Microsoft BASIC PDS 7.1 могут входить и
массивы.
57
"ПРИВЕТ"
11 $ 25,000,000"
"Число работников"
Пример:
PRINT "Средняя заработная плата"
Числовые константы представляют собой положительные или
отрицательные числа. Они могут быть тех же типов, что и пере-
менные — целые или длинные целые типа, обычной или двойной
точности:
Целый тип: 68, +407 , -1
Длинный целый тип: 95000000, -400141
Обычной точности: 9.0846
Двойной точности: 4.35D-10
Пример:
PRINT 15000
Именованные константы
Они также бывают символьные и числовые, тех же типов,
что и неименованные. Чтобы использовать именованную кон-
станту, ее необходимо объявить при помощи ключевого слова
CONST, например:
CONST MaxArray% = 512
В этом примере объявляется целочисленная константа
МахАггау и ей присваивается значение 512. В дальнейшем к этой
константе можно обращаться по имени:
DIM Tovar$(МахАггау)
Символьная константа объявляется и используется аналогично:
CONST BAD$ = "mbtl20o016eeel2c"
PLAY BAD
58
При обращении к именованным константам вы можете
опускать расширение, как показано в этих примерах.
Использование именованных констант имеет ряд преимуществ
по сравнению с использованием для этих целей переменных:
• Однажды определив константу, вы не сможете случайно из-
менить ее значение. BASIC сразу выдаст сообщение об ошиб-
ке "Duplicate Definition" (Двойное определение);
• Именованная константа доступна всем процедурам и функ-
циям данного модуля1. В случае же использования перемен-
ной, вы должны будете объявить ее как SHARED во всех
процедурах и функциях модуля;
• BASIC выполняет операции с константами быстрее, чем с пе-
ременными.
Если подвести курсор к названию именованной константы
где-либо в Вашей программе и нажать клавишу {F1} среда QB
покажет тип и значение этой константы:
Удобно использовать именованные константы для обозначе-
ния функциональных клавиш. Это очень помогает при написа-
нии программ — не надо держать в голове, коды этих клавиш —
вместо этого можно просто написать:
CONST Р1% = 59, F2% = 60, F3% = 61, F4% = 62, F5% = 63
CONST F6% = 64, F7% = 65, F8% = 66, F9% = 67, F10% = 68
SELECT CASE Kod
CASE IS = Fl: ...
CASE IS = F2: ...
CASE F3 TO F9: ...
CASE IS = F10: ...
END SELECT
1 Подробнее см. в разделе "Модульное программирование"
59
Переменные
Переменная — эта величина, которая может меняться при
выполнении программы. Если привести пример из житейской
практики, то можно сказать, что переменная величина, к приме-
ру, сколько у Вас сейчас денег, или ближе к компьютерной прак-
тике, сколько свободного места осталось у Вас на жестком диске.
Переменные бывают простые (символьного типа, числового
типа и пользовательского типа) и переменные массивы — пред-
ставляющего собой группу объектов одного типа.
Имена переменных
Имена переменных могут содержать до 40 символов. В име-
ни переменных могут содержаться латинские буквы, числа, деся-
тичная точка, и символы определения типа (%, &, !, # и $). Пер-
вый символ должен быть латинской буквой. Если переменная
начинается с FN, подразумевается вызов функции1 DEF FN.
Имя переменной не может быть зарезервированным словом
QuickBASIC, хотя допускается комбинация зарезервированного
слова и других символов.
Так, в примере содержится ошибка — LOCATE (разместить)
является зарезервированным словом (без учета регистра):
locate = 7
Однако следующий пример допустим:
LocateCursor = 7
Зарезервированными словами в QuickBASIC являются команды,
операторы, имена функций. Список зарезервированных слов
QuickBASIC и их краткое толкование приведены в Приложении 7.
Давая имена переменным, вы можете комбинировать в них
прописные и строчные буквы. Хотя BASIC не различает пропис-
ные и строчные буквы при работе с переменными, это очень
удобно для программиста, поскольку в имени переменной он
может сделать акцент на ее назначение, например:
1 Подробнее см. в главе третьей главе "Программные конструкции"
60
PrixodSklad% = 1000
ErrorHandler% = 7
DetailName$ = '"Гурбодетандер"
QB внимательно следит за тем, чтобы комбинация пропис-
ных и строчных букв была бы одинакова для всех переменных.
Так, если вы назвали переменную happynewyear, а затем, к при-
меру, обратились к ней, как к переменной с именем
HappyNewYear, то QB сразу же изменит название happynewyear
на HappyNewYear везде, где она встречается.
Переменные числового типа
Переменные числового типа представляют собой, естествен-
но, числа. Они бывают целые (INTEGER), длинные целые
(LONG INTEGER), обычной точности (SINGLE), двойной точ-
ности (DOUBLE):
Целые (INTEGER) — занимают в памяти 2 байта и исполь-
зуются для значений в диапазоне от -32768 до +32768. Присвоить
переменной целый тип можно следующим образом:
а) поставить в начало программы оператор объявления цело-
го типа данных DEFINT' (DEFINED INTEGER):
'объявить переменные в программе (от А до Z) целого типа
DEFINT A-Z
'Переменная Flag - целая, так как она начинается с
'буквы F, которая входит в диапазон A-Z
Flag = 1
б) Явно задать переменную с помощью суффикса "%"
'Переменная Flag% - целого типа
Flag% = 1
в) Использовать оператор описания переменной
1 описываем переменную как целую
DIM Flag AS INTEGER
1 Считается хорошим стилем программирования начинать программу, объя-
вив все переменные целыми, так как выполнение операций над целыми числами
BASIC проводит гораздо быстрее, чем над данными других типов. Если же про-
грамме необходимы данные других типов, воспользуйтесь явным заданием типа
данных при помощи соответствующего суффикса или оператором описания пе-
ременных
61
Длинные целые (LONG) — 4 байта. Используются для значе-
ний в диапазоне от -2,147,483,648 до +2,147,483,647. Они исполь-
зуются в тех случаях, когда необходимы операции с целочислен-
ными переменными, выходящими за рамки диапазона целых чи-
сел в представлении BASIC. Присвоить переменной длинный це-
лый тип можно следующим образом:
а) поставить в начало программы оператор объявления длин-
ного целого типа данных DEFLNG (DEFINED LONG):
'объявить переменные в программе (от В до С)
'длинного целого типа
DEFLNG B-C
'Переменная BisunessTotal - длинная целая, так как
'она начинается с буквы В, которая входит в диапазон В-С
BisunessTotal = 999999999
б) Явно задать переменную с помощью суффикса "&":
'Переменная BisunessTotal& - длинная целая
BisunessTotal& = 999999999
в) Использовать оператор описания переменной:
'описываем переменную как длинную целую
DIM BisunessTotal AS LONG
Обычной точности (SINGLE) — 4 байта. Используется для
значений в диапазоне от -3.402823Е+38 до -1.40129Е-45 для от-
рицательных значений и от +1.40129Е-45 до -3.402823Е+38 для
положительных значений. Если тип числовой переменной не за-
дан (оператором DEFTnn, суффиксом или оператором описания
типа), то она автоматически становится обычной точности1.
1 Это приводит к типичным ошибкам начинающего BASIC-программиста.
Если в начале программы не поставить DEFINT или пропустить суффикс опре-
деления типа переменной, то она считается вещественной обычной точности,
что приводит:
• к значительному замедлению цикла FOR...NEXT, если такая переменная
используется в качестве счетчика цикла (он должен быть INTEGER или LONG
INTEGER);
• потере значности при точных математических вычислениях (DOUBLE не
дает таких ошибок округления);
• снижению скорости работы (иногда в 5-10 раз, особенно на машинах без
сопроцессора) при компиляции такой программы, так как BASIC подключает
библиотеки для работы с числами с плавающей точкой, требующих интенсивных
математических вычислений).
Таким образом, старайтесь избегать использования вещественных перемен-
ных обычной точности. Это окупится более быстрой, точной и аккуратной рабо-
той Вашей программы.
62
Присвоить переменной тип обычной точности можно следу-
ющим образом:
а) поставить в начало программы оператор объявления дан-
ных обычной точности DEFSNG (DEFINED SINGLE).
1 объявить переменные в программе, начинающиеся с буквы S
'обычной точности
DEFSNG S
'Переменная SingleValue - обычной точности, так как она
1 начинается с буквы S
SingleValue = 123.321
б) Явно задать переменную с помощью суффикса "!". Следу-
ет учесть, что поскольку переменная в BASIC имеет тип обычной
точности по умолчанию, то числовая переменная, у которой ука-
зан суффикс "!" и та, у которой этот суффикс отсутствует, счи-
таются одинаковым и не различаются языком BASIC.
'Переменная SingleValue! - обычной точности, она же
'переменная SingleValue
SingleValue! = 123.321
PRINT SingleValue!, SingleValue
Результат:
123.321 123.321
в) Использовать оператор описания переменной
1 описываем переменную обычной точности
DIM SingleValue AS SINGLE
Двойной точности (DOUBLE) — 8 байт. Используется для
значений в диапазоне от 1.797693134862316Е+308 до -4.94965Е-
324 для отрицательных значений и от 4.94965Е-324 до
1.797693134862316Е+308 для положительных значений. Обычно
применяется для точных математических вычислений, не допус-
кающих потерю значности. Присвоить переменной тип двойной
точности можно следующим образом:
а) поставить в начало программы оператор объявления длин-
ного типа данных типа данных DEFLNG (DEFINED LONG):
'объявить переменные, начинающие с буквы D, а также
'входящие в диапазон от М до Р, двойной точности
DEFDBL D, М-Р
63
'Переменная Determinant - двойной точности, так как она
'начинается с буквы D
Determinant = 53.49852432
б) Явно задать переменную с помощью суффикса "#"
'Переменная Determinant* - двойной точности
Determinant* = 53.49852432
в) Использовать оператор описания переменной
1 описываем переменную двойной точности
DIM Determinant AS DOUBLE
Переменные символьного типа
Переменные символьного типа (строки) — могут включать
в себя любые символы из таблицы ASCII. Для присваивания
значения символьной переменной, значение берется в кавыч-
ки. Попутно замечу, что только символьным переменным
можно присваивать значения, содержащие русские буквы
(символы с кодами 128-175 и 224-241 согласно Альтернатив-
ной кодировке).
Символьные переменные бывают переменной длины и фик-
сированной длины.
Строка переменной длины (STRING) — это последователь-
ность длиной до 32567 символов из таблицы ASCII. В памяти она
занимает столько байт, какова ее длина + 4 байта на описатель.
Присвоить символьной переменной тип строки переменной дли-
ны можно следующим образом:
а) поставить в начало программы оператор объявления типа
строки переменной длины DEFSTR (DEFINE STRING):
1 объявить переменные, начинающие с буквы L
'как строки переменной длины
DEFSTR L
'Переменная Language - строка переменной длины, так как
'она начинается с буквы L
Language = "QuickBASIC - навсегда!"
б) Явно задать переменную с помощью суффикса "$":
'Переменная Language$ - строка переменной длины
Language$ = "QuickBASIC - навсегда!"
64
в) Использовать оператор описания переменной:
описываем переменную как строку переменной длины
DIM Determinant AS STRING
Строка фиксированной длины (STRING * num) — символь-
ная строка длинною num байт. В памяти такая строка занимает
num байт.
Присвоить символьной переменной тип строки переменной
длины можно, используя оператор описания переменной:
1 описываем переменную как строку фиксированной длины
DIM Language AS STRING * 10
Language = "QuickBASIC - навсегда!"
PRINT ">";Language;"<"
Результат:
>QuickBASIC<
Переменные пользовательского типа данных
Если данные, которые вы используете в программе, необходимо
сгруппировать по какому-либо признаку, то для этого очень удобно
использовать пользовательский тип данных (записи). Он составляется
из простых типов данных (числовых и символьных), описанных выше.
Например, нам необходимо ввести табельный номер работ-
ника, его фамилию и тарифную ставку.
1 Определим пользовательский тип данных Record
'с помощью оператора TYPE
ТУРЕ Record
TabNomer AS INTEGER
Family AS STRING * 15
Stavka AS DOUBLE
END TYPE
'Присваиваем переменной Rabotnik пользовательский тип
'данных Record
DIM Rabotnik AS Record
1 Последовательно вводим значение каждого элемента записи
INPUT "Введите табельный номер"; Rabotnik.TabNomer
INPUT "Введите фамилию работника"; Rabotnik.Family
INPUT "Введите тарифную ставку"; Rabotnik.Stavka
Пользовательский тип данных занимает в памяти столько байт,
сколько занимают в сумме каждый из составляющих его элементов.
65
Для нашего примера запись Rabotnik включает целое число B бай-
та), строку фиксированной длины A5 байт) и число удвоенной точ-
ности (8 байт). Таким образом она имеет размер 25 байт.
Типы данных, определяемые пользователем, могут включать
любые типы стандартных данных, кроме строк переменной дли-
ны и массивов1.
Сводная таблица описания типов данных
Суф-
фикс
%
&
1
#
$
$
Описание
ASjran
INTEGER
LONG
SINGLE^
DOUBLE
STRING
STRING*
num
Пользо-
ватель-
ский тип
Объявление
DEF_™n
DEFINT
DEFLNG
DEFSNG
DEFDBL
DE.FSTR
Тип переме-
ной
Целая
Длинная
целая
Обычной
точности
Двойной
точности
Строка
переменной
длины
Строка фик-
сированной
длины
Занимаемый
объем
2 байта
4 байта
4 байта
8 байт
Занимает 4 байта
под описатель +
1 байт на каждый
символ в строке
Занимает num
байт
Занимает
столько байт,
сколько зани-
мают в сумме
отдельные эле-
менты
1 В пользовательский тип данных Microsoft BASIC PDS 7.1 могут входить и
массивы.
2 Для тех переменных и констант, тип которых не задан явно оператором
описания типа, принимается тип SINGLE.
66
Переменные-массивы
Если в программе используется группа однотипных пере-
менных (например оценки каждого студента в группе, дневная
температура в течение месяца, и т. д.), то такую группу однород-
ных объектов удобно представить в виде массива переменных.
Отдельные переменные в массиве называются элементами, по-
этому для присвоения им значений можно использовать операто-
ры и функции QuickBASIC.
Каждый элемент в массиве имеет номер (индекс), по кото-
рому можно обратиться к значению элемента. Индекс — число-
вое выражение целого типа. Размерностью называется число ин-
дексов, определяющих элемент массива. Например VA0) — зна-
чение в одноразмерном массиве (векторе), Т$A,4) — двухразмер-
ный массив (матрица).
Количество элементов в массиве называется размером масси-
ва. По умолчанию размер любого массива принимается равным
10 элементам.
Организация массивов в языке BASIC
67
I Объявляется массив из 10-и
DIM A%A0)
' Размерность массива — 1, это вектор
I Присваивание знамения элементу
Эле»*** :'aYmV ' К
массива • А*'. f' ^
А%B) = 4
А%C) - 3
А%D) - 1
А% ( 5 ) "* 2 Значение элемента массива
А%F) - 8
А%G) - б
А%(8) - 9
А%(9) -10
А% A0) - 7
' Индекс элементе, мяпгии^
Каждый массив, используемый в программе, должен быть
заранее объявлен оператором DIM (если размер массива не пред-
полагается менять) или REDIM (если размер массива будет ме-
няться). При объявлении массива можно указывать границы для
его размерностей (верхнюю и нижнюю), например:
'объявляется целочисленный массив с элементами
'А%A0), А%A1), А%A2), А%A3), А%A4), А%A5)
DIM A%A0 ТО 15)
Если массив не будет объявлен до его использования, то при
запуске программы вы можете получить сообщение об ошибке:
"Array not denned" (Массив не определен).
При задании размеров массива вы должны учитывать следу-
ющие ограничения:
• Максимальный размер массива — 65535 байт;
• Максимальное число размерностей — 8;
• Максимальный номер индекса — 32768.
Так, если вы объявляете числовой массив обычной точности,
в котором каждый элемент занимает 4 байта, то максимальный
размер массива, который может быть указан в операторе DIM со-
ставляет 65535 / 4 = 16383. При превышении этого значения
BASIC выдаст сообщение об ошибке "Subscript out of range"
(Индекс вне диапазона). Более подробно об ограничениях BASIC
написано в Приложении 4 "Ограничения QuickBASIC".
Правила использования массива такие же, как и для пере-
менной. Для обозначения отдельного элемента используется имя
массива, за которым следует индекс (или индексы) этого масси-
ва, заключенные в круглые скобки. Объявленный массив "может
иметь любой тип, включая пользовательский.
TYPE TreeNode
LeftPrt AS INTEGER
RightPrt AS INTEGER
DataField AS STRING * 20
END TYPE
DIM TreeE00) AS TreeNode
Каждый элемент в массиве Tree являются записью типа
TreeNode. Для доступа к каждому элементу записи используется
форма:
имя_переменной.имя_элемента
68
'объявляется константа
CONST MAX = 500
TYPE Personal
Nomer AS INTEGER
Name AS STRING * 25
END TYPE
DIM Farmer(MAX) AS Personal
PRINT Farmer(I).Nomer; " ";Farmer(I).Name
Для определения объема памяти под массив, умножьте число
элементов на число байт, занимаемым каждым элементом.
DIM Arrayld TO 100) AS INTEGER
DIM Array2#(-5 TO 5)
В первом случае в массиве Array 1 100 целых элементов. Та-
ким образом он занимает 200 байт A00 *2 ). В массиве Аггау2 11
элементов двойной точности. Занимаемое место в памяти для
массива — 88 байт (И * 8).
Следует учесть, что фактически память отводится больше,
так как QuickBASIC хранит сведения о массиве также в памяти.
Большие динамические массивы (*)
При написании программ иногда возникает необходимость
использовать массивы размером более чем 64 Kb. Такие массивы
называются большими (huge) динамическими массивами. Huge-
массивы могут иметь размер, превышающий 64 Kb ограничение.
Для описания huge-массива необходимо проделать следующее:
1) Загрузить среду QB с опцией /Ah (Array huge)
C:\QB45>qb test.bas /Ah
2) Объявить массив как обычно, при помощи оператора DIM
При этом надо иметь ввиду следующее:
а) Huge-массивы не могут занимать больше 128К памяти, ес-
ли размер индивидуальных элементов не является степенью чис-
ла 2. Например:
TYPE ElementType
a AS INTEGER ' 2 байта
b AS LONG ' 4 байта
с AS SINGLE ' 4 байта
d AS DOUBLE ' 8 байт
e AS STRING * 15 '15 байт
END TYPE 'Всего 33 байта - размер ElementType
69
MaxElement% = 3 971
DIM HugeArrayd to MaxElement%) AS ElementType
Длина записи ElementType — 33 байта, значит массив
HugeArray не может превышать 128 Kb. A28 * 1024 / 33 = 3971)
б) Если же размер элементов является степенью 2
B,4,8,16,32...), то размер Huge-массива ограничен только свобод-
ной оперативной памятью. Однако имейте ввиду следующее —
BASIC — совершенно не "жадный" и может выделить программе
всю доступную память. В результате может возникнуть ситуация,
когда ему самому не хватит памяти для работы, и ошибка "Out of
memory" (Исчерпана оперативная память). Поэтому используя
функцию FRE(-l), выясните, сколько памяти свободно, и оставь-
те QuickBASIC хотя бы 10% на его собственные нужды:
TYPE ElementType
a AS INTEGER '2 байта
b AS LONG '4 байта
с AS SINGLE '4 байта
d AS DOUBLE '8 байт
e AS STRING * 14 44 байта
END TYPE 'Всего 32 байта - размер ElementType
'размер свободной оперативной памяти
FreeMemory& = PRE(-l)
'великодушно берем всего 90%
RealMemory& = .9 * FreeMemory&
'определяем максимальный элемент
MaxElement% = RealMemoryk \ 32
CLS
PRINT "Свободная оперативная память"; FreeMemory&\1024;
PRINT "Kb"
PRINT "Доступная оперативная память"; RealMemoryk \ 1024;
PRINT "Kb"
PRINT "Объявлен массив из"; MaxElement%; "элементов"
DIM HugeArrayd TO MaxElement%) AS ElementType
FreeMemory& = FRE(-l)
PRINT "Осталось оперативной памяти"; FreeMemory& \ 1024;
PRINT "Kb"
Результат:
Свободная оперативная память 241 Kb
Доступная оперативная память 217 Kb
Объявлен массив из 6960 элементов
Осталось оперативной памяти 24 Kb
70
Использование опции /Ah заставляет все динамические мас-
сивы описывать как большие (huge). Доступ к большим массивам
несколько замедлен вследствие обращения к индивидуальным
элементам по дальней ссылке.
Если вы определили переменную с помощью оператора опи-
сания типа или объявления типа, то чтобы узнать тип перемен-
ной, достаточно подвести к ней курсор, и нажать F1 — среда QB
определит тип этой переменой и укажет, в каком модуле, проце-
дуре или функции1 она используется.
Для простых переменных (числовых или символьных) указы-
вается ее тип:
Выражения и операции
Последовательность операций, которые необходимо произве-
сти над данными, чтобы получить требуемое значение называется
выражением. Результатом выражения может быть символьная или
числовая константа, переменная или значение.
В языке BASIC существует пять категорий операций, пере-
численные далее:
1 Подробнее см. в главе третьей главе "Программные конструкции"
71
Для элемента записи пользовательского типа данных, кроме
того, указывается структура записи:
1. Арифметические операции;
2. Операции отношений;
3. Логические операции;
4. Функциональные операции;
5. Строковые операции.
Арифметические операции
В QuickBASIC существуют следующие арифметические опе-
рации, которые перечислены в порядке убывания приоритета
выполнения:
л
+,-
V
\
MOD
+,-
возведение в степень
присвоение знака числу1
умножение, деление
целочисленное деление
остаток после целочисленного деления
сложение, вычитание
Возведение в степень (л)
1 обратите внимание на точку с запятой после оператора
1 PRINT - это позволяет вывести результат на одной строке
INPUT "Введите число "; Number%
INPUT "Введите степень "; Exponent%
PRINT "Степень числа равна ";
PRINT Number% л Exponent%
Пример:
Введите число ? 2
Введите степень ? 5
Степень числа равна 32
Присвоение знака числу (-)
INPUT "Введите число ";Number%
PRINT "Число с обратным знаком будет
PRINT Number%
1 При возведении в степень возникает исключение. Приоритет операции
присвоения знака считается выше приоритета операции возведения в степень.
72
Пример:
Введите число ? -7 5
Число с обратным знаком будет 75
Умножение и деление (*, /)
INPUT "Введите первое число "; Numberl%
INPUT "Введите второе число "; Number2%
PRINT: PRINT "Произведение", "Деление"
PRINT Numberl% * Number2%, Numberl% / Number2%
Пример:
Введите первое число ? 10
Введите второе число ? 5
Произведение
50
Деление
2
Целочисленное деление (\)
INPUT "Введите первое число "; Numberl%
INPUT "Введите второе число "; Number2%
PRINT "Целочисленное деление равняется '
PRINT Number1% \ Number2%
Пример:
Введите первое число ? 54
Введите второе число ? 21
Целочисленное деление равняется 2
Нахождение остатка (MOD)
INPUT "Введите первое число "; Numberl%
INPUT "Введите второе число "; Number2%
PRINT "Остаток от деления равняется ";
PRINT Numberl% MOD Number2%
Пример:
Введите первое число ? 100
Введите второе число ? 33
Остаток от деления равняется 1
Сложение и вычитание (+,-)
INPUT "Введите первое число "; Numberl%
INPUT "Введите второе число "; Number2%
73
PRINT: PRINT "Сложение", "Вычитание"
PRINT Numberl% + Number2%, Numberl% - Number2%
Пример:
Введите первое число ? 43
Введите второе число ? 10
Сложение
53
Вычитание
33
Порядок вычисления выражений
В выражении сначала выполняются операторы более высоко-
го приоритета, затем операторы одного уровня слева направо.
Например:
1 Значение А в этом выражении = 2.5
А = 3 + 6/12 * 3 - 2
Порядок выполнения операторов в этом выражении:
1.6/ 12(= 0.5)
2. 0.5 * 3(= 1.5)
3. 3 + 1.5(= 4.5)
4. 4.5 - 2(= 2.5)
Скобки нарушают естественный порядок вычисления ариф-
метического выражения. Сначала выполняются вычисления в
скобках.
Алгебраическое
выражение
X-Y
г
XY
Z
X + Y
г
X(-Y)
Выражение
в языке QuickBASIC
(X - Y) / Z
X* Y/Z
(X + Y) / Z
X * (-Y)
74
Две связанные операции могут быть разделены скобками.
Это операции *-,*+, А-иА+.В тоже время последнее выра-
жение можно записать в виде X * -Y.
Переполнение и деление на ноль
Если при работе программы возникает деление на ноль
или арифметическое переполнение, то возникают ошибки вы-
полнения "Division by Zero" (Деление на ноль) и "Overflow"
(Переполнение). Их можно отследить, используя операторы
отслеживания событий, о которых будет подробно рассказано
позднее.
Операции отношения:
Эти операции используются для сравнения арифметических
выражений. В QuickBASIC существует шесть операций отноше-
ния, перечисленных в таблице:
-
>
<
о
<=
>=
равно1
больше
меньше
не равно
меньше или
больше или
равно
равно
Операторы отношения используют два значения. Результатом
операции отношения является либо "TRUE" (ИСТИНА — нену-
левое значение2), либо "FALSE" — (ЛОЖЬ — ноль). Управляю-
щие операторы в программе могут использовать результат опера-
ции отношения.
1 Символ "="обозначает не только операцию отношения, но и оператор при-
сваивания
2 Внутреннее представление "TRUE" (ИСТИНА) в QuickBASIC -1 Таким об-
разом, выполнив PRINT 10 > 3 мы получим в результате -1
75
Оператор
=
о
<
>
<=
>=
Значение
Равенство
Неравенство
Меньше
Больше
Меньше или равно
Больше или равно
Выражение в BASIC
X = Y
Х<> Y
Х< Y
X>Y
X<=Y
X>=Y
Если в одном выражении встречаются и арифметические
операторы и операторы отношения, то первыми выполняются
арифметические операторы. Так, в примере, сначала вычисляется
значение выражения X + Y, а затем значение (Т - 1) / Z.
X + Y< (T - 1) /Z
При использовании значений обычной и двойной точности
будьте внимательны, используя операции отношения = и О. Де-
ло в том, что результаты могут отличаться на ничтожно малую
величину, но это может привести к ошибке в Вашей программе.
IF А! = 0.0 THEN PRINT "Точное равенство"
Но в случае, если А! — очень малая величина, например
1.0Е-23, оператор PRINT исполнятся не будет.
Кроме того, .ЕХЕ-программа и программа в среде
QuickBASIC могут давать различные результаты. .ЕХЕ-код более
точен при сравнении чисел обычной и двойной точности. Так,
следующий пример будет выдавать "Равно" в QuickBASIC и "Не
равно" в ЕХЕ.
В! = 1.0: А! = В! / 3.0
IF А! = В! / 3.0 THEN PRINT "Равно" ELSE PRINT "He
равно"
Поскольку .ЕХЕ-файл более эффективно использует микро-
схему сопроцессора (или эмуляцию сопроцессора), то значение
переменной А! и результат выражения В! / 3.0 не совсем тожде-
ственны.
76
Присвойте значение выражения временной переменной, и
вы решите эту проблему. Этот фрагмент работает одинаково и в
среде QuickBASIC и в .ЕХЕ-виде.
В! = 1.0: А! = В! / 3.0
Ттр! = В! / 3.0
IF A! = Trap! THEN PRINT "Равно" ELSE PRINT "He равно"
Если же вам все-таки необходимо сравнение чисел обычной
точности, сравните разницу этих переменных:
В! = 1.0: А! = В! / 3.0
IF ABS(A! - В! / 3.0) < 9.9Е^08 THEN
PRINT "Равно"
ELSE
PRINT "He равно"
END IF
Логические операции
Логические операции осуществляют манипуляции над бита-
ми. По другому они называются "Булевы операции". Они воз-
вращают значения "TRUE" (ИСТИНА — не нулевое значение,
внутренние представление BASIC = -1) и "FALSE" (ЛОЖЬ —
нулевое значение, внутренние представление BASIC = 0 )
IF D < 200 AND F < 4 THEN CALL Process
WHILE I > 10 OR К < 0 ...
WEND
IF NOT P THEN PRINT "Файл не найден"
В QuickBASIC существует шесть логических операторов, на-
звание и толкование которых приведены ниже:
77
Опера-
тор
NOT
AND
OR
XOR
EQV
IMP
Название
Отрицание
Логическое
умножение
Логическое
сложение
Исключающее
ИЛИ
Эквивалент-
ность
Импликация
Объяснение
NOT А истинно тогда и только тогда,
когда А ложно
A AND В истинно тогда и только тог-
да, когда истинно А и истинно В
A OR В истинно тогда и только тогда,
когда хотя бы одно из А и В истинно
A XOR В истинно тогда и только тогда,
когда значения А и В не совпадают
A EQV В истинно тогда и только тог-
да, когда А и В одновременно истин-
ны или одновременно ложны
A IMP В принимает значение "ложь"
если А истинно а В ложно, и значе-
ние "истина" в других случаях.
'В этом примере показана работа со всеми логическими
операторами Qu i с kBASIС:
DECLARE SUB TruthTable (X%, Y%)
DEFINT A-Z
CLS
PRINT " X Y NOT AND OR
PRINT "XOR EQV IMP"
PRINT
I = 10: J = 15
'X = TRUE (-1); Y = TRUE (-1)
X = (I = 10): Y = (J = 15)
CALL TruthTable(X, Y)
'X = TRUE (-1); Y = FALSE @)
X = (I > 9) : Y = (J > 15)
CALL TruthTable(X, Y)
"X = FALSE @); Y = TRUE (-1)
X = (I <> 10): Y = (J < 16)
CALL TruthTable(X, Y):
¦X = FALSE @); Y = FALSE @)
X = (I < 10) : Y = (J < 15)
78
CALL TruthTable(X, Y)
END
SUB TruthTable (X%, Y%) STATIC
PRINT X; " "; Y; " "; NOT X; " "; X AND Y; "
PRINT X OR Y; " "; X XOR Y; " "; X EQV Y;
PRINT " "; X IMP Y
PRINT
END SUB
Результат
X Y NOT AND OR XOR EQV IMP
-1 -1 0-1-10 -1 -1
-10 0 0-1-10 0
0-1-10 -1 -1 0 -1
0 0-10 0 0-1-1
Функциональные операции
Функциональные операции определяют правила работы с
функциями. Функции используются в выражениях для осуществ-
ления заранее определенных операций. Например:
А = SQRB0.25) + SQRC7)
В QuickBASIC существуют два вида функций: встроенные и
определенные пользователем. Примерами встроенных функций
может служить вышеприведенная пример вычисления квадратно-
го корня (SQR), а также синуса (SIN), косинуса (COSI и др.
Встроенные функции более подробно описаны в разделе "Обра-
ботка числовых данных" и "Обработка символьных данных".
Вы можете определить функцию при помощи новой конст-
рукции FUNCTION...END FUNCTION или воспользоваться бо-
лее старой конструкцией DEF...END DEF. Пользовательские
1 Появление синуса и косинуса в тексте нашей книги напоминает старый
анекдот — "Неуспевающий студент приходит сдавать экзамен по высшей мате-
матике и списывает ответ на свой вопрос. Подойдя к профессору, он не может
сказать ни слова по поводу написанного. Но вдруг натыкается на знакомые бу-
ковки — sin Тут он и говорит: "Профессор — а вот и синус, а вот и косинус — и
это все я написал! Мне вполне можно поставить тройку..."
79
функции действуют только в той программе, где они определены
и не являются частью языка (если они не скомпилированы в
Quick-библиотеку). В дополнении к FUNCTION и DEF FN, вы
также можете определять процедуры при помощи конструкции
SUB. О пользовательских функциях рассказано в разделе "Мо-
дульное программирование" этой главы.
Строковые операции
Над строками можно осуществлять следующие действия —
конкатенация (сложение) и сравнение строк.
Конкатенация (сложение) строк
Конкатенация — это сложение двух символьных строк. Для
сложения используется символ (+). В примере результатом сло-
жения переменных А$ и В$ является значение FILENAME.
А$ = "FILE": B$ = "NAME"
PRINT A$ + В$;
PRINT "NEW " + А$ + В$
Результат:
FILENAME NEW FILENAME
Сравнение строк
Сравнение строк производится при помощи операторов срав-
нения: <>, =, <, >, <=, >= Сравнение строк производится в со-
ответствии с ASCII кодами каждого символа в сравниваемых
строках. Если ASCII коды равны, то строки считаются равными.
Строка, символы которой имеют большие ASCII коды, считается
большей. Если одна из сравниваемых строк короче другой, то она
считается меньшей (если до этого места строки были равными).
При сравнении учитываются начальные и конечные пробелы.
Примеры правильных операций сравнения1:
"АА" < "ВБ"
"FILENAME" = "FILE" + "NAME"
1 При сравнении строк, содержащих символы кириллицы следует соблюдать
определенную осторожность, и не полагаться целиком на сравнение средствами
BASIC. Дело в том, что расширенная ASCII таблица содержит вместо символов
кириллицы буквы европейских алфавитов, что может привести к некорректному
сравнению строк.
80
11 Х&" > "Х#"
"фф " > "фф"
"кг" > "КГ"
"СЛОН" < "СЛОНЫ"
В$ < "9-12-78" ' где В$ = "8-12-78"
Сравнение строк можно использовать для оценки их содер-
жимого, если эти строки содержат числа. ASCII коды символов
приведены в Приложении 5.
Операторы передачи управления
При разработке программ часто приходится изменять поря-
док следования операторов. Только в очень простых программах
операторы выполняются один за другим — управление передает-
ся последовательно, от оператору к оператору. На практике же,
необходимые средства для изменения порядка следования опера-
торов, другими словами, передачи управления — обеспечивают
операторы цикла и условные операторы.
Операторы цикла
Циклы используются в том случае, когда вам необходимо не-
сколько раз выполнить один и тот же фрагмент исходного текста.
В BASIC существуют три вида циклов:
FOR...NEXT;
DO... LOOP;
WHILE...WEND
FOR...NEXT
Цикл FOR...NEXT — это цикл с заранее заданным количе-
ством повторений. Можно также выйти из цикла не дожидаясь
выполнение всех повторений — воспользуйтесь альтернативным
выходом из цикла при помощи оператора EXIT FOR. Управление
будет передано на оператор, стоящий после NEXT.
Пример:
1 этот цикл повторяется 5 раз
FOR i% = 1 ТО 5
PRINT "Хорошо живет на свете Винни-Пух!"
NEXT i%
81
Результат:
Хорошо живет на свете Винни-Пух!
Хорошо живет на свете Винни-Пух!
Хорошо живет на свете Винни-Пух!
Хорошо живет на свете Винни-Пух!
Хорошо живет на свете Винни-Пух!
DO...LOOP
Цикл DO...LOOP выполняется до тех пор, пока истинно ус-
ловие в начале или конце цикла. А также из цикла возможен аль-
тернативный выход — вне зависимости от того выполнено ли ус-
ловие выхода, из цикла можно выйти оператором EXIT DO, ко-
торый передает управление на оператор, следующий за LOOP.
Пример:
'этот цикл повторяется до тех пор (DO), пока пользователь
'не введет число, превышающее 10 (LOOP WHILE n <=10) —
'повторять, пока п меньше или равно 10)
DO
INPUT "Введите число N ?"; п
LOOP WHILE n <= 10
WHILE...WEND
При использовании цикла WHILE...WEND условие может
быть только в начале цикла. Альтернативный выход из цикла
WHILE...WEND - невозможен.
Пример:
WHILE n <= 10
INPUT "Введите число N ?"; п
WEND
Условные операторы
Условные операторы BASIC помогают вам осуществить "вет-
вление" программы, т. е. передать управление по условию, на ту
или иную "ветку" — это может быть фрагмент текста, процедура
SUB или FUNCTION, подпрограмма GOSUB...RETURN, или
даже другой модуль. Виды условных операторов BASIC:
IF...THEN...ELSE
SELECT...END SELECT
82
IF...THEN...ELSE
IF...THEN...ELSE обычно используется, когда проверяется
одно или два условия в программе.
Пример:
IP CheckPrinter% = TRUE THEN
PRINT "Принтер готов для работы..."
ELSE
PRINT "У принтера сегодня выходной ..."
END IF
SELECT... END SELECT
Если же необходимо осуществить проверку более сложных
условий, чем ДА/НЕТ, целесообразно использовать условный
оператор SELECT... END SELECT.
SELECT CASE Declaim%
CASE IS = 1
PRINT "Любит ..."
CASE 2 TO 999
PRINT "He любит ..."
CASE IS = 0, IS = 1000, IS < -1
PRINT "Замужем"
CASE ELSE
PRINT "При исполнении ..."
END SELECT
Избегайте устаревших конструкций
Может возникнуть вопрос, почему автор ни словом не об-
молвился про оператор GOTO. Дело в том, что оператор GO-
TO — старейший и неструктурированный оператор языка BASIC.
Программу с обилием GOTO трудно читать, отлаживать, моди-
фицировать, так как она не имеет четкой структуры.
Использование в программе оператора GOTO свидетельству-
ет о том, что программист не полностью овладел всем богатством
управляющих структур языка QuickBASIC, или не знает их воз-
можностей, а кроме того, не существует программных конструк-
83
ций, где действительно было бы необходимо применение опера-
тора GOTO1.
Приведу примеры того, как можно избежать применения
GOTO и других устаревших конструкций, которые достались
QuickBASIC "по наследству" от первого поколения языка
BASIC — интерпретаторов GWBASIC и BASICA2.
Как получить код нажатой клавиши:
ml: А$ = INKEY$: IF А$ = "" GOTO ml
Эту конструкцию можно переписать, используя цикл
DO...LOOP WHILE:
DO: A$= INKEY$: LOOP WHILE A$ =
Как выйти из цикла по условию:
FOR i = 1 ТО 1000
IF Flag% = TRUE THEN GOTO m999
NEXT i
1 Основная теорема структурного программирования, доказанная
Э Дейкстрой гласит: "Алгоритм любой сложности можно реализовать, используя
только три конструкции: следование (оператор за оператором), повторение
(цикл) и выбор (альтернатива)"
2 Фирма Microsoft всегда была очень щепетильна в отношении совместимости
своих программных продуктов Так, QuickBASIC полностью поддерживает все
возможности языков GWBASIC и BASICA, BASIC Professional Development
System — все возможности QuickBASIC. К сожалению, этого нельзя сказать о
последнем поколении ялжа BASIC — Visual BASIC for Windows, который не
поддерживает даже подмножество QuickBASIC.
84
m999:
В этом случае можно воспользоваться альтернативным выхо-
дом из цикла FOR. NEXT - EXIT FOR:
FOR i = 1 TO 1000
IF Flag% = TRUE THEN EXIT FOR
NEXT i
Точно также можно выйти и из цикла DO...LOOP:
DO
IF Flag% = TRUE THEN EXIT DO
LOOP
Предвижу вопрос: а если нужно выйти из середины конст-
рукции WHILE...WEND - ведь оператор EXIT WHILE не пре-
дусмотрен (также как и EXIT SELECTI ? Казалось, бы — ведь в
таких случаях можно просто написать:
WHILE A$ о "Конец"
IF Flag = FALSE THEN GOTO m998
WEND
m998:
1 Вопросы "почему?" направляйте по адресу:
United States of America
Microsoft Corporation
One Microsoft Way Redmond,
WA 98052-6399 (800) 227-4679
85
Я считаю, что и в этом случае применение оператора GOTO
излишним. Конечно, чтобы обойти это ограничение приходится
идти на хитрость — обрамлять конструкцию бесконечным цик-
лом DO...LOOP и выходить с помощью EXIT DO — даже в этом
случае, это гораздо удобнее, нагляднее, и я бы сказал красивее:
DO
WHILE A$ <> "Конец"
IF Flag = FALSE THEN EXIT DO
WEND
LOOP
Также можно организовать и "EXIT SELECT":
DO
INPUT Kod
SELECT CASE KOD
CASE IS = ...
CASE IS = 0: EXIT DO
CASE ELSE ...
END SELECT
LOOP
Как избежать синдрома "ёжика в тумане"
При организации ветвления бесконечные операторы GOTO
мешают понять логику программы:
30 INPUT A
IF A > 100 THEN PRINT "Это много": GOTO 30
IF A = 100 THEN GOTO 3 00
PRINT A/100: GOTO 3 0
300 ...
Вместо этого можно использовать или блочную форму опе-
ратора IF..THEN...ELSE в окружении цикла DO...LOOP WHILE:
DO
INPUT A
IF A < 100 THEN
86
PRINT A / 100
'ELSEIF A > 100 THEN
PRINT "слишком много"
END IF
LOOP WHILE A <> 100
...или конструкцию SELECT...CASE в окружении цикла DO ...
LOOP
DO
INPUT A
SELECT CASE A
CASE IS < 100: PRINT A / 100
CASE IS > 100: PRINT "слишком много"
CASE IS = 100: EXIT DO
END SELECT
LOOP
Как правильно "разветвиться"
При организации ветвления вместо устаревшей управляющей
конструкции ON...GOSUB используйте более современную кон-
струкцию SELECT...END SELECT:
m0: INPUT A
ON A GOSUB ml, m2, тЗ , тЗ , m4, m4, m4
GOTO m5
ml:
X = у * z
RETURN
m2 :
RETURN
m3:
RETURN
m4 :
RETURN
m5: ...
He правда ли, с первого раза трудно понять, что это фраг-
мент программы делает. Приходится проговаривать про себя:
87
"Если значение А равно единице, то ... перейти на метку... метку
ml, вычислить значение X... вернуться на следующий оператор пос-
ле ON...GOSUB ... это переход на метку т5 ... метка т5— это
продолжение выполнения программы..."
Посмотрите, насколько удобнее использование конструкции
SELECT...END SELECT:
INPUT A
SELECT CASE A
•CASE IS = 1:
X = у * z
CASE IS = 2
CASE IS = 3, 4
CASE 5 TO 7
END SELECT
"Если значение А равно единице, вычислить значение X и поки-
нуть SELECT...END SELECT' - и все? - и все!
В разделе "Модульное программирование" речь пойдет о
том, как организовать Вашу программу в виде независимых
структур — процедур SUB и FUNCTION, функций DEF FN и
подпрограмм GOSUB...RETURN — объединенных в один или
несколько модулей. При первом чтении этой книги вы можете
пропустить этот раздел, и вернуться к нему позднее.
Ввод и вывод значений
Ввод значений
После того, как вы определились с тем, переменные каких
типов вы будете использовать в программе, им необходимо при-
своить начальные значения.
Если значений не много, можно использовать операцию
присваивания:
Message$ = "Внимание!"
Total = 555
Можно использовать константы:
CONST Message$ = "Внимание!", Total = 555
Для большого количества переменных можно использовать
оператор DATA:
DATA "Лена", 1976, "Катя", 1975, "Оля", 1980
READ Girll$, yearl$, Girl2$, year2$, Girl3$, year3$
Эти способы удобно использовать в тех случаях, когда про-
грамме нужны фиксированные, заранее заданные значения. А ес-
ли нужно менять значения по ходу работы программы? Вносить
изменения в текст программы при каждом изменении — не са-
мый лучший выход.
INPUT
К счастью, в BASIC существует оператор INPUT, который
позволяет запросить у пользователя значение необходимой пере-
менной.
1 Введенное с клавиатуры имя присваивается
1 переменной Fam$
INPUT "Введите ваше имя "; Fam$
'Результат выводится на экран
PRINT "Здравствуйте, товарищ "; Fam$; "!"
Результат:
Введите ваше имя ? Петя
Здравствуйте, товарищ Петя!
Можно ввести одновременно значения нескольких переменных,
при этом значения должны отделяться запятыми. Тип вводимых зна-
чений должен соответствовать типам переменных, перечисленных в
операторе INPUT, иначе BASIC выдаст сообщение "Redo from start"
(Начните сначала). Нажатие клавиши {ENTER} заканчивает ввод.
89
INPUT "Введите имя и год рождения "; Fam$, уеаг%
PRINT Fam$; ", вы родились в"; STR$(уеаг%); "году."
Результат:
Введите ваше имя и год рождения ? Вася, 1977
Вася, вы родились в 1977 году.
LINE INPUT
Так как вводимые значения в операторе INPUT должны от-
деляться запятыми, при помощи него нельзя ввести строку сим-
волов, например фразу, в которой содержатся запятые, — BASIC
воспримет их как разделитель.
В этом случае используется оператор LINE INPUT:
LINE INPUT "Введите ключевую фразу "; frase$
PRINT "вы ввели: " + CHR$C4) + frase$ + CHR$C4)
Результат:
Введите ключевую фразу ? Казнить нельзя, помиловать
вы ввели "Казнить нельзя, помиловать"
INPUT$
Иногда необходимо ввести фиксированную строку символов
так, чтобы они не печатались на экране — например, ну очень
секретную информацию.. В этом случает выручает оператор
INKEY$. Он ждет нажатия заданного количества символов. В
данном примере это используется для ввода пароля.
1 выводим на экран напоминание
PRINT "Введите пароль F букв) для дальнейшей работы"
'цикл DO...LOOP повторяется до ввода правильного пароля
DO
'Ждем ввода 5 символов
Parol$ = INPUT$E)
LOOP WHILE Parol$ ^> "Пароль"
Если же вам необходимо отследить нажатие управляющих
клавиш: {ENTER}, {ESC}, функциональных клавиш, тогда целе-
сообразно использовать оператор INKEY$. В отличии от опера-
торов INPUT, LINE INPUT и INPUTS, которые ждут ввода зна-
90
чений с клавиатуры, INKEYS этого не делает, поэтому оператор
INKEYS всегда используется в цикле:
'выводим на экран напоминание
PRINT "Нажмите клавишу {ENTER} или {ESC}"
1 цикл DO... LOOP повторяется пока не будет нажата
'клавиша {ENTER} (код 13) или {ESC} (код 27)
DO
KeyString = INKEY$
LOOP WHILE KeyString$ <> CHR$A3) OR KeyString$ <>
CHR$B7)
Более подробно об операторах ввода рассказано в главе 5
"Ввод/вывод на внешние устройства"
Вывод значений
Недостаточно только присвоить значение переменной или кон-
станте. В конечном счете программа работает не ради себя, а ради
человека, и должна вывести значения в понятной ему форме.
PRINT
Для вывода значений на экран дисплея используется опера-
тор PRINT:
Vopros$ = "Почем опиум для народа ???"
PRINT " Имею вопрос - "; Vopros$
Результат:'
Имею вопрос - Почем опиум для народа ???
Также как и оператор INPUT, PRINT позволяет вывести не-
сколько значений, при этом разделителями могут служить запя-
тая "," или точка с запятой ";":
Subject$ = "Компьютер"
Country$ = "США"
PRINT Subject$; Country$
PRINT
PRINT Subject$, Country$
91
Результат:
КомпьютерСША
Компьютер США
Оператор PRINT без параметров выводит на экран пустую
строку. Если необходимо вывести на экран строку, содержащую
запятые — указывайте код запятой в таблице ASCII C4) в списке
параметров вызова оператора PRINT:
PRINT CHR$C4) + "QuickBASIC" + CHR$C4)
Результат:
"QuickBASIC"
PRINT USING
Если необходимо вывести на экран строку символов по за-
ранее известному формату, используйте оператор PRINT USING:
Subject$ = "Компьютер"
Country$ = "США"
Price% = 999
Format$ ="Изделие: \ \ из \ \ по цене $###.##"
PRINT USING Format$; Subjects,- CountryS; Price%
Результат:
Изделие: Компьютер из США по цене $999.00
LPRINT и LPRINT USING
Операторы PRINT и PRINT USING выводят информацию
на экран. Для того, чтобы напечатать ее, используйте операторы
LPRINT и LPRINT USING:
Test$ = "Проверка принтера ..."
'эта строка выводит значение переменной Test$ на эк-
ран
PRINT Test$
'эта строка выводит значение переменной Test$ на принтер
LPRINT Test$
92
Более подробно об операторах вывода можно прочитать в
главе 5 "Ввод/вывод на внешние устройства"
LOCATE
Для того, чтобы красиво разместить текст на экране, в языке
BASIC есть оператор LOCATE. В текстовом режиме экран разби-
вается на 25 строк и 80 столбцов, что позволяет вывести символ в
любом месте экрана.
Пример: Вывод сообщения в центре экрана, на 12 строке,
J6 столбце.
LOCATE 12, 36: PRINT "И все-таки она вертится!"
Для рисования одинарных и двойных линий, рамок и зак-
раски изображений шаблонами, среди элементов таблицы ASCII
имеются символы псевдографики, приведенные в Приложении 5 в
разделе "Символы псевдографики для рисования рамок и таблиц".
Они позволяют создавать изображения на экране, не используя
медлительный графический режим1. См. Главу 6 "Графика и
звук", раздел -х мерные объекты в текстовом режиме"
Способ вывода еимволов псевдографики ничем не отличает-
ся от вывода символьных переменных и констант — используйте
оператор PRINT:
FOR i = 1 ТО 10: PRINT STRING$(i,"|"): NEXT i
Ниже приведена программа, рисующая график. Она исполь-
зует оператор LOCATE для рисования самого графика, коорди-
натной сетки и подписи к нему:
'Все переменные целые
DEFINT A-Z
DATA Урожайность зерновых в колхозе "Путь к убытку"
DATA 45,50,40,30,25,20,25
1 считывание значений
DIM ValueG)
READ Maintitle$
FOR i = 1 TO 7
1 А при работе с Microsoft BASIC PDS вы сможете даже загрузить в текстовом
режиме свои собственные экранные шрифты, расширив тем самым набор сим-
волов псевдографики или изменив очертания существующих.
93
READ Valued)
NEXT i
1 рисуется рамка
COLOR 0, 3: CLS : COLOR 0, 7
FOR i - 4 TO 20
LOCATE i, 10: PRINT SPACE$F0)
NEXT i
COLOR 0, 3: LOCATE 4, 70: PRINT "m"
FOR i = 5 TO 20
LOCATE i, 70: PRINT "|"
NEXT i
FOR i = 11 TO 70
LOCATE 21, l: PRINT»""
NEXT i
COLOR 0, 7
'рисуется координатная сетка
FOR i = 7 TO 17
LOCATE i, 17: PRINT "|"
NEXT i
FOR i = 18 TO 65
LOCATE 18, i: PRINT "-"
NEXT i
LOCATE 18, 16: PRINT "—{-"
start = 7
FOR i = 50 TO 0 STEP -10
LOCATE start, 13: PRINT i
start = start + 2
NEXT i
'Вывод заголовка
LOCATE 5, 20: PRINT Maintitle$
1 Вывод значений
start = 21
FOR i = 1 TO 7
visota = Valued) / 5
COLOR i - 1, 7
LOCATE 17 - visota, start: PRINT Value(i)
FOR j = visota TO 1 STEP -1
LOCATE 18 - j, Start: PRINT STRING$D, "||" )
NEXT j
start = start + 6
NEXT i
DO: LOOP WHILE INKEY$ =
94
Результат:
Почему BASIC не выговаривает русскую букву "р"
"Взирая на солнце, прищурь глаза свои, и ты смело разглядишь в
нем пятна " — говаривал Козьма Прутков. Одним из самых обид-
ных "пятен" языка QuickBASIC является то, что стандартными
средствами (INPUT, INPUTS, LINE INPUT, INKEY$) невоз-
можно ввести символ с кодом 224 — это малая русская буква "р"
в альтернативной кодировке. Это связано с некорректным опро-
сом клавиатуры, который выполняет BASIC.
Но что же остается делать нам, "русскоговорящим" пользо-
вателям? "Если нельзя, но очень хочется, то можно!". Существует
три способа решения этой проблемы:
1. Использовать драйвер русских букв с изменяемой раскладкой
клавиатуры, который бы подставлял английскую букву "р"
вместо русской "р". (См. раздел "Как нам обустроить
QuickBASIC?" из Главы Первой). Однако, если вы вводите
таким способом, скажем фамилии, то их невозможно будет
отсортировать по алфавиту;
2. Отказаться от стандартных операторов BASIC и опрашивать
клавиатуру самостоятельно, используя прерывание BIOS 16h,
95
функция 0. Текст такой процедуры приведен в главе 12
"Расширение возможностей QuickBASIC 4.5";
3. Перейти на следующую версию языка — Microsoft BASIC
Professional Development System, где эта ошибка, наконец, ис-
правлена.
Модульное программирование (*)
"Служил Гаврила программистом,
Софтвер Гаврила сочинял.
Из под пера его со свистом
Программный модуль вылетал..."
Почти по Ильфу и Петрову
При разработке собственной программы у каждого програм-
миста через некоторое время появляется большой набор соб-
ственных заготовок, неординарных решений и т. д., которые он
хотел бы использовать во всех своих творениях.
QuickBASIC предоставляет такую возможность, позволяя
разрабатывать программы по модульному принципу. Модуль —
это отдельная, полностью независимая от других, часть Вашей
программы. Каждая программа на QuickBASIC может состоять из
одного или нескольких модулей.
Каждый модуль имеет главную часть. В главной части моду-
ля описываются процедуры и функции модуля (операторами
DECLARE), функции DEF FN, константы (оператор CONST).
Один из модулей называется главным. Он содержит так на-
зываемую точку входа, с которой начинается выполнение про-
граммы. В каждой программе может быть только один главный
модуль.
К главному модулю можно подключить один или несколько
вспомогательных (дополнительных) модулей. В чем же преиму-
щество модульного программирования?
• Так как вспомогательные модули — это отдельные файлы
программ, в них обычно выносятся процедуры и функции,
которые используются одновременно в нескольких програм-
мах. Таким образом, вы как бы собираете программу из гото-
вых блоков (модулей);
96
Если вы дополняете или исправляете какую-либо процедуру
или функцию из вспомогательного модуля, то все исправле-
ния автоматически становятся доступны всем Вашим про-
граммы, которые эти модули используют;
Сосредоточение вспомогательных модулей в одном месте об-
легчает поиск нужного фрагмента исходного текста, и позво-
ляет избежать ситуации, когда одна и та же процедура суще-
ствует в нескольких вариантах в каждой программе.
В составе модуля можно выделить следующие самостоятель-
ные блоки: функции DEF FN, процедуры SUB и FUNCTION.
Функция DEF FN
Функция DEF FN — входит в главную часть модуля. Как и
процедура FUNCTION, DEF FN возвращает одно значение и ис-
пользуется аналогично встроенной функции QuickBASIC.
1 Функция вычисляет десятичный логарифм числа, используя
встроенную функцию нахождения натурального логарифма.
DEF FNLoglO (X)
FNLoglO = LOG(X) / LOG(IO.O)
END DEF
97
Структура модульной программы
Главный модуль содержит
точку входа, с которой начи-
нается исполнение программы
Дополнительные модули, которых
может несколько, содержат проце-
дуры и функции для главного модуля
INPUT "Введите число: ",Num
PRINT 0 Л LoglO(";Num;") is ";10.O^FNLoglO(Num)
END
Имя функции всегда должно начинаться с букв FN. DEF FN не
может быть рекурсивной (не может вызывать сама себя), и должна
быть определена перед использованием. Использовать функцию
DEF FN можно только в том модуле, в котором она определена.
Функция DEF FN — это устаревшая программная конструк-
ция, доставшаяся QuickBASIC "по наследству" от GWBASIC.
Практически во всех случаях лучше использовать более совре-
менную конструкцию FUNCTION...END FUNCTION1.
Процедура FUNCTION
Процедура FUNCTION является более мощной альтернати-
вой DEF FN. Так же как и DEF FN, FUNCTION возвращает
одиночное значение и может использоваться в выражениях. Од-
нако существуют и отличия.
Процедура FUNCTION может быть рекурсивной (вызывать
сама себя).
В отличии от функции DEF FN процедура FUNCTION мо-
жет использоваться вне того модуля, где она определена. Это
значит, что процедура FUNCTION, которая находится во вспо-
могательном модуле, становится доступна любому модулю Вашей
программы. Не забудьте, однако добавить оператор DECLARE в
те модули, где она используется.
Текст процедуры FUNCTION не входит в главную часть модуля.
DECLARE FUNCTION LoglO(X)
INPUT "Введите число: ",Num
PRINT 0 Л LoglO(";Num;") is ";10.O^LoglO(Num)
END
1 Однако существуют редкие случаи, когда использование функции DEF FN
предпочтительнее. Дело в том, что в отличии от FUNCTION, функция DEF FN
не проверяет тип числового аргумента. Например функция FNS возвращает сим-
вольное представление любого числового аргумента:
DEF fns$ (z)
'превращение в строку
fns$ = LTRIM$(STR$(z))
END DEF
При использовании функции FUNCTION пришлось бы писать четыре оди-
наковых функции для целых, длинных целых, обычной и двойной точности ти-
пов данных.
98
1 Функция вычисляет десятичный логарифм числа, используя
1 встроенную функцию нахождения натурального логарифма.
DEF FNLoglO (X)
LoglO = LOG(X) / LOGA0.0)
END FUNCTION
Процедура SUB
В отличии от функции DEF FN и FUNCTION, SUB вызыва-
ется как отдельный оператор.
' Напечатать сообщение в Центре экрана.
CLS
CALL PrintMessage A2, 40, "Hello!")
END
' процедура печати сообщения в указанных строке и столбце.
SUB PrintMessage (Row%, Col%, Message$)
1 Запоминание текущей позиции курсора.
CurRow% = CSRLIN
CurCol% = POS(O)
1 Вывод сообщения
LOCATE Row%, COL% : PRINT Message$;
1 Восстановление текущей позиции курсора.
LOCATE CurRow%, CurCol%
END SUB
Процедура SUB может возвращать несколько значений в вы-
зывающую подпрограмму. SUB не может быть использована как
часть выражения, а только как оператор.
Процедура SUB возвращает значения, производя вычисления
над переменными из списка аргументов. Это единственная воз-
можность для SUB переслать значения.
Если процедура SUB объявлена оператором DECLARE, то
при вызове процедуры вы можете опустить ключевое слово
CALL.
DECLARE SUB PrintMessage (Row%, Col%, Msg$)
1 Напечатать сообщение в центре экрана.
CLS
PrintMessage 12, 40, "Hello!"
END
Вы можете писать процедуры, которые могут вызывать сами
себя — то есть процедуры SUB могут быть рекурсивными.
99
Также как и FUNCTION, процедура SUB может использо-
ваться вне того модуля, где она определена. Таким образом, про-
цедура SUB, которая находится во вспомогательном модуле, стано-
вится доступна любому модулю Вашей программы. Не забудьте,
однако добавить оператор DECLARE в те модули, где она исполь-
зуется. Текст процедуры SUB не входит в главную часть модуля.
Рекурсия
QuickBASIC позволяет вам писать рекурсивные процедуры SUB
и FUNCTION (процедуры, вызывающие сами себя). В рекурсивных
процедурах реализован принцип "Разделяй и властвуй" — сложные
алгоритмы разбиваются на более простые и решаются.
1 Этот пример использует рекурсивную процедуру FUNCTION
1 для поиска и возврата длины строки
DECLARE FUNCTION StrgLng% (X$)
CLS
INPUT "Введите строку: "; InString$
PRINT "Длина строки равна "; StrgLng%(InString$)
FUNCTION StrgLng% (X$)
IF X$ = "" THEN
'Длина нулевой строки равна нулю
StrLng% = 0
ELSE
'Ненулевая строка - рекурсивный вызов.
'Длина ненулевой строки равна 1 плюс
'длина оставшейся части строки
StrgLng% = 1 + StrgLng%(MID$(X$, 2))
END IF
END FUNCTION
Границы использования переменных и констант
В языке QuickBASIC вы можете контролировать область дей-
ствия переменных и констант. Это позволит вам писать компакт-
ные процедуры, которые не влияют на работу друг друга. В тоже
время вы можете объявить, что часть переменных доступна всем
процедурам в модуле (совместное использование).
Область действия переменных и констант может быть:
1. Глобальной;
2. Локальной;
3. Совместно используемой.
100
Глобальные переменные и константы
Глобальными могут быть как переменные, так и символьные
константы. Переменная (константа) считается глобальной, если
она определена на уровне модуля. Для того, чтобы сделать пере-
менную глобальной необходимо добавить атрибут SHARED при
описании переменной оператором DIM, REDIM или COMMON.
Для констант достаточно оператора CONST в главном модуле:
DEFINT A-Z
CONST MAXLINE = 255, TABSPACE = 8
DIM SHARED TabStops(MAXLINE)
SUB SetTabPos
END SUB
Локальные переменные и константы
Локальные переменные и константы существуют только в
модуле или процедуре, где они используются. Таким образом, ес-
ли не объявлено иное, то все переменные в каждом модуле
(процедуре) считаются локальными. В случае, если в другом мо-
дуле (процедуре) используется переменная с этим же именем, то
QuickBASIC считает ее новой переменной.
При входе в процедуру или функцию значения переменных
обнуляются.
Если вы не хотите, чтобы значения переменных обнулялись,
то при добавьте ключевое слово STATIC при описании процеду-
ры, при этом значения переменных будут сохраняться между вы-
зовами процедур.
SUB SetStops (x%,xl%,i%) STATIC
END SUB
101
При помощи оператора STATIC можно сохранять значения
отдельных переменных между вызовами процедур1.
SUB SetStops (x%,xl%,i%)
STATIC i
END SUB
Совместно используемые переменные
Вместо того, чтобы объявлять переменные глобальными при
помощи оператора SHARED, вы можете совместно использовать
переменные между определенными процедурами. Так, массив
SetTabPos совместно используется только в главном модуле и
процедурах SetTabPos и ThisIsATab. В других процедурах и функ-
циях он не доступен.
DIM TabStops(MAXLINE)
SUB SetStops STATIC
SHARED TabStopsO
END SUB
FUNCTION ThisIsATab(LastColum as INTEGER) STATIC
SHARED TabStopsO
END SUB
Переменные в функции DEF FN
Все переменные функции DEF FN являются частью модуль-
ного кода. Чтобы сделать переменную в функции DEF FN ло-
кальной, вы должны явно указать при определении переменной
оператор STATIC. В данной функции DEF FN оператор STATIC
делает переменную I локальной:
1 Поэтому не используйте оператор STATIC в рекурсивных процедурах.
102
CONST NO=0, YES = NOT NO
DEF FNIsThereAZ (a$)
STATIC I
FOR 1 = 1 TO LEN(A$)
IF UCASE(MID$(A$,I,1)) = "Z" THEN
FNIsThereAZ = YES
EXIT DEF
END IF
NEXT I
FNIsThereAZ = NO
END DEF
Параметры в процедурах SUB и FUNCTION
Каждая процедура SUB и FUNCTION должна быть по свое-
му уникальна, поэтому невозможно точно ответить на вопрос —
сколько нужно передавать параметров. Но сформулировать об-
щие положения можно.
Решая подобного рода задачи, как мне кажется, следует до
минимума сократить количество параметров в процедурах и функ-
циях. Наиболее оптимальным следует признать использования
"правила кино" — как фильме не должно быть более 7 действую-
щих лиц (больше человек не может запомнить), так и число пара-
метров по возможности не'должно превышать этого числа. Ниже
перечислены приемы минимизации количества параметров:
• Значения, передаваемые между служебными процедурами,
следует описывать с атрибутом SHARED и не включать в
список параметров;
• Цвета должны быть "зашиты" в процедуру. Если цвет все-
таки необходим, то его можно передать одним шестнадцате-
ричным значением:
CALL ColorExample (&H16) '1 - фоновый цвет, 6 - ос-
новной
SUB ColorExample (col%)
PRINT "Основной цвет = "; col% MOD 16
PRINT "Основной цвет = "; col% \ 16
END SUB
• В процедуру или функцию не должны передаваться парамет-
ры, которые можно вычислить другим способом. Например,
103
если в процедуру, формирующую окно-список, передается
вектор, содержащий значения элементов, то можно вычис-
лить количество элементов в векторе (функция UBOUND), и
ширину окна (по самому широкому элементу).
Использование включаемых (INCLUDEI файлов
Для каждой процедуры SUB и FUNCTION, которые встре-
чаются в программе, BASIC генерирует соответствующий опера-
тор DECLARE. Если Вашей программе большое количество про-
цедур и функций (а сюда еще надо прибавить процедуры и фун-
кции вспомогательных модулей), то длинный список операторов
DECLARE отвлекает внимание от текста основной программы.
Чтобы этого избежать, можно использовать включаемый
(INCLUDE) файл. Встретив в тексте программы ссылку на INC-
LUDE-файл, BASIC автоматически переключается на обработку
этого файла и возвращается в программу после завершения работы.
Кроме операторов DECLARE, в INCLUDE-файл обычно
включаются определения констант и функций DEF FN.
К примеру, если Ваша программа использует процедуры SUB и
FUNCTION ClearScreenO, LineDraw(), MessageBox(), Ramka(),
WaitKey(), SeredinaS (), требует констант TRUE и FALSE, определя-
ет все переменные как целые, и требует FN-функцию fns$(), то на-
чало Вашей программы будет выглядеть примерно так:
DECLARE SUB ClearScreen ()
DECLARE SUB LineDraw (x%, y%, xl%, yl%)
DECLARE SUB MessageBox (message$, kod%)
DECLARE SUB Ramka (x%, y%, menu$(), vyb%)
DECLARE SUB WaitKey (kod%)
DECLARE FUNCTION Seredina$ (line$, dlina%)
CONST TRUE% = -1, FALSE% = 0
DEFINT A-Z
DEF fns$ (z%)
fns$ = LTRIM$(STR$(z))
END DEF
1 основной текст программы
DO
LOOP
END
1 См. Приложение 7 "Метакоманды"
104
Однако, используя INCLUDE-файл INTERFAC.BI вы може-
те записать то же самое гораздо проще:
'$INCLUDE: 'interfас.bi'
1 основной текст программы
DO
LOOP
END
При этом содержание файла INTERFAC.BI выглядит следу-
ющим образом:
DECLARE SUB ClearScreen ()
DECLARE SUB LineDraw (x%, y%, xl%, yl%)
DECLARE SUB MessageBox (message$, kod%)
DECLARE SUB Ramka (x%, y%, menu$(), vyb%)
DECLARE SUB WaitKey (kod%)
DECLARE FUNCTION Seredina$ (line$, dlina%)
CONST TRUE% = -1, FALSE% = 0
DEFINT A-Z
DEF fns$ (z%)
fns$ = LTRIM$(STR$B))
END DEF
Чтобы добавить INCLUDE-файл в Вашу программу необхо-
димо проделать следующее:
1. Выделить {SHIFT+стрелки} операторы программы, подлежащие
переносу в INCLUDE-файл: DECLARE, CONST, DEFjran,
функции FN и перенести их в буфер при помощи клавиш
{SHIFT-DEL};
2. Создать новый файл {ALT-F, С} как INCLUDE-файл, (пункт
INCLUDE) и перенести в него содержимое буфера {SHIFT-INS};
3. В главную часть всех модулей программы добавить директиву
'SINCLUDE: 'имявключаемогофайла'
Построение многомодульной программы
Исходный текст на языке BASIC
В этом разделе на конкретном примере будет показано, как
построить многомодульную программу. Она содержит главный
модуль TEST.BAS, а также вспомогательный модуль INTERFAC,
в" котором находятся процедуры, обеспечивающие работу с
пользовательским интерфейсом:
• ClearScreen — заполняет экран символами ":|"
• LineDraw — рисует рамку с тенью;
• MessageBox — выводит сообщение в центре экрана;
• Ramka — обеспечивает работу с меню;
• Seredina$ — выравнивает символьную строку.
Для начала введите текст программы и сохраните его под
именем TEST.BAS
1 это операторы объявления процедур и функций
'QuickBASIC поставит их самостоятельно
DECLARE SUB ClearScreen ()
DECLARE SUB LineDraw (x%, y%, xl%, yl%)
DECLARE SUB MessageBox (message$, kod%)
DECLARE SUB Ramka (x%, y%, menu$(), vyb%)
DECLARE SUB WaitKey (kod%)
DECLARE FUNCTION Seredina$ (line$, dlina%)
'объявление констант функциональных клавиш
CONST UP% = 72, DOWN% = 80, ESC% = 27, LEFT% = 75
CONST RIGHT% =77, ENTER% =13
1 объявление констант TRUE и FALSE
CONST TRUE% = -1, FALSE% = 0
'объявление "музыкальных констант"
CONST Simple$ = MFT255L16O6CO4GEDCBT255L16O6CO4_
GEDCBT2 5 5L16O6CO4GEDC"
CONST bad$ = "mftl20o016eeel2c"
CONST good$ = "mft200o215cl7el7g>14c<18g>12c"
'все переменные целые
DEFINT A-Z
1 в символьном массиве meny$ - 4 элемента
REDIM meny$D)
106
107
'присваиваем значение элементам массива
meny$(l) = "Вывести сообщение"
meny$B) = "Вывести сообщение со счетчиком"
meny$C) = "Вывести сообщение с кнопкой ОК"
meny$D) = "Завершить работу программы"
DO
'на чистом экране рисуем меню
1 после выбора элемента меню очищаем экран
CALL ClearScreen
CALL RamkaB, 2, meny$(), vybor)
CALL ClearScreen
1 проверяем значение переменной vybor
SELECT CASE vybor
CASE IS = 1
1 выводим сообщение
MessageBox "QuickBASIC - лучший язык _
программирования!", 1
PLAY good$: SLEEP 5
CASE IS = 2
'выводим сообщение со счетчиком
MessageBox "Подождите, я думаю ...", 1
'рисуем счетчик
CALL LineDrawA5, 19, 19, 62)
COLOR 0, 7: LOCATE 17, 21: PRINT STRING$D0, "_")
'выводим в цикле 40 символов с кодом 219
1 и гудим для разнообразия
FOR i = 1 ТО 40
LOCATE 17, 20 + i: PRINT "_"
LOCATE 16, 35: PRINT STR$E00 * i) + " герц"
SOUND 500 * i, 3
NEXT i
CASE IS = 3.
'выводим сообщение с кнопкой ОК
MessageBox "И все-таки я работаю ! ! ! ", 2
CASE IS = 4 'выводим запрос на выход
flag = 3:
MessageBox "вы точно хотите меня покинуть ?", flag
'если ответ "ДА" то очищаем экран
'и заканчиваем программу
IF flag = TRUE THEN PLAY bad$: COLOR 7, 0: CLS : END
'иначе возвращаемся обратно
PLAY good$
END SELECT
LOOP
SUB ClearScreen
' Эта процедура очищает экран
I********************************
'устанавливаем черный цвет на бирюзовом поле
COLOR 0, 3
'Каждая процедура или функция, которая выводит что-нибудь
'на экран должна отключать курсор, чтобы он не мелькал
LOCATE , , О
1 закрашиваем экран, выводя на него
'25 строк из 80 символов с кодом 176
FOR 1 = 1 ТО 25
1 точка с запятой после оператора PRINT запрещает
'прокручивать экран на 24 и 25 строке
LOCATE i, 1: PRINT STRINGS(80, );
NEXT i
END SUB
SUB LineDraw (x, y, xl, yl)
*****************************************************
' Эта процедура рисует прямоугольную рамку с тенью
1 х,у - верхний левый угол
' xl,yl - нижний правый угол
'устанавливаем черный цвет символов на белом фоне
COLOR 0, 7
'Отключаем курсор
LOCATE , , 0
1 рисуем верхнюю линию
LOCATE х, у: PRINT " г" + STRING$ (yl - у - 1, "-") + "-, »
'рисуем промежуточные линии
FOR i = х + 1 ТО xl - 1
LOCATE i, у: PRINT "|" + SPACE$(yl - у - 1) + "|"
NEXT i
1 рисуем нижние линии
LOCATE xl, у: PRINT " L" + STRING$ (yl - у - 1, "-" ) + "-1 "
'Сделаем рамке "интеллектуальную тень". "Интеллектуальной"
'тень называется потому, что символы, которые она
'закрывает, не пропадают, а проступают из-под нее.
'Для этого при помощи функции SCREEN считываем код каждого
'символа и выводим его же серым на черном фоне
1 Подробнее см. Главу Шестую "Графика и звук", раздел -х мерные эффек-
ты в текстовом режиме".
108
COLOR 8, О
'выводим правую часть тени
FOR i=x+lTOxl+l
FOR j = 1 TO 2
'код символа в i-строке j+yl-столбца
kod = ASC(CHR$(SCREEN(i, j + yl)))
1 выводим его же серым на черном
LOCATE i, j + yl: PRINT CHR$(kod)
NEXT j
NEXT i
'выводим нижнюю часть тени
FOR i = у + 2 ТО yl
'код символа в xl+1-строке i-столбца
kod = ASC(CHR$(SCREEN(xl + 1, i)))
1 выводим его же серым на черном
LOCATE xl + 1, i: PRINT CHR$(kod)
NEXT i
END SUB
SUB MessageBox (message$, kod)
i****************************************************
1 Эта процедура выводит сообщение message$ в центре
' экрана в зависимости от параметра kod:
' 1 - обычное сообщение
1 2 - сообщение с кнопкой " Ок "
13 - сообщение с кнопками " ДА " и " НЕТ "
|****************************************************
SELECT CASE kod
CASE IS = 1 ' 1 - обычное сообщение
CALL LineDrawF, 15, 10, 65)
COLOR 0, 7: LOCATE 8, 16
PRINT Seredina$(message$, 49)
CASE IS = 2 '2 - сообщение с кнопкой " Ок "
CALL LineDraw(9, 15, 15, 65)
COLOR 0, 7: LOCATE 11, 16
PRINT Seredina$(message$, 49)
LOCATE 12, 38: PRINT ", , "
LOCATE 13, 38: PRINT "j ОК |"
LOCATE 14, 38: PRINT n| '"
LOCATE 13, 40, 1, 1, 13
PLAY Simple$
DO
CALL WaitKey(kod)
LOOP WHILE kod <> ENTER
109
CASE IS = 3 '3 - сообщение с кнопками
1 "ДА " и " НЕТ "
CALL LineDraw(9, 15, 15, 65)
COLOR 0, 7: LOCATE 11, 16
PRINT Seredina$(message$, 49)
LOCATE 12, 30: PRINT "| 1"
LOCATE 13, 30: PRINT "| Да j"
LOCATE 14, 30: PRINT "' '"
LOCATE 12, 45: PRINT "| 1"
LOCATE 13, 45: PRINT " | Нет | "
LOCATE 14, 45: PRINT "' '"
kod = TRUE
DO
IF kod = TRUE THEN
LOCATE 13, 32, 1, 1, 13
ELSE
LOCATE 13, 47, 1, 1, 13
END IF
WaitKey AnyKey
SELECT CASE AnyKey
CASE IS = ENTER
EXIT DO
CASE IS = ESC
kod = FALSE: EXIT DO
CASE IS = LEFT, RIGHT
kod = NOT (kod): SOUND 500 * B - kod), .5
CASE ELSE
BEEP
END SELECT
LOOP
END SELECT
END SUB
SUB Ramka (x, y, line$(), vyb)
i****************************************************
' Эта процедура выводит рисует меню на экране
1 х, у - верхний левый угол меню
1 line$() - вектор названий элементов меню
1 vyb - номер выбранного элемента меню
'гасится экранный курсор
LOCATE , , 0
'определяется число элементов в векторе line$()
kolvo = UBOUND(line$): dlina = 1
'если номер выбора не задан, то он первый
IF vyb = 0 THEN vyb = 1
НО
'определяем самого "длинного" из элементов вектора
line$()
FOR i = 1 ТО kolvo
IF LEN(line$(i)) > dlina THEN dlina = LEN(line$(i))
NEXT i
'рисуем рамку для меню
CALL LineDraw(x, у, х + kolvo + 1, у + dlina + 3)
'устанавливаем черный цвет на белом фоне
COLOR 0, 7
'выводим элементы вектора line$()
FOR i = 1 ТО kolvo
LOCATE x + i, у + 2: PRINT line$(i)
NEXT i
'устанавливаем красный цвет на белом фоне
COLOR 4, 7
DO
'очищаем место для указателя
FOR i = 1 ТО kolvo
LOCATE x + i, у + 1: PRINT " "
NEXT i
'рисуем сам указатель
LOCATE x + vyb, у + 1: PRINT CHR$A6)
1 ждем нажатия клавиши
WaitKey AnyKey
1 анализируем нажатую клавишу
SELECT CASE AnyKey
CASE IS = ENTER
'клавиша ENTER - выходим из цикла и из процедуры
EXIT DO
CASE IS = UP
'клавиша "стрелка вверх" - уменьшаем vyb на 1
vyb = vyb - 1: IF vyb = 0 THEN vyb = kolvo
SOUND 500 * vyb, .5
CASE IS = DOWN
'клавиша "стрелка вниз" - увеличиваем vyb на 1
vyb = vyb + 1: IF vyb > kolvo THEN vyb = 1
SOUND 500 * vyb, .5
CASE ELSE
'иначе обиженно гудим
BEEP
END SELECT
LOOP
END SUB
111
FUNCTION Seredma$ (lme$, dlma)
i************************************************
1 Эта функция выравнивает символьную строку,
1 добавляя пробелы справа и слева
1 lme$ - символьная строка
1 dlma - ее будущая длина
1************************************************
'убираем у символьной строки пробелы справа и слева
lme$ = RTRIM$(LTRIM$(line$) )
1 определяем ее реальную длину
real = LEN(line$)
'определяем "добавку", и если она не нужна, то
'уходим из функции
dobavka = dlma - real
IF dobavka < 0 THEN EXIT FUNCTION
1 количество пробелов слева и справа
spaceI = dobavka \ 2
space2 = dobavka \ 2
1 компенсируем возможные ошибки при делении
IF spacel + real + space2 < dlma THEN
space2 = space2 + 1
END IF
'присваиваем полученное значение функции
Seredma$ = SPACES {spacel) + line$ + SPACE$ (space2)
END FUNCTION
SUB WaitKey (kod)
1 Эта процедура возвращает код клавиши:
1 ESC, ENTER, DOWN, UP, LEFT, RIGHT
1 код - код клавиши
i***************************************
'очищаем буфер клавиатуры
DO: LOOP WHILE INKEY$ <> ""
DO
'ждем нажатия какого-нибудь символа
а$ = "": DO: a$ = INKEY$: LOOP WHILE a$ = ""
IF LEN(a$) = 1 THEN
1 если нажата обычная клавиша и если это ENTER или ESC,
1 то выходим из цикла DO... LOOP и из процедуры
IF a$ = CHR$(ENTER) THEN kod = ENTER: EXIT DO
IF a$ = CHR$(ESC) THEN kod = ESC: EXIT DO
ELSE
112
'если нажата функциональная клавиша, то берем ее
'скан-код и проверяем, не равен ли он коду UP, DOWN,
'LEFT или RIGHT 'если да, то выходим из цикла и из
' процедуры
kod = ASC(RIGHTS(a$, 1))
IF kod = UP OR kod = DOWN OR kod = LEFT OR kod = RIGHT THEN
EXIT DO
END IF
LOOP
END SUB
При запуске экрана в верхнем левом углу появляется меню,
которое выводится в бесконечном цикле DO...LOOP. Меню со-
держит четыре пункта:
• Вывести сообщение;
• Вывести сообщение со счетчиком;
• Вывести сообщение с кнопкой ОК;
• Завершить работу программы
>Вывести сообщение
Вывести сообщение со счетчиком
Вывести сообщение с кнопкой ОК
Завершить работу программы
При выборе первого варианта вызывается процедура
MessageBox с названием "QuickBASIC — лучший язык програм-
мирования" и параметром 1 (вывести простое сообщение). Затем
играется музыкальная константа GOD$ и производится задержка
5 секунд
QuickBASIC - лучший язык программирования!
При выборе второго варианта также вызывается процедура
MessageBox с параметром 1, затем в цикле производится генера-
ция звуковых колебаний от 500 до 20000 герц, с имитацией эк-
ранного счетчика.
Подождите, я думаю
5000 герц
При четвертом и последнем варианте вызывается процедура
MessageBox с параметром 3 (выбор "ДА" или "НЕТ") Результат вы-
бора заносится в переменную flag Если значение переменной flag
равно константе TRUE (ИСТИНА) то производится выход из про-
граммы с исполнением музыкальной константы BAD$.
В противном случае играется константа GOODS и цикл по-
вторяется
114
И все-таки я работаю !?!
Ок
При выборе третьего варианта вызывается процедура
MessageBox с параметром 2 (кнопка ОК)
После того, как вы ввели текст этой программы, отладили
ее, и она работает так, как описано выше, приступим к построе-
нию многомодульной программы
Все процедуры программы TEST являются универсальны-
ми — их можно использовать и в других программах, а для этого
необходимо их выделить в отдельный модуль, назовем его
INTERFAC.BAS.
Нажмите клавишу {F2} — вы увидите список загруженных
модулей (он один — TEST.BAS) и процедуры SUB и
FUNCTION, относящиеся к этому модулю.
Создадим новый модуль с именем INTERFAS.BAS1. На-
жмите {ALT-F, С}, введите название этого модуля (расширение
.BAS можно не указывать) и нажмите {ENTER}.
1 Interface — "интерфейс, стых Совокупность средств и правил, обес-
печивающих логическое или физическое взаимодействие устройств и/или про-
грамм вычислительной системы
115
Вы точно хотите меня покинуть ?
В списке загруженных модулей появился еще один
INTERFAC.BAS.
Теперь наша задача заклю-
чается в том, чтобы перебросить
процедуры из модуля TEST в
модуль INTERFAC. Установите
выделенную строку на первую
процедуру в списке (это
ClearScreen). Используя клавишу
{TAB}1 подведите курсор к ко-
манде < Move > (Передвинуть) и
нажмите {ENTER}. В появив-
шемся окне выберите модуль, в
который передвигаются проце-
дуры - INTERFAC.BAS
1 Любители хвостатых могут воспользоваться мышью
116
Теперь у модуля INTERFAC появилась процедура
ClearScreen.
Аналогично перебросьте остальные процедуры.
Теперь необходимо перенести в новый модуль INTERFAC.
BAS объявления процедур и функций, определения констант и
операторы объявления типа данных.
Выделите необходимый фрагмент исходного текста из глав-
ной части модуля TEST.BAS ({SHIFT+стрелки}), скопируйте его
в буфер ({CTRL-INS}) и перенесите в главную часть модуля
INTERFAC ({SHIFT+INS}).
117
Главная часть модуля INTERFAC.BAS должна выглядеть так:1
DECLARE SUB ClearScreen ()
DECLARE SUB LmeDraw (x%, y%, xl%, yl%)
DECLARE SUB MessageBox (message$, kod%)
DECLARE SUB Ramka (x%, y%, menu$(), vyb%)
DECLARE SUB WaitKey (kod%)
DECLARE FUNCTION Seredina$ (line$, dlina%)
CONST UP% = 72, DOWN% = 80, ESC% = 27, LEFT% = 75
CONST RIGHT% = 77, ENTER% = 13
CONST TRUE% = -1, FALSE% = 0
CONST Simple$ = MFT255L16O6CO4GEDCBT255L16O6CO4_
GEDCBT255L16O6CO4GEDC"
CONST bad$ = "mftl20o016eeel2c"
CONST good$ = "mft200o215cl7el7g>14c<18g>12c"
DEFINT A-Z
Сохраните сделанные изменения. При выходе из среды QB,
вы заметите, что помимо файлов TEST.BAS и INTERFAC.BAS,
на диске появился файл TEST. МАК. В нем содержится список
модулей, которые требуются программе TEST:
TEST.BAS
INTERFAC.BAS
Когда вы будете загружать программу TEST в следующий раз
QB автоматически подгрузит INTERFAC.BAS
Построение Quick-библиотеки
Если вспомогательный модуль полностью готов и отлажен,
то имеет смысл скомпилировать его в Quick-библиотеку. Проце-
дуры, которые находятся в Quick-библиотеках, становятся расши-
рением самого языка BASIC.
Загрузите в среду QB только файл INTERFAC.BAS. Нажмите
{ALT-R, L}. Введите имя Quick-библиотеки (без расширения) и вы-
берите пункт < Make library and Exit > (сделать библиотеку и выйти).
1 Этот фрагмент можно поместить во включаемый файл INCLUDE.BI, и помес-
тить директиву 'SINCLUDE 'interfac bi' в главную часть модуля TEST BAS и
INTERFAC BAS, как было описано в разделе "Использование включаемых
(INCLUDE) файлов"
118
BASIC построит две библиотеки:
1. INTERFAC.QLB — служит для работы в среде QB;
2. INTERFAC.LIB — необходима для компиляции Вашей
прграммы в .ЕХЕ-файл.
Перед запуском программы уничтожьте файл TEST. МАК — он
больше не нужен, ведь все необходимые процедуры теперь находятся
в Quick-библиотеке. Для загрузки среды QB с Quick-библиотекой ис-
пользуется ключ /L (более подробно о ключах запуска среды QB рас-
сказано в приложении 2 "Запуск, редактирование и отладка програм-
мы"). Загрузим TEST.BAS с Quick-библиотекой INTERFAC.QLB :
C:\QB45>QB TEST /L INTERFAC
Теперь, при нажатии клавиши {F2} высвечивается только глав-
ный модуль программы TEST, а процедуры вспомогательного моду-
ля INTERFAC. BAS находятся в Quick-библиотеке и не видны.
Использование Quick-библиотек обладает следующими дос-
тоинствами:
• загрузка библиотеки в среду .QB происходит гораздо быстрее,
чем исходного текста;
119
так как процедуры Quick-библиотек уже откомпилированы,
они выполняются быстрее;
Quick-библиотеки занимают меньше оперативной памяти,
чем исходные тексты.
В тоже время, следует учитывать и недостатки:
откомпилированные Quick-библиотеки не содержат средств
отладки, предоставляемых средой QB, поэтому при наличии в
ошибок в Quick-библиотеке компьютер может "зависнуть";
при запуске среды QB к ней можно подключить только одну
Quick-библиотеку, вне зависимости от наличия свободной
памяти, в тоже время в виде исходных текстов можно под-
ключить несколько модулей (их количество ограничено толь-
ко объемом оперативной памяти1).
1 В среду QB можно загрузить в виде исходных модулей не более 5000-5500
строк текста. Это ограничение снято в Microsoft BASIC PDS 7.1 — среда QBX по-
зволяет использовать для загрузки и размещения программ и данных до 1.2 Mb до-
полнительной отображаемой памяти, организованной по стандарту EMS 4.0
ОПЕРАТОРЫ ОПИСАНИЯ
CONST
CONST — оператор, описывающий константы, которые ис-
пользуются вместо числовых или символьных значений.
CONST константа = выражение [, константа = выраже-
ние] . . .
• константа — имя константы, допускаемое в языке BASIC;
• выражение — выражение, допускаемое в языке BASIC.
Нельзя использовать конкатенацию (сложение символьных
строк) и функции с параметрами, такие как SIN или CHR$.
Тип констант определяется по суффиксу в конце имени:
%
&
!
#
$
целочисленная константа;
константа двойной точности;
константа обычной точности1;
константа двойной точности;
символьная константа.
Константы, описанные в процедурах SUB или FUNCTION,
являются локальными для данной SUB или FUNCTION. Кон-
1 Если суффикс опущен, то константа считается обычной точности.
станта, описанная в главном модуле, является глобальной. Ис-
пользование констант обладает рядом несомненных достоинств:
• Константы нужно определять только один раз во всем модуле;
• Константы нельзя изменить;
• В ЕХЕ-программах использование констант дает более эф-
фективный код, чем использование переменных;
• Константы делают программу легко изменяемой.
Пример. Подсчет слов, строк, символов в текстовом
файле.
DEFINT A-Z
CONST BLANK = 32, ENDFILE = 26, CR = 13, LF = 10
CONST TABC = 9, YES = -1, NO = 0
CLS
INPUT "Введите имя файла: ",FileName$
IF FileName$ ="" THEN END
OPEN FileName$ FOR INPUT AS #1
Words = 0: Lines = 0: Characters = 0
InaWord = NO
DO UNTIL EOF(l)
с = ASC(INPUT$A,#1))
Characters = Characters + 1
IF с = BLANK or с = CR or с = LF or С = TABC THEN
1 Если прочитанный символ является пробелом,
1 табулятором, символом перевода каретки или
1 возврата строки, то это не слово.
IF с = CR THEN Lines = Lines + 1
InaWord = NO
ELSEIF InaWord = NO THEN
1 Символ может входить в состав слова.
InaWord = YES
Words = Words + 1
END IF
LOOP
PRINT Characters, Words, Lines
END
DEFmn
DEPran — оператор описания типов переменных.
122
DEFINT интервал [,интервал]... —целый;
DEFLNG интервал [,интервал]... - длинный целый;
DEFSNG интервал [.интервал]... — обычной точности;
DEFDBL интервал [,интервал]... — двойной точности;
DEFSTR интервал [,интервал]... — символьный.
• интервал имеет форму буква 1[-буква2],
где буква 1 и буква2 — любая из букв латинского алфавита.
Переменные и функции, чьи имена начинаются с букв, вхо-
дящих в данный интервал, имеют по умолчанию тип, определен-
ный тремя последними буквами оператора (INT, SNG, DBL,
LNG или STR).
DIM
DIM — оператор, объявляющий одну или несколько пере-
менных и выделяющий для них необходимый объем памяти.
DIM [SHARED] переменная[(границы)] [AS тип]
[,переменная[(границы)] [AS тип].. .
• переменная — имя переменной или массива;
• SHARED — атрибут SHARED предписывает всем процедурам
в данном модуле совместно использовать массивы и перемен-
ные указанные в операторе DIM. Это не оператор SHARED,
который влияет на переменные внутри одной процедуры SUB
или FUNCTION;
• границы — границы размерности массива — верхняя и ниж-
няя граница индексов;
• AS тип — определяет тип переменной — обычный или
пользовательский. К обычным типам BASIC относятся:
INTEGER, LONG, SINGLE, DOUBLE, STRING.
Границы массивов в операторе DIM имеют следующую форму:
[меньшая ТО] большая [,[меньшая ТО] большая]...
Ключевое слово ТО предоставляет возможность указать и
нижнюю и верхнюю границы массива. Следующие операторы эк-
вивалентны (если OPTION BASE = 0 или отсутствует):
123
DIM A(8,3)
DIM A@ TO 8, 0 TO 3)
DIM A(8,0 TO 3)
С ключом ТО вам не обязательно указывать только положи-
тельные границы. Возможные значения границ находятся в пре-
делах от -32768 до 32767:
DIM A(-4 ТО 10)
DIM B(-99 ТО -5,-3 ТО 0)
Если у вас есть массив, не описанный оператором DIM, то
верхняя граница каждой размерности не должна превышать ДО1.
Если же вы обращаетесь к элементу массива, индекс которого
лежит вне указанных границ, то возникает ошибка "Subscript out
of range" (Индекс вне диапазона).
Оператор DIM обнуляет все элементы числовых массивов, а
символьным — присваивает значение пустой строки (""). Пере-
менные полей и записей также обнуляются, включая поля фик-
сированной длины.
Если вы попытаетесь определить массив оператором DIM
после того, как вы уже обращались к его элементам, то получите
ошибку "Array already dimensioned" (Массив уже определен).
Лучше всего поставить DIM в самом начале программы.
Ограничения на размеры массивов в приведены в Приложе-
нии 4 "Ограничения QuickBASIC".
Оператор DIM может применяться для описания типов перемен-
ных. Например, следующий оператор описывает переменную как це-
лую, хотя никакой декларации типов оператором DEFINT до этого не
производилось:
DIM NumberOfBytes AS INTEGER
DIM также дает возможность описания определенных пере-
менных как записей. В следующем примере переменная TopCard
описана как переменная пользовательского типа (запись):
TYPE Card
Suit AS STRING * 9
Value AS INTEGER
END TYPE
DIM TopCard AS Card
Таким же образом можно описывать и массивы записей:
1 Лучше такого не допускать — описывайте каждый используемый Вами мас-
сив в начале модуля или процедуры.
124
DIM Deckd TO 52) AS Card
Пример. Нахождение максимального и минимального зна-
чений элементов массива.
CONST MAXDIM =20
DIM A(l TO MAXDIM)
1 Использование DIM для описания двух целых переменных.
' Все остальные переменные имеют обычную точность.
DIM NumValues AS INTEGER, I AS INTEGER
NumVal = 0
PRINT "Вводите числа. END - конец ввода."
DO
INPUT A$
IF UCASE$(A$) = "END" OR NumVal >= MAXDIM THEN EXIT DO
NumVal = NumValues + 1
A(NumVal) = VAL(A$)
LOOP
IF NumVal > 0 THEN
Max = A(l)
Min = A(l)
FOR 1=1 TO NumVal
IF A(I) > Max THEN Max = A(I)
IF A(I) < Min THEN Min = A(I)
NEXT I
PRINT "Максимум ="; Max;" Минимум ="; Min
ELSE
PRINT "Недостаточно чисел..."
END IF
Вводите числа. END - конец ввода.
? 23.2
? 11.3
? 1.6
? end
Максимум = 23.2 Минимум = 1.6
REDIM
REDIM — оператор объявления массивов. Изменяет объем
памяти, выделенной массивам $DYNAMIC (динамическим) .
REDIM [SHARED] массив(границы)[AS тип]
[,массив (границы) [AS тип]]...
125
• SHARED — позволяет всем процедурам модуля совместно
использовать элементы массива. Отличается от оператора
SHARED, который влияет только на переменные внутри мо-
дуля. Атрибут SHARED может быть указан на модульном
уровне;
• массив — имя массива;
• границы — границы размерности массива — верхняя и ниж-
няя граница индексов;
• AS тип — описывает переменные обычного или пользователь-
ского типа. К обычным типам BASIC относятся: INTEGER,
LONG, SINGLE, DOUBLE, STRING.
Границы задаются следующим образом:
[нижняя ТО] верхняя [,[нижняя ТО] верхняя]...
Ключ ТО указывает на то, что определяются и верхняя, и
нижняя границы данной размерности массива.
Все массивы, описанные данным оператором, являются
SDYNAMIC. Можно только изменить границы размерностей
массива оператором REDIM, но нельзя изменить число размер-
ностей. Следующий пример является правильным:
'$DYNAMIC
DIM AE0,50)
ERASE A
'Массив А имеет две размерности.
REDIM АB0,15)
Однако, следующий пример имеет ошибку, при его выпол-
нении вы получите сообщение "Wrong number of dimensions"
(Неверное число размерностей):
1$DYNAMIC
DIM AE0,50)
ERASE A
1 Размерностей стало 3. Ошибка.
REDIM AE,5,5)
126
LBOUND
LBOUND — функция памяти, возвращающая нижнюю гра-
ницу (наименьшее значение индекса) массива.
LBOUND(массив,[размерность])
• массив — имя массива;
• размерность — целое выражение в пределах от 1 до числа раз-
мерностей массива. Указывает, по какой размерности брать
нижнюю границу. Для массива-вектора может быть опущено.
Пример:
DIM A(l ТО 100, 0 ТО 50, -3 ТО 4)
Значение:
LBOUND (АД) = 1
LBOUND(А,2) = 0
LBOUND(А,3) = -3
Нижняя граница массивов по умолчанию равна 0 (оператор
OPTION BASE = 0 или отсутствует) или 1 (оператор OPTION
BASE = 1).
Массивы, описанные с ключевым словом ТО в операторе
DIM могут иметь любое целое значение в качестве нижней гра-
ницы.
Можно использовать короткий синтаксис LBOUND (массив)
для одноразмерного массива (вектора).
Пример:
OPTION BASE I
DIM AE0)
Значение:
LBOUND (A) = 1
Для нахождения верхней границы массива используется
функция UBOUND.
127
UBOUND
UBOUND — функция памяти, возвращающая верхнюю гра-
ницу массива по указанной размерности.
иВО1ШБ(массив[,размерность])
• массив — имя массива;
• размерность — целое выражение в пределах от 1 до числа раз-
мерностей массива. Указывает, по какой размерности брать
верхнюю границу. Для массива-вектора может быть опущено.
Примеры:
DIM A(l ТО 100, 1 ТО 50, -3 ТО 4)
Значение:
UBOUND(А,1) = 100
UBOUND(А,2) = 50
UBOUND(А,3) = 4
TYPE
TYPE — оператор описания QuickBASIC, определяющий тип
данных, состоящих из нескольких типов — пользовательский тип.
TYPE имя_типа
элемент AS тип
[элемент AS тип]
END TYPE
• имятипа — имя пользовательского типа данных;
• элемент — имя элемента пользовательского типа;
• тип — типы данных языка BASIC: INTEGER, LONG,
SINGLE, DOUBLE, STRING * num или другой пользователь-
ский тип.
Символьные строки в пользовательском типе данных долж-
ны быть строками фиксированной длины:
128
Keyword AS STRING * 40
Пользовательский тип должен быть описан оператором
TYPE только в главном модуле. Для описания какой-либо пере-
менной как пользовательской используются операторы DIM,
REDIM, COMMON, STATIC, SHARED.
Пользовательские типы данных имеют другое название —
записи.
OPTION BASE
OPTION BASE — объявление нижней границы массивов.
OPTION BASE n
• n = 0 или 1.
OPTION BASE не обязателен. По умолчанию равен 0. Син-
таксис оператора DIM позволяет сделать это проще. OPTION
BASE может использоваться только один раз в модуле, до описа-
ния всех массивов.
Пример. Установка нижней границы массивов = 1.
CLS
OPTION BASE I
DIM AB0)
PRINT "Нижняя граница массива А ="; LBOUND(A)
PRINT "Верхняя граница массива А ="; UBOUND(A)
Результат:
Нижняя граница массива А = 1
Верхняя граница массива А = 20
COMMON
COMMON — оператор, описывающий глобальные пере-
менные для их совместного использования между модулями или
для передачи в цепочную программу.
COMMON [SHARED] [/имя_6лока/] список
• SHARED — Атрибут, определяющий, что переменные могут
совместно использоваться всеми процедурами SUB и
FUNCTION в модуле. При этом нет необходимости в исполь-
129
зовании оператора SHARED внутри процедуры SUB или
FUNCTION;
• имяблока — идентификатор блока (до 40 знаков в имени)
для указания группы переменных. Используется для разделе-
ния только определенных переменных. Если у блока есть
имя, он считается именованным;
• список — список переменных, разделяемых между модулями
или цепочными программами:
переменная [AS тип][, переменная [AS тип]] ...
Оператор COMMON выделяет место для переменных в спе-
циальной области памяти (общая область), что позволяет моду-
лями или программам совместно использовать переменные.
Так как COMMON устанавливает глобальные переменные для
всей программы, он должен находиться перед выполняемыми опера-
торами, но ему могут предшествовать следующие операторы:
COMMON
DEFjran
SHARED
CONST
DIM
STATIC
DATA
OPTION BASE
TYPE...END
TYPE
DECLARE
REM
Все метако-
манды
Переменные в блоках COMMON в разных модулях должны
иметь одинаковый тип в одинаковых позициях, но не обязатель-
но одинаковые имена.
Пример:
1 Главная программа
COMMON a, D, Е
а = 5: D = 8: Е = 10
'Другой модуль
'А = 5, Е = 8, D = 10
COMMON a, E, D
И статические и динамические массивы размещаются в
COMMON путем указания имени массива с пустыми скобками.
Статический массив должен быть предварительно описан опера-
тором DIM. Динамический массив может быть описан позже
130
операторами DIM или REDIM, так как в блоке COMMON раз-
мещаются не его элементы, а описатель массива.
Размер общей области может быть различным в разных мо-
дулях или программах, если используется неименованный блок
COMMON. Если программа совместно использует блок
COMMON с процедурой в библиотеке пользователя, то вызывае-
мая программы не может увеличит размер блока.
Очень трудно обнаружить причину ошибки при некоррект-
ном использовании оператора COMMON. Поэтому создайте
включаемый INCLUDE-файл с описанием блоков COMMON и
вызывайте его с помощью метакоманды $INCLUDE в каждой
программе:
'Файл menu.bas
1 $INCLUDE: 'COMDEF.BI'
CF^IN "progl"
END
'Файл progl.bas
1 $INCLUDE: 'COMDEF.BI'
END
'Файл comdef.bi
DIM aA00), B$B00)
COMMON I, J, K, a() COMMON a$, B$(), X, У, Z
Использование именованного блока COMMON
Именованный блок COMMON представляет собой простой
способ для совместного использования переменных между моду-
лями, так как многие модули требуют только те переменные, ко-
торые им нужны.
Ниже приведен пример программы, вычисляющей объем и
плотность прямоугольной призмы, которая использует имено-
ванный блок COMMON для разделения различных переменных
между двумя процедурами. Процедура VOLUME требует только
переменные, представляющие длины сторон (COMMON блок
SIDES). Процедура DENSITY требует также переменные, пред-
ставляющие вес (COMMON блок WEIGHT).
'Главная программа
DIM SC)
COMMON /Srdes/ S()
COMMON /Weight/ С
С = 52: S(i) = 3: SB) = 3: SC) = 6
131
CALL Volume
CALL Density
END
COMMON и .EXE файлы
При передаче управления другой программе через CHAIN
(передача управления другому файлу "по цепочке"), с помощью
оператора COMMON или именованного блока COMMON невоз-
можно передать глобальные переменные. Это происходит в том
случае, когда вы компилируете Вашу программу "Stand-Alone
EXE File" (Автономный EXE Файл).
Существует три пути решения этой проблемы:
1. Компилировать программу с опцией "Requiring BRUN45.EXE"
(требуется BRUN45.EXE);
2. Передавать параметры через временный дисковый файл;
3. Использовать межпрограмный 16-байтный буфер. Этот буфер
специально предназначен для обмена сообщениями между
программами:
'Файл programl.bas посылает сообщение Message$
DIM Message$ AS STRING * 16
Message$ = "Тестовая строка"
DEF SEG = 0
FOR i = 0 TO 15
POKE &H4F0 + i, ASC(MID$(message$, i + 1, 1))
NEXT i
DEF SEG
CHAIN "program2"
END
'Файл program2.bas считывает сообщение Message$:
DIM Message$ AS STRING * 16
DEF SEG = 0
132
1 Процедура VOLUME в отдельном модуле
DIM SC)
COMMON SHARED /Sides/ SO
SUB Volume STATIC
Vol = S(l) - SB) - SC)
END SUB
FOR i = О ТО 15
MID$(message$, i + 1, 1) = CHR$(PEEK(&H4F0 + i))
NEXT i
DEF SEG
END
DATA
DATA — оператор, хранящий числовые и символьные дан-
ные для их последующего чтения оператором READ.
DATA константа[,константа]...
• константа — любая числовая или символьная константа.
Если символьная константа содержит запятые, двоеточия,
начальные или конечные пробелы, то она должна быть заключе-
на в кавычки.
Все операторы DATA должны располагаться в главной части
модуля.
READ
READ — оператор ввода/вывода, читающий данные из спис-
ка оператора DATA и присваивающий их значения переменным.
READ переменные
• переменные — список переменных, разделенных запятыми.
Эти переменные получают данные. Данные могут быть сим-
вольными или числовыми.
Операторы READ всегда используются совместно с операто-
рами DATA. READ присваивает значения из списка DATA свое-
му списку переменных один к одному. Типы данных и перемен-
ных должны соответствовать: чтение числового значения в сим-
вольную переменную не приведет к ошибке, напротив, попытка
считать символьную строку в числовую переменную вызовет
ошибку "Type mismatch" (Ошибка в типе данных).
Чтение числового значения, слишком большого для пере-
менной, также приведет к ошибке "Overflow" (Переполнение).
133
Символьные строки длиннее, чем соответствующие перемен-
ные, усекаются. Если они короче, то дополняются справа пробе-
лами и выравниваются по левой границе.
Оператором READ могут считываться только отдельные эле-
менты переменных пользовательского типа.
Один оператор READ может читать несколько операторов
DATA (данные должны идти в соответствующем порядке), и на-
оборот, несколько операторов READ могут читать один оператор
DATA. Если список переменных больше, чем список данных,
выдается сообщение об ошибке "Out of DATA" (Конец данных в
операторе DATA). Если список переменных короче, чем список
данных, следующий оператор READ начинает читать первый не-
прочитанный элемент; если данные не прочитаны никакими
READ, то они игнорируются.
Оператор RESTORE позволяет повторно считать данные из
списка DATA.
Пример. Представление пустых элементов списка.
DATA abc,,def
DATA 1,,2
READ A$, B$, C$ 'B$ = ""
PRINT A$, B$, C$
PRINT
READ А, В, С 'В = О
PRINT А, В, С
abc de f
10 2
RESTORE
RESTORE — оператор ввода/вывода, позволяющий операто-
ру READ повторно считать данные из списка оператора DATA.
RESTORE [метка]
• метка — метка оператора DATA, с которого нужно начать
считывать новую порцию данных.
Если метка опущена, то следующий оператор READ будет
считывать данные из первого в программе оператора DATA.
134
Пример. Представление пустых элементов списка.
DATA "Красный", "Желтый", "Зеленый"
ml:
DATA "Синий", "Фиолетовый", "Бордовый"
READ A$, В$, С$
PRINT A$, В$, С$
PRINT
RESTORE
READ Red$, Yellow$, Green$
PRINT Red$, Yellow$, Green$
PRINT
RESTORE Ml:
READ A$, B$, C$
PRINT A$, B$, C$
Вывод:
Красный Желтый Зеленый
Красный Желтый Зеленый
Синий Фиолетовый Бордовый
От Издательства
Данная книга, изданная впервые в 1994
году для широкого круга профессионалов
и любителей языка QuickBASIC 4.5,
приобрела большую популярность в
ВУЗах, колледжах, школах и лицеях
страны. Не будучи изначально кано-
ническим учебником, она переиздается в
качестве пособия ввиду острой пот-
ребности учебных заведений в литературе
по языкам программирования.
Издательство, заинтересованое в усовер-
шенствовании книги, с благодарностью
примет все критические замечания, советы
и пожелания педагогов и учащихся.
ОПЕРАТОРЫ ПЕРЕДАЧИ
УПРАВЛЕНИЯ
Операторы цикла
Циклы повторяют блок операторов определенное количество
раз, либо пока условие цикла не станет истинным или ложным.
В QuickBASIC существуют три вида циклов:
1. FOR...NEXT;
2. WHILE...WEND;
3. DO... LOOP;
FOR...NEXT
FOR...NEXT — управляющий оператор , повторяющий блок
операторов указанное число раз.
Синтаксис
FOR счетчик = начало ТО конец [STEP шаг]
[операторы_цикла]
[EXIT FOR]
NEXT [счетчик [,счетчик...]]
Пример
FOR 1% = 1 ТО 10
Аггау%A%) = 1%
NEXT
• счетчик — числовая переменная, используемая как счетчик
цикла;
• начало — начальное значение счетчика;
• конец — конечное значение счетчика;
• шаг — шаг изменения значения счетчика, по умолчанию 1.
Цикл FOR...NEXT выполняется только в том случае, если
начало плюс шаг меньше или равно конечному значению счетчи-
ка. Если конец меньше начала, то шаг должен быть отрицатель-
ным. На рисунке показана логика цикла FOR...NEXT при поло-
жительном значении шага.
( Начало цикла J
СЧ6ТЧИК = тттяр
Логика цикла FORJMEXT
при положительном значении шага
Нет
Выполняются
операторы цикла
(между TOR и NEXT)
Увеличивается счетчик
счет
ю"счетчик +1 или
подсчетчик + шаг
Да
С
Конец цикла
)
Пример:
FOR i = 32 ТО 255
PRINT CHR$(i);
NEXT i
Далее показана логика цикла FOR...NEXT при отрицатель-
ном значении шага.
138
Пример:
FOR i = 255 TO 32 STEP -1
PRINT CHR$(i);
NEXT i
Цикл выполняется до тех пор, пока текущее значение счетчика
не выйдет за рамки его конечного значения. При завершении теку-
щего цикла к значению счетчика прибавляется значение шага.
Если начало и конец имеют одно и то же значение, цикл
выполняется один раз, вне зависимости от значения шага. Если
шаг равен нулю, цикл продолжается неопределенное время.
Допускается вкладывать циклы FOR...NEXT, то есть поме-
щать цикл FOR...NEXT внутри другого цикла FOR...NEXT. Счет-
чикам вложенных циклов необходимо давать разные имена1.
Оператор NEXT для внутреннего цикла должен предшество-
вать оператору NEXT для внешнего цикла.
FOR I = 1 ТО 10 ' Это внешний цикл
FOR J = 1 ТО 10 ' Это вложенный цикл
FOR К = 1 ТО 10 ' Еще один вложенный цикл
NEXT К
NEXT J
NEXT I
1 Обычно при использовании циклов FOR.. NEXT первому счетчику цикла
дается имя i, вложенному в него — j, затем к, 1 и далее по алфавиту.
139
Логика цикла FOR-NEXT
при отрицательном значении шага
Начало цикла
счетчик = шаг
Конец цикла
Выполняются
операторы цикла
(между FOR и NEXT)
Уменьшается счетчик:
счетчик=счетчик -1 или
счетчик=счетчик - шаг
Оператор NEXT вида: NEXT К, J, I эквивалентен операто-
рам: NEXT К: NEXT J: NEXT I
Если вам необходимо выйти из цикла до его завершения,
используйте оператор альтернативного выхода из цикла EXIT
FOR:
FOR I = 1 ТО 10
IF GodBye = TRUE THEN EXIT FOR
NEXT I
Если вы опустите переменную-счетчик в операторе NEXT, он
будет принадлежать ближайшему открытому оператору FOR1. Ес-
ли такового нет, вы получите сообщение об ошибке "NEXT
without FOR" (NEXT без FOR).
QuickBASIC поддерживает значения двойной точности в ка-
честве параметров начала, конца и счетчика цикла FOR...NEXT,
но лучше использовать целые переменные2.
Пример: вывод первых 11 столбцов треугольника Паска-
ля. Каждый элемент треугольника является суммой двух
элементов слева от него.
CLS
CONST maxcol=ll
DIM A(maxcol,maxcol)
FOR m = 1 TO MAXCOL
'Верхняя и нижняя границы = 1.
Л(т,1) = 1 : A(m,m) = 1
NEXT m
1 Рекомендуется этого не делать из соображений удобочитаемости исходного
текста программы. Например:
'счетчики циклов опущены
FOR i = 1 ТО 10: FOR j = 1 ТО 15: ... : NEXT :NEXT
'счетчики циклов присутствуют
FOR i = 1 ТО 10: FOR j = 1 TO 15: .. : NEXTj: NEXT I
2 Это значительно сокращает время работы цикла, особенно это становится
заметно в программах, требующих интенсивных математических вычислений.
140
FOR m = 3 TO MAXCOL
FOR n = 2 TO m-1
A(m,n) = A(m-l,n-l) + A(m-l,n)
NEXT n
NEXT m
'Вывод с середины экрана.
startrow = 13
FOR m = 1 TO MAXCOL
col = 6 - m
row = startrow
FOR n = 1 TO m
LOCATE row,col : PRINT A(m,n)
row = row + 2
NEXT n
PRINT: startrow = startrow - 1
NEXT m
Результат:
WHILE... WEND
WHILE...WEND — управляющий оператор, выполняющий
блок операторов до тех пор, пока указанное условие истинно.
141
1
1 10
1 9
1 8 45
1 7 36
1 6 28 120
15 21 84
14 15 56 210
13 10 35 126
12 6 20 70 252
13 10 25 126
14 15 56 210
15 21 84
1 6 28 120
1 7 36
1 8 45
1 9
1 10
1
Синтаксис
WHILE условие
[операторы]
WEND
INPUT R$
WHILE R$
PRINT
INPUT
WEND
о "Д"
"Ответ
R$
Пример
AND R$
должен
о "Н"
быть Д или Н"
• условие — логическое выражение, возвращающее не ноль
("истина") или ноль ("ложь");
• операторы — любое количество операторов.
Пока условие истинно (его значение не равно нулю), опера-
торы будут циклически выполняться. Если условие ложно (его
значение равно нулю), выполняется оператор, следующий за
WEND.
( Начало цикла )
Логика цикла WHILE-WEND
Вычисляется
условие цикла
Да
Выполняются
операторы цикла
(между WHILE и WEND)
Нет
j
( Конец цикла J
142
Циклы WHILE...WEND могут вкладываться друг в друга лю-
бое число раз, но каждому оператору WHILE должен соответ-
ствовать свой WEND. WHILE без WEND приводит к ошибке
"WHILE without WEND" (WHILE без WEND), a WEND без
WHILE- к ошибке "WEND without WHILE" (WEND без
WHILE).
Пример. Пузырьковая сортировка массива.
DEFINT A-Z
CONST FALSE = 0, TRUE = NOT FALSE
'резервируется массив из десяти символьных элементов
DIM a$A0)
присваивается значение
1 каждому элементу массива пр
а$A)
а$B)
а$C)
а$D)
а$E)
а$F)
а$G)
а$(8)
а$(9)
а$A0)
max =
= "Москва"
= "Ленинград"
= "Куйбышев"
= "Алма-Ата"
= "Хабаровск"
= "Новосибирск"
= "Владивосток"
= "Калинин"
= "Дмитров"
= "Жуковский"
UBOUND(a$): exchange =
TRUE
' Сортировать, пока все элементы не изменятся.
WHILE exchange = TRUE
exchange = FALSE
' Сравнение элементов массива попарно. Если произошла
1 замена, присвоить переменной exchange значение TRUE.
FOR i = 2 ТО max
IF a$(i - 1) > a$(i) THEN
exchange = TRUE
SWAP a$(i - 1), a$(i)
END IF
NEXT i
WEND
CLS
1 вывести на экран отсортированный массив
FOR i = 1 ТО max: PRINT a$(i): NEXT i
END
ИЗ
Результат:
Алма-Ата
Владивосток
Дмитров
Жуковский
Калинин
Куйбышев
Ленинград
Москва
Новосибирск
Хабаровск
DO...LOOP
DO...LOOP — управляющий оператор, который повторяет
блок операторов, пока условие истинно, или до тех пор, когда
оно станет ложным. Существует два варианта цикла DO...LOOP:
• Цикл DO...LOOP с проверкой выражения в начале:
DO WHILE...LOOP;
DO UNTIL...LOOP;
• Цикл DO...LOOP с проверкой выражения в конце:
DO...LOOP WHILE;
DO ...LOOP UNTIL;
Проверка выражения в начале цикла:
Синтаксис
DO [{WHILE | UNTIL}
логичесое_выражение]
[операторы_цикла]
[EXIT DO]
LOOP
Пример
DO UNTIL INKEY$ <> ""
'Пустой цикл, в котором ожидается
'нажатие любой клавиши
LOOP
логическое_выражение — выражение, имеющее ненулевое
значение (истина) или нулевое (ложь);
операторы_цикла — любое количество операторов, которые
выполняются, пока выражение истинно.
144
145
Логика цикла DO WHILE-LOOP
Логика цикла DO UNTNLJ.OOP
Проверка выражения в конце цикла:
Синтаксис
DO
[операторы_цикла]
[EXIT DO]
LOOP [WHILE I UNTIL
логическое_выражение]
DO
INPUT "
Total =
LOOP WHILE
Пример
Число: "
Total +
Ch <> 0
; Ch
Ch
логическоевыражение — выражение, имеющее ненулевое
значение (истина) или нулевое (ложь);
операторыцикла — любое количество операторов, которые
выполняются, пока выражение истинно.
I Напало цикла )
Логика цикла DOJ.OOP WHLE
истина?
Нет
Конец цикла
146
( Начало цикла )
Логика цикла DO-LOOP UNTIL
Вьшолыяются операторы
цикла (между DO и условием
LOOPUNTDL)
Вычисляется
условие цикла
Нет
Если опустить проверку условия в начале или в конце цикла
DO...LOOP, то вы получите бесконечный цикл. Чтобы выйти из
бесконечного цикла DO...LOOP используйте оператор EXIT DO
(EXIT DO также может оказаться полезным для альтернативного
выхода из цикла DO...LOOP с проверкой выражения в начале
или в конце):
Nomeг = 1
DO
Nomer = Nomer + 1
IF Nomer = 444 THEN EXIT DO
LOOP
Пример. Программа пузырьковой сортировки массива.
DEFINT A-Z
CONST noexchange = -1
'резервирование массива из 12 элементов
DIM ExesA2)
147
'заполняем массив числами
FOR i = 1 ТО 12
Exes(i) = 13 - i
NEXT i
limit = 12
CLS
PRINT "Исходный массив:"
FOR i = 1 TO 12
PRINT Exes(i);
NEXT i
LOCATE 4, 1: INPUT "Нажмите ENTER", press$
DO
exchange = noexchange
FOR i = 1 TO limit - 1
IF Exes(i) > Exes(i + 1) THEN
SWAP Exes(i), Exes(i + 1)
exchange = i
END IF ¦
NEXT i
limit = exchange
'Сортировать, пока все элементы не ранжированы.
LOOP UNTIL exchange = noexchange
PRINT
PRINT "Отсортированный массив:"
FOR i = 1 TO 12
PRINT Exes(i);
NEXT i
END
Результат:
Исходный массив:
12 11 10 987654321
Нажмите ENTER
Отсортированный массив:
123456789 10 11 12
148
Условные операторы
IF...THEN...ELSE
IF...THEN...ELSE — управляющий оператор, осуществляющий
условное ветвление операций, основанное на оценке логического
выражения. Выражение может быть истинным или ложным.
IF...THEN...ELSE можно записать в блочной или линейной
форме.
Блочная форма
Синтаксис
IF логическое_выражение_1 THEN
[олераторы_1]
[ELSEIF логическое выражение_2
THEN
[операторы_2]
•
¦ .
[ELSE
[операторы_п]]
END IF
IF X >
PRINT
ELSEIF
PRINT
ELSE
PRINT
END IF
Примеры
0 THEN
"X - положительно"
X < 0 THEN
"X - отрицательно"
"X - ноль"
• логическое_выражение_1 — выражение, возвращающее не-
нулевое значение (истина) или ноль (ложь);
• операторы_1 — любое количество операторов, выполняющих-
ся при условии: логическое_выражение_1 — "истина";
149
• логическое_выражение_2 — выражение, возвращающее не-
нулевое значение (истина) или ноль (ложь);
• операторы_2 — любое количество операторов, выполняющих-
ся при условии: логическое_выражение_2 — "истина";
• операторы_п — операторы выполняющиеся при прочих усло-
виях.
Линейная форма
IF логическое_выражение THEN операторы_1 [ELSE операторы_2]
• операторы_1 — операторы, выполняющиеся при значении
логического выражения "истина";
• операторы_2 — при значении "ложь".
Логика работы при блочной и линейной форме
При блочной форме, QuickBASIC тестирует первое логи-
ческое выражение. Если оно ненулевое ("истина"), выпол-
няются операторы блока THEN. Если первое выражение рав-
но нулю ("ложь"), QuickBASIC оценивает каждое условие
ELSEIF. При выполнении такого условия выполняются опе-
раторы данного блока. Если ни одно из условий ELSEIF не
выполнено (все = "ложь"), выполняются операторы блока
ELSE.
Блоки ELSE и ELSEIF могут быть опущены. В блочную
структуру IF можно вставить любое количество условий ELSEIF.
Каждый из блоков может также содержать вложенные блочные
структуры IF.
Для идентификации блочной структуры IF QuickBASIC оп-
ределяет, что находится в строке после слова THEN. Структура
считается линейной, если после THEN есть операторы (кроме
комментариев).
Операторы IF, ELSE, ELSEIF и END IF должны быть пер-
выми операторами в строке. Блок должен заканчиваться операто-
ром END IF.
Если проверяется одно или два условия, то имеет смысл ис-
пользовать линейную форму IF...THEN...ELSE:
IF Otvet$ = "НЕТ" THEN PRINT "ПРОЩАЙ, АМИГО!"
IF Nomer = 1 THEN PRINT A$ ELSE INPUT B$
150
Если предполагается проверять больше, чем два условия,
то используйте блочную форму IF...THEN...ELSE. Программы,
написанные с использованием блочной формы легче читаются
и отлаживаются. При проверке сложных условий можно ис-
пользовать и более современную конструкцию SELECT...END
SELECT.
Пример. Использование линейной формы IF...THEN...ELSE:
CLS
DO
INPUT "Введите число, большее 0 и меньшее 1000:", х
IF х >= 0 AND х < 1000 THEN EXIT DO ELSE PRINT
"Повторите"
LOOP
IF x < 10 THEN у = 1 ELSE IF x < 100 THEN у = 2 ELSE у = 3
PRINT "Число имеет"; у; "знаков"
Пример. Использование блочной формы IF...THEN...ELSE:
CLS
DO
INPUT "Введите число, большее 0 и меньшее 1000:", х
IF х >= 0 AND х < 1000 THEN
EXIT DO
ELSE
•PRINT "Повторите"
END IF
LOOP
IF x < 10 THEN
у = 1
ELSEIF x < 100 THEN
У = 2
ELSE
у = 3
END IF
PRINT "Число имеет"; у; "знаков *
SELECT...END SELECT
SELECT CASE — управляющий оператор, выполняющий
один из нескольких блоков операторов в зависимости от значе-
ния выражения.
151
Синтаксис
SELECT CASE выражение_выбора
[CASE список_выражений_1]
[операторы_цикла_1]
[CASE список_выражений_2]
[операторы_цикла_2]]
[CASE ELSE
[операторы_цикла_п]]
END SELECT
Пример
INPUT TestValue
SELECT CAST TestValue
CASE 1, 3, 5, 7, 9
PRINT "Нечетное"
CASE 2, 4, 6, 8
PRINT "Четное"
CASE IS < 1
PRINT "Очень маленькое"
CASE IS > 9
PRINT "Очень большое"
CASE ELSE
PRINT "He целое значение"
END SELECT
• выражениевыбора — любое числовое или символьное выра-
жение;
• список_выражений — одно или более выражений такого же
типа, как и выражениевыбора. Ключевое слово CASE долж-
но предшествовать блоку операторов;
• операторыцикла — содержат любое количество операторов.
Элементы списка_выражений должны иметь одну из следу-
ющих трех форм:
выражение[,выражение...];
выражение ТО выражение;
IS выражение с операцией.
выражение — любое числовое или символьное выражение
того же типа, что и выражениевыбора;
операция — любая из следующих операций:
152
<
<=
>
о
=
меньше;
меньше либо
больше;
больше либо
не равно;
равно
равно;
равно;
Если выражение_выбора отвечает условиям спискавыра-
жений данного блока CASE, выполняются операторы из этого
блока. После этого управление передается оператору, следующе-
му за END SELECT.
Если вы используете ключевое слово ТО для определения
пределов выражения, то меньшее значение должно быть первым.
Например, операторы блока CASE -I TO -5 не выполняются, ес-
ли выражение_выбора равно -4. Эта строка должна быть написа-
на как CASE -5 ТО -1.
Операции сравнения можно использовать только с ключевым
словом IS.
Блок операторов CASE ELSE выполняется только в том слу-
чае, если выражениевыбора не удовлетворяет ни одному из ус-
ловий CASE. Обычно используется для обработки нежелательных
значений.
Если нет блока операторов CASE ELSE и нет ни одного вы-
ражения в условиях CASE, программа выполняется без ошибок.
Можно использовать несколько выражений или пределов в
каждом условии CASE. Например:
CASE I TO 4, 7 ТО 9, 11, 13, IS > MaxNumber%
Это же справедливо и для символьных выражений:
CASE "трактор", "ЭЭЭЭ" ТО "ЯЯЯЯ", Testltem$
Здесь CASE выбирает те строки символов, которые^ равны
значению "трактор", текущему значению TestltemS, или находят-
ся между "ЭЭЭЭ" и "ЯЯЯЯ" в алфавитном порядке.
Строки оцениваются в соответствии с ASCII-кодами их сим-
волов. Строчные буквы имеют большие ASCII-коды, чем про-
писные, например:
153
"кот" > "Кот" > "КОТ"
Если выражение_выбора удовлетворяет нескольким условиям
CASE, выполняется блок операторов, идущий первым.
Блоки SELECT CASE могут быть вложенными. Каждый блок
должен иметь завершение END SELECT.
Пример. Распознавание нажатия различных клавиш.
CONST DOWN = 80, UP = 72, LEFT = 75, RIGHT = 77
CONST ESC = 27, ENTER=13
CONST HOME = 71, ENDKEY = 79, PgDn = 81, PgUp = 73
DO
1 Нажатие клавиши
DO
choice$ = INKEY$
LOOP WHILE choice$ = ""
IF LEN(choice$) = 1 THEN
'Клавиши ASCII
SELECT CASE ASC(choice$)
CASE ESC '
PRINT "ESC"
END
CASE ENTER
PRINT "ENTER"
CASE IS < 32, 127
PRINT "Управляющие коды"
CASE 48 TO 57
PRINT "Число: "; choice$
CASE 65 TO 90, 128 TO 159
PRINT "Прописная буква: " ,• choice$
CASE 97 TO 122, 160 TO 175, 224 TO 241
PRINT "Строчная буква: "; choice$
CASE 17 6 TO 223
PRINT "Символ псевдографики: "; choice$
CASE ELSE
PRINT "Знак пунктуации: "; choice$
END SELECT
ELSE
'Преобразование расширенного кода
choice$ = RIGHT$(choice$, 1)
SELECT CASE choice$
CASE CHR$(DOWN)
PRINT "Стрелка вниз"
CASE CHR$(UP)
PRINT "Стрелка вверх"
154
CASE CHR$(PgDn)
PRINT "PGDN"
CASE CHR$(PgUp)
PRINT "PGUP"
CASE CHR$(HOME)
PRINT "HOME"
CASE CHR$(ENDKEY)
PRINT "END"
CASE CHR$(RIGHT)
PRINT "Стрелка вправо"
CASE CHR$(LEFT)
PRINT, "стрелка влево"
CASE ELSE
BEEP
END SELECT
END IF
LOOP
Подпрограммы
GOSUB...RETURN
GOSUB...RETURN — управляющие операторы вызова под-
программы и выхода из нее.
GOSUB метка_1
[операторы]
RETURN [метка_2]
• метка_1 — метка первой строки подпрограммы;
• метка_2 — метка строки, куда возвращается управление после
выхода из подпрограммы.
Вы можете вызвать подпрограмму любое количество раз.
Можно вызвать одну подпрограмму из другой. В тоже время под-
программа не может вызывать сама себя (быть рекурсивной). Од-
на подпрограмма может иметь несколько операторов RETURN.
GOSUB и RETURN должны находиться в одном модуле.
RETURN не может использоваться для передачи управления из
одной процедуры типа SUB или FUNCTION другой процедуре.
GOSUB...RETURN — устаревшая программная конструкция.
Вместо нее лучше использовать процедуры SUB или FUNCTION,
функцию DEF FN. Использовать в GOSUB...RETURN имеет смысл
155
только внутри процедур SUB или FUNCTION, при обращении к од-
ному фрагменту текста, когда выделение фрагмента в отдельную про-
цедуру нецелесообразно.
х%: GOSUB DrawResult
х% Л 2: GOSUB DrawResult
х% Л 4: GOSUB DrawResult
DrawResult:
IF y% = О THEN BEEP: RETURN
LOCATE 11, 10: PRINT y%
RETURN
SUB TestSub
SELECT CASE
CASE IS =
CASE IS =
CASE IS =
CASE ELSE
END SELECT
END SUB
(x%)
x%
1:
2:
3:
: .
y%
y%
y%
Функции
DEFFN
DEF FN — оператор, описывающий функцию как пользова-
тельскую.
Функция DEF FN может быть записана в блочной или в ли-
нейной форме.
DEF FNmmh[(параметры)] = выражение
Линейная форма
Блочная форма
DEF FNmmh [(параметры)]
[операторы]
FNимя = выражение
[операторы]
[EXIT DEF]
[операторы]
END DEF
• имя — имя переменной, до 40 знаков. Имя, комбинируемое с
FN, является именем функции. Имя может иметь знак опре-
деления типа, который указывает на тип возвращаемого зна-
156
чения. Для присвоения значения функции, присвойте его
полному имени так, как обычной переменной:
FNString$ = "Нет ответа."
• параметры — список переменных, разделенных запятыми.
При вызове функции, значения каждого аргумента присваи-
ваются соответствующему параметру. Аргументы передаются
по значению. DEF FN не поддерживает массивы, записи или
символьные строки фиксированной длины в качестве аргу-
ментов;
• выражение — выражение, вычисляющее результат функции.
В линейном синтаксисе выражение является телом функции.
Если нет выражений, присвоенных имени функции, по умол-
чанию возвращается 0 для числовой функции и пустая строка
("") для символьной функции.
Логика работы при блочной и линейной форме
Перед использованием, функция DEF FN должна быть оп-
ределена, иначе ее вызов приведет к ошибке "Function not
defined" (Функция не определена).
DEF FN не может находиться внутри другого определения
DEF FN. Функция также не может быть рекурсивной (вызывать
сама себя).
Для выхода из блочной функции до ее завершения исполь-
зуйте оператор EXIT DEF. Функция может вызываться только из
того модуля, в котором она определена; обращения из других мо-
дулей недействительны. Поэтому, если в программе несколько
модулей, то вы должны поместить определение функции DEF
FN в каждый модуль, или использовать включаемый (INCLUDE)
файл с определением функции DEF FN.
Вместо функции DEF FN имеет смысл использовать более
современную конструкцию FUNCTION...END FUNCTION. Бу-
дучи один раз определена, процедура FUNCTION может затем
быть вызвана из любого модуля Вашей программы. Кроме того в
процедуру FUNCTION можно передавать массивы и записи. Од-
нако, в редких случаях, использование функции DEF FN более
целесообразно, чем процедуры FUNCTION. Функция DEF FN
не проверяет тип передаваемого ей числового аргумента, что по-
зволяет писать функции DEF FN, которым можно передавать
любой числовой аргумент:
'функция fns$ превращает любое число в символьную строку
'и убирает начальный пробел
DEF fns$ (a):fns$ (а) = LTRIM$(STR$(а))
157
а = 100:
а = 100:
а# = 100:
а% = 100:
а& = 100:
результат
> 100<
>100<
>100<
>100<
>100<
PRINT "
PRINT "
PRINT
PRINT
PRINT
:
>" ;
>" ;
11 >••
ii >n
11 >"
STR$(a); "<"
fns$(a); "<"
; fns$(a#); "<¦
; fns$(a%); "<'
; fns$(a&); "<"
Процедуры (*)
FUNCTION
FUNCTION...END FUNCTION — оператор, указывающий
начало и конец процедуры FUNCTION.
FUNCTION имя [(параметры)][STATIC]
[операторы]
имя = выражение
[операторы]
END FUNCTION
• имя — задается как обычная переменная. Определяет тип
возвращаемых данных;
• параметры — список переменных, значения которых переда-
ются функции при ее вызове. Изменение значения параметра
внутри функции изменит его значение в вызывающем модуле;
• выражение — возвращаемое значение функции. Если имени
функции ничего не присваивается, возвращается значение по
умолчанию: для числовых функций — ноль, для символь-
ных — пустая строка ("");
• STATIC — указывает, что локальные переменные функции
сохраняются между вызовами. Иначе локальные переменные
считаются динамическими и их значения теряются при выхо-
де из функции. Атрибут STATIC не влияет на переменные,
описанные вне функции операторами DIM или COMMON с
атрибутом SHARED.
158
Чтобы передать в процедуру в качестве аргумента массив до-
статочно указать пустые скобки.
FUNCTION ParseLine (Keywords$(), KeywordTypes())
Процедура FUNCTION похожа на SUB. Она принимает па-
раметры, состоит из серии операторов и изменяет значения па-
раметров. В отличие от SUB, FUNCTION вызывается подобно
встроенной функции языка BASIC.
Также как и SUB, FUNCTION имеет локальные перемен-
ные. Любая переменная, не входящая в список параметров, явля-
ется локальной, за исключением переменных, описанных опера-
тором SHARED внутри процедуры или операторами DIM или
COMMON с атрибутом SHARED в главном модуле.
Для возвращения значения из функции, присвойте его име-
ни функции. Например, в функции BinarySearch вы можете при-
своить значение внутренней константы FALSE имени функции
для указания на то, что искомый контекст не найден:
FUNCTION BinarySearch(...)
CONST FALSE=0
1 Ничего не найдено. Вернуть FALSE.
IF Lower > Upper THEN
BinarySearch=FALSE
EXIT FUNCTION
END IF
END FUNCTION
Применение ключа STATIC слегка повышает скорость вы-
полнения, но STATIC не используется с рекурсивными процеду-
рами FUNCTION. Кроме того, при использовании ключа STA-
TIC вы должны сами заботится о присвоении начальных значе-
ний всем переменных процедуры, так как их старые значения со-
храняются между вызовами. Лучше не использовать этот ключ и
возложить эти проблемы на BASIC.
Рекурсивные процедуры FUNCTION
Процедуры FUNCTION могут быть рекурсивными, то есть
вызывать сами себя. Типичным случаем применения рекурсии
является функция вычисления факториала1:
1 Здесь п! обозначает факториал числа п, а не переменную п обычной точности
159
n!=n*(n-l)*(n-2)*...2*1
К примеру факториал числа 5 вычисляется как:
5! = 5*3*4*2*1 = 120
При использовании рекурсии вы обязательно должны пре-
дусмотреть условие выхода. В данном случае — при вводе нулево-
го значения (по определению факториал нуля равен единице).
Пример. Вычисление факториала
DECLARE FUNCTION Factorial* (n%)
Formats = "##_! = ###################«
DO
INPUT "Введите число от 0 до 20 (или -1 для выхода): "; Num%
IF Num% >= 0 AND Num% <= 20 THEN
PRINT USING Format$; Num%; Factorial*(Num%)
END IF
LOOP WHILE Num% >= 0
END
FUNCTION Factorial* (n%) STATIC
IF n% > 0 THEN 'Factorial вызывается снова, если
'N больше нуля.
Factorial* = n% * Factorial*(n% - 1)
ELSE
Factorial* = 1
END IF
END FUNCTION
SUB
SUB...END SUB — оператор, указывающий начало и конец
процедуры SUB.
SUB имя[список_параметров][STATIC]
[операторы]
[EXIT SUB]
[операторы]
END SUB
• имя — переменная, до 40 знаков, имя процедуры. Это имя не
должно использоваться другими операторами FUNCTION
или SUB или в подключаемой библиотеке;
160
• списокпараметров — содержит имена простых переменных и
массивов, передаваемых в процедуру. Имена в списке разде-
ляются запятыми. Любое изменение аргумента в процедуре
приведет к изменению его значения в вызывающем модуле.
Список_параметров имеет следующую форму:
переменная[()] [AS тип][, переменная[( )] [AS тип]]...
• переменная — имя переменной или массива (массив задается
с пустыми скобками);
• тип — тип переменной, может быть INTEGER, LONG, SINGLE,
DOUBLE, STRING или пользовательским. Не может быть фик-
сированной строкой. Строки фиксированной длины необходимо
преобразовать в строки переменной длины.
SUB и END SUB отмечают начало и конец процедуры, вы мо-
жете использовать оператор EXIT SUB для выхода из процедуры.
Процедуры вызываются оператором CALL или путем указа-
ния ее имени со списком аргументом. SUB используются подоб-
но операторам языка. Процедура SUB (также как и FUNCTION)
может быть рекурсивной.
Атрибут STATIC указывает, что все переменные, локальные
для процедуры SUB, являются статическими (STATIC) — их зна-
чения сохраняются между вызовами. Использование ключа STA-
TIC несколько повышает скорость выполнения процедуры, в то-
же время STATIC не используется в рекурсивных процедурах1.
Все переменные являются локальными, кроме тех, которые
описаны операторами DIM, REDIM, COMMON как SHARED в
главном модуле, или оператором SHARED в самой процедуре.
Внутри процедуры SUB нельзя определять процедуры SUB и
FUNCTION, функции DEF FN, а также использовать операторы
GOSUB, GOTO, RETURN для входа в процедуру или выхода из
процедуры.
Передача параметров в процедуры SUB и
FUNCTION (*)
Прежде чем использовать в программе процедуру SUB или
FUNCTION, необходимо уяснить отличие термина "параметр" от
термина "аргумент".
См. описание процедуры FUNCTION
161
Параметр
Имя переменной, используемое
в операторе SUB, FUNCTION
или DECLARE
Аргумент
Константа, переменная или
выражение, которое передает-
ся в процедуру SUB или FUN-
CTION при их вызове.
Как показано на рисунке, когда процедура вызывается, аргу-
менты передаются в тело процедуры через заголовок, причем
первый параметр получает значение первого аргумента, второй
параметр получает значение второго аргумента и так далее.
Параметры и аргументы
е процедурах SUB и FUNCTION
Аргументы
Вызов процедуры
Заголовок процедуры
CALL TestSub
f
(А%,
В!, "text")
SUB TestSub (Pl%, P2!, P3$) STATIC
v. u j
Параметры
Этот рисунок также демонстрирует еще одно важное прави-
ло: Хотя имена в списке аргументов и в списке параметров могут
быть разными, но между аргументами и параметрами должно
быть взаимно однозначное соответствие, т. е. должно совпадать
их количество и типы.
Список параметров может состоять из:
• имен переменных, кроме строк фиксированной длины;
• имен массивов, которые записываются следующим образом:
сначала указывается имя массива, за которым следуют пустые
скобки.
162
Список аргументов может состоять из:
• констант;
• выражений;
• имен переменных;
• имен массивов (с пустыми скобками)
Например, определение списка параметров процедуры
TestSub (Заголовок процедуры):
SUB TestSub (А%, Array(), RecVar as RecType, Cs$)
END SUB
Первый параметр А% — целое число; второй параметр
ArrayO — числовой массив обычной точности;1 третий параметр,
RecVar, является переменной-записью типа RecType, и четвертый
параметр, Cs$ — символьная строка.
Вызов процедуры TestSub демонстрирует передачу процедуре
TestSub четырех аргументов соответствующего типа:
TYPE RecType
Rank AS STRING * 12
SerialNum AS LONG
END TYPE
DIM RecVar as RecType
CALL TestSub (X%, A(), RecVar, "Дельфин")
FUNCTION или SUB — проблема выбора (*)
Если при разработке программы, у вас возникнет вопрос, ка-
кую из процедур, FUNCTION или SUB лучше всего применить,
воспользуйтесь этими рекомендациями.
Процедура FUNCTION возвращает одиночное значение, по-
этому ее использование оправдано в тех случаях, когда возврат
одного значения решает эту проблему. К примеру, если перед от-
1 Числовые переменные без явного указания их типа считаются обычной точ-
ности.
163
крытием файла, вам нужно убедиться, что он существует (необ-
ходимо получить одно значение — ДА или НЕТ), можно исполь-
зовать процедуру FUNCTION:
DECLARE FUNCTION Exist (file$)
DEFINT A-Z
CONST TRUE% = -1, FALSE% = 0
INPUT "Введите имя файла"; FileName$
IF Exist (FileName$) THEN
PRINT "Этот файл существует"
ELSE
PRINT "Такого файла нет"
END IF
FUNCTION Exist (file$)
i ****************************************************
'эта функция проверяет, если такой файл
'если есть, процедуре Exist присваивается значение -1
1 (Истина) иначе значение 0 (Ложно)
|****************************************************
1 определяем незанятый номер файла
nf = FREEFILE
'открываем файл как двоичный
OPEN file$ FOR BINARY AS #nf
1 проверяем длину файла в байтах
IF LOF(nf) > О THEN
'если длина больше нуля, то файл существует
CLOSE #nf: Exist = TRUE
ELSE
'если файл не существовал, то открытие его как двоичного
1 приводит к появлению на диске файла с нулевой длиной,
1 а такой файл нужно уничтожить.
CLOSE #nf: KILL file$
Exist = FALSE
END IF
Напротив, процедура SUB используется в тех случаях, когда
необходимо провести какие-либо действия над переменными из
списка аргументов, либо получить несколько выходных значений.
Предположим, вам необходимо транспонировать матрицу
(проще говоря — транспонировать матрицу — это значит поло-
жить ее "на бок"). Использование процедуры SUB решает эту
проблему:
DECLARE SUB TransMatrix (a%(), b%())
1 все переменные целые
DEFINT A-Z
164
'резервируется массив для исходной
'и транспонированной матриц
DIM MatrixlE, 5), matrix2E, 5)
'матрица Matrixl заполняется числами от 1 до 25
start = 1
FOR i = 1 ТО 5
FOR j = 1 TO 5
Matrixl(i, j) = start
start = start + 1
NEXT j
NEXT i
CLS
'выводится исходная матрица
PRINT "Исходная матрица:": PRINT
FOR i = 1 TO 5
FOR j = 1 TO 5
PRINT USING "## "; Matrixl(i, j);
NEXT j
PRINT
NEXT i
PRINT
1 производится транспонирование матрицы
CALL TransMatrix(Matrixl(), matrix2())
1 выводится транспонированная матрица
PRINT "Транспонированная матрица": PRINT
FOR i = 1 TO 5
FOR j = 1 TO 5
PRINT USING "## "; matrix2(i, j);
NEXT j
PRINT
NEXT i
SUB TransMatrix (a(), b())
i л**************************************
'эта процедура транспонирует матрицу а()
'результат заносится в матрицу Ь()
I***************************************
'Определяется размерность матрицы а,
'предполагается, что матрица "квадратная"
'т. е. число строк=числу столбцов
kolvo = UBOUND(a)
FOR i = 1 ТО kolvo
FOR j = 1 TO kolvo
b(j, i) = a(i, j)
NEXT j
NEXT i
END SUB
165
Результат
Исходная ]
1
6
11
16
21
2
7
12
17
22
матрица:
3
8
13
18
23
4
9
14
19
24
Транспонированная
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
5
10
15
20
25
маа
21
22
23
24
25
Другие управляющие операторы
END
END — оператор-указатель конца программы, процедуры
или блока.
END [DEF I FUNCTION I IF I SELECT | SUB I TYPE]
END DEF
END FUNCTION
END IF
END SELECT
END SUB
END TYPE
Конец определения функции DEF FN;
Конец процедуры FUNCTION;
Конец блока IF...THEN...ELSE;
Конец блока SELECT CASE;
Конец процедуры SUB;
Конец описания
пользовательского типа данных.
Простой END останавливает выполнение программы и
закрывает все файлы. В .ЕХЕ-программах возвращает управле-
ние операционной системе. В среде QuickBASIC возвращает
управление среде.
Компилятор всегда подразумевает END как окончание програм-
мы, так что конце программы оператор END можно опускать.
166
EXIT
EXIT — управляющий оператор, производящий выход из
блока или модуля до его завершения.
EXIT DEF I DO I FOR I FUNCTION I SUB
EXIT DEF
EXIT FOR
EXIT
FUNCTION
EXIT SUB
Выход из функции DEF FN при выполнении
какого-либо условия. Программа продолжает
работу с оператора, идущего после вызова
этой функции;
Альтернативный выход из цикла FOR...NEXT;
Выход из процедуры FUNCTION. Программа
продолжается с оператора, идущего после
вызова функции;
Выход из процедуры SUB. Программа продол-
жается после оператора CALL.
Операторы EXIT не означают конец данной структуры или
модуля. Они используются только для альтернативного выхода.
Для организации конца используется управляющий оператор
END.
Пример. Использование оператора EXIT FOR. Удаление
концевых пробелов из символьной строки.
s$ = "Программное обеспечение "
3 = О
1 Сканируем строку от конца к началу и находим
' первый символ, не являющийся пробелом.
FOR i = LEN(s$) TO 1 STEP -1
с$ = MID${s$,i,l)
IF c$ <> " " THEN
j = i
EXIT FOR ' символ найден, выходим из цикла
END IF
NEXT i
1 Удалим ненужные символы справа.
s$ = LEFT$(s$,j)
PRINT ">"; s$; "<"
END
167
Результат:
>Программное обеспечение<
STOP
STOP — управляющий оператор, останавливающий выпол-
нение программы.
STOP
При запуске в среде QuickBASIC оператор STOP оставляет
файлы открытыми и не производит выхода в операционную сис-
тему. Напротив, оператор STOP в .ЕХЕ-файле закрывает все
файлы и передает управление операционной системе.
Раньше оператор STOP использовался как средство отладки,
для того, чтобы прервать выполнение программы в нужном мес-
те. В среде QB имеется более удобное средство — "Toggle
Breakpoint" (Точка Прерывания). Чтобы поставить точку преры-
вания подведите курсор к нужной строке программы и нажмите
клавишу {F9}. Запустите программу на выполнение ({SHIFT-F5}).
Когда программа достигнет точки прерывания, она остановится,
вы сможете посмотреть значения переменных ({SHIFT-F9}), до-
бавить или убрать наблюдение, или продолжить выполнение
программы {F5}.
SYSTEM
SYSTEM — управляющий оператор, закрывает все открытые
файлы и возвращает управление операционной системе.
SYSTEM
Оператор SYSTEM производит выход в систему из среды
QuickBASIC только тогда, когда программа запущена с команд-
ной строки с ключом /RUN.
Ввод SYSTEM в окне Immediate приведет к выходу из среды
QuickBASIC.
В .ЕХЕ-программах END и SYSTEM действуют идентично.
Использовать SYSTEM имеет смысл в том случае, когда вы хоти-
те запускать программу в виде исходного текста (не компилируя
ее в .ЕХЕ-файл).
168
Пример. Предположим, у нас имеется программа TEST.BAS
PRINT "Я очень умная программа!": PRINT
PRINT "Исполняюсь автономно, как .ЕХЕ-файл"
SYSTEM
Если запустить эту программу с ключом1 /RUN, то она от-
работает, и передаст управление операционной системе, не пока-
зывая своего исходного текста:
C:\QB45>qb /runTEST.BAS
1 Более подробно о ключах запуска среды QB написано в Приложении 2
"Запуск, редактирование и отладка программы".
169
ВВОД-ВЫВОД НА
ВНЕШНИЕ УСТРОЙСТВА
Клавиатура
INPUT
INPUT — оператор ввода/вывода, считывающий данные с
клавиатуры во время выполнения программы и размещающий их
в списке переменных.
INPUT[;][вопрос"{;I,}]переменные
• ; — точка с запятой сразу после INPUT оставляет курсор на
той же линии экрана после нажатия клавиши {ENTER};
• "вопрос" — символьная константа. Приглашение к вводу
данных;
• ; — печатает знак вопроса после символьной строки;
• , — печатает строку без знака вопроса;
• переменные — список переменных, разделенных запятыми,
принимающий введенные значения.
Оператор INPUT останавливает программу и ждет ввода
данных. Количество вводимых данных должно соответствовать
количеству переменных в списке. Первый символ после очеред-
ной запятой, если это не пробел, ASCII 13 (CR — возврат карет-
От Издательства
Данная книга, изданная впервые в 1994
году для широкого круга профессионалов
и любителей языка QuickBASIC 4.5,
приобрела большую популярность в
ВУЗах, колледжах, школах и лицеях
страны. Не будучи изначально кано-
ническим учебником, она переиздается в
качестве пособия ввиду острой пот-
ребности учебных заведений в литературе
по языкам программирования.
Издательство, заинтересованое в усовер-
шенствовании книги, с благодарностью
примет все критические замечания, советы
и пожелания педагогов и учащихся.
ки) или ASCII 10 (LF — перевод строки), подразумевается как
начало новой вводимой единицы.
Переменные могут быть числовыми или символьными, эле-
ментами массивов, элементами записей. Типы данных в списке и
вводимых с клавиатуры должны совпадать. Если в символьной
строке необходимо ввести запятую, то символьную строку нужно
заключить в кавычки.
Данные для переменных пользовательского типа (записей)
юлжны вводиться раздельно:
ГУРЕ Demograph
FullName AS STRING * 25
Age AS INTEGER
END TYPE
DIM Person AS Demograph
INPUT "Введите имя и возраст: ";Person.FullName,
Person.Age
Если вы ввели значения не тех типов, или их количество не
совпадает с количеством переменных в списке, вы получите со-
общение об ошибке "Redo from start" (Повторите сначала).
Пока вы не закончили ввод, значения не присваиваются пе-
ременным. Можно редактировать вводимые данные до нажатия
клавиши {ENTER}. Клавиши редактирования в основном анало-
гичны клавишам редактирования среды QB:
Клавиша
RIGHT
LEFT
CTRL+RIGHT
CTRL+LEFT
HOME
END
INS
TAB
DEL
BACKSPACE
Выполняемое действие
Курсор на один символ вправо;
Курсор на один символ влево;
Курсор на одно слово вправо;
Курсор на одно слово влево;
Курсор к началу вводимой строки;
Курсор к концу вводимой строки;
Переключение вставка/замещение;
Табуляция вправо;
Стереть символ, на который указывает курсор;
Стереть символ перед курсором. В начале
строки — указанный курсором;
172
CTRL+END
ESC
ENTER
CTRL+T
CTRL+BREAK
или CTRL+C
Стереть от курсора до конца строки;
Стереть всю строку ввода;
Конец ввода;
Включает/выключает список значений
F-клавиш в последней строке экрана;
В среде QuickBASIC обрывает выполнение
программы. В .ЕХЕ-программе — вызывает
аварийный выход в DOS.
LINE INPUT
LINE INPUT — оператор ввода/вывода, присваивающий
вводимую строку (до 255 символов) символьной переменной без
влияния знаков-разделителей.
LINE INPUT[;] ["вопрос";] символьная_переменная
• вопрос — символьная константа, приглашение на ввод дан-
ных. Можно включить в нее знак вопроса "?";
• символьная_переменная — принимает все символы до нажа-
тия клавиши ENTER.
В отличии от оператора INPUT знак "?" после вопроса не
выводится. Знак ";" перед вопросом сохраняет курсор на той же
строке после нажатия клавиши ENTER. LINE INPUT использует
те же клавиши редактирования, что и INPUT.
INPUTS
INPUTS — функция ввода/вывода, читающая символьные
строки с клавиатуры.
INPUT$(n)
• п — количество символов, читаемых с клавиатуры.
Знаки не дублируются на экран (ввод без эха). Можно прер-
вать исполнение данной функции нажатием CTRL+BREAK. В
отличии от функции INKEYS данная функция ждет ввода ука-
занного количества символов.
173
Пример. Задержка исполнения программы до нажатия клавиши.
CLS
PRINT "Для продолжения нажмите любую клавишу"
INPUT$A)
INKEY$
INKEY$ — функция ввода/вывода, читающая символы с
клавиатуры.
INKEY$
INKEYS возвращает одно- или двухбайтную строку, содер-
жащую символ, считанный с клавиатуры. Если символ не был
считан, то возвращается нулевая строка (то есть данная функция
не ожидает ввода в отличии от оператора INPUTS).
Однобайтная строка содержит ASCII-символ. Двухбайтная
строка содержит расширенный код: первый символ равен ASCII
О, второй — расширенный код специальных клавиш и клавиш
управления курсором.
INKEYS не дублирует ввод с клавиатуры выводом на экран
(ввод осуществляется без эха). Особо обрабатываются нажатия
клавиш:
CTRL+BREAK
CTRL+ALT+DEL
CTRL+NUMLOCK
или PAUSE
PRINT SCREEN
Останавливается выполнение в среде
QuickBASIC. В .ЕХЕ-виде не обрабатывается;
Происходит перезагрузка компьютера;
Приостановка выполнения программы;
Печать содержимого экрана.
Пример. Задержка до нажатия клавиши.
PRINT "Нажмите любую клавишу..."
DO
LOOP WHILE INKEY$ =""
174
Экран
PRINT
PRINT — оператор ввода/вывода, выдающий данные на эк-
ран.
PRINT [список_выражений][{,I;}]
• Список_выражений — выражения любого типа, кроме
пользовательского. Символьные константы в списке выраже-
ний должны заключаться в кавычки.
Если все аргументы опущены, выводится пустая строка. Если
списоквыражений указан, то значения выражений выводятся на
экран по порядку
Положительные числа выводятся с пробелом перед значени-
ем, отрицательные выводятся со знаком "минус".
Существует два формата вывода чисел обычной и двойной
точности: с фиксированной и плавающей точкой. Если выводит-
ся значение обычной точности с семью или менее значащими
цифрами или число двойной точности с пятнадцатью или менее
значащими цифрами без потери точности, они выводятся в фор-
мате с фиксированной точкой. Иначе — с плавающей. Например,
число 1.1 Е-6 выводится как .0000011, а число 1.1Е-7 выводится
как 1.1 Е-7. Или число 1.ID-15 - как .0000000000000011, а число
1.1D-16- как 1.1D-16.
Для печати информации отдельных элементов пользовательско-
го типа данных , пользуйтесь выводом ее отдельных элементов:
ТУРЕ МуТуре
Word AS STRING * 20
Count AS LONG
END TYPE
DIM Myrec AS MyType
PRINT Myrec.Word
Позиция каждого выводимого элемента списка выражений
определяется знаками-разделителями списка. BASIC делит строку
175
экрана на зоны по 14 символов каждая. В списке выражений за-
пятая перед элементом указывает на то, что он будет выведен с
начала следующей зоны. Точка с запятой означает, что этот эле-
мент будет выведен сразу после предыдущего. Пробелы или зна-
ки табуляции имеют такой же эффект, как и точка с запятой.
Если запятая или точка с запятой завершают список выра-
жений, то следующий оператор PRINT начинает вывод с той же
строки. Если список не завершается разделителем, то следующий
оператор начнет вывод со следующей строки. Когда печатаемая
строка длиннее, чем ширина экрана, то вывод продолжается со
следующей строки.
Примеры. Использование запятых и точек с запятой.
CLS
X = 5
PRINT Х+5, Х- 5, X* (-5),ХЛ5
END
Результат:
10 0 -25 3125
CLS
FOR X = 1 ТО 5
J = J + 5
К = К + 10
PRINT J; К;
NEXT X
Результат:
5 10 10 20 15 30 20 40 25 50
PRINT USING
PRINT USING — оператор ввода/вывода, осуществляющий
вывод на экран по указанному формату.
PRINT USING формат; список_выражений [ {, I ,-} ]
• формат — символьное выражение, содержит специальные
символы, управляющие представлением выводимых данных;
• Списоквыражений — выражения любого типа, кроме
пользовательского. Символьные константы в списке выраже-
ний должны заключаться в кавычки.
176
Форматы для вывода символьных значений
Сим-
вол
!
\\
&
Описание
Вывод первого символа указанной строки;
Вывод 2 + п символов из строки, где п — число пробе-
лов между двумя слэшами. Если слэши набраны без
пробелов, то выводятся два начальных символа строки.
Если поле вывода больше, чем длина строки, то строка
выравнивается влево, а справа печатаются пробелы;
Вывод строки любой длины. Строка выводится без мо-
дификаций.
Пример. Вывод символьных данных.
Конструкция:
PRINT USING "!"; Москва
PRINT USING "\ \"; Ленинград
PRINT USING ">\ \<"; Дмитров
PRINT USING "&"; Санкт-Петербург
Результат:
м
Лен
>Дмитров <
Санкт-Петербург
Форматы для вывода числовых значений.
Сим-
вол
#
+
Описание
Представляет одну цифровую позицию. Если выводимое
число имеет меньше цифр, чем указано позиций, то оно
выравнивается вправо, дополняясь слева пробелами.
Выводит десятичную точку. Может быть вставлена в
любое место числового поля. Если символ указан, точ-
ка всегда печатается, независимо от точности значения.
Лишние дробные знаки отсекаются.
Вывод знака числа (плюс или минус), либо перед чис-
ловым полем, либо после — как указано.
177
-
**
$$
**$
-
Вывод минуса перед отрицательным числом, либо пе-
ред числовым полем, либо после — как указано.
Заменить левые пробелы перед числом звездочками.
Две звездочки указывают, что выводить следует два или
более знака.
Поставить перед числом в указанном поле знак долла-
ра. Два доллара указывают, что выводить следует два
знака, один из которых — доллар.
Комбинирует эффект двух звездочек и двух долларов.
Пустые места поля слева замещаются звездочками, а
впереди числа ставится знак доллара. **$ указывают
три или более позиций, одна из которых — знак долла-
ра. Если выводится отрицательное число, то минус ста-
вится перед долларом.
Если перед числовым полем поставлена запятая, то каж-
дые три знака до десятичной точки отделяются запятыми
(выделяются сотни, тысячи и т. д. по американскому
формату представления чисел). Запятая не влияет на вы-
вод чисел в экспоненциальной форме (ЛАЛА или ЛЛЛАЛ).
Знак подчеркивания означает, что следующий символ вы-
водится не как управляющий, а как литерал. Для вывода
одного символа подчеркивания поставьте два ( ) в
строке формата.
Если выводимое число не помещается в поле формата, то
перед ним выводится знак процента (%).
Типы выводимых значений в списке_выражений должны со-
ответствовать типам полей данных в строке формата.
Действие символов-разделителей списка_выражений описано
в операторе PRINT.
Пример. Вывод числовых данных.
Конструкция:
PRINT USING
PRINT USING
PRINT USING
•##.##"; .78
'###.##"; 987.654
'##.## "; 10.2, 5.3
Результат:
0.78
987.65
10.20 5.30
178
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
USING
USING
USING
USING
USING
USING
USING
USING
USING
USING
USING
USING
USING
"####,.
"##.##л
».####л
"+.##АЛ
"+.##лл
"; -68.95, 2.4
"; -68.95, 22.44
11; 12.39, -0.9
##"; 456.78
##"; 2.34
##"; 1234.5
ллл"; 234.56
л/чл-"; -888888
лл"; 123
ллл"; 123
"_!##.##_!"; 12.34
; 111.22
.999
-68.95 +2.40
68.95- 22.45
*12.4 **0.9
$456.78
***$2.34
1,234.50
2.35Е+02
.8889Е+06
+.12Е+03
+.12Е+003
112.34!
%111.22
%1.00
WRITE
WRITE — оператор ввода/вывода, посылающий данные на
экран.
WRITE [список_выражений]
• списоквыражений — содержит одно или несколько выраже-
ний, разделенных запятыми.
Если список_выражений опущен, печатается пустая строка. Вы-
водимые значения разделяются запятыми. Символьные строки зак-
лючаются в кавычки. После печати последнего выражения в списке
вставляются символы возврата каретки и перевода строки. WRITE
записывает числовые значения без начальных и конечных пробелов.
Пример. Различие между WRITE и PRINT.
CLS
А = 80: В = 90: С$ = " Это все." : D = -1.0Е-13
WRITE А, В, С$, D
PRINT А, В, С$, D
Результат:
80, 90, "Это все.", -1Е-13
80 90 Это все. -1Е-13
179
LOCATE
LOCATE — оператор ввода/вывода, передвигающий курсор в
указанную позицию экрана.
LOCATE [строка][,[столбец][,[курсор][,[начало, ко-
нец] ] ] ]
• строка — номер строки на экране. Если параметр не указан,
то номер строки не меняется;
• столбец — номер столбца на экране. Если параметр не ука-
зан, то номер столбца не меняется;
• курсор — логический параметр, указывающий видимость кур-
сора. Если равен 0, то курсор не виден, если равен 1, то ви-
ден;
• начало — начальная скан-линия курсора; конец — конечная
скан-линия курсора.
Можно опустить любой параметр в операторе. Если опустить
строку и столбец, LOCATE оставит курсор на позиции, установ-
ленной предыдущим оператором LOCATE или предыдущим опе-
ратором ввода/вывода. Для других аргументов сохраняются пре-
дыдущие значения.
Начало и конец определяются скан-линиями экрана, кото-
рые зависят от его разрешения. Эти аргументы описывают форму
курсора. Если начало меньше конца, курсор будет двойным.
Если выполнен оператор KEY ON, то последняя строка эк-
рана недоступна, Выполните оператор KEY OFF, и LOCATE по-
лучит доступ к ней.
Примеры.
CLS ' Перемещение курсора в 5 строку, 5 колонку.
LOCATE 5, 5 PRINT "С"
DO: LOOP WHILE INKEY$ = ""
1 Перемещение курсора в верхний левый угол экрана.
LOCATE 1,1 PRINT "С"
DO: LOOP WHILE 1NKEY$ = ""
1 Делает курсор видимым. Позиция не меняется.
LOCATE ,,1 PRINT "С"
DO: LOOP WHILE INKEY$ = ""
' Изменяет форму курсора.
LOCATE,,,7
PRINT "С" .
DO: LOOP WHILE INKEY$ = ""
180
1 Комбинация всех действий.
LOCATE 5,1,1,0,7: PRINT "С"
CSRLIN
CSRLIN — функция ввода/вывода, возвращающая значение
текущей строки, в которой находится курсор.
n = CSRLIN
Пример:
LOCATE 20, 1
PRINT CSRLIN
Результат:
20
POS
POS — функция ввода/вывода, возвращающая номер столб-
ца, в котором находится курсор.
POS(O)
Пример. Использование POS для печати новой строки
после того, как введено 40 символов.
CLS
PRINT "Нажмите ESC для завершения."
PRINT
DO-
DO WHILE POS@) < 41 'Оставаться на той же строке,
DO 'пока не напечатано 40 символов.
har$ = INKEY$
LOOP WHILE Char$ = ""
' Если нажата клавиша ESC, то конец.
' Иначе - вывести символ на экран.
IF ASC(Char$) = 27 THEN END ELSE PRINT Char$;
LOOP
PRINT
LOOP
181
SPC
SPC1 — функция ввода/вывода, пропускающая п пробелов в
текущей строке при выполнении оператора PRINT или LPRINT.
SPC(n)
• п — числовое выражение в пределах 0—32767, обозначает ко-
личество пробелов, пропускаемых в текущей строке.
Пример.
CLS
PRINT "ГДЕ-ТО"; SPCA5); "ЗДЕСЬ"
Результат:
ГДЕ-ТО ЗДЕСЬ
TAB
TAB — функция ввода/вывода, сдвигающая позицию вывода
при использовании операторов PRINT или LPRINT.
TAB(столбец)
• столбец — числовое выражение, в пределах от 1 до ширины выво-
да.
Аргумент "столбец" — новая колонка вывода в данной стро-
ке. Если текущая колонка больше, чем столбец, то вывод в дан-
ную позицию будет произведен уже на другой строке. Если аргу-
мент "столбец" больше, чем ширина вывода, то вывод начнется с
позиции, определяемой выражением 1 + (столбец MOD ширина).
Если столбец меньше 1, вывод начнется с позиции 1. TAB ис-
пользуется только с операторами PRINT и LPRINT.
Пример.
PRINT TABA287); "Один"
'PRINT TABB55); "Два"
PRINT TAB(-5); "Три"
PRINT 23456789012345678901234567890"; ТАВB0); "Четыре"
' Функция SPC работает очень медленно. Вместо нее лучше использовать
аналогичную по своим возможностям функцию SPACES.
182
Результат:
Один
Два
Три
123456789012345678901234567 890
Четыре
WIDTH
WIDTH — оператор ввода/вывода, устанавливающий ширину
строки вывода файла или устройства, а также количество строк и
столбцов экрана.
Форма: Синтаксис:
1 WIDTH [столбцы],[строки]
2 WIDTH #номер_файла,ширина
3 WIDTH устройство,ширина
4 WIDTH LPRINT ширина
Форма
1
2
3
4
Описание
Устанавливает количество столбцов и строк экрана.
Число столбцов может быть 40 или 80. По умолчанию
80. Число строк может быть 25, 30, 43, 50 или 60, в
зависимости от адаптера и режима экрана (см. опера-
тор SCREEN). По умолчанию 25.
Устанавливает ширину вывода устройства, открытого
как файл (например, LPT1: или CONS:). Аргумент
номер файла — это номер устройства, открытого опе-
ратором OPEN.
Устанавливает ширину вывода устройства, заданного
символьной константой (например, "CONS:"). Это
определение действует до открытия устройства как
файл оператором OPEN. He действует, если устрой-
ство уже открыто.
Устанавливает ширину вывода принтера для всех
последующих операторов LPRINT.
183
Пример. Установка 43 строк на экране1
WIDTH 80, 43
FOR i = 1 ТО 43
LOCATE i, 1
PRINT "Строка "; i; SPC(i); "*";
NEXT i
DO: LOOP WHILE INKEY$ = ""
Пример. Установка ширины печати в 255 символов
LPRINT "Без оператора WIDTH"
FOR 1% = 128 ТО 255: LPRINT CHR%(I%);: NEXT I
LPRINT "С оператором WIDTH"
WIDTH "LPT1:", 25 5
FOR 1% = 12 8 TO 255: LPRINT CHR%(I%);: NEXT I
Файлы
OPEN
OPEN — оператор ввода/вывода, включающий ввод/вывод в
файл или устройство.
OPEN файл [FOR тип] [ACCESS доступ] [блок]
AS [#]номер [LEN=nroiHa]
• файл — символьное выражение, определяющее имя устрой-
ства или файла, включая путь;
• тип — одно из описанных ниже ключевых слов;
• номер — целое выражение от 1 до 255, номер файла;
• длина — длина записи. По умолчания равна 128 байт для
файлов прямого доступа и 512 для файлов последовательного
доступа. Для двоичных файлов длину указывать не требуется.
Вы должны открыть файл перед любыми операциями вво-
да/вывода, производимыми с ним. OPEN размещает буфер для
ввода/вывода и устанавливает тип доступа к файлу.
1 В текстовом режиме для дисплея EGA можно установить 25 или 43 строки,
для VGA — 25, 43, 50 и 60 F0 — только в графическом режиме SCREEN 12).
Число столбцов может быть 40 (только 25 строк) или 80. Установки текстового
экрана по умолчанию — 80 столбцов, 25 строк
184
Тип
OUTPUT
INPUT
APPEND
RANDOM
BINARY
Описание
Определяет последовательный вывод;
Определяет последовательный ввод;
Определяет последовательный вывод с добавлением,
т. е. устанавливает указатель записи к концу файла.
Операторы PRINT # и WRITE # добавляют выво-
димые данные к концу файла;
Определяет прямой ввод/вывод (умалчиваемый
тип). Если нет условия ACCESS, доступ выполняет-
ся в следующем порядке: 1. Чтение/запись; 2. Толь-
ко запись; 3. Только чтение.
Определяет двоичный ввод/вывод. Можно читать
или писать информацию любого байта файла опера-
торами GET и PUT.
Если тип опущен, по умолчанию присваивается тип RANDOM.
Выражение "Доступ" определяет разрешенные операции с
открытым файлом. Если другой процесс уже открыл файл, и зап-
ретил к нему доступ, то оператор OPEN выдает сообщение об
ошибке "Permission denied" (Доступ запрещен).
Условие ACCESS работает с оператором OPEN только в вер-
сии DOS, поддерживающей сети (DOS версии 3.0 или выше). В
дополнение, вы должны запустить программу SHARE.EXE (или
сетевую программу) для разрешения операций блокировки. Ран-
ние версии DOS возвращают сообщение об ошибке "Advanced
feature unavailable" (Расширенное средство невозможно). Аргу-
мент "Доступ" может быть следующим:
Тип доступа
READ
WRITE
READ
WRITE
Описание
Только для чтения;
Только для записи;
Чтение и запись. Этот тип доступа возможен только
для файлов RANDOM, BINARY и APPEND.
185
Условие "Блок" работает в мультизадачной среде для разде-
ления доступа между процессами к открытому файлу.
Тип блока
по умолчанию
SHARED
LOCK READ
LOCK WRITE
LOCK READ
WRITE
Описание
Если не указан, то файл может быть открыт
любое число раз для чтения/записи только
данным процессом. Другие процессы не име-
ют доступа к файлу, пока он открыт;
Любые процессы на любой машине могут иметь
доступ для чтения/записи данного файла;
Другие процессы не имеют возможности чи-
тать; этот файл. Эта блокировка возможна, ес-
ли другие процессы ранее не блокировали до-
ступ для чтения к этому файлу;
Другие процессы не имеют возможности пи-
сать в этот файл. Эта блокировка возможна,
если другие процессы ранее не блокировали
доступ для записи к этому файлу;
Другие процессы не имеют возможности чи-
тать и писать этот файл. Эта блокировка воз-
можна, если другие процессы не блокировали
ранее доступ для записи и/или для чтения к
этому файлу.
Когда OPEN встречает блокированный файл, он выдает
ошибку "Permission denied" (Доступ запрещен).
Значение длины записи не может превышать 32767 байт. Если
файл открыт как двоичный, ключ LEN игнорируется. Для файлов
последовательного типа длина не означает длину каждой записи, так
как такие файлы могут иметь записи различной длины. Она означа-
ет размер буфера — то есть сколько символов загружаются в буфер
перед записью или после чтения. Чем больше буфер, тем быстрее
ввод/вывод. По умолчанию размер буфера — 512 байт.
Устройства, перечисленные ниже, QuickBASIC поддерживает
как файлы:
KYBD:
CONS:
SCRN:
клавиатура;
консоль;
экран;
186
COMn: — COM порт № n;
LPTn: — LPT порт № п.
Система ввода/вывода позволяет вам иметь доступ к соб-
ственным устройствам. Символьные устройства открываются и
используются так же, как и дисковые файлы. Но символы не бу-
феризуются для них, как это делается для файлов. Длина записи
для устройств равна 1.
BASIC посылает только символ возврата каретки (ASCII
13 — CR) после конца строки. Если устройство требует и символ
перевода строки, это должен обеспечить драйвер.
Ни одно из устройств прямо не поддерживает двоичный тип,
за исключением принтеров (LPT1:, LPT2:). Для этого служит
ключевое слово BIN:
OPEN "LPT1:BIN" FOR OUTPUT AS #1
Открытие принтера по типу BIN отменяет печать символа
возврата каретки (ASCII 13 — CR) в конце строки.
Для типов INPUT, RANDOM и BINARY вы можете открыть тот
же файл с другим номером без закрытия его. Но для типов OUTPUT
или APPEND необходимо сначала закрыть открытый файл.
CLOSE
CLOSE — оператор ввода/вывода, закрывающий файл или
устройство.
CLOSE [[#]номер_файла[,[#] номер_файла]...]
• номерфайла — логический номер открытого файла.
Если все аргументы опущены, закрываются все файлы и уст-
ройства.
CLOSE очищает весь буфер для закрываемого файла или ус-
тройства. Операторы CLEAR, END, RESET, RUN, и SYSTEM
закрывают все файлы автоматически.
RESET
RESET — оператор файлового ввода/вывода, закрывающий
все файлы.
187
RESET
Данный оператор закрывает все открытые файлы и записы-
вает данные из буферов на диск. Все файлы, находящиеся на
дискете обязательно должны быть закрыты перед удалением дис-
ка из дисковода.
GET
GET — оператор файлового ввода/вывода, читающий с диска
файл в буфер прямого доступа или в переменную
GET [#]номер_файла[,[номер_записи][,переменная]]
• номерфайла — номер открытого оператором OPEN файла;
• номерзаписи — для файлов прямого доступа — номер чита-
емой записи. Для двоичных файлов — байтовая позиция в
файле, откуда начинается чтение. Первая запись или байтовая
позиция в файле равны 1. Если вы опустите номер записи, то
будет читаться следующая запись или байт (после последних
GET или PUT, или указанная последним оператором SEEK).
Наибольший возможный номер равен 2Л31 - 1 или 2147483647;
• переменная — переменная, получающая данные из файла.
Если вы указали переменную, то CVD, CVL, CVI, CVS не
требуются для преобразования полей записи в числа. Таким
образом, можно не указывать оператором FIELD размещение
полей в записи. Можно использовать переменную, длина ко-
торой не превышает длины записи.
Для двоичных файлов вы можете использовать любую пере-
менную. Читается столько байт, какова длина этой переменной.
Если вы используете символьную переменную переменной дли-
ны, читается столько байт, сколько символов в значении пере-
менной. Например, следующие два оператора читают 10 байт из
файла номер 1:
VarStrings$ = STRING$ A0, " ")
GET #1, , VarString$
Длина записи не может быть больше 32767 байт.
188
Если вы используете GET с оператором FIELD, можно чи-
тать символы из буфера операторами INPUT # или LINE
INPUT # после GET.
Можно использовать функцию EOF после оператора GET,
чтобы посмотреть, не подошел ли указатель номера записи к
концу файла.
Пример. Открытие файла GULLAP.DAT для прямого доступа
и вывод его содержимого на экран.
TYPE TestRecord
NameField AS STRING * 20
ScoreField AS SINGLE
END TYPE
' Описание переменной типа запись.
DIM Rec AS TestRecord
I*********************************************
1 Эта часть программы создает файл прямого
1 доступа для дальнейшей демонстрации.
'Л***************************.*****************
OPEN "GULLAP.DAT" FOR RANDOM AS #1 LEN = LEN(Rec)
CLS
RESTORE
READ NameField$, ScoreField
i = 0
DO WHILE UCASE$(NameField$) <> "END"
i = i + 1
Rec.NameField = NameField$
Rec.ScoreField = ScoreField PUT #1, i, Rec
READ NameField$, ScoreField
IF NaraeField$ = "END" THEN EXIT DO
LOOP
CLOSE #1
DATA "Роберт", 100 DATA "Алиса", 95 DATA "Алексей",
72 DATA "Василий", 90 DATA "Григорий", 92 DATA "END",
0
********************************
'Демонстрация оператора GET.
i*******************************
DIM FileBuffer AS TestRecord
OPEN "GULLAP.DAT" FOR RANDOM AS #1
LEN=LEN(FileBuffer) ' Подсчет количества записей в
файле.
Мах = LOF(l) \ LEN(FileBuffer)
189
' Чтение и вывод содержимого записи.
FOR i = 1 ТО Мах
GET #1, i, FileBuffer
PRINT FileBuffer.NameField, FileBuffer.ScoreField
NEXT i
CLOSE #1
END
Результат:
Роберт
Алиса
Алексей
Василий
Григорий
100
95
72
90
92
PUT
PUT — оператор файлового ввода/вывода, записывающий
информацию из переменной или буфера в файл прямого доступа
или двоичный файл.
PUT [#]номер_файла[,[номер_записи][,переменная]]
• номерфайла — номер, использованный в операторе OPEN
для открытия файла прямого доступа или двоичного;
• номерзаписи — для файлов прямого доступа это номер за-
писи, в которую идет вывод данных. Для двоичных файлов —
байтовая позиция в файле. Первая запись имеет номер 1. Ес-
ли номер записи опущен, то используется следующая запись
или байт после прошлого вызова GET или PUT, или указан-
ная оператором SEEK. Наибольший возможный номер запи-
си равен 2л31-1 или 2,147,483,647;
• переменная — переменная, содержащая информацию, запи-
сываемую в файл. Оператор PUT записывает столько байт в
файл, сколько байт содержит переменная. Если вы используе-
те переменную, то вам не нужны MKI$, MKL$, MKS$,
MKD$ для преобразования типов данных и оператор FIELD.
Для файлов прямого доступа можно использовать перемен-
ную длиной меньше или равной длине записи. Можно опреде-
190
лить поля записи в переменной типа запись. Для двоичных фай-
лов можно использовать любые переменные. Длина записи — не
более 32767 байт.
Можно опустить номер записи или переменную, добавив за-
пятые:
PUT #4, , FileBuffer
Если вы опустите номер записи и переменную, то запятые не
нужны:
PUT #4
В этом случае в файл идет запись из буфера, определенного
оператором FIELD, что возможно только для файлов прямого
доступа.
При использовании файлового буфера FIELD, операторы
LSET, RSET, PRINT # , PRINT # USING и WRITE # могут ис-
пользоваться для записи символов в буфер перед выполнением
оператора PUT. При записи путем WRITE #, буфер заполняется
вплоть до символа перевода каретки (ASCII 13). Любая попытка
записи или чтения после конца буфера приведет к сообщению об
ошибке "FIELD overflow" (FIELD переполнен).
См. пример к оператору GET.
INPUT #
INPUT # — оператор файлового ввода/вывода, читающий
данные из файла или последовательного устройства и присваи-
вающий их переменным.
INPUT #номер_файла,переменные
• номер_файла; — это номер открытого файла;
• переменные — список переменных, которым присваиваются
значения, читаемые из файла. Типы данных должны соответ-
ствовать друг другу.
Ввод данных из файла производится так же, как ввод с кла-
виатуры. Данные могут разделяться пробелами, символами воз-
врата каретки, перевода строки (ASCII 13 и 10) или запятыми.
Начальные пробелы игнорируются. Знак конца файла CTRL-Z
(ASCII 26) завершает набор данных.
191
Если вводятся символьные строки, оператор игнорирует
пробелы, а разделителями считаются запятые, символы конца
строки (LF) и перевода каретки.
Пример. Чтение тестовых оценок из файла последова-
тельного доступа и подсчет средней оценки по группе
студентов. Файл CLASS.DAT содержит оценки 97 84 63 89
100.
DEFINT A-Z
CLS
OPEN "class.dat" FOR INPUT AS #1
DO WHILE NOT EOF(l)
Count = Count + 1
INPUT #1, Score
Total = Total + Score
PRINT Count; Score
LOOP
PRINT "Всего:"; Count; " Средняя оценка:"; Total / Count
END
Результат:
1 97
2 84
3 63
4 89
5 100
Всего: 5 Средняя оценка: 86.6
LINE INPUT*
LINE INPUT # — оператор файлового ввода/вывода, чита-
ющий символьную строку без разделителей из файла последова-
тельного доступа в указанную переменную.
LINE INPUT #номер_файла, символьная_переменная
• номер_файла — номер открытого последовательного файла;
• символьная_переменная — переменная, в которую считы-
ваются все символы текущей строки в файле до ее конца (до
знаков ASCII 13 и 10).
Пример.
OPEN "LIST.DAT" FOR OUTPUT AS #1
PRINT "Информация о покупателях:"
DO
PRINT
192
INPUT " Фамилия: ", LName$
INPUT " Имя: ", PrName$
INPUT " Возраст: ", Age$
INPUT " Пол: ", Sex$
WRITE #1, LName$, FrName$, Age$, Sex$
INPUT "Добавить Y/N "; R$
LOOP WHILE UCASE$(R$)="Y"
CLOSE #1
1 Распечатка файла.
OPEN "LIST.DAT" FOR INPUT AS #1
CLS
PRINT "Записи в файле:" : PRINT
DO WHILE NOT EOF(l)
LINE INPUT #1, REC$
PRINT REC$
LOOP
Результат:
Информация о покупателях:
Фамилия: Тер-Иванов
Имя: Роберт
Возраст: 3 5
Пол: М
Добавить Y/N ? у
Фамилия: Иванова
Имя: Лена
Возраст: 27
ПОЛ: Ж
Добавить Y/N ? N
Записи в файле:
"Тер-Иванов", "Роберт", 5", "М"
"Иванова", "Лена", 7", "Ж"
INPUTS
INPUTS — функция файлового ввода/вывода, читающая
символьные строки из указанного файла.
INPUT$(n[,[#]номер_файла])
• п — числовое выражение, количество символов, читаемых из
файла.
Если файл открыт для прямого доступа, то аргумент п должен
быть меньше или равен длине записи, установленной ключевым
193
словом LEN оператора OPEN (по умолчанию 128, если длина запи-
си не установлена). Если файл открыт для двоичного или последова-
тельного доступа, п должен быть меньше или равен 32767.
Если номер файла не указан, то символы читаются со стандарт-
ного устройства ввода. (Если ввод не переназначен, это клавиатура).
Для .ЕХЕ файлов в среде DOS можно переназначить ввод путем
указания в командной строке символов <, >, » или |, которые ис-
пользуются для переопределения стандартного ввода и вывода.
Знаки не дублируются на экран (ввод без эха). Можно обо-
рвать исполнение данной функции нажатием {CTRL-BREAK}.
Пример. Программа выводит файл на экран, не печатая
специальные символы. Для тестирования можно взять лю-
бой текстовый файл.
1 ASCII-коды для табуляции и перевода строки.
CONST HTAB = 9, LFEED =10
CLS
INPUT "Введите имя файла "; FileName$
OPEN FileName$ FOR INPUT AS #1
DO WHILE NOT EOF(l)
1 Ввод одного символа из файла.
s$ = INPUT$A, #1)
с = ASC(S$)
' Этот символ можно печатать?
IF с >= 32 OR с = HTAB OR с = LFEED THEN
PRINT s$;
ELSE
PRINT " ";
END IF
LOOP
CLOSE: END
PRINT #, PRINT # USING
PRINT #, PRINT # USING — операторы файлового вво-
да/вывода, записывающие данные в последовательный файл.
PRINT #номер_файла, [USING формат;] спи-
сок_выражений[,I;]
• номер_файла — номер открытого последовательного файла;
• список_выражений — содержит значения, записываемые в
файл. Если он пуст, то записывается пустая строка.
194
PRINT # работает так же, как PRINT, и записывает данные в
файл. Пробелы между элементами списка записываются в файл.
Пример. Использование разделителей данных.
CLS
А$ = "ФОТОАППАРАТ АВТОМАТИЧЕСКИЙ"
В$= 0 октября 1967 года"
С$ = 2" :
Q$ = CHR$C4) '34 - код кавычек
OPEN "INVENT.DAT" FOR OUTPUT AS #1
'Запись А$, B$, C$ без разделителей.
PRINT #1, А$; В$; С$
'Запись А$, В$, С$ с разделителями.
PRINT #1, Q$; A$; Q$; Q$; В$; Q$; Q$; C$; Q$
CLOSE #1
OPEN "INVENT.DAT" FOR INPUT AS #1
FOR 1% = 1 TO 2
INPUT #1, First$, Second$, Third$
PRINT First$; Second$; Third$
PRINT
NEXT 1%
CLOSE #1
Результат:
ФОТОАППАРАТ АВТОМАТИЧЕСКИЙ30 октября 1967 года42
ФОТОАППАРАТ АВТОМАТИЧЕСКИЙ, 30 октября 1967 года, 42
WRITE
WRITE # — оператор файлового ввода/вывода, посылающий
данные в последовательный файл.
WRITE #номер_файла[,список_выражений]
• номер_файла — номер открытого оператором OPEN файла.
Файл должен быть типа OUTPUT или APPEND;
t
• список_?ыражений — содержит одно или несколько выраже-
ний, разделенных запятыми, значения которых выводятся в
файл.
Если список выражений опущен, выводится пустая строка.
Выводимые значения разделяются запятыми. Символьные
строки заключаются в кавычки. После печати последнего выра-
195
жения в списке вставляются символы ASCII 13 (CR — возврат
каретки) и ASCII 10 (LF — перевод строки). WRITE # записыва-
ет числовые значения без начальных и конечных пробелов.
Если WRITE # попытается записать данные в последова-
тельный файл, блокированный оператором LOCK, то выдается
сообщение об ошибке "Permission denied" (Доступ запрещен).
Пример. Иллюстрирует различия между операторами WRITE #
и PRINT #.
А$ = "Видеомагнитофон JVC" : В$ = "$299.00"
OPEN "prices.dat" FOR OUTPUT AS #1
1 Записываем А$ и В$ оператором PRINT #.
PRINT #1, А$, В$
' Записываем А$ и В$ оператором WRITE #.
WRITE #1, А$, В$
CLOSE #1
Вывод. Содержимое файла PRICES.DAT .-
Видеомагнитофон JVC $299.95
"JVC Video Recorder" "$299.95"
BSAVE
BSAVE — оператор ввода/вывода, перемещающий содержи-
мое фрагмента памяти в файл или устройство.
BSAVE файл, смещение, длина
• файл — символьное выражение, определяющее имя файла
или устройства, куда записывается образ памяти;
• смещение — стартовый адрес памяти относительно текущего
сегмента, откуда берется данный фрагмент;
• длина — числовое выражение от 0 до 65535 — количество
байт памяти для записи.
При использовании оператора BSAVE нельзя использовать
устройства (SCRN: and CONS:).
Пример. Рисуем розовый куб внутри белого прямоуголь-
ника , затем оператором BSAVE записываем графический
образ в файл MAGCUBE.GRH.
196
DIM Cubed TO 675)
SCREEN 1
1 Рисуем белый прямоугольник.
LINE A40, 25)-A40 + 100, 125), 3, В
' Рисуем розовый куб внутри прямоугольника.
DRAW "C2 ВМ140,50 М+50,-25 М+50,25 М-50,25 М-50,-25"
DRAW "М+0,50 М+50,25 М+50,-25 М+0,-50 ВМ190,75
М+0,50"
' Записываем образ в массив Cube().
GET A40, 25)-B40, 125), Cube
1 Устанавливаем сегмент памяти на массив Cube().
DEF SEG = VARSEG(CubeA))
' Записываем файл MAGCUBE.GRH.
' 27 00 - количество байт в массиве
1 D байта на элемент - 675).-
BSAVE -MAGCUBE.GRH", VARPTR(CubeA)), 27 00
1 Восстанавливаем первоначальный сегмент.
DEF SEG
Результат:
197
BLOAD
BLOAD — оператор ввода/вывода, загружающий файл образа
памяти, записанный оператором BSAVE с диска или из устрой-
ства.
BLOAD файл[,смещение]
• файл — символьное выражение, определяющее файл или уст-
ройство, на котором записан образ памяти;
• смещение — место в памяти, куда загружается файл.
Оператор BLOAD нельзя использовать с устройством KYBD:
(клавиатура).
BLOAD позволяет загружать программу или данные, записан-
ные как образ фрагмента памяти. Такой файл представляет собой
побайтную копию того, что находится в этот момент в памяти.
Стартовый адрес для загрузки определяется как смещение
относительно сегментного адреса, установленного оператором
DEF SEG. Если смещение не указано, используется смещение,
записанное в файле. Поэтому файл загружается по тому же адре-
су, из которого он был записан. Если сегмент не определен опе-
ратором DEF SEG, используется по умолчанию сегмент данных
QuickBASIC.
Пример. Использование BLOAD для считывания графичес-
кого изображения розового куба внутри белого прямоу-
гольника, записанного оператором BSAVE на диск в файл
MAGCUBE.GRH.
DIM Cubed TO 67 5)
' Установка режима экрана. Он должен быть таким же,
' каким был при записи в файл данного образа.
SCREEN 1
' Установка начального сегмента памяти на массив Cube().
DEF SEG = VARSEG(Cubed) )
1 Загрузка образа из файла в массив.
BLOAD "MAGCUBE.GRH", VARPTR(CubeA))
' Восстановление первоначального сегмента памяти.
DEF SEG
1 Выдача на экран содержимого массива.
PUT (80, 10), Cube
198
EOF
EOF — функция файлового ввода-вывода, определяющая ус-
ловие конца файла.
EOF(номер_файла)
• номер_файла — номер открытого файла.
Функция EOF возвращает -1 ("истина"), если указатель в
файле последовательного доступа дошел до его конца. Эта функ-
ция может использоваться для тестирования конца файла при
вводе данных — для того, чтобы избежать ошибки "Input past end
of file" (Ввод после конца файла).
Когда EOF используется для файла прямого или двоичного
доступа, то "истина" возвращается при попытке оператора GET
считать запись после конца файла.
EOF не может использоваться с устройствами SCRN:,
KYBD:, CONS: и LPTn:.
Пример. Чтение данных из файла DATA.IN в массив М,
используя конструкцию DO LOOP. Цикл выполняется до
тех пор, пока функция EOF не укажет на конец файла.
DIM M@ ТО 2000)
OPEN "DATA.IN" FOR INPUT AS 1
с = 0
DO WHILE NOT EOF(l) AND с <= 2000
INPUT #1, M(c)
с = с + 1
LOOP
CLS
d = 0
DO WHILE d < с
PRINT M(d) ;
d = d + 1
LOOP
Содержимое Файла DATA-IN :
10 20 30 40 50 60 70 80 90
Результат:
10 20 30 40 50 60 70 80 90
199
LOF
LOF — функция файлового ввода/вывода, возвращающая
длину файла в байтах.
ЬОР(номерфайла)
• номер_файла — номер открытого файла.
При открытии файла любого типа доступа эта функция вы-
дает его размер в байтах.
LOF не используется для устройств SCRN:, KYBD:, CONS: и
LPTn:. При обращении к устройству, открытому как файл опера-
тором OPEN COM, функция LOF возвращает число свободных
байт в выходном буфере.
Пример:
INPUT "Введите имя файла"; FileName$
OPEN FileName$ FOR BINARY AS #1
FileSize& = LOF(l)
CLOSE #1
PRINT "Длина файла"; FileName$; " составляет ";
FileSizek \ 1024 ; "Kb"
FIELD
FIELD — оператор файлового ввода/вывода, выделяющий
место для переменных в буфере файла прямого доступа.
FIELD [#]номер_файла, длина AS переменная [,длина AS пере-
менная] . . .
• номер_файла — номер открытого файла;
• длина — число символов в поле данных;
• переменная — переменная, которой присвоено данное поле.
Общее число байт — длин полей, описанных оператором
FIELD, не должно превышать длины записи, определенной при
открытии файла. По умолчанию длина записи равна 128 байт.
200
Для одного файла может быть задано любое количество опе-
раторов FIELD.
Все описатели полей для файла уничтожаются при его зак-
рытии, поэтому все символьные переменные, присвоенные по-
лям, обнуляются.
Не используйте переменные полей в операторе INPUT или в
операторах присваивания, так как данные переменные занимают
определенное место в памяти, отведенной под файловый буфер.
Пример. Иллюстрация буфера файла прямого доступа:
В первом операторе FIELD 62-байтовый буфер разделен
между тремя переменными NameF, Addr, City
Во втором операторе FIELD буфер присвоен только одной
переменной Plist$.
TYPE Buffer
NameF AS STRING * 25
Addr AS STRING * 25
City AS STRING * 12
END TYPE
DIM RecBuffer AS Buffer
1 Эта часть программы создает файл прямого
1 доступа LIST.DAT для последующей демонстрации.
OPEN "LIST.DAT" FOR RANDOM AS #1 LEN = LEN(RecBuffer)
CLS
RESTORE
READ NameF$, Addr$, City$
i = 0
DO WHILE UCASE$(NameF$) <> "END"
i = i + 1
RecBuffer.NameF = NameF$
RecBuffer.Addr = Addr$
RecBuffer.City = City$
PUT #1, i, RecBuffer
READ NameF$, Addr$, City$
IF NameF$ = "END" THEN EXIT DO
LOOP
CLOSE #1
DATA "Роберт", "ул.Ленина, д.216, кв.5", "Ленинград"
DATA "Алиса", "ул.Мичурина, д.3 5 кв.4", "Владивосток"
DATA "Алексей", "ул.Лавочкина, д,18", "Аклис"
DATA "Антон", "ул.Дубки, д.40", "Москва"
DATA "END",0,0,
201
I***************************************************
1 Демонстрация оператора FIELD.
' Определение полей и присваивание их длин константам
CONST NA = 25, AD = 25, СТ = 12
CONST RECLEN = NA + AD + СТ
OPEN "LIST.DAT" FOR RANDOM AS #1 LEN = RECLEN
FIELD #1, NA AS NameF$, AD AS Addr$, CT AS City$
FIELD #1, RECLEN AS Plist$
GET #1, 1
DO WHILE NOT EOF(l)
Info$ = Plist$
PRINT Info$: PRINT
a$ = NameF$: PRINT a$
b$ = Addr$: PRINT b$
c$ = City$: PRINT c$
PRINT
GET #1
LOOP
CLOSE #1
DO: LOOP WHILE INKEY$ = ""
Результат:
Роберт ул.Ленина, д.216, кв.5 Ленинград
Роберт
ул.Ленина, д.216, кв.5
Ленинград
Алиса ул.Мичурина, д.35 кв.4 Владивосток
Алиса
ул.Мичурина, д.35 кв.4
Владивосток
Алексей ул.Лавочкина, д,18 Аклис
Алексей
ул.Лавочкина, д,18
Аклис
Антон ул.Дубки, д.40 Москва
Антон
ул.Дубки, д.40
Москва
202
LSET, RSET
LSET, RSET — операторы файлового ввода/вывода, преобра-
зующие данные из памяти в буфер файла прямого доступа (для
оператора PUT), копирующие символьные переменные в пере-
менные поля и выравнивающие их слева (LSET) или справа
(RSET). Они копируют также одну запись в другую без сравнения
типов данных.
LSET I RSET переменная = выражение I переменная1 = пере-
менная2
• переменная — любая символьная переменная;
• выражение — символьное выражение, присваиваемое данной
переменной и выравниваемое по левому (правому) краю.
Символьная переменная обычно является переменной поля
файла прямого доступа, описанной оператором FIELD, хотя мо-
жет быть любой символьной переменной.
Если символьное выражение требует меньше байт, чем опре-
делено для переменной, функция LSET сдвигает его значение
влево, добавляя пробелы в конец, a RIGHT — сдвигает вправо,
добавляя пробелы в начало строки. Если строка длиннее, чем пе-
ременная, то и LSET, и RSET отсекают лишние символы справа.
Числовые значения могут быть преобразованы в строки перед
присвоением их операторами LSET или RSET.
Можно использовать LSET или RSET для присвоения значе-
ний переменной, не определенной оператором FIELD для вы-
равнивания строки влево или вправо. Например:
A$=SPACE$B0)
RSET A$=N$
Здесь строка N$ выравнивается вправо в 20-символьной
строке А$, что удобно для форматного вывода на печать.
Можно использовать LSET, RSET для присвоения значения од-
ной переменной пользовательского типа (записи) — другой.
Пример. Копирование содержимого переменной RecTwo в
RecOne:
TYPE TwoString
StrFld AS STRING * 2
END TYPE
203
TYPE ThreeString
StrFld AS STRING * 3
END TYPE
DIM RecOne AS TwoString, RecTwo AS ThreeString
LSET RecOne = RecTwo
Здесь LSET использован для копирования переменных раз-
личных типов. Но так как длина RecOne два байта, только два
байта копируются из RecTwo. LSET копирует наименьшее коли-
чество байт из двух переменных типа запись.
Пример. Действия оператора RSET над строками перемен-
ной и фиксированной длины.
DIM TmpStr2 AS STRING * 10
CLS
PRINT " 1 2 3"
PRINT 2345678901234567 8901234567890"
' Используем RSET для пустой строки.
' Строка не будет печататься, т.к. она пустая.
TmpStr$ = ""
RSET TmpStr$ = "Первая"
PRINT TmpStr$
1 Используем RSET для строки переменной длины.
TmpStr$ = SPACE$B0)
RSET TmpStr$ = "Вторая"
PRINT TmpStr$
1 Используем RSET для строки фиксированной длины 10.
RSET TmpStr2 = "Третья"
PRINT TmpStr2
Результат:
12 3
12345678901234567 89012345 67 890
Вторая
Первая
FILEATTR
FILEATTR — функция файлового ввода/вывода, выдающая
информацию об открытом файле.
FILEATTR (номер_файла, атрибут)
• номерфайла — номер открытого файла;
204
атрибут — числовое выражение, имеющее значение либо 1,
либо 2, определяющее вид возвращаемой информации. Если
атрибут равен 1, возвращается тип файла. Если атрибут равен
2, возвращается описатель файла DOS.
Возвращаемые значения при атрибуте равном 1:
Значение
1
2
4
8
32
Тип
INPUT
OUTPUT
RANDOM
APPEND
BINARY
Пример. Открытие двух файлов и вывод описателя файла
DOS и его атрибута при помощи оператора FILEATTR.
OPEN "tempfll.dat" FOR APPEND AS #1
OPEN "tempfl2.dat" FOR RANDOM AS #2
PRINT "Номер Описатель Тип"
PRINT 1, FILEATTRA,2) , FILEATTRA,1)
PRINT 2, FILEATTRB,2), FILEATTRB,1)
END
Результат:
Номер Описатель Тип
15 8
2 6 4
FREEFILE
FREEFILE — функция файлового ввода/вывода, выдающая
следующий свободный номер файла.
FREEFILE
Вы можете использовать эту функцию для того, чтобы про-
цедуры SUB или FUNCTION не использовали занятые номера
файлов.
205
Пример.
INPUT "Введите имя файла: ", FileName$
Filenum = FREEFILE
OPEN FileName$ FOR OUTPUT AS Filenum
PRINT FileName$;" открыт как #"; Filenum
CLOSE
Результат:
Введите имя файла: DATA.DAT
DATA.DAT открыт как # 1
IOCTL
IOCTL — оператор файлового ввода/вывода, передающий
управляющую строку драйверу устройства.
IOCTL [#]номер_файла, строка
• номер_файла — номер открытого устройства;
• строка — управляющая последовательность команд, посылае-
мая в драйвер устройства. Длина строки не должна превы-
шать 32767 байт.
IOCTL работает только при выполнении трех условий:
1. Драйвер устройства установлен;
2. Драйвер устройства воспринимает команды IOCTL. См. до-
кументацию драйвера. Можно протестировать драйвер на
поддержку IOCTL через функцию DOS 44h прерывания 21h
используя CALL INTERRUPT;'
3. Устройство открыто оператором OPEN.
Большинство стандартных драйверов не воспринимают ко-
манд IOCTL, хотя вы можете определить, имеет ли данный драй-
вер подобный интерфейс.
IOCTL$
IOCTL$ — функция файлового ввода/вывода, принимающая
управляющую строку от драйвера устройства.
IOCTL$ ([#]номер_файла)
1 Подробнее о вызовах прерываний DOS и BIOS см. Главу 12 "Расширение
возможностей QuickBASIC 4.5"
206
• номерфайла — номер открытого устройства.
Данная функция используется для проверки выполнения
оператора IOCTL или для получения информации от драйвера о
текущем статусе.
Устройства LPT1:, СОМ1:, COM2:, SCRN:, CONS: не под-
держивают IOCTL.
Можно вызвать функцию IOCTL$ для опроса коммуникаци-
онного устройства о его скорости обмена, информации о после-
дней ошибке и т. д. Вид получаемой информации зависит от
конкретного драйвера устройства. Все замечания для оператора
IOCTL, справедливы и для функции IOCTL$.
LOC
LOC — функция файлового ввода/вывода, выдающая теку-
щую позицию в файле.
LOC (номер_файла)
• номерфайла — номер открытого файла или устройства.
Для файлов прямого доступа, LOC возвращает номер после-
дней записи, к которой было обращение чтения/записи. Для
файлов последовательного доступа, LOC возвращает текущую
байтовую позицию, деленную на 128. Для двоичных файлов, LOC
возвращает позицию последнего считанного или записанного
байта.
Для устройства COMn:, LOC возвращает число символов во
входной очереди, ожидающей чтения. Значения зависит от того,
открыто устройство как файл типа ASCII или двоичный. Для ти-
па ASCII процедуры низкого уровня останавливают входной по-
ток при получении символа EOF. Для двоичного файла EOF иг-
норируется и файл может читаться дальше.
LOC не используется с устройствами SCRN:, KYBD:, LPTn:.
LOCK...UNLOCK
LOCK...UNLOCK — операторы файлового ввода/вывода,
контролирующие доступ других процессов ко всему или части
открытого файла. Используются в сетевой среде, где несколько
207
процессов могут иметь доступ к одному файлу. Требуют наличия
DOS 3.1 или выше.
LOCK [#]номер_файла [.запись I[начало] ТО конец]
[операторы]
UNLOCK [#]номер_файла[,запись I[начало] ТО конец]
• номерфайла — номер открытого файла;
• запись — номер записи или байта, который требуется забло-
кировать для других процессов (от 1 до 2147483647 — байто-
вая позиция, от 1 до 32767 — запись). Длина записи может
быть длиной до 32767 байт;
• начало — номер начальной записи или байта;
• конец — номер конечной записи или байта.
Для файлов двоичного доступа аргументы запись, начало и
конец представляются в виде байтовой позиции относительно
начала файла. Первый байт в файле имеет номер 1.
Для файлов прямого доступа эти аргументы представляются
в виде номера записи относительно начала файла. Первая запись
имеет номер 1.
Операторы LOCK и UNLOCK всегда используются в паре.
Аргументы в них также должны соответствовать.
Если вы указали только одну запись, то именно она будет
блокирована или деблокирована. Если вы указали несколько за-
писей и опустили начало, то все записи от первой до указанного
вами конца будут блокированы или деблокированы. LOCK без
аргументов блокирует весь файл, a UNLOCK — деблокирует.
Если файл был открыт для последовательного ввода или вы-
вода, LOCK и UNLOCK блокируют или деблокируют весь файл,
несмотря на указанные аргументы. LOCK и UNLOCK функцио-
нируют только при наличии DOS, поддерживающей сети (версии
3.1 или выше). В добавление, каждый терминал и сервер должны
запустить программу DOS SHARE.EXE для разрешения одновре-
менного доступа к файлом.
Будьте осторожны при деблокировании файла оператором
UNLOCK перед закрытием файла или завершением Вашей про-
граммы. Сбои при удалении блокировок могут привести к по-
вреждению содержимого файла.
При попытке обратиться к заблокированному файлу, воз-
можны следующие сообщения об ошибках:
208
"Bad record number" (Неверный номер записи);
"Permission denied" (Доступ невозможен).
Пример. Требуется DOS 3.1 или выше.
TYPE AccountRec
Payer AS STRING * 15
Address AS STRING * 20
Place AS STRING * 20
Money AS SINGLE
END TYPE
DIM CustRec AS AccountRec
OPEN "MONITOR" SHARED AS #1 LEN = LEN(CustRec)
DO
CLS: LOCATE 10,10
INPUT "Номер покупателя "; Number%
1 Блокирование текущей записи для других процессов.
LOCK #1, Number%
GET #1, Number%
LOCATE 11,10: PRINT "Покупатель: ";CustRec.Payer
LOCATE 12,10: PRINT "Адрес: ";CustRec.Address
LOCATE 13,10: PRINT "Задолжал $: ";CustRec.Money
LOCATE 15,10: INPUT "Вернул $: ";Change!
CustRec.Owe = CustRec.Owe + Change!
PUT #1, Number%
' Деблокирование записи.
UNLOCK #1, Number%
LOCATE 17,10: INPUT "Следующий Y/N "; Continue$
Update$ = UCASE$(LEFT$(Continue$,1))
LOOP WHILE Update$ = "Y"
SEEK
SEEK — функция файлового ввода/вывода, возвращает те-
кущую позицию в файле.
SEEK(номер_файла)
• номер_файла — номер открытого файла любого типа доступа.
Для файлов прямого доступа возвращает номер текущей за-
писи. Для остальных — текущую байтовую позицию отно-
сительно начала файла. Первый байт или запись равны 1.
209
SEEK возвращает значение в пределах 1 — 2,147,483,647 (эк-
вивалентно 2А31 -1).
Для устройства, открытого как файл, функция возвращает
ноль. Устройства SCRN:, CONS:, KYBD:, COMn: и LPTn: не
поддерживают SEEK.
Пример. Фрагмент программы, приведенный ниже, выводит
сообщение, показывающее, в какой части файла были
сделаны последние запись или чтение:
SELECT CASE (SEEK(l))
CASE IS < .333 * LOF(l)
PRINT "Первая треть файла."
CASE .333 * LOF(l) TO .6 67 * LOFA)
PRINT "Вторая треть файла."
CASE IS >= .667 - LOF(l)
PRINT "Последняя треть файла."
CASE ELSE
END SELECT
SEEK
SEEK — оператор файлового ввода/вывода, устанав-
ливающий позицию в файле для операций чтения или записи.
SEEK [#]номер_файла,позиция
• номерфайла — номер файла, открытого оператором OPEN;
• позиция — числовое выражение, указывающее следующую
позицию чтения или записи: для файлов типа RANDOM по-
зиция — это номер записи, для файлов типа BINARY,
INPUT, OUTPUT, или APPEND позиция - номер байта от
начала файла.
Позиция должна быть в пределах 1-2147483647 (эквивалент-
но 231 - 1).
Номер записи, указанный в операторах GET или PUT, ста-
новится текущей позицией в файле.
Выполнение SEEK с отрицательным или нулевым значением
позиции производит ошибку "Bad record number" (Неверный но-
мер записи).
При выполнении над устройством, не поддерживающим SEEK,
действие оператора игнорируется и позиция не изменяется.
Пример. Использования функции и оператора SEEK.
210
CONST FALSE=0, TRUE=NOT FALSE
TYPE TestRecord
NameField AS STRING * 20
ScoreField AS SINGLE
END TYPE
DIM RecordVar AS TestRecord
1 Эта часть программы создает файл прямого
1 доступа для последующей демонстрации.
¦ ***************************************************
OPEN "GULLAP.DAT" FOR RANDOM AS #1 LEN = LEN(Rec)
CLS
RESTORE
READ NameField$, ScoreField
i = 0
DO WHILE UCASE$(NameField$) <> "END"
i = i + 1
RecordVar.NameField = NameField$
RecordVar.ScoreField = ScoreField
PUT #1, i, RecordVar
READ NameField$, ScoreField
IF NameField$ = "END" THEN EXIT DO
LOOP
CLOSE #1
DATA "Роберт", 100
DATA "Алиса" 95
DATA "Алексей", 72
DATA "Василий", 90
DATA "Георгий", 92
DATA "END", 0
i****************************************************
' Демонстрация функции SEEK и оператора SEEK,
i****************************************************
DIM FileBuffer AS TestRecord
OPEN "GULLAP.DAT" FOR RANDOM AS #1 LEN=LEN(FileBuffer)
1 Подсчитываем количество записей в файле.
Мах = LOF(l) / LEN(FileBuffer)
' Читаем и проверяем содержимое записи.
FOR I = 1 ТО Мах
GET #1, I, FileBuffer
IF FileBuffer.NameField = "Alex" THEN
ReWriteFlag = TRUE
EXIT FOR
END IF
NEXT I
211
IF ReWriteFlag = TRUE THEN
1 Установим указатель на начало данной записи,
1 т.к. сейчас он находится на начале следующей.
FileBuffer.ScoreField = 50
SEEK #1, SEEK(l) * LEN(RecordVar)
PUT #1 , , RecordVar
END IF
CLOSE #1
END
Принтер
LPOS
LPOS — функция ввода/вывода, возвращающая текущую по-
зицию печатающей головки принтера в буфере принтера.
LPOS(n)
• п — числовое выражение от 0 до 3, указатель порта принтера.
0 или 1 означает LPT1:, 2 означает LPT2:, и т. д.
Текущая позиция, возвращаемая функцией LPOS может не
совпадать с физическим положением печатающей головки, так
как принтеры могут не воспринимать знаков табуляции и иметь
буфер для печати.
LPRINT, LPRINT USING
LPRINT, LPRINT USING — операторы ввода/вывода, печа-
тающие данные на принтер LPT1.
LPRINT [список_выражений][;I,]
LPRINT USING формат; список_выражений[;I,]
• список_выражений — одно или более выражений, разделен-
ных ";" или ",".
• формат — в операторе LPRINT USING — символьная пере-
менная или константа, содержащая специальные форма-
тирующие символы и другие знаки.
212
Если все аргументы опущены, то на принтер выводится пус-
тая строка.
Эти операторы работают аналогично операторам PRINT и
PRINT USING, но вывод данных идет на принтер и номер файла
не требуется.
Оператор LPRINT по умолчанию подразумевает принтер с
шириной строки 80 знаков. Можно изменить ее оператором
WIDTH LPRINT.
При работе оператора LPRINT CHR$A3), BASIC обязатель-
но выводит LPRINT CHR$A3) (возврат каретки) и LPRINT
CHR$A0) (перевод строки).
Пример. Изменение ширины печати для оператора LPRINT
'Ширина печати установлена в 132 символа
WIDTH LPRINT 132
Порты
INP
INP — функция ввода/вывода, читающая байт из порта вво-
да/вывода.
ШР(порт)
• порт — числовое выражение от 0 до 65535, определяющее
порт оборудования компьютера.
Операторы INP и OUT дают программе контроль над обору-
дованием через порты ввода/вывода. Будьте осторожны с этими
операторами, так как вы получаете доступ непосредственно к
оборудованию.
Пример. Проверка готовности принтера к печати
IF (INP(&H379) AND 208) о 208 THEN
LOCATE 1,1: PRINT "Принтер не готов к печати !"
ВЕЕР
ELSE
LOCATE 1,1: PRINT "Принтер готов к печати !"
END IF
213
OUT
OUT — оператор ввода/вывода, посылающий байт в порт
ввода/вывода.
OUT порт, данные
• порт — целое числовое выражение от 0 до 65535, определяю-
щее требуемый порт ввода/вывода.
• данные — целое числовое выражение от 0 до 255, данные, по-
сылаемые в порт.
OPEN COM
OPEN COM — оператор ввода/вывода, открывающий и ини-
циализирующий коммуникационный канал для связи через мо-
дем или коммуникационный порт. '
OPEN "COMn: опции1 опции2" [FOR тип] AS [#]номер [ЬЕЫ=длина]
• п — номер коммуникационного порта, 1 или 2
• опции 1 — имеют следующий вид:
[скорость][,[проверка][,[данные][,[стоп-биты]]]]
• опции2 — могут определить до 10 управляющих параметров;
• номер — номер файла, присвоенный данному каналу.
Опции 1
Скорость
Проверка
Данные
Стоп-биты
Описание
Количество бод (бит в секунду, проходящих че-
рез канал). Возможны скорости 75, ПО, 150,
300, 600, 1200, 1800, 2400 и 9600 бод.
Метод проверки на четность. Значения: N
(нет), Е (четность), О (нечетность), S (пусто),
М (метка).
Количество битов данных в байте. Возможные
значения: 5, 6, 7, 8.
Количество стоповых битов. Возможно 1, 1.5, 2.
214
Если вы установили 8 бит данных на байт, вы должны опре-
делить проверку N.
Если вы не указали одну из опций 1, то пустое место в опера-
торе должно отделяться запятой:
OPEN "COM1: ,,,,CD1500" FOR INPUT AS #1
Для опций2 аргумент m дается в миллисекундах. По умолча-
нию m = 1000.
Опции
2
ASC
BIN
CD[m]
CS[m]
DS[m]
LF
Описание
Открывает устройство по типу ASCII. При этом симво-
лы табуляции заменяются на пробелы, в конец строки
ставится символ возврата каретки, а в конец файла —
CTRL+Z. При закрытии канала в линию RS-232 всегда
посылается CTRL+Z.
Открывает устройство по двоичному типу. Эта опция ис-
ключает опцию LF. BIN выбирается по умолчанию. При
этом символы табуляции не заменяются на пробелы, в
конец строки не добавляется символ возврата каретки, а в
конец файла — символ CTRL+Z.
Управляет тайм-аутом линии Data Carrier Detect
(DCD — "обнаружен носитель данных")- Если DCD не
получала сигнала m миллисекунд, генерируется тайма-
ут устройства (задержка во времени).
Управляет тайм-аутом линии Clear To Send (CTS —
"очистка посылки"). Если CTS не получала сигнала m
миллисекунд, генерируется тайм-аут устройства
(задержка во времени).
Управляет таймаутом линии Data Set Ready (DSR —
"готовность набора данных"). Если DSR не получала
сигнала m миллисекунд, генерируется таймаут устрой-
ства (задержка во времени).
Позволяет коммуникационным файлам распечатываться
на принтер. Когда LF указан, символ перевода строки
(OAh) автоматически добавляется к символу возврата ка-
ретки (ODh). Если для чтения из такого файла исполь-
зуются операторы INPUT и LINE INPUT, их ввод за-
вершается при распознавании символа перевода карет-
ки, игнорируя символ перевода строки.
215
OPjm]
RB[n]
RS
TB[n]
Управляет ожиданием открытия канала. Параметр m —
это число от 0 до 65535, количество миллисекунд ожи-
дания начала активности коммуникационных линий.
Если ОР задан без параметра, оператор ожидает 10 се-
кунд. Если ОР опущен, OPEN COM ожидает в 10 раз
больше, чем максимальное значение таймаута опций
CD и/или DS.
Устанавливает размер буфера-приемника п байт. Если
п опущено или опция опущена, используется текущее
значение, установленное опцией /С командной строки
QuickBASIC или компилятора. По умолчанию 512 байт.
Максимально — 32767 байт.
Suppresses detection линии Request To Send (RTS —
"Запрос на посылку").
Устанавливает буфер передачи п байт. Если п опущено
или опция опущена, используется текущее значение.
По умолчанию — 512 байт.
Опции2, разделенные запятыми, могут вводиться в список в
любом порядке. Для CS[m], DS[m] и CD[m], если не получена
сигнала в течение m миллисекунд, генерируется тайм-аут. Значе-
ние m может быть в пределах 0-65535, по умолчанию 1000. Зна-
чение CD по умолчанию 0. Если m равно 0 для опции, то опция
игнорируется. Линия CTS проверяется независимо от того, есть
или нет данных в буфере передачи, если указана опция CS. Ли-
нии DSR и DCD проверяются на таймауты, если соответствую-
щие опции (DS, CD) указаны.
Аргумент тип — один из следующих:
Тип
OUTPUT
INPUT
RANDOM
Описание
Определяет последовательный вывод
Определяет последовательный ввод
Определяет прямой тип ввода/вывода
Если тип опущен, то по умолчанию он устанавливается как
прямой тип ввода/вывода. Оператор OPEN COM должен быть
выполнен перед использованием с интерфейсом RS-232.
216
Если устройство открыто по типу RANDOM, опция LEN оп-
ределяет длину буфера прямого доступа. По умолчанию длина
буфера равна 128 байт. Можно использовать любые операторы
прямого ввода/вывода, такие как GET и PUT для чтения/записи
устройства.
Оператор OPEN COM делает следующие шаги по открытию
коммуникационного устройства:
1. Коммуникационные буферы размещены и прерывания включены.
2. Флаг линии Data Terminal Ready (DTR — "готовность компь-
ютера") поднят.
3. Если опции ОР или DS ненулевые, оператор ожидает указанное
время поднятия флага линии Data Set Ready (DSR — "готовность
модема"). В случае тайм-аута процесс переходит к шагу 6.
4. Флаг линии Request To Send (RTS — "запрос на посылку")
поднимается, если опция RS не указана.
5. Если опции ОР или CD ненулевые, OPEN COM ожидает указан-
ное время поднятия флага линии Data Carrier Detect (DCD —
"обнаружен носитель данных"). В случае таймаута процесс пере-
ходит к шагу 6. Иначе, OPEN COM успешно выполнен.
6. Открытие прервано из-за тайм-аута. Процесс закрывает буфера,
выключает прерывания и очищает все управляющие линии.
Используйте относительно большие значения параметра оп-
ции ОР по сравнению с параметрами опций CS, DS, CD. Если
две программы включаются в коммуникационную связь, им обе-
им требуется время для выполнения оператора СОМ.
Все синтаксические ошибки оператора OPEN COM выдают
сообщения вида "Bad file name" ("Плохое имя файла").
Пример: Открытие коммуникационного канала 1 (СОМ1:) по
типу произвольного ввода/вывода. Установлена
скорость передачи 9600 бод, без проверки на чет-
ность, 8 битов данных, 1 бит стоповый. Ввод и
вывод осуществляется в двоичном режиме. Канал
открыт как файл номер 2.
OPEN "COM1:9600, N, 8, 1, BIN" AS 2
217
Поскольку телефонная линия очень медленная1, то связь с
модемом — эта одна из областей, где программирования на
BASIC ничем не хуже, чем на языке ассемблера.
Пример: Упрощенная схема работы с модемом:
'устанавливаем бит DTR
OUT BaseAddress +4, 1
'Теперь посылаем управляющую строку для вызова и
'установления связи - этот код меняется от модема к модему
DO
'получаем регистр статуса модема
х = INP(BaseAddress + 2)
LOOP WHILE x AND 2 о 2 'ждем, пока будет установлен бит 1
'получаем регистр статуса модема
OUT BaseAddress + 4, 3
DO
'получаем регистр статуса модема
х = INP(BaseAddress + 2)
LOOP WHILE x AND 2 о 1 'ждем, пока будет установлен бит О
1 теперь можно начать передачу данных
STICK
STICK — функция ввода/вывода, возвращает х, у-координа-
ты двух джойстиков.
STICK(п)
• п — числовое выражение в пределах 0—3, указывает возвраща-
емое значение возможных координат джойстиков выдать:
Аргумент
0
1
2
3
Возвращаемое значение
х-координата джойстика А
у-координата джойстика А
х-координата джойстика В
у-координата джойстика В
1 Более подробно о работе модемами, телефонными линиями и глобальными
сетями вы можете прочитать в книге "Компьютер на связи!" (Григорий Зельднер
и др.), выпушенной издательством "ABF" в 1996 году.
218
Координаты х и у имеют пределы 1—200. Вы должны выз-
вать функцию STICK(O) перед вызовами STICK(l), STICKB),
STICKC). STICK(O) не только возвращает х-координату джой-
стика А, но также записывает другие координаты джойстиков.
Эти записанные координаты возвращаются путем вызова
STICKA)...STICKC).
STRIG
STRIG — функция ввода/вывода, возвращает статус указан-
ного триггера джойстика.
STRIG(П)
• п — числовое выражение в пределах 0—7, указывает вид воз-
вращаемой информации.
Функция STRIG используется для проверки статуса триггера
джойстика. QuickBASIC не поддерживает операторов STRIG ON и
STRIG OFF.
Числовое выражение п указывает джойстик и триггер, статус
которого необходимо проверить:
Аргу-
мент
0
1
2
3
4
5
6
7
Возвращаемое значение
-1, если нижняя кнопка джойстика А была нажата с
прошлого вызова STRIG(O). 0, если нет
-1, если нижняя кнопка джойстика А сейчас нажата.
0, если нет
-1, если нижняя кнопка джойстика В была нажата с
прошлого вызова STRIGB). 0, если нет
-1, если нижняя кнопка джойстика В сейчас нажата.
0, если нет
-1, если верхняя кнопка джойстика А была нажата с
прошлого вызова STRIGD). 0, если нет
-1, если верхняя кнопка джойстика А сейчас нажата.
0,если нет
-1, если верхняя кнопка джойстика В была нажата с
прошлого вызова STRIGF). 0, если нет
-1, если верхняя кнопка джойстика В сейчас нажата.
0, если нет.
219
Можно также применить отслеживание событий джойстика
оператором ON STRIG, но нельзя использовать функцию STRIG
при отслеживании джойстика, т. к. это может разрушить процесс
отслеживания.
WAIT
WAIT — управляющий оператор, приостанавливающий вы-
полнение программы до получения из порта необходимых дан-
ных.
WAIT порт, AND-выражение[,XOR-выражение]
• порт — целое выражение в пределах 0—255, адрес порта;
• AND-выражение — целое выражение, комбинируемое с дан-
ными, получаемыми из порта операцией AND;
• XOR-выражение — целое выражение, комбинируемое с дан-
ными, получаемыми из порта, операцией XOR.
Оператор WAIT приостанавливает программу до тех пор, по-
ка определенный битовый образ не будет получен из данного
порта. Получаемые данные комбинируются операцией XOR с
XOR-выражением, если оно указано. Полученный результат ком-
бинируется с AND-выражением операцией AND.
Если результат равен 0, BASIC читает данные из порта снова.
Если результат ненулевой, выполнение программы продолжается.
Если XOR-выражение опущено, подразумевается, что оно равно 0.
Возможно неопределенно долгое повторение оператора
WAIT, если произошел сбой порта ввода/вывода. В этом случае
может помочь только перезагрузка компьютера.
Пример. Иллюстрирует оператор WAIT:
WAIT HandShakePort, 2
Этот оператор предписывает делать операцию AND до тех
пор, пока не будет получен байт через порт HandShakePort с би-
товым представлением 2 @0000010).
220
ГРАФИКА И ЗВУК
Графика
CLS
CLS — оператор, очищающий экран дисплея.
CLS [0I1I2]
• если все аргументы опущены, очищаются и графический и
текстовый экраны, установленные оператором VIEW или взя-
тые по умолчанию;
• 0 — очищает и текстовый и графический экраны;
• 1 — очищает только графический экран, если он активен;
• 2 — очищает только текстовый экран, исключая нижнюю
строку.
Пример: на графическом экране рисуются окружности. На
текстовый экран выдаются сообщения. Периодически очи-
щаются раздельно графический и текстовый экраны.
RANDOMIZE TIMER
SCREEN 1
' Установка графического экрана вывода.
VIEW E,5)-(Ю0,80) ,3,1
1 Установка текстового экрана вывода.
VIEW PRINT 12 ТО 24
LOCATE 25,1 -. PRINT "Нажмите любую клавишу."
Count = О
DO
1 Рисуются окружности случайным образом.
CIRCLE E0,40),INT(C5-4)-RND + 5),(Count MOD 4)
1 Стирание графического окна через 3 0 окружностей.
IF (Count MOD 30) =0 THEN CLS 1
PRINT "Hello.
1 Стирание текстового окна через 45 сообщений.
IF (Count MOD 45) =0 THEN CLS 2
Count = Count + 1
LOOP UNTIL INKEY$ <> ""
He I lo
He I lo
Hello
He I lo
He I lo
Hello
He I lo
He I
He I
He I
He I
He I
He I
He I
lo
о
о,
о
О:
о.
о,
Hello.
Hello.
Не Ilo.
Hello.
Hello.
Hello.
He No.
el lo. Hello.
He
He
He lo.
He lo.
ij jo
el lo
el lo
I lo
I lo
He
ello. He
lo.
lo.
Ужмите любчн» клаВишч.
COLOR
COLOR — оператор, устанавливающий экранные цвета.
COLOR [основной][,[фоновый][,рамка ]]
• основной — цвет текста (в пределах 0—31, где 16—31 мерцающие);
• фоновый — цвет экрана (в пределах 0—7);
• рамка — цвет вокруг экрана (в пределах 0—15).
222
Номера экранных цветов
0
1
2
3
4
5
6
7
черный
голубой
зеленый
бирюзовый
красный
розовый
коричневый
белый
8
9
10
11
12
13
14
15
серый
ярко-голубой
ярко-зеленый
ярко-бирюзовый
ярко-красный
ярко-розовый
желтый
ярко-белый
SCREEN О
Описание экранных режимов
Изменяет текущий основной и фоновый цвета выво-
димого на экран текста и цвет рамки вокруг экрана,
вы можете выбрать мерцающий вариант цвета путем
добавления 16 к основному цвету. Например, мерца-
ющий цвет 7 равен 7 + 16, или 23. Мерцание фоново-
го цвета не поддерживается. EGA, VGA и MCGA не
поддерживают цвет рамки.
SCREEN 1
В данном режиме COLOR имеет особый синтаксис,
который включает номер палитры. Он определяет,
какой из двух наборов цветов используется. По умол-
чанию, цвета для параметра палитры соответствуют
цветам оператора PALETTE для EGA:
COLOR , 0'Как в следующих трех операторах
PALETTE 1, 2'атрибут 1 = цвет 2 (зеленый)
PALETTE 2, 4'атрибут 2 = цвет 4 (красный)
PALETTE 3, 6'атрибут 3 = цвет б (желтый)
COLOR , 1'Как в следующих трех операторах
PALETTE 1, 3'атрибут 1 = цвет 3 (бирюзовый)
PALETTE 2, 5'атрибут 2 = цвет 5 (розовый)
PALETTE 3, 7'атрибут 3 = цвет 7 (белый)
223
В данном режиме оператор COLOR отменяет дей-
ствие предыдущих операторов PALETTE.
SCREEN 2
При вызове данного оператора выдается сообщение
"Illegal function call" ("Неверный вызов функции").
SCREEN 7, 8, 9, 10
В этих режимах цвет рамки не задается. Фоновый
цвет определяется значением соответствующего пара-
метра, тогда как основной цвет зависит от содержа-
ния текущей палитры и определяется по номеру ат-
рибута в данной палитре.
SCREEN 11
Используйте оператор PALETTE для установки цвета
в данном режиме. Оператор COLOR приведет к
ошибке "Illegal function call" ("Неверный вызов фун-
кции").
SCREEN 12, 13
Фоновый цвет в данных режимах отсутствует. Ис-
пользуйте только основной цвет. Детали см. в описа-
нии оператора SCREEN.
Если основной и фоновый цвета одинаковы, выводимые
символы становятся невидимыми. По умолчанию фоновый
цвет — черный @) для всех конфигураций дисплейных адаптеров
и всех экранных режимов.
В режимах 12 и 13 вы можете установить фоновый цвет пу-
тем присвоения номера цвета атрибуту 0 оператором PALETTE.
Например, чтобы сделать фоновый цвет равным 8224 (светло-фи-
олетовый), вы должны задать следующий оператор PALETTE:
PALETTE 0, 8224
В режиме 11 вы можете определить и основной и фоновый
цвета путем присвоения номера цвета атрибуту 0 оператором
PALETTE.
Если у вас адаптер EGA, VGA, или MCGA, оператор PA-
LETTE даст вам возможность присвоить различные цвета ат-
рибутам цвета в указанных пределах для основного и фоново-
го цветов.
224
Пример: эффекты оператора COLOR в различных режимах
экрана.
SCREEN 0 ' текст
COLOR 1, 2
CLS
LOCATE 12,25: PRINT "Нажмите любую клавишу..."
DO: LOOP WHILE INKEY$ =
SCREEN 1 ' графика 320 x 200
' фоновый = 1 (голубой)
1 основной = четная палитра (красный, зеленый, желтый)
COLOR 1, 0
LINE B0, 20) - C00, 180) , 3, В
LOCATE 12,7: PRINT "Нажмите любую клавишу..."
DO: LOOP WHILE INKEY$ = ""
1 фоновый = 2 (зеленый)
' основной = нечетная палитра (белый, розовый, бирюзовый)
COLOR 2, 1
LINE B0, 20) - C00, 180), 3, В
LOCATE 12,7: PRINT "Нажмите любую клавишу..."
DO: LOOP WHILE INKEY$ = ""
SCREEN 0 ' текст
COLOR 7, 0
CLS
END
PALETTE, PALETTE USING
PALETTE, PALETTE USING — операторы установки цвета,
изменяющие один или более цветов в палитре. Работают только с
адаптерами EGA, VGA, MCGA.
PALETTE [атрибут, цвет]
PALETTE USING массив[(индекс)]
• атрибут — атрибут палитры, который нужно изменить @—15);
• цвет — цвет, присваиваемый атрибуту. Должен быть длинным
целым выражением для VGA и MCGA в режимах экрана 11—
13. Целое или длинное целое выражение используется с EGA;
• массив — массив, содержащий номера цветов, присваиваемых
атрибутам текущего режима экрана. Адаптеры VGA и MCGA
требуют длинного целого массива в режимах 11—13. EGA тре-
бует целый или длинный целый массив;
• индекс — индекс начального элемента массива, используемый
для установки палитры.
225
Оператор предоставляет возможность изменять дисплейные
цвета (двоичные значения, используемые адаптером), присвоен-
ные атрибутам цвета. Все операторы BASIC, такие как CIRCLE,
COLOR, DRAW, LINE используют атрибуты цвета, а не действи-
тельные значения экранных цветов.
Когда в программе задается режим экрана, атрибуты уста-
навливаются по умолчанию. (См. оператор SCREEN, где указан
список цветов по умолчанию). В адаптерах EGA, VGA и MCGA
эти цвета по умолчанию могут быть выбраны из нескольких воз-
можных, так как адаптер может генерировать гораздо больше
цветов, чем количество атрибутов.
Этим атрибутам можно присвоить различные цвета этим атри-
бутам, получая доступ к управлению цветами экрана. PALETTE без
аргументов восстанавливает палитру в исходное состояние.
При выполнении оператора PALETTE с аргументами адаптер
устанавливает дисплейный цвет, заданный оператором, вместо
атрибута, используемого по умолчанию. Изменение параметра
атрибута немедленно приведет к изменению цвета текущей кар-
тинки на экране.
Например, текущая палитра содержит цвета 0, 1, 2 и 3 в че-
тырех атрибутах номер 0, 1, 2 и 3. Оператор
DRAW "C3L100"
выбирает атрибут 3 и рисует линию из 100 точек атрибутом 3, ко-
торый содержит цвет 3. Если выполнить оператор
PALETTE 3,2
то значение цвета атрибута 3 станет равным 2. Весь текст или
графика, находящиеся на экране, поменяют цвет атрибута 3 на
значение 2. Новая палитра содержит цвета 0, 1, 2 и 2.
Используя опцию USING, можно изменить всю палитру одним
оператором PALETTE. Аргумент массив представляет собой целый
или длинный целый массив, а аргумент индекс указывает первый
элемент массива, используемый для установки палитры. Каждый ат-
рибут в палитре получает соответствующий цвет из массива, начиная
с элемента, указанного индексом. Массив должен быть достаточного
размера, чтобы в него вошли значения всех атрибутов палитры. На-
пример, если присваиваются цвета всем 16 атрибутам и индекс равен
5, массив должен иметь размерность не менее 20 элементов
(интервал 5-20 состоит из 16 элементов):
226
DIM PAL%B0)
PALETTE USING PAL%E)
Аргумент массива -1 оставляет атрибут без изменения. Все
другие отрицательные значения ошибочны.
VGA использует особый способ формирования значения цвета.
Для вычисления цвета выберите интенсивность красной, зеленой и
синей составляющих. Интенсивность — это число от 0 (низкая) до
63 (высокая).
Формула вычисления номера цвета:
цвет = 6553 6 * синий + 256 * зеленый + красный
Так как существуют пустые промежутки в интервале возмож-
ных цветов, используйте эту формулу перед установкой цвета.
Для аналогового монохромного монитора IBM цвета VGA
преобразуются в оттенки серого по следующей формуле, исполь-
зующей весовые части составляющих:
оттенок = 11% синий + 59% зеленый + 3 0% красный
Например, если интенсивности соответственно равны 45, 20
и 20, оттенок серого будет равен:
.11 * 45 + .59 * 20 + .30 * 20 или 22.
PCOPY
PCOPY — оператор экранного вывода, копирующий одну
экранную страницу в другую.
PCOPY источник, приемник
• источник — целое числовое выражение от 0 до п, указывающее
на сегмент видеопамяти, содержащий экранную страницу. Значе-
ние п зависит от размера видеопамяти и режима экрана;
• приемник — целое числовое выражение от 0 до п, указываю-
щее на сегмент видеопамяти, куда помещается копия.
Количество экранных страниц зависит от текущего режима
экрана и типа дисплея.
227
SCREEN (функция)
SCREEN — графическая функция, читающая ASCII-код
символа или его цвет в указанном месте экрана.
SCREEN (строка, столбец[,флаг_цвета])
• строка — номер строки экрана, целое выражение без знака;
• столбец — номер столбца экрана, целое выражение без знака;
• флаг_цвета — целое числовое выражение. Если флагцвета не
равен нулю, SCREEN возвращает значение цвета. Если он ра-
вен нулю или отсутствует, возвращается ASCII-код символа,
находящегося в указанном месте;
Если символ в позиции A0,10) — А, то в следующем приме-
ре функция выдает 65, ASCII-код латинской буквы А.
X = SCREENA0,10)
Значение цвета в текстовом режиме экрана кодируется сле-
дующим образом: основной + фоновый * 16.
SCREEN (оператор)
SCREEN — графический оператор, устанавливающий спе-
цификацию экрана.
SCREEN [режим]
[,[цвет]][,[стр_вывода]][,[стр_экрана]]
• режим — целое выражение, указывающее режим экрана;
• цвет — определяет, будет ли информация выдаваться в цвете.
Числовое выражение в пределах 0—255:
• если цвет не равен нулю, информация выдается только
черно-белом виде;
• если цвет равен нулю, цвет сохраняется;
• значение аргумента цвет инвертируется в режиме 0;
• в режимах 2 и выше аргумент игнорируется.
228
• стр_вывода — числовое выражение, номер активной экранной
страницы, на которую выводится текст или графика;
• стр_экрана — числовое выражение, номер текущей экранной
страницы.
VIEW PRINT
VIEW PRINT — оператор ввода/вывода, устанавливающий
границы текстового окна вывода
VIEW PRINT [верх ТО низ]
• выполнение без аргументов определяет весь экран как окно выво-
да;
• верх — числовое выражение, первая строка текстового вывода;
• низ — последняя линия текстового вывода.
Число строк на экране зависит от режима экрана и наличия
ключа /Н при запуске среды QB. Для информации о размерах
экрана см. оператор WIDTH.
Операторы и функции ввода/вывода оперируют с определен-
ным окном вывода, включая операторы CLS, LOCATE, PRINT и
функцию SCREEN. См. пример к оператору CLS.
VIEW
VIEW — графический оператор, определяющий границы
виртуального экрана графического вывода.
VIEW [[SCREEN] (xl,yl)-(х2, у2) [,[цвет][,рамка]]]
• SCREEN — опция SCREEN определяет, что координаты х и у
любой выводимой точки имеют абсолютные значения, а не
относительные по отношению к границам виртуального окна.
Графика выводится только внутри окна. Если SCREEN опу-
щен, все точки выводятся с координатами, относительными
границ окна (xl и yl добавляются к значениям координат пе-
ред выводом);
• (xl,yl)-(x2, у2) — определяет прямоугольную область на экра-
не — виртуальное окно. Координаты xl, yl, х2, у2 являются
229
числовыми значениями верхнего левого и нижнего правого
углов прямоугольника;
• цвет — атрибут цвета указывает, каким цветом будет закраше-
но окно. Если цвет опущен, окно не закрашивается;
• рамка — любое числовое выражение рисует рамку вокруг ок-
на, если есть место на экране. Если аргумент опущен, рамка
не рисуется.
Оператор VIEW определяет "окно вывода", или прямоуголь-
ную площадь на экране, куда будет выводиться графика. Все ко-
ординаты — аргументы этого оператора должны находиться в
пределах экрана.
Если VIEW выполняется без аргументов, окном вывода будет
весь экран. Операторы RUN и SCREEN также определяют весь
экран для вывода и отменяют действие оператора VIEW.
См. пример к оператору CLS.
WINDOW
WINDOW — графический оператор, определяющий размеры
текущего окна вывода.
WINDOW [[SCREEN] (xl,yl) - (х2, у2)]
• если все аргументы опущены, окно вывода займет весь экран;
• (xl,yl) - (х2, у2) — числа обычной точности, определяющие
координаты прямоугольного окна вывода.
Оператор WINDOW позволяет создать координатную систему
для рисования линий, графиков или других объектов без задания аб-
солютных координат на экране. Таким образом, координаты всех
точек определяются как относительные к данному окну вывода.
Все последующие графические операторы используют новые
координаты, и их вывод идет в данное окно. Размер окна вывода
может быть изменен оператором VIEW.
Операторы RUN или WINDOW без аргументов отменяют
окно вывода. Вариант WINDOW SCREEN преобразует направле-
ние координаты у в декартово представление, т. е. значения у
идут от большего к меньшему сверху вниз.
Следует учесть, что применение оператора WINDOW при-
мерно в 2 раза снижает скорость вывода графики на экран.
230
CIRCLE
CIRCLE — графический оператор, рисующий эллипс или
окружность с определенным центром и радиусом.
CIRCLE [STEP]
(х,у),радиус[,[цвет][,[начало][,[конец][,коэф-т]]]]
• (х,у) — экранные координаты центра окружности или эллипса;
• радиус — радиус круга или эллипса в текущей координатной
системе;
• STEP — указывает, что х,у — относительный центр от текущей
позиции курсора;
• начало, конец — используются для рисования дуг. Их значе-
ния находятся в пределах от -2 * PI до 2 * PI радиан, где PI =
3.141593. По умолчанию начало = 0, конец = 2 * PI. Если на-
чало и конец < О, CIRCLE рисует радиус до этой точки дуги и
считает начало и конец > 0. Начальный угол должен быть
меньше конечного. Если вы указали конец без начала, дуга
рисуется от 2 * PI до конца. Если вы указали начало без кон-
ца, дуга рисуется от начала до нуля;
• цвет — атрибут цвета. По умолчанию — основной цвет;
• коэф-т — коэффициент сжатия — отношение радиуса "у" к
радиусу "х". По умолчанию этот коэффициент принимается
для рисования окружности. Отношение вычисляется следую-
щим образом:
4 * (у-координаты точки/ х-координаты точки)/3
Здесь х-координаты точки и у-координаты точки определяют-
ся разрешением экрана. Например, если режим экрана 1 C20
х 200), то коэффициент сжатия будет равен:
4 * B00/320)/3 или 5/6
Если коэффициент сжатия < 1, радиус будет — "х", если ко-
эффициент > 1, радиус будет — "у".
231
Для того, чтобы нарисовать радиуса с углом 0 (горизонталь-
ный вектор), не задавайте угол как -0; используйте очень малое
отрицательное значение:
' Рисуется четверть круга:
SCREEN 2
CIRCLE B00, 100), 60, , -.0001, -1.57
Вы можете опустить аргументы в середине оператора, но обяза-
тельно включите запятые. В следующем операторе цвет опущен:
CIRCLE STEPA50, 200), 94, , 0, 6.28
При опускании последних аргументов, можно не ставить за-
пятые. Последняя точка после завершения CIRCLE — центр ок-
ружности. Координаты вне центра окружности могут быть вне
пределов экрана.
Пример: Нарисовать фигуру, показанную на рисунке.
CONST PI = 3.141593
SCREEN 2
1 Нарисовать круг без верхнего левого сегмента.
CIRCLE C20,100), 200,, -PI, -PI/2
232
' Нарисовать круг внутри этого сегмента.
CIRCLE STEP (-100,-42),100
' Нарисовать маленький эллипс внутри круга.
CIRCLE STEP@,0), 100,,,, 5/25
LOCATE 25,1 : PRINT "Нажмите любую клавишу.
DO: LOOP WHILE INKEY$ =""
LINE
LINE — графический оператор, рисующий линию или пря-
моугольник.
LINE [[STEP] (xl,yl)]-[STEP] (x2, у2)
[,[цвет][,[B[F]][.стиль]]]
• (xl,yl) — координаты начала линии;
• (х2, у2) — координаты конца линии;
• STEP — указывает на относительные координаты, то есть ко-
ординаты вычисляются как смещения относительно последней
точки.
Последнюю точку можно указать очисткой экрана операто-
рами CLS и SCREEN (центр экрана), а также операторами PSET,
PRESET, CIRCLE и DRAW.
Варианты рисования с аргументом STEP рассмотрены ниже.
Последней точкой является A0,10):
Оператор
LINE -E0,50)
LINE -STEPE0,50)
LINE B5,25)-STEPE0,50)
LINE STEPB5,25)-STEPE0,50)
LINE STEPB5,25)-E0,50)
Объяснение
Рисует от A0,10) до E0,50)
Рисует от A0,10) до F0,60),
т. к. 10 + 50 = 60
Рисует от B5,25) до G5,75),
т.к. 25 + 50 = 75
Рисует от C5,35) до (85,85),
т. к. 10 + 25 = 35 и 35 + 50 = 85
Рисует от C5,35) до E0,50),
т. к. 10 + 25 = 35
233
• цвет — номер цвета линии. Если заданы опции В или BF,
прямоугольник рисуется этим цветом;
• В — опция, рисующая прямоугольник с координатами верхне-
го левого угла (xl,yl) и нижнего правого угла (х2, у2);
• BF — опция, рисующая закрашенный указанным цветом пря-
моугольник;
•- стиль — 16-битовая маска, задающая тип линии. Оператор
LINE читает биты маски слева направо. Если бит = 0, точка
не рисуется, если бит = 1, рисуется точка данного цвета.
Так как бит 0 в стиле не меняет точки на экране, можно на-
рисовать фоновую линию. Стиль не влияет на закрашенные пря-
моугольники.
Если указанные координаты выходят за текущий экран вы-
вода, "лишняя" линяя обрезается у границы экрана вывода.
Пример: Построение узора при помощи оператора LINE
1 все переменные целые
DEFINT A-Z
'графический режим 640x350x16 цветов
SCREEN 9
FOR i = 1 ТО 600
FOR j = 1 ТО 15
COLOR j
LINE G1 * j, 25)-(i * 50, 725)
NEXT j
NEXT i
FOR i = 600 TO 1 STEP -1
FOR j = 1 TO 15
COLOR j
LINE G1 * j, 25)-(i * 50, 725)
NEXT j
NEXT i
DO: LOOP WHILE INKEY$ = ""
234
PRESET
PRESET — графический оператор, рисующий точку на экране.
PRESET [STEP](x,y)[,цвет]
• (х,у) — координаты точки;
• STEP — указывает, что координаты берутся как смещение от-
носительно текущего положения графического курсора;
• цвет — атрибут цвета точки. Если опущен, используется фоно-
вый цвет.
PRESET работает так же, как PSET, но, если цвет не указан,
то используется фоновый цвет.
Если координаты точки находятся вне экрана, то никаких
действий не производится и сообщений об ошибке не выдается.
PSET
PSET — графический оператор, рисующий точку на экране.
PSET [STEP](x,y) [,цвет]
235
• (х,у) — координаты точки на экране;
• STEP — указывает, что координаты берутся как смещение от-
носительно текущего положения графического курсора;
• если цвет опущен, используется текущий основной цвет.
PSET работает так же, как PRESET, но, если цвет не указан,
то используется основной цвет.
Если координаты точки находятся вне экрана, то никаких
действий не производится и сообщений об ошибке не выдается.
Пример: оператор PSET рисует линию из 20 точек, а опера-
тор PRESET стирает ее. В целом получается движение отрез-
ка.
SCREEN I: COLOR 1,1: CLS
FOR I = 0 TO 299 STEP 3
FOR J = I TO 20 + I
PSET (J, 50), 2
NEXT J
FOR J = I TO 20 + I
PRESET (J, 50)
NEXT J
NEXT I
DRAW
DRAW — графический оператор, интерпретирующий сим-
вольное выражение и рисующий графический объект.
DRAW символьное_выражение
• символьное_выражение — одна или более команд рисования.
Оператор DRAW объединяет многие возможности других
графических операторов в своем макроязыке. Команды макро-
языка описывают действия, необходимые для создания образов:
движение точки, углы поворота, цвет, масштаб.
Команды движения относительно текущей точки:
• В — двигаться, но не рисовать;
• N — двигаться, рисовать, вернуться в исходную точку
236
Эти команды определяют движение в относительных единицах.
По умолчанию — на одну точку. Единица движения модифицирует-
ся командой S, которая устанавливает масштаб. Каждая команда
движения задает перемещение относительно текущей графической
позиции. До выполнения какой-либо команды — это центр экрана.
Ко-
манда
U[n]
D[n]
L[n]
R[n]
E[n]
F[n]
G[n]
H[n]
M x,y
Описание
Вверх на п
Вниз на п
Влево на п
Вправо на п
Диагонально вверх и вправо на п
Диагонально вниз и вправо на п
Диагонально вниз и влево на п
Диагонально вверх и влево на п
Двигаться абсолютно или относительно. Если х или у
имеют знак (+ или -), движение осуществляется относи-
тельно текущей точки, т. е. значения х и у будут прибав-
лены к значениям соответствующих текущих координат. '
Если знаков нет, то движение абсолютное, т. е. из теку-
щей точки в точку с данными координатами.
Команды установки угла, цвета и масштаба
Ко-
манды
An
ТАп
Описание
Установка угла поворота п. Значение п находится в преде-
лах от 0 до 3, где 0 = 0°, 1 = 90°, 2 = 180° и 3 = 270°. Раз-
меры фигур, повернутых на угол 90° или 270° масштаби-
руются в отношении 4/3 к их размерам в углах 0° или 180°
Поворачивает изображение на угол в п градусов. Зна-
чение п находится в пределах от -360 до 360. Если п >
0, то поворот производится против часовой стрелки,
иначе — по часовой стрелке
237
Cn
¦ Sn
P n, m
Установка цвета п
Установка масштабного фактора п, где п находится в
пределах от 1 до 255. Масштабный фактор увеличива-
ет единицы перемещения команд U, D ,L ,R и отно-
сительной М
Установка цвета нарисованной фигуры: п — цвет со-
держимого ограниченной области, m — цвет границ
Вызов подкоманды:
"X" + VARPTR$(символьное_выражение)
Выполнить подкоманду, заданную в символьном выражении.
Пример: Использования оператора DRAW для рисования
бирюзового треугольника с розовыми ребрами.
SCREEN 1
DRAW "C2"
DRAW "F60 L120 Е60"
DRAW "BD3 0"
DRAW "PI,2"
Результат:
' Установить розовый цвет.
1 Нарисовать треугольник.
1 Переместиться внутрь фигуры.
1 Закрасить бирюзовым цветом.
PAINT
PAINT — графический оператор, закрашивающий ограни-
ченную площадь указанным цветом или образом.
238
PAINT [STEP] (x,у)[,[краска] [,[цвет рамки] [,фон]]]
• STEP — Определяет координаты как относительные к после-
дней нарисованной точке. Например, если последняя точка
была A0,10), то координаты с шагом STEP D,5) будут равны
D+10,5+10) или A4,15);
• (х,у) — координаты, где начинается закраска. Точка может
быть указана внутри фигуры или вне, но не на границе. Если
точка внутри, то закрашивается внутренняя часть фигуры. Ес-
ли точка вне фигуры, то закрашивается фон;
• краска — числовое или символьное выражение. Если это чис-
ловое выражение, оно представляет атрибут цвета. Если аргу-
мент не указан, используется атрибут фона. Если аргумент яв-
ляется символьным выражением, то PAINT закрашивает фигу-
ру образом (указанной в этом выражении битовой маской);
• цвет рамки — числовое выражение, определяющее атрибут
цвета границы фигуры. Если цвет границы указан, то площадь
ограничивается линиями данного цвета. Если аргумент опу-
щен, используется аргумент "краска";
• фон — символьное значение "вырезка стиля фона" для про-
пуска проверки завершения окраски на границах области. Ок-
раска завершается, когда встречаются точки цвета краски.
Указание фона позволяет окрашивать поверх закрашенной
площади. Если фон опущен, то его значение равно CHR$ @)
Окраска завершается, когда не осталось ни одной точки в
данной области, которая не сменила цвет. Оператор допускает
точки границ области за пределами экрана.
Образ для оператора PAINT имеет 8 бит в ширину и до 64
битов в длину. В строке образа каждые 8 бит байта составляют
маску вдоль оси х, указывающую на установку точек. Синтаксис
конструкции:
PAINT (x,y), CHR$(aprl) + CHR$(apr2) +...+ CHR$(aprN)
Аргументы CHR$ — числа от 0 до 255, представляющие двоич-
ные маски образа вдоль оси х. Всего может быть до 64 элементов,
каждый из которых генерирует часть образа. Например, 85 в двоич-
ном виде представляет 01010101; графический образ на черно-белом
экране, генерируемый CHR$(85) — восьмиточечная линия, в кото-
рой четные точки белые, а нечетные — черные. Таким образом,
каждый бит 1 рисует соответствующую точку, а бит 0 — стирает ее.
239
Если указан параметр фон, он определяет "вырезку стиля
фона" для пропуска границ при завершении окраски. Нельзя
указать более чем два совпадающих байта в строке образа и в
строке вырезки стиля фона. Указание более чем двух совпадаю-
щих байт вызывает сообщение об ошибке "Illegal function call"
(Неверный вызов функции).
Вырезка стиля фона позволяет использовать различные от-
тенки.
Пример: рисунок розовой рыбки с бирюзовым хвостом.
CONST PI = 3.1415926536
CLS
SCREEN 1
CIRCLE A90, 100), 100, 1, , , .3 ' Тело.
CIRCLE B65, 92), 5, 1, , , .7 ' Глаз.
PAINT A90, 100), 2, 1 ' Окраска тела.
LINE D0, 120)-STEP @, -40), 2 ' Хвост.
LINE -STEP F0, 20) , 2
LINE -STEP (-60, 20) , 2
PAINT E0, 100), 1, 2 ' Окраска хвоста.
CIRCLE B50,100),30, 0, PI-3/4, PI- 5/4,1.5
Жабры.
FOR Y = 90 TO 110 STEP 4
LINE D0, Y)-E2, Y), 0' Оперение хвоста.
NEXT
Вывод:
240
GET
GET — графический оператор, считывающий графическое
изображение с экрана в массив.
GET [STEP](xl,yl)-[STEP](x2, у 2).массив[(индексы)]
• xl, yl, х2 ,у2 — координаты, отмечающие прямоугольную об-
ласть на экране. Координаты левого верхнего и правого ниж-
него углов прямоугольника;
• STEP — параметр, указывающий, что координаты берутся от-
носительно последней нарисованной точки;
• массив — имя массива, для записи изображения. Массив мо-
жет быть любого числового типа. Его размер должен вместить
изображение;
• индексы — числовые константы или переменные, указываю-
щие, где начинается запись изображения в массив.
GET считывает изображение с экрана в массив, PUT транс-
формирует изображение из массива на экран.
Размер массива в байтах вычисляется по формуле:
4 + ШТ(((х2 - xl + 1) * (бит_на_пиксел_в_слое) + 7)/8)
• слои * ((у2 - yl) + 1)
Число бит на точку в слое и число слоев зависят от специ-
фикаций оператора SCREEN. Таблица иллюстрирует эти значе-
ния для каждого режима экрана:
Режим экрана
1
2
7
8
9
10
11
12
13
Битов на точку
в одном слое
2
1
1
1
1
1
1
1
8
Количество слоев
1
1
4
4
4
2
1
4
1
241
Количество байт на элемент в числовых массивах:
2 — целый;
4 — длинный целый;
4 — обычной точности;
8 — двойной точности.
Например, вы хотите разместить изображение среднего раз-
решения (SCREEN 2). Координаты картинки: @,0)-C2,32). Тре-
буемый размер массива в байтах равен:
4 + INT(C3 * 1 + 7) /8) * 1 * C3) или 169 байт.
Это значит, что целый массив из 85 элементов, назовем его А%
А%(85) = 85 * 2 = 170 байт
вместит всю картинку. См. пример к оператору PUT.
Операторы GET и PUT могут использоваться для мульти-
пликации и анимации изображений, однако лучше всего для этих
целей использовать специализированные библиотеки для
QuickBASIC, такие как PCX Programmer's ToolKit или VEGX for
QuickBASIC programmers. Речь о них пойдет дальше, в разделе
"Библиотеки для работы с изображениями".
PUT
PUT — графический оператор, рисующий на экране изобра-
жение, взятое в массив оператором GET.
PUT [STEP](х, у),массив[(индексы)][,действие]
• (х,у) — координаты верхнего левого угла прямоугольника, в
котором будет размещаться изображение;
• STEP — указывает, что координаты берутся как смещение от-
носительно текущего положения графического курсора;
• массив — имя массива с изображением;
• индексы — начальные "координаты" массива с изображением.
По умолчанию — начало массива;
242
действие — параметр, позволяющий накладывать образ на эк-
ран со специальными эффектами (XOR по умолчанию):
Действие
PSET
PRESET
AND
OR
XOR
Описание
Переводит данные точка-за-точкой на экран. Каж-
дая точка имеет тот же цветовой атрибут, который
был при считывании массива оператором GET
Так же, как и PSET, но выдается инверсное изобра-
жение, ("негатив")
Изображение накладывается на существующую кар-
тинку. Получается результат логического умноже-
ния: точки, имеющие одинаковый цвет, сохраняют-
ся, а остальные меняют цвет
Используется так же. Получается результат логичес-
кого "или" между образом и картинкой. Новое
изображение не стирает предыдущего
Используется для анимации. Действует так, что точки
на экране, имеющие тот же цвет, что и образ, инверти-
руются. Когда образ помещается на одно и то же место
дважды, предыдущая картинка восстанавливается. Это
позволяет двигать образ по экрану, не стирая фона
Пример: прыгающий мячик.
DEFINT A-Z
DIM Ball(84) ' Массив, содержащий картинку.
SCREEN 2 INPUT "Нажмите ENTER, чтобы начать", Test$
CLS
CIRCLE A6, 16), 14
PAINT A6, 16), 1
GET @, 0)-C2, 32), Ball
X = 0 : Y = 0
Xdelta = 2 : Ydelta = 1
Рисуем мячик.
DO
Мячик прыгает, пока не нажата клавиша.
X = X + Xdelta : Y = Y + Ydelta
IF INKEY$ <> "" THEN EXIT DO
1 Отражение мячика от левой и правой границ.
IF (X < 1 OR X > 600) THEN
Xdelta = -Xdelta
BEEP
END IF
243
' Отражение мячика от верхней и нижней границ.
IF (Y < 1 OR Y > 160) THEN
Ydelta = -Ydelta
BEEP
END IF
' Перерисовываем мячик, стирая старый.
PUT (X, Y), Ball, PSET
LOOP
END
Результат:
POINT
POINT — графическая функция, читающая номер цвета точ-
ки экрана или возвращающая координаты точки.
POINT (x,y) POINT (номер)
• (х,у) — координаты графической точки, цвет которой требует-
ся узнать;
• номер — числовое выражение от 0 до 3, указывающее один из
четырех способов определения текущей позиции графического
курсора.
244
При вызове функции с двумя координатами х,у можно уз-
нать цвет данной точки. Если указанная точка не находится на
экране, POINT возвращает -1.
POINT с одним аргументом позволяет определить координа-
ты графического курсора.
Аргу-
мент
0
1
2
3
Возвращаемое значение
Физическая х-координата
Физическая у-координата
Относительная х-координата. Если не использовался
оператор WINDOW, возвращается то же значение, что
и с аргументом 0
Относительная у-координата. Если не использовался
оператор WINDOW, возвращается то же значение, что
и с аргументом 1
Пример: перерисовка эллипса с заданным углом наклона
DEFINT X, Y
SCREEN 1
INPUT "Введите угол в градусах @-90): ", Ang
Ang = C.1415926* / 180) * Ang ' В радианы.
Cs = COS(Ang) : Sn = SIN(Ang)
CIRCLE D5, 70), 50, 2, , , 21 Рисунок эллипса.
PAINT D5, 70), 2 ' Окраска эллипса.
FOR У = 20 TO 120
FOR X = 20 TO 70
' Проверка каждой точки в районе эллипса.
IF POINT(X, Y) о 0 THEN
1 Если точка принадлежит эллипсу, рисуем
' соответствующую точку в "отраженном" эллипсе.
Xnew = (X * Cs - Y * Sn) + 200
Ynew = (X * Sn + Y * Cs)
PSET(Xnew, Ynew), 2
END IF
NEXT X
NEXT Y
END
245
Вывод:
Введите угол В градусах (О - 90>: 75
Press any key to continue
PMAP
PMAP — графическая функция, преобразующая относитель-
ные координаты окна графического вывода в физические и об-
ратно.
РМАР (выражение, функция)
• выражение — преобразуемые координаты точки;
• функция — числовое выражение, имеющее целое значение от
О до 3, указывающее вид возвращаемой информации.
Зна-
чение
0
1
2
3
Описание
Преобразует выражение к физической х-координате
Преобразует выражение к физической у-координате
Преобразует выражение к относительной х-координате
Преобразует выражение к относительной у-координате
246
Пример:
SCREEN 2
1 Определение окна вывода.
WINDOW SCREEN (80,100) - B00,200)
1 Определение физических координат
' правого нижнего угла окна вывода.
X = РМАРB00,0) 'X = 63 9
Y = РМАРB00,1) 'Y = 199
' Определение относительных координат
' точки с физическими координатами 639,199.
X = РМАРF39,2) 'X = 200
Y = РМАРA99,3) "Y = 200
3-х мерные объекты
в текстовом режиме
Всеобщая одержимость графическими оболочкам, такими как
Windows и им подобные, охватило кажется всех, или почти всех1.
Однако за все приходится платить, и использование графического
режима приводит к резкому снижению быстродействия2.
Действительно в текстовом режиме (80 х 25) необходимо ма-
нипулировать всего 2000 знакоместами на экране, в то время как
в графическом режиме высокого разрешения F40 х 480) — при-
ходится оперировать 307200 элементами изображения, и это еще
без учета цвета. Но для большинства приложений вполне доста-
точно текстового режима экрана. Используя приведенные ниже
примеры, вы сможете придать своей текстовой программе эффект
"объемности", не используя медлительный графический режим.
Объемные кнопки
При создании эффекта "объемных" кнопок применяется
следующий прием. Выводится кнопка белым цветом (цвет № 7) с
тенью из символов "и" и '1". При нажатии на нее кнопка стано-
вится ярко-белого цвета (цвет № 15), сдвигается на один символ
1 Американский журнал "PC magazine" писал по этому подводу. "К 2000 году
система Windows будет работать везде, кроме разве что стоп-сигналов и тосте-
ров..."
2 Конечно, для машин с процессором i486DX и PENTIUM, это не так акту-
ально, но для большинства российских программистов, имеющих в своем распо-
ряжении 286 и 386 машины (а кое-где и 86), снижение быстродействия очень
заметно.
247
вправо, тень убирается. В таком состоянии кнопка остается на-
жатой примерно 0.5 сек.
При программировании возникают две задачи:
1. Кнопка должна быть ярко белой, но BASIC может использо-
вать только 8 цветов в качестве фона — здесь может помочь
переопределение цветов оператором PALETTE;
2. Требуется задержка 0.5 сек, но функция TIMER и оператор
SLEEP оперируют целыми секундами, а использования опе-
ратора SOUND приводит к неприятному "щелчку". Решени-
ем может служить прямое чтение младшего байта счетчика
суток - РЕЕК(&Н46С).
DEFINT A-Z
'переопределяем цвета - цвет N6 стал ярко-белым
PALETTE б, 63
'очищаем экран
COLOR 0, 7: CLS : COLOR 0, 3
1 выводим рамку
LOCATE 10, 23: PRINT " [—" + STRING$C0, "-") + "-, "
FOR i = 1 TO 5
LOCATE 10 + i, 23: PRINT "|" + SPACE$C0) + "|"
NEXT i
LOCATE 16, 23: PRINT "L" + STRING$C0, "-") + "J"
LOCATE 12, 27
PRINT "Эффект " + CHR$C4) + "объемной" + CHR$C4) + "
кнопки "
Button$ = CHR$A6) + " Ok " + CHR$A7): a$ = ""
DO WHILE a$ <> CHR$B7)
'рисуем кнопку
COLOR 0, 7: LOCATE 14, 33: PRINT Button$
COLOR 0, 3: LOCATE 14, 43: PRINT "e"
LOCATE 15, 34: PRINT STRING$A0, "¦")
1 ждем нажатия любой клавиши
DO: a$ = INKEY$: LOOP WHILE a$ = ""
1 стираем тень и сдвигаем кнопку вправо
COLOR 0, 3: LOCATE 14, 33: PRINT " "
COLOR 0, 6: LOCATE 14, 34: PRINT Button$
COLOR 0, 3: LOCATE 15, 34: PRINT SPACE$A0)
'обеспечиваем задержку 0.5 секунд
DEF SEG = 0
start = PEEK(&H46C): finish = start + 9
248
IF finish > 255 THEN finish = finish - 255
DO: LOOP WHILE PEEK(&H46C) <> finish
DEF SEG
LOOP
Вывод:'
Рамки и тени
Другим широко известным трехмерным эффектом является
рисование рамок, "отбрасывающих" тень. Для рисования рамок и
таблиц используются символы, приведенные в Приложении 5,
раздел "Символы псевдографики для рисования рамок и таблиц".
Существует несколько разновидностей рамок и теней.
Рамки могут состоять :
• из одинарных линий;
• из двойных линий;
• из комбинации одинарных и двойных линий;
• только из пробелов.
В свою очередь тени подразделяются на:
• "Изящные", составленные из символов "¦"и "|", могут быть
использованы только на однородном фоне;
• "Неинтеллектуальные", составленные из символов "Щ'и 'Щ'
(или " и "|1", Ц' и "ШГ, "Щ' и "И')> которые могут выво-
дится на любом фоне. Однако символы, которые закрывает
тень, не видны из-под нее;
1 В дополнение к "объемным" кнопкам в текстовом режиме, в Microsoft
BASIC PDS существует еще возможность загрузить свои собственные экран-
ные шрифты. Это позволяет вывести в текстовом режиме недостающие симво-
лы, и в частности, расширить символы псевдографики набором своих соб-
ственных рамок.
249
• "Интеллектуальные", меняющие цвет символов, которые они
закрывают, на серый (основной цвет № 8, фоновый — № 0);
т е символы как бы "проступают" из-под тени, создавая
полную иллюзию "объемности".
Пример: вывод трех рамок:
а) из пробелов с "изящной" тенью;
б) из одиночных линий с "неителлектуальной" тенью;
в) из пробелов с "интеллектуальной" тенью.
DEFINT A-Z
COLOR 0, 3: CLS
'рамка из пробелов с "изящной" тенью
COLOR 0, 7: LOCATE 4, 5- PRINT SPACE$C0)
LOCATE 4, 35: COLOR 0, 3: PRINT "ш": COLOR 0, 7
FOR l = 1 TO 6
LOCATE 4+1, 5: PRINT SPACE$C0); "§"
NEXT l
COLOR 0, 3: LOCATE 11, 6: PRINT STRING$C0, "¦")
COLOR 0, 7: LOCATE 7, 12: PRINT "Рамка без линии"
'рамка из одиночных линий с "неинтеллектуальной" тенью
COLOR 0, 7
LOCATE 4, 45: PRINT" г" + STRING$B8, "-" ) + "-, "
FOR l = 1 ТО 5
LOCATE 4 + 1, 45: PRINT " | " + SPACE$B8) + "|"; "Щ"
NEXT l ,
LOCATE 10, 45: PRINT " L" + STRING$B8, "-") + "-> "; "¦"
LOCATE 7, 52: PRINT "Рамка с линией"
COLOR 0,3: LOCATE 11, 47: PRINT STRING$C0, "¦")
'рамка из пробелов с "интеллектуальной" тенью
COLOR 0, 3 j
'заполнение фоном
FOR 1 = 1 ТО 12 ,» ,
LOCATE 13 + 1, 2: PRINT STRING$G8, "*");
NEXT l JN
'рисование рамки у
COLOR 0, 7: LOCATE 16, 5: PRINT SPACE$G0)
FOR l = 1 TO б
LOCATE 16 + l, 5: PRINT SPACE${70)
NEXT l
'Рисование "интеллектуальной" тени
'С помощью функции SCREEN считываются коды символов,
'и выводятся на то же место, но другого цвета1
1 Вместо этого можно было напрямую менять атрибуты символов, не перери-
совывая их, а обращаясь к видеопамяти с помощью операторов РЕЕК и РОКЕ,
однако это неоправдано усложнило бы программу
250
COLOR 8,0
'боковая тень
FOR i = 1 ТО 6
FOR з = 1 ТО 2
symbol$ = CHR$(SCREENA6 + i, 7 4 + ц))
LOCATE 16 + l, 74 + 3: PRINT symbol$
NEXT j
NEXT 1
1 Нижняя тень
FOR 1 = 1 TO 7 0
symbol$ = CHR$(SCREENB3, 6+1))
LOCATE 23, 6 + 1: PRINT symbol$
NEXT 1
COLOR 0, 7: LOCATE 19, 26:
PRINT "Рамка с " + CHR$C4) + "интеллектуальной"
CHR$C4) + "тенью"
DO: LOOP WHILE INKEY$ = ""
Результат:
Поля для ввода данных
Еще одной трехмерной структурой можно считать поля для ввода
данных Здесь эффект объемности возникает из за того, что часть рам-
ки, состоящей из одинарных или двойных линий выводится ярко-
белым цветом (№ 15), а часть черным (№ 0). При этом сама рамка
размещается на белом фоне (№ 7).
251
Поле может быть1
• Выпуклым' Верхняя половина рамки ярко-белая, нижняя —-
черная;
• "Впуклым Верхняя половина рамки черная, нижняя — ярко-
белая
Комбинируя одинарные и двойные линии, а также эффект
выпуклости и "впуклости" можно выделять активное поле, кон-
струировать из полей "нажимающиеся" кнопки и т д.
Пример: Рисование объемных полей для ввода данных
DEFINT A-Z
1 заполнение фоном
COLOR 0, 7: CLS
FOR 1 = 1 ТО 25
LOCATE 1, 1: PRINT STRING${80, " ");
NEXT i
1 рисование рамки
COLOR 0, 7
LOCATE 4, 4: PRINT "r" + STRINGSF9, "-") + "n"
FOR l = 1 TO 14
LOCATE 4 + i, 4: PRINT "|" + SPACE$F9) + "|"
NEXT l
LOCATE 18, 4: PRINT " L" + STRING$F9, "-") + "-I "
1 выпуклое поле для ввода данных
COLOR 15, 7:
LOCATE 7, 22: PRINT "г" + STRINGSD8, "-")
LOCATE 8, 22: PRINT "|"
LOCATE 9, 22: PRINT "L"
COLOR 0, 7:
LOCATE 7, 71: PRINT "
LOCATE 8, 71: PRINT ' j"
LOCATE 9, 23: PRINT STRING$D8, "-"); "-I "
LOCATE 8, 6: PRINT "Выпуклое поле:"
'"впуклое" поле для ввода данных
COLOR 0, 7:
LOCATE 12, 22: PRINT "г" + STRINGSD8, "-")
LOCATE 13, 22: PRINT "|"
LOCATE 14, 22: PRINT "L"
COLOR 15, 7:
LOCATE 12, 71: PRINT "-] "
1 Автор берет на себя смелость обогатить "великий и могучий" русский язык
этим термином В математике можно сказать про кривые — выпуклые и вогну-
тые, но где вы видели вогнутое поле для ввода9
252
LOCATE 13, 71: PRINT "|"
LOCATE 14, 23: PRINT STRING$D8, "-"); "J"
COLOR 0, 7
LOCATE 13, 6: PRINT CHR$C4) + "Впуклое" + CHR$C4) + " поле:"
DO: LOOP WHILE INKEY$ = ""
Результат:
Библиотеки для работы с
изображениями (*)
Встроенные графические средства языка QuickBASIC хорошо
подходят только для рисования и передвижения небольших гео-
метрический объектов — прямых, эллипсов, ломанных линий.
Этого оказывается недостаточно, если вы хотите работать со слож-
ными сканированными или рисованными изображениями. В этом
случае могут помочь специализированные библиотеки для работы
с изображениями В этот разделе рассматриваются две такие биб-
лиотеки: PCX Programmer's ToolKit и VEGX for QuickBASIC
PCX Programmer's ToolKit
Пакет разработчика графических программ в формате РСХ-
"PCX Programmer's ToolKit, v 3.53, Copyright (с) GENUS Microprog-
ramming, Inc, 1988-1989 All Right Reserved "
253
Пакет программиста PCX позволяет разработчикам создавать
прикладные программы, обладающие средствами показа, сохра-
нения, печати и манипулирования изображениями формата PCX.
Вследствие того, что пакет поддерживает 95% адаптеров дисплея,
он может быть использован во многих разнообразных областях —
от показа заголовков и эмблем программ при начальной загрузке
до создания интерактивных видео- и демонстрационных про-
грамм. Его возможности:
• 62 процедуры FUNCTION, 9 сервисных программ и 300 стра-
ниц документации;
• 21 видеорежим, вплоть до разрешения 800 х 600 в 256 цветах;
• Показ изображений на всем экране или его части; плюс ди-
намическая прокрутка больших изображений в окнах;
• Двуцветная печать изображений на лазерном принтере;
• Прокрутка, печать и замещение экранных страниц;
• Библиотеки для работы с среде QB1 (.QLB — 46 Kb), компи-
ляции в .ЕХЕ файл (.LIB — 52 Kb) и включаемый файл, содер-
жащий определения констант и процедур (.BI — 16 Kb).
Для работы с пакетом вы должны загрузить среду QB с биб-
лиотекой PCX_QB.QLB:
C:\QB45>qb program /L pcx_qb.qlb
Пример: Вывод на экран файла SIMPLE.PCX
'включаемый файл библиотеки PCX Programmer ToolKit
'$INCLUDE: 'pcxlib.bi'
' Установка типа дисплея, имени файла и кода возврата
pcxtype% = pcxCGA.4
pcximage$ = "Simple.PCX"
retcode% = -999
' Установить тип дисплея
retcode% = pcxSetDisplay%(pcxtype%)
1 Войти в графический режим
retcode% = pcxSetMode%(pcxGRAPHICS)
' Показать картинку
IF (retcode% = pcxSUCCESS) THEN
dispret% = pcxFileDisplay%(pcximage$, 0, 0, 0)
1 К сожалению, пакет не включает библиотеки для работы с Microsoft BASIC
PDS 7.1
254
' Ждать нажатия клавиши
DO: LOOP WHILE INKEY$ = ""
1 Вернуться в текстовый режим
etcode% = pcxSetMode%(pcxTEXT)
END IF
1 Проверить, все ли в порядке
IF (dispret% <> pcxSUCCESS) THEN
PRINT "Возникла ошибка: ["; dispret%; "]"
PRINT "Возможно дисплей не поддерживает CGA или же"
PRINT "файла SIMPLE.PCX нет в текущей директории..."
END IF
END
Результат:
Undo Page Edit Style Adjust Pick Misc
VEGX for QuickBASIC
Пакет разработчика графических программ в формате VEGX:
"VGA and EGA Graphics file formats for QuickBASIC and Professional BASIC
Programmers, Version 2.0, November, 1990, Copyright, 1990, Dwain Goforth,
Milestone Software, Arcata, California. All rights reserved."
255
VEGX — это набор двух графических форматов для QuickBASIC.
VGX поддерживает 640x480 16-цветный (SCREEN 12) формат, в то
время как EGX предназначен для 640x350 16-цветный (SCREEN 9)
формат. К его несомненным достоинствам относятся:
• Моментальная загрузка и показ графических файлов;
• В нем всего две процедуры SUB с простым и удобными фор-
матом вызова — VGXLoad и VGXSave;
• Сжатый формат при хранении на диске;
• Видеоэффекты гашения и появления изображения;
• Библиотеки для работы в среде QB1 (.QLB — 15 Kb) и ком-
пиляции в .ЕХЕ-файл (.LIB — 14 Kb);
• Утилиты для сохранения графических экранов и перевода
.PCX файлов в формат VEGX.
Для работы с пакетом вы должны загрузить среду QB с биб-
лиотекой VEGX45.QLB:
C:\QB45>QB program /L vegx45.glb
Пример: Вывод на экран файла DINON.VBX
1 Имеются библиотеки для работы с QuickBASIC 4 00, QuickBASIC 4 50 и
Microsoft BASIC PDS 7 x
256
DEFINT A-Z
DECLARE SUB VGXLoad (fil$, PalFlag)
'режим 640 x 480 x 16 цветов
SCREEN 12
'Показать файл DINON.VBX, эффект 4 - всплывание рисунка
CALL VGXLoad (" dmon" , 4)
DO: LOOP WHILE INKEY$ = ""
1 текстовый режим
SCREEN 0
Звук и музыка
ВЕЕР
ВЕЕР — оператор, генерирующий звук.
ВЕЕР
Звук, генерируемый оператором ВЕЕР аналогичен следую-
щей команде:
PRINT CHR$G)
PLAY
PLAY — оператор ввода/вывода, играющий музыку.
PLAY командная_строка
Командная строка содержит следующие музыкальные коман-
ды, перечисленные в таблицах:
Команды октавы и тона
Октава
On
>
<
Действие
Устанавливает текущую октаву.
Всего семь октав, от 0 до 6
Повышает октаву на 1
Уменьшает октаву на 1
257
Тон
A-G
Nn
Действие
Играет ноту A-G ("до" - "си")
Играет ноту п, в пределах 0—84 (в семи возможных
октавах всего 84 ноты); п = 0 означает паузу
Суф-
фиксы
# или +
-
Действие
Следует за нотой и играет ее в режиме "диез"
Следует за нотой и играет ее в режиме "бемоль"
Команды длительности и темпа
Длитель-
ность
Ln
MN
ML
MS
Действие
Устанавливает длительность каждой ноты. L 4 — чет-
вертая нота, L 1 — целая нота и т. д. Пределы п: 1-64.
Длительность может следовать за нотой, если не
нужно изменять длительность всей последовательнос-
ти. Например, А 16 эквивалентно L 16 А
Устанавливает "нормальный стиль", т. е. ноты играются
7/8 времени, определенного длительностью L
Устанавливает "стиль легато", т. е. ноты играются пол-
ный период, установленный командой L
Устанавливает "стиль стаккато", т. е. ноты играются
3/4 периода, указанного командой L
Темп
Рп
Тп
Действие
Устанавливает паузу длительностью п, в пределах 1—
64. Параметр п должен быть задан явно.
Устанавливает темп звучания, число четверных нот в
одной минуте. Пределы п: 32-255. По умолчанию п =
120. Из-за низкой скорости таймера E5 прерываний в
сек.) некоторые ноты могут не звучать при высоких
значениях темпа (L 64 при Т 255, к примеру)
258
Точка после ноты указывает на то, что она должна
звучать 3/2 времени, указанного L. После ноты может
стоять несколько точек, каждая из которых добавляет
половину предыдущей длительности. Например: А.
звучит 1 + 1/2 или 3/2 длительности; А., звучит 1 +
1/2 + 1/4 или 7/4 длительности. Точки могут стоять и
после паузы Р, регулируя ее длительность.
Переключения звучания на основное или фоновое
Операция
MF
MB
Действие
Устанавливает музыку, генерируемую операторами
PLAY и SOUND, в основное звучание. Это значит,
что последующая нота звучит только после заверше-
ния предыдущей. Кроме того, действие других опера-
торов приостанавливается до завершения звучания
Музыкальные операторы генерируют звук в фоновом
режиме. Это значит, что каждая нота или звук поме-
щаются в буфер, позволяя другим операторам выпол-
няться, пока музыка звучит. Максимальное количе-
ство нот, помещающихся в буфер, равно 32
Вызов подкоманды:
"X" +
VARPTR$(cTpoKa)
Выполняет подкоманду, указанную в
строке
Пример 1: Использование оператора PLAY для генерации
звуковых эффектов.
DEFINT A-Z
CONST Cuckoo$ = "T120Ll6MLO3BF#"
CONST Zap$ = "T255L64MLO4BAGFEDC<BAGFEDEC<BAGFED_
C<BA GFEDC<BAGFEDC"
CONST Tifweet$ = "T255L32O4mlDGD<G>DGDDGDGBAGF#EE"
CONST Zang$ = "T255L64MLO2BCADGEFEGDACBCADGEFEGDACB"
CONST Downer$ = "T150L64MSO4BGEC<AFLl6D"
CONST UpScale$ = "T150L64MSO3DFA>CEGL16B"
CONST Tweedle$ = "T240L64MLO4EGEGEGCFCFCFGEGEGE"
CONST Whoople$ = "T255L64O4CDEFGABO3CDEFGABO2CDEFGAB"
CONST Bongee$ = "T255L64MLO1BAGFEDC<BAGFEDCP16>CD_
259
EFGAB>CDEFGABP32"
CONST Uhoh$ = "T25 5L64MLO1CDEFGAB>CDEFGABP16<BAGF_
EDC<BAGFEDCP32"
CONST BobWhite$ = "T120L16O4C*.Pl6T255L64mlC#DD#EF_
F#GG#AA#BO5CC#DD#EF"
CONST Whung$ = "T255L32mlO3CD<CD>>CD«CD>>CD<<CD>CD"
CONST Phone$ = "T240L64MLO4EGEGEGEGEGEGEGEGEGEGEGEGE_
GEGEG"
CONST Tweet$ = "O4T255L64MLB-BB-BAGAG.>EGG>EGG"
CONST Wolf$ = "T200L64MLO4C#DD#EFF#GG#AA#B>CC#D_
D#EFP8.<C#DD#EFF#GG#AA#B>CC#DD#EFFED#DC#C<BA#AG#GGF_
#FED#DC#"
CONST Fweet$ = "T255L64MsO4C#DD#EFF#GG#AA#B>CC#_
DD#EF"
COLOR i
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
DO
0, 7:
" 1.
11 2.
11 3.
11 4.
11 5.
11 6.
" 7.
11 8.
" 9.
11 10.
11 11.
" 12.
" 13.
" 14.
11 15.
" 16.
LOCATE 19,
LOCATE 19
CLS
Cuckoo"
Zap"
Tifweet"
Zang"
Downer"
Upscale"
Tweedle"
Whoople"
Bongee"
Uhoh"
BobWhite
Whung"
Phone"
Tweet"
Wolf"
Fweet"
1: PRINT "
"
'Введите номер эффекта @ - выход)
, 45: INPUT Nomer
SELECT CASE Nomer
CASE
CASE
CASE
CASE
CASE
CASE
CASE
CASE
CASE
CASE
CASE
CASE
CASE
CASE
CASE
IS =
IS =
IS =
IS =
IS =
IS =
IS =
IS =
IS =
IS =
IS =
IS =
IS =
IS =
IS =
0: EXIT
1: PLAY
2: PLAY
3: PLAY
4: PLAY
5: PLAY
6: PLAY
7: PLAY
8: PLAY•
9: PLAY
10: PLAY
11: PLAY
12: PLAY
13: PLAY
14: PLAY
DO
Cuckoo$
Zap$
Tifweet$
Zang$
Downer$
UpScale$
Tweedle$
Whoople$
Bongee$
Uhoh$
BobWhite$
Whung $
Phone$
TweetS
260
CASE IS = 15: PLAY Wolf$
CASE IS = 16: PLAY Fweet$
CASE ELSE: BEEP
END SELECT
LOOP
COLOR 7, 0: CLS : END
Пример 2: Использование оператора PLAY для проигрыва-
ния музыкальных фрагментов.
DEFINT A-Z
DO
COLOR 7, 0: CLS : PRINT
PRINT " 1. Штраус. Вальс 'Голубой Дунай' "
PRINT " 2. Моцарт. Симфония N 40 "
PRINT " 3. Моцарт. Турецкий марш "
PRINT " 4. Марш 'Прощание славянки'"
PRINT
PRINT " 5. Туш "
PRINT " б. Песня о крокодиле Гене"
PRINT " 7. Повесть о зеленом кузнечике"
PRINT " 8. Марш Мендельсона в миноре"
PRINT
PRINT " 9. Гимн Соединенных Штатов Америки"
PRINT 0. Гимн Советского Союза"
PRINT : PRINT : INPUT "Введите номер мелодии @ -
выход) -> ", п
SELECT CASE n
CASE IS = 0: EXIT DO
CASE IS = 1
1 Штраус. Вальс 'Голубой Дунай'
PLAY "mf ms tl37 o216d f# a 16ap6 16>a арб f# f#p6"
PLAY "o216d d f# a 16ap6 16>a арб g дрб"
PLAY "o216c# c# e 16b Ьрб 16>Ь Ьрб g gp6"
PLAY "o216c# c# e 16b Ьрб 16>b Ьрб f# f#p6"
PLAY "o216d d f# a >dp6 >d dp6 <a арб"
PLAY "o216d d f# a >dp6 >d dp6 <b Ьрб"
PLAY "o216e e g b 13b.. 16g# a >13f#.."
PLAY "tl30 16d <f# 16f#..e b..a dpl2 112d d.p6."
PLAY 6a дрб а дрб a 13>f#.. 16e <a f#p6 a f#p6 a_
13>e.. "
PLAY 6d <a дрб а дрб a 13>f#.. 16e <a >d e f#_
13a 16gll2f# f# 16f# e d"
CASE IS = 2
' Моцарт. Симфония N 40
PLAY "msmftl90o318e- d 14d 18e- d 14d 18e-_
d 14d 14b-p4"
PLAY 8b- a 14g 18g f 14e- 18e- d 14c cp4"
261
PLAY 8d с 14c 18d с 14c 18d с 14c ap4 "
PLAY 8a g 14g- 18g- e- 14d 18d с о2 14b- b-p4"
PLAY "o318b- a mll4a o4c o3g- a g dp4"
PLAY "mso318b- a mll4a o4c o3g- a g b-"
PLAY 8a g f e- 14d o2f# gab- o318c o2b- 14a_
g o3dp4"
PLAY "mlo412c# 14dp4 "
PLAY "mlo412c# 14dp4 "
PLAY "mlo412c# 18dp8 c#p8 dp8 C#p8 dp8 "
CASE IS = 3
' Моцарт. Турецкий марш
FOR i = 1 TO 2
PLAY "T130 ML L16 02 BAG#A03 C8 P8 L16 DC 02 B_
03 С E8 P8 FED#E BAG#A BAG#A"
PLAY "MN 04 C4 03 A8 04 C16.O3 G64A64 L8 В
MS AGA16.ML G64A64 В MS AGA16."
PLAY "ML G64A64 В MS AGF#E4"
NEXT i
PLAY "T130 MS 03 L8 EF GG ML LIб AGFE D8 02 MS_
G8 MS 03 L8 EF GG ML L16 AGFE"
PLAY "MN D4 MS C8 D8 MS E8E8 ML FEDC 02 ML B8_
MS E8 03 MS C8D8 MS E8E8 ML FEDC"
PLAY 2 MS B4 В MLAG#A 03 C8 P8 DC 02 В 03 C_
E8 P8 FED#E BAG#A BAG#A"
PLAY 4 MN C4 L8 MS 03 AB04 С 03 BAG #AEFD
C4O2 ML B32.C32.B32. A16 B16 A4"
CASE IS = 4
1 Марш 'Прощание славянки'
PLAY "T125 >03 ML L64 GA-B 04 L4 MS С L4 03 MS _
A-GF L8 E-. L16 F L8 D. L16 E- L4 C"
PLAY "MN L8 GA- L4 G MN L8 E-D L4 С L8 <B >C ML L4_
D.<L8 В L4 MN G"
PLAY ">MN L8 GA- L4 G L8 GG >ML L4 D L8 E-D L2_
MN C."
PLAY "L8 С <B > L4 D L8 С < A-L4 F L8 A->C L4 <_
ML G. L8 E-MN L4 С MN"
PLAY "L8 GA- L4 G L8 DE- L4 G L8 DE- L2 C."
FOR i = 1 TO 2
PLAY "O1L4 G> L2E-. L8 D. L16C L2D.<L4 G>_
L2D. L8 E-. L16D L2C.<L4 G> L2C. L8 D. L16C_
ML L2FMS L8F "
PLAY "L8 FGA-MN L4G L8 F. L16 E- L4 D L8 E-._
L16 D MS L8CL16 CC18CC L4C"
NEXT i
PLAY 3 ML P4 L64 bed 04 L4 MS E-E-E-<MLg>e-c<g _
18 e-cl2 MN d.ML14 g>d< 18 gbl4>d 18e-dl2cp8"
PLAY "MN<18 b-a-gl4f>dp8 <18 fgfl4e->cp8 <18_
e-fe-14da-g<b>18cll6ccl8ccc>"
PLAY "MN<18 b-a-gl4f>dp8 <18 fgf14e->cp8<18_
e-fe-14da-gb>18cll6ccl8ccc>"
262
CASE IS = 5
'Туш
PLAY "<C4E8G8"
PLAY ">C16C16C16C1SCI6C16C16C16"
PLAY "D16D16D16D16D16D16D16D16"
PLAY "E4D4C8C16.C32C8P8"
CASE IS = 6
1 Песня о крокодиле Гене
PLAY "T255o2CL4C+L4CL4P4olF01L4GL4G+L4FL4"
PLAY "o2CL4C+L4CL4P4olGL4G+L4A+olL4GL4"
PLAY "T255o2CL4C+L4CL4P4olGL4G+L2A+L4o2CL4C+L4_
mlC L2CL4"
CASE IS = 7
1 Повесть о зеленом кузнечике
PLAY "MFT240AEAEAG#G#P4G#EG#EG#AAP4"
PLAY "AEAEAG#G#P4G#EG#EG#AP2"
PLAY "ABB8B8B4B4>CC8C8CCC<BAG#AAP4"
PLAY "ABB8B8B4B4>CC8C8CCC<BAG#AP4n
CASE IS = 8
'Марш Мендельсона в миноре
PLAY "T90MLL8O2A4O3FEDC#D4O2A4B-4O2 _
C#EGB- AG F4EFD4 F4 В- А 03 DC"
PLAY "F4EDCO2B-AB-16 03 C16 02 F4 E4MN F2.MS _
03 A4 02F ML 03AGF El 6 F16 G C2"
PLAY "MS F4 02 D ML 03 F E D C#16 D16 E 02 _
A4A8P8 А В 03 C# D E F"
PLAY "G E C# B- A G F16 E16 D8 E4 C#4 D2"
CASE IS = 9
1 Гимн Соединенных Штатов Америки
PLAY "T100O3L8E-.L16CO2L4A-O3L4CE-L2A-O4L8_
C.O3L16B-L4A-CDL2E-L8E-E-O4L4C."
PLAY "O3L8B-L4A-L2GL8FGL4A-A-E-CO2L4A-O4L8CCL4_
CD-E-L2E-L8D-CO3L4B-O4L4CD-L2D-L8D-"
PLAY "D-L4C.O3L8B-L4A-L2GL8FL16G.L4A-CDL2E-L8E-_
E-L4A-A-L8A-GL4FFFB-O4L8D-CO3L8B-»
PLAY "A-L4A-L4G.P8L8E-E-O3L4A-.L8B-O4L8CD-L2E-O_
3L8A-B-O4L4C.L8D-O3L4B-L2A-.."
CASE IS = 10
1 Гимн Советского Союза
PLAY "tl20o218g4.p8g>c4<g.ab4e.ea4g.fg4c.cd4d_
.ef4f.g7"
PLAY "a4b.>cd2<g>e4d.cd4<g.g>c4<b.ab4e.ea_
4g.fg4c.c>c4<b.ag2"
CASE ELSE
BEEP
END SELECT
LOOP
COLOR 7, 0: CLS : END
263
SOUND
SOUND — оператор ввода/вывода, генерирующий звук через
динамик.
SOUND частота, длительность
• частота — числовое выражение в пределах 37-32767, частота
звука в циклах/сек или в Гц;
• длительность — числовое выражение в пределах 0-65535, число
отсчетов системного таймера, определяющее продолжительность
звучания. В одной секунде 18.2 отсчетов таймера.
Если длительность равна нулю, звук, генерируемый текущим
оператором SOUND, выключается.
Пример: Использование оператора SOUND для генерации
звуковых эффектов.
DEFINT A-Z
COLOR 0, 7: CLS
PRINT
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT "
PRINT
DO
LOCATE
ход) ->
LOCATE
SELECT
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
I 20
20
Oh"
Space"
Gurgle"
Spectre"
Grup"
Chirp"
Waver"
Who"
Mew"
Phone"
siren"
Zhoup"
Vrowr"
Zhou"
Art"
Coo"
Squawk"
, 1: PRINT " Вве,
, 45: INPUT Nomer
CASE Nomer
CASE IS =
0
Введите номер эффекта @ - вы-
264
265
EXIT DO
CASE IS = 1
FOR I = 800 TO 2000 STEP 100 'Oh
SOUND I, .2
NEXT I
FOR I = 2000 TO 50 STEP -100
SOUND I, .2
NEXT I
CASE IS = 2
FOR I = 1000 TO 40 STEP -20 'Space
SOUND I, .2
NEXT I
CASE IS = 3
FOR I = 10 TO 50 STEP 10 'Gurgle'
FOR J = 50 TO 10 STEP -10
SOUND I л 2 + J л 2, .1
NEXT J
NEXT I
CASE IS = 4
FOR Z = 1 TO 100 'Spectre
SOUND (SIN(Z) +40) * 50, .2
NEXT Z
CASE IS = 5
FOR I = 10 TO 50 STEP 10 'Grup
FOR J = 50 TO 10 STEP -10
SOUND I * J, .1
NEXT J
NEXT I
CASE IS = 6
FOR I = 30 TO 60 STEP 10 'Chirp
FOR J = 60 TO 30 STEP -10
SOUND I * J, .2
NEXT J
NEXT I
CASE IS = 7
FOR Z = 1 TO 45 'Waver
SOUND (SIN(Z) + 20) * 30, .2
NEXT Z
CASE IS = 8
FOR Y = 100 TO 80 STEP -1 "Who
SOUND (TAN(Y) + 36) * 25, .8
SOUND (SIN(Y) +20) * 50, .4
NEXT Y
CASE IS = 9
FOR Y = 100 TO 80 STEP -1 'Mew
SOUND (TAN(Y) + 50) * 25, .4
NEXT Y
CASE IS = 10
FOR Y = 1 TO 10 'Phone
SOUND 1195, .4
SOUND 2571, .4
NEXT Y
CASE IS = 11
FOR Y = 1 TO 3 'siren
SOUND 550, 9
SOUND 400, 9
Работа с оцифрованным звуком (*)
Пару лет назад встроенных возможностей BASIC по извлечению
звуков из встроенного динамика компьютера было более чем доста-
точно. Но времена меняются. Все большее распространение получают
звуковые платы, а с ними — системы multimedia1. Независимые раз-
работчики библиотек для QuickBASIC тоже не стоят на месте. В этом
1 Системы "Multimedia" — аппаратные и программные средства, обеспечивающие
работу с подвижными и неподвижными изображениями, анимированной компьютер-
ной графикой и текстом, речью и высококачественным звуком
266
NEXT Y
CASE IS = 12
FOR Z = 3 TO 12 'Zhoup
SOUND 120 + Z Л 4, .1
SOUND 0, .1
NEXT Z
CASE IS = 13
FOR Z = 12 TO 3 STEP -1 'Vrowr
SOUND 120 + Z Л 4, .1
SOUND 0, .1
NEXT Z
CASE IS = 14
FOR I = 40 TO 15 STEP -1 'Zhou
SOUND I * 90, .1
SOUND I * 80, .1
SOUND I * 70, .1
SOUND I * 60, .1
SOUND I * 50, .1
NEXT I
CASE IS = 15
FOR I = 1 TO 10 'Art
SOUND 1195 - 50 * I, .3
SOUND 1195 + 50 * I, .3
NEXT I
CASE IS = 16
FOR I = 0 TO 150 STEP 10 'Coo
SOUND 1295 - I, .4
SOUND 1095 +1, .4
NEXT I
CASE IS = 17
FOR I = 1 TO 20 'Squawk
SOUND I * 50, .1
SOUND I * 100, .1
SOUND I * 150, .1
NEXT I
CASE ELSE: BEEP
END SELECT
LOOP
COLOR 7, 0: CLS : END
разделе речь пойдет о библиотеке для программирования звуковых
карт AdLib и Sound Blaster — QBXCTV.
Используя этот пакет вместе с пакетом VEGX для работы с
изображениями, вы вполне сможете создавать собственные про-
фессиональные приложения, работающие со звуком и изображе-
ниями, ничуть не уступающие приложениям Windows, а кое в
чем (хотя бы по скорости работы) значительно их превосходя-
щие. Это могут быть обучающие, прикладные или игровые про-
граммы высокого класса и многое другое — возможностей синте-
за звука и изображения видимо-невидимо.
QB SoundBlaster ToolKit
Пакет для программирования звуковых карт:
"QBXCTV — SoundBlaster™ Creative Voice Library for QuickBASIC
4.5, (c) Cornel Huth,1991"
QBXCTV — это совместимый со звуковой картой SoundBla-
ster™ пакет разработчика для работы с оцифрованным звуком в
среде Microsoft QuickBASIC 4.51. Его основные возможности:
• Наличие библиотек для работы в среде QB (.QLB — 14 Kb) и
для компиляции в .ЕХЕ-файлы (.LIB — 15 Kb), а также
включаемые файлы с описанием процедур и типов данных
(.BI - 2 Kb);
• Доступ к музыкальным инструментам для карт AdLib и
SoundBlaster в формате BNK;
• Поддержка всех функций драйвера CT-VOICE.DRV, а также
звуковых файлов формата VOKXIT;
• Прямой доступ к памяти (DMA) обеспечивает возможность
фонового ввода ввод и вывода звука;
• Подробная документация.
Для работы с пакетом вы должны иметь звуковую карту, со-
вместимую с SoundBlaster и загрузить среду QB с библиотекой
QBXSB1N.QLB:
C:\QB45>qb program /L qbxsbln.qlb
1 Имеются библиотеки для Microsoft BASIC PDS 7.x
267
Пример: Вывод звукового файла WATSON.VOC
DEFINT A-Z
'Включаемые файлы пакета
'$INCLUDE: 'QBXIOL.BI1
'$INCLUDE: 'QBXCTV.BI'
'$INCLUDE: 'QBXFMI.BI'
CLS
1 определение наличия звуковой карты
STAT = CTVdetect
IF STAT > 0 THEN END
FileName$ = "WATSON.VOC"
PRINT "Проигрывается файл: "; FileName$
1 Открывается звуковой файл и определяется его длина
STAT = OpenDevice(FileName$ + CHR$@), 2, handle, flen&)
1Считываются данные и выделяется буфер
1 достаточной длины для размещения данных
REDIM VocBuff(О ТО flen&) AS INTEGER
vseg = VARSEG(VocBuff@))
voff = VARPTR(VocBuff@))
STAT = ReadDevice(handle, 0, flen&, vseg, voff)
STAT = CloseDevice(handle)
'Включается динамик звуковой карты
STAT = CTVspeakerA)
'и воспроизводится звук
STAT = CTVoutput(vseg, voff + 26)
IF STAT = 0 THEN
'Во время воспроизведения можно что-либо делать
DO
STAT = CTVstatus
LOOP WHILE STAT
END IF
1 Сброс всех установок в исходное положение
STAT = CTVuninstall
PRINT "Готово!"
END
ПРОЧИЕ ОПЕРАТОРЫ ЯЗЫКА
SLEEP
SLEEP — управляющий оператор, приостанавливающий вы-
полнение программы.
SLEEP [секунды]
Если аргумент опущен или равен нулю, программа приоста-
навливается до нажатия любой клавиши или возникновения раз-
решенного события.
Если аргумент задан, программа приостанавливается на ука-
занное количество секунд, нажатия любой клавиши или возник-
новения разрешенного события — в зависимости от того, что
произойдет раньше.
Пример:
CLS
PRINT "Подождите 10 секунд..."
SLEEP 10
PRINT "Готово!"
END
REM
REM — оператор, указывающий на комментарий.
REM комментарий
' комментарий
• комментарий — любой текст, который вы вставляете в про-
грамму как пояснение операторов и структур. В комментарий
можно включать и символы кириллицы.
REM не компилируется, но сохраняется в исходном тексте
программы. Таким образом использование комментариев в Ва-
шей программе не влияет на скорость работы .ЕХЕ файла.
Комментарии нужны для программиста. Если программа хо-
рошо документирована, т. е. в ней объясняется работа каждой
процедуры, модуля, структуры, то с такой программой легко и
удобно работать, даже если вы вернулись к ней спустя год, а при
наличие комментариев вы без труда разберетесь даже в листинге
вашего коллеги. Другим способом повысит удобочитаемость про-
грамм является использование абзацных отступов. Например, опе-
раторы внутри цикла записываются со смещением (достаточно 2-3
пробела). Кроме этого, блоки текста отделяйте пустыми строками,
чтобы программа не выглядела как один сплошной свиток текста.
Вместо ключевого слова REM можно использовать апостроф (').
При записи комментария с использованием REM в конце строки
операторов, комментарий необходимо отделять двоеточием, а при за-
писи с использованием апострофа, двоеточие можно опускать:
FOR 1 = 1 ТО 10: NEXT 1: REM Это пустой цикл
FOR i = 1 ТО 10: NEXT i 'Это пустой цикл
Пример. Использование комментариев и абзацных отсту-
пов
'Старайтесь не писать программы в таком стиле...
DO
INPUT A
SELECT CASE A
CASE IS = ...
CASE IS = ...
CASE ELSE ...
FOR i = 1 TO 10
NEXT I
EXIT DO
END SELECT
LOOP
'А лучше в таком...
DO 'Входим в бесконечный цикл
1 Получаем значение
INPUT "Введите значение переменной А"; А
270
LOOP
SWAP
SWAP — оператор, взаимно меняющий значения двух пере-
менных.
SWAP переменная1, переменная2
• переменная 1 и переменная2 — любые переменные (но не мас-
сивы) одного и того же типа.
Пример: сортировка символьного массива по возрастанию
ASCII-кодов символов.
DECLARE SUB ShellSort (Array$())
'все переменные целые
DEFINT A-Z
'максимальной количество элементов массива Аггау$()
CONST Max =10
1 Объявляется размерность массива
DIM Array$(Max)
CLS
'присвоение значений элементам
Array$A) = "Scale"
Array$B) = "Масштаб"
Array$C) = "Parameter"
Array$D) = "Параметр"
Array$E) = "Division"
Array$F) = "Деление"
Array$G) = "Computer"
Array$(8) = "Компьютер"
Array$(9) = "Ядро"
Array$A0) = "Kernel"
'вызов процедуры сортировки
CALL ShellSort(Array$())
271
SELECT CASE A
CASE IS = ..." в случае, если А = ...
CASE IS = ..." в случае, если А = ...
CASE ELSE ...' а иначе ...
'чего-нибудь считаем
FOR l = 1 TO 10
NEXT I
'выходим из цикла DO
EXIT DO
END SELECT
'вывод исходных значений
FOR i = 1 ТО Мах
PRINT Array$(i%)
NEXT i%
END
SUB Shell Sort (Array$ ()) STATIC
i***************************************************
1 Эта процедура сортирует символьный массив Array$(}
Num% = UBOUND(Array$)
Span% = Num% \ 2
DO WHILE Span% > 0
FOR i% = Span% TO Num% - 1
J% = i% - Span% + 1
FOR J% = (i% - Span% +1) TO 1 STEP -Span%
IF Array$(J%) <= Array$(J% + Span%) THEN EXIT FOR
' Взаимная замена двух элементов массива.
SWAP Array$(J%), Array$(J% + Span%)
NEXT J%
NEXT i%
Span% = Span% \ 2
LOOP
END SUB
Результат:
Computer
Division
Kernel
Parameter
Scale
Деление
Компьютер
Масштаб
Параметр
Ядро
ERASE
ERASE — оператор управления памятью, обнуляющий эле-
менты статических (SSTATIC) массивов или уничтожающий ди-
намические (SDYNAMIC) массивы.
ERASE массив [,массив...]
• массив — имя описанного массива.
Оператор ERASE обнуляет числовые элементы массивов
SSTATIC и присваивает значение пустой строки элементам символь-
272
ных массивов. Если массив определен оператором TYPE как массив
пользовательского типа, ERASE обнуляет элементы каждой записи.
Использование ERASE для массивов $DYNAMIC освобожда-
ет память, занятую этими массивами. Если программа вновь об-
ращается к этим массивам снова, они должны быть заново опи-
саны операторами DIM или REDIM. Повторное определение
массива оператором DIM без предварительного стирания выдаст
ошибку "Array already dimensioned" (Массив уже определен).
Оператор ERASE не требуется, если массивы переопределяются с
помощью REDIM.
Пример: использование REDIM для размещения массива
записей. Удаление массива из памяти оператором ERASE.
TYPE KeyElement
Word AS STRING * 20
Count AS INTEGER
END TYPE
1 Метакоманда делает массивы динамическими.
' $DYNAMIC
CLS
1 Описание массива записей из 100 элементов.
REDIM WordsA00) AS KeyElement
Words(99)-Word = "ERASE"
Words(99).Count = 2
PRINT "Слово 99 = "; Words(99).Word
PRINT "Счетчик ="; Words(99).Count
' Освобождение памяти, занимаемой Words().
ERASE Words
END
Слово 99 = ERASE
Счетчик = 2
CLEAR
CLEAR — оператор управления памятью, обнуляющий все пе-
ременные, закрывающий файлы, устанавливающий размер стека.
CLEAR [,,стек]
• стек — параметр, устанавливающий размер стека для вашей
программы.
Если Ваша программа имеет много вложенных подпрограмм
или процедур, или использует рекурсивные процедуры, то размер
стека имеет смысл увеличить.
273
Очистка стека разрушает все адреса возврата из подпрограмм,
вызываемых оператором GOSUB. Это может привести к некоррек-
тному выполнению оператора RETURN и к ошибке "RETURN
without GOSUB" (RETURN без GOSUB). Также нельзя использо-
вать CLEAR внутри SUB или FUNCTION — вы получите ошибку
"Illegal function call" (Неверный вызов функции).
Пример: очистка всех переменных программы и увеличе-
ние размера стека на 2000 байт.
CLEAR , ,2000
8
ВСТРОЕННЫЕ
МАТЕМАТИЧЕСКИЕ ФУНКЦИИ
И ФУНКЦИИ ОБРАБОТКИ
ДАННЫХ
Математические функции
ABS
ABS — математическая функция, возвращающая абсолютное
значение числового выражения.
ABS(числовое выражение)
Пример: вычисление приблизительного значения кубичес-
кого корня методом итераций. Функция ABS используется
для оценки точности приближения.
DEFDBL A-Z
Precision = .0000001*
CLS
INPUT "Введите число: ", Value
1 Начальные установки.
XI = 0.0# : Х2 = Value
' Выполнять итерации, пока разница между двумя
1 приближениями не достигнет требуемой точности.
DO UNTIL ABS(XI - Х2) < Precision
X = (XI + Х2) / 2.0#
IF X * X * X * Value < 0.0# THEN
XI = X
ELSE
X2 = X
END IF
LOOP
PRINT "Кубический корень равен"; X
Результат:
Введите число: 27
Кубический корень равен 2.999999972060323
ЕХР
ЕХР — математическая функция, вычисляющее основание
натурального логарифма (число е) в степени заданного аргумента.
ЕХР(числовое_выражение)
• числовоевыражение — выражение, не превышающее
88.02969.
Пример: расчет численности колонии бактерий.
CLS
INPUT "Исходная численность колонии"; ColonyO
INPUT "Дневной рост колонии в процентах"; Rate
R = Rate / 100 : Form$ = "## ######"
PRINT : PRINT "ДеньЧисленность"
FOR T = 0 TO 15 STEP 5
PRINT USING Form$; T, ColonyO * EXP(R * T)
NEXT
Результат:
Исходная численность колонии? 10000
Дневной рост колонии в процентах? 10
День Численность
0 10000
5 16487
10 27183
15 44817
276
LOG
LOG — математическая функция, возвращающая натураль-
ный логарифм числового выражения.
LOG(числовое_выражение)
• числовое_выражение — аргумент функции, должен иметь зна-
чение, большее нуля.
MOD
MOD — арифметическая операция.
числовое_выражение1 MOD числовое_выражение2
Операция нахождения остатка от целочисленного деления.
Например:
PRINT 19 MOD 6.7 '19 MOD 6.7 = 5
SGN
SGN — математическая функция, возвращающая знак чис-
лового выражения.
SGN(числовое_выражение)
Числовое
выражение
>0
= 0
<0
Значение SNG
+1
0
-1
SQR
SQR — математическая функция, которая возвращает квад-
ратный корень числового выражения.
SQR(числовое_выражение)
277
• числовоевыражение — должно иметь значению большее или
равное нулю.
Пример: рисунок графика функций
у = V-x для -9 <= х < О
у = yfx для 0 <= х <= 9
SCREEN I : COLOR I
WINDOW (-9,-.25)-(9,3.25)
LINE (-9,0)-(9,0) 'Ось Х.
LINE @,-.25)-@,3.25) 'Ось Y.
FOR X = -9 TO 9
LINE(X,.04)-(X,-.O4) 'Шкала по оси X.
NEXT
FOR Y = .25 TO 3.25 STEP .25
LINE (-.08,Y)-(.12,Y) 'Шкала по оси Y.
NEXT
1 Первая точка функции.
PSET (-9,3)
FOR X = -9 TO 9 STEP .25
Y = SQR(ABS(X)) 'Аргумент SQR не может быть отрицательным
LINE -(X,Y),2 'Рисунок линии.
NEXT
Результат:
278
ATN
ATN — математическая функция, возвращающая арктангенс
числового выражения.
ATN(числовое выражение)
• числовое выражение — может быть любого числового типа.
По умолчанию ATN выдает число обычной точности. Если
аргумент функции двойной точности, ATN выдает число двойной
точности.
Результат выдается в радианах в пределах от PI/2 до PI/2 ра-
диан. Для преобразования градусной меры в радианы умножьте
градусы на PI/180. Чтобы преобразовать радианы в градусы, надо
умножить радианы на 57.2958.
Пример:
CONST PI = 3.141592653
PRINT ATN(TAN(PI / 4.0)), PI / 4.0
Результат:
.78539816325 .78539816325
COS
COS — математическая функция, возвращающая значения
синуса от угла в радианах.
COS(числовое_выражение)
• числовоевыражение — угол в радианах.
Пример: рисунок спиралей Архимеда.
CONST PI = 3.141593
SCREEN 1 : COLOR 7
1 Определение окна вывода.
WINDOW (-4,-6) - (8,2)
1 Вывод координатной оси.
LINE @,0) - B.2 * PI, 0),1
279
' Вывод десяти спиралей.
FOR N = 1.1 ТО .1 STEP -.1
PSET @,0)
FOR Angle = 0 ТО 2 * PI STEP .04
'Полярные координаты.
R = N - Angle
'Преобразование в декартовы координаты.
X = R * COS(Angle)
Y = R * SIN(Angle) '
Вывод пинии.
LINE -(X,Y),1
NEXT Angle
NEXT N
Результат:
'pess апч кеч to conti nue
SIN
SIN — математическая функция, возвращающая значение
синуса от заданного угла в радианах.
SIN(числовое_выражение)
280
• числовое выражение — угол, выраженный в радианах.
Функция SIN вычисляется с двойной точностью, если чис-
ловое выражение имеет двойную точность. Иначе синус вычисля-
ется с обычной точностью.
Можно преобразовать значение угла из градусов в радианы пу-
тем умножения градусов на PI/180. Обратное преобразование полу-
чается умножением радиан на 57.2958. Пример использования фун-
кции COS был приведен выше, при описании функции SIN.
TAN
TAN — математическая функция, возвращающая тангенс уг-
ла в радианах.
TAN(числовое_выражение)
• числовоевыражение — угол в радианах.
TAN вычисляется с обычной точностью. Если аргумент задан
с двойной точностью, то TAN будет вычислен также с двойной
точностью.
Можно преобразовать угол в градусах в радианы путем ум-
ножения его на PI/180. Для обратного преобразования умножьте
радианы на 57.2958.
Пример. Эта программа использует функцию TAN для то-
го, чтобы вычислить высоту объекта, используя рассто-
яние от объекта и угол подъема. Она рисует треуголь-
ник , опираясь на основание и вычисленную высоту.
'экранный режим 640 х 200 2 цвета
SCREEN 2
INPUT "ДЛИНА ОСНОВАНИЯ: ", Baselen
INPUT "УГОЛ ПОДЪЕМА (ГРАДУСЫ, МИНУТЫ): ", Deg, Min
'Перевод в радианы
Ang = C.1415928# / 180) * (Deg + Min / 60)
'Вычисление высоты.
Height = Baselen * TAN(Ang)
PRINT "ВЫСОТА ="; Height
'Screen 2 - 640 x 200 пикселов.
Aspect = 4 * B00 / 640) / 3
H = 180 - Height
281
В = 15 + (Baselen / Aspect)
LINE A5, 180)-(В, 180) 'Рисование треугольника
LINE -(В, Н)
LINE -A5, 180)
LOCATE 24, 1: PRINT "Нажмите любую клавишу...";
DO
LOOP WHILE INKEY$ = ""
Результат:
Секанс и другие....
В языке BASIC нет встроенных функций секанс, косеканс, ко-
тангенс, арксинус, арккосинус, арккотангенс и некоторых других
тригонометрических и гиперболических функций, однако их мож-
но вычислить, используя имеющиеся встроенные функции.
Пример:
sec х (секанс):
SEC(X) = 1 / COS(X)
cosec x (косеканс):
COSEC(X) = 1 / SIN(X)
arcsin x (арксинус):
ARCSIN(X) = ATN (X/ SQR A - X * X)
282
arccos x (арккосинус):
ARCCOS(X) = 1.570796 - ATN (X / SQR A - X * X)
arcctg x (арккотангенс):
ACTN(X) = 1.570796 - ATN (X)
sh x(гиперболический синус):
SINH(X) = (EXP(X) - EXP(-X)) / 2
ch x (гиперболический косинус):
COSH(X) = (EXP(X) + EXP(-X)) / 2
th x {гиперболический тангенс):
TANH(X) = (EXP(X) - EXP(-X)) / (EXP(X) + EXP(-X))
cth x (гиперболический котангенс):
COTH(X) = (EXP(X) + EXP(-X)) / (EXP(X) - EXP(-X))
arcsh x (гиперболический арксинус):
ARCSH (X) = LOG(X + SQR(X * X + 1))
arcch x (гиперболический арккосинус):
ARCCOSH (X) = LOG(X + SQR(X * X - 1))
RANDOMIZE
RANDOMIZE — математический оператор, запускающий ге-
нератор случайных чисел.
RANDOMIZE [выражение]
• если аргумент опущен, BASIC выдаст сообщение для ввода
любого числа, запускающего генератор: Random Number Seed
(-32768 to 32767)?
• выражение — может быть любого типа.
Если генератор случайных чисел не запущен, функция RND
будет выдавать одну и ту же последовательность чисел при каж-
дом запуске программы. Для изменения последовательности по-
ставьте оператор RANDOMIZE в начало программы и изменяйте
аргумент перед каждым запуском программы. Используйте для
этого функцию TIMER.
Пример. Рисование узора при помощи случайных значений
координат в операторе LINE:
1 Все переменные целые
DEFINT A-Z
283
1 Запускаем генератор случайных чисел
RANDOMIZE TIMER
'640x350x16 цветов
SCREEN 9
1 Внешний цикл
FOR i = 1 ТО 1000
1 Внутренний цикл
FOR j = 1 ТО 10
1 Изменяем цвет
COLOR j
1 Рисуем линию
LINE (i, INT(RND * 750) - (INT(RND * 750)))-(RND, i)
NEXT j
NEXT i
Результат:
RND
RND — математическая функция, возвращающая случайное
число обычной точности в интервале от 0 до 1.
RND[(n)]
284
• если аргумент опущен, возвращается следующее число из пос-
ледовательности случайных чисел;
• п — определяет, как генерируется следующее число:
• п < 0 — всегда возвращает то же число для любого п;
• п > 0 — возвращает следующее число из последовательности;
• п = 0 — возвращает последнее выданное число.
В случае, если не запущен генератор случайных чисел, одна
и та же последовательность будет генерироваться при каждом за-
пуске программы. Для запуска генератора используйте функцию
TIMER:
RANDOMIZE TIMER
Для генерации случайного числа в нужном интервале служит
формула:
INT ((max - min +1) - RND + min,
где max — верхняя граница интервала, a min — нижняя.
Пример: моделирование двух игровых кубиков.
1 Используем таймер для запуска
' генератора случайных чисел
RANDOMIZE TIMER
CLS
DO
' Моделируем кубики функцией RND.
Dl = INT(RND - 6) + 1
D2 = INT(RND - 6) + 1
PRINT "Выпало"; Dl; "и"; D2; " сумма"; Dl + D2
INPUT "Еще Y/N "; Resp$
PRINT
LOOP UNTIL UCASE$(MID$(Resp$, 1, 1)) = "N"
END
Результат:
Выпало З и 5 сумма 8
Еще Y/N? у
Выпало 1 и 3 сумма 4
Еще Y/N? у
Выпало 4 и 1 сумма 5
Еще Y/N? n
285
Функции обработки числовых и
символьных данных
Функции округления
FIX
FIX — математическая функция, возвращающая целую часть
числового выражения.
FIX(числовое_выражение)
FIX(x) эквивалентно выражению SGN(x)*INT(ABS(x)). Раз-
личие между FIX и INT состоит в том, что при х < О FIX выдает
первое отрицательное целое, большее х, тогда как INT выдает
первое отрицательное целое, меньшее х.
INT
INT — математическая функция, возвращающая первое це-
лое, меньшее или равное данному числовому выражению.
INT(числовое_выражение)
Пример: сравнение функций INT, CINT и FIX.
CLS
PRINT " N", "INT(N)","CINT(N)","FIX(N)" : PRINT
FOR 1% = 1 TO 6
READ N
PRINT N, INT(N), CINT(N), FIX(N)
NEXT
DATA 99.3, 99.5, 99.7, -99.3, -99.5, -99.7
286
Результат:
N
99.3
99.5
99.7
-99.3
-99.5
-99.7
INT(N)
99
99
99
-100
-100
-100
CINT(N)
99
100
100
-99
-100
-100
FIX(N)
99
99
99
-99
-99
-99
Преобразование типов данных
CINT
CINT — функция, преобразующая числовое выражение в це-
лое число путем округления дробной части выражения.
CINT(числовое_выражение)
CLNG
CLNG — функция преобразования, приводящая числовое
выражение к длинному целому D байта) путем округления дроб-
ной части.
CLNG(числовое_выражение)
Пример: Использование функции CLNG для округления
числа перед переводом его в длинное целое.
А = 32767.45: В = 32767.55
PRINT CLNG(A); CLNG(B)
Результат:
32767 32768
CSNG
CSNG — функция, преобразующая числовое выражение в
значение обычной точности.
CSNG(числовое_выражение)
287
Пример: округление перед преобразованием.
А# = 975.3421115#
В# = 975.3421555*
PRINT A#; CSNG(A#); B#; CSNG(B#)
Результат:
975.3421115 975.3421 975.3421555 975.3422
CDBL
CDBL — функция, преобразующая числовое выражение в
число двойной точности.
CDBL(числовое_выражение)
Пример: Влияние точности на преобразование.
X = 7 / 9 ' выражение обычной точности
Х# = 7 / 9 ' выражение обычной точности
PRINT X
PRINT X#
PRINT CDBL(X)
PRINT 7# / 9# ' выражение двойной точности
Результат:
.7777 78
.7777777910232544
.7777777910232544
.7777777777777778
CHR$
CHR$ — символьная функция, возвращающая строку из од-
ного символа, ASCII-код которого является аргументом.
CHR$(код)
• код — числовое выражение от 0 до 255, один из ASCII-кодов.
Пример: Вывод второй половины ASCII-таблицы
1 Все переменные целые
DEFINT A-Z
288
1 Заголовок таблицы
CLS
PRINT SPACE$B0) + "Расширенная ASCII-таблица"
PRINT
'Верхняя рамка
PRINT "Т"'": F0R 1 = 1 ТО 8: PRINT " 1 г"'' :NEXT i
PRINT
'Рисование таблицы. Функция CHR$ используется для
1 представления символа по его коду.
FOR i = 1 ТО 16
FOR j = 128 ТО 255 STEP 16
PRINT USING "|###| ! "; j + i - 1; CHR$(j + l - 1);
NEXT j
PRINT "|"
NEXT i
1 Нижняя рамка
PRINT "-1-" ; : FOR l = 1 TO 8 : PRINT " ' L" ; : NEXT i
1 Ожидание нажатия любой клавиши
DO: LOOP WHILE INKEY$ = ""
Результат:
Расширенная ASCII-таблица
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
й
Б
В
Г
д
Е
Ж
3
И
Й
к
л
м
н
0
п
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
Р
С
Т
У
ф
X
Ц
Ч
и
щ
Ъ
Ы
Ь
3
0
я
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
а
6
В
г
Ъ
в
ж
3
и
й
к
л
и
н
о
11
176
177
178
179
180
181
182
1ВЗ
1В4
185
186
187
188
189
190
191
11
л
II
11
л
1
192
193
194
195
196
19?
198
199
ZOO
201
202
203
Z04
205
206
207
L
X
т
4-
\
|
и
If
Л
Т[
1
i
х
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
л
т
И
t
г
1
+
J
i
i
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
Р
с
т
и
Ф
X
Ц
ч
и
ч
ь
ы
ь
э
ю
я
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
Ё
в
>
<
J
"Г
SS
»
п
г
ш
ASC
ASC — функция, возвращающая числовое значение ASCII-
кода первого символа в символьном выражении.
ASC(символьное_выражение)
289
Пример: подсчет контрольной суммы.
CLS
INPUT "Введите строку : ", Nm$
TmpVal = 0
FOR i = 1 ТО LEN(Nm$)
1 Суммирование кодов отдельных букв.
TmpVal = TmpVal + ASC(MID$(Nm$, i, 1))
NEXT I
PRINT "Контрольная сумма = "; TmpVal
Вывод:
Введите строку : United States
Контрольная сумма = 1277
Упаковка данных
CVI, CVL, CVS ,CVD
CVI, CVL, CVS ,CVD — функции, интерпретирующие сим-
вольные переменные как числа.
CVI( 2-байтная строка)
CVL D-байтная строка)
CVS D-байтная строка)
CVD (8-байтная строка)
CVI, CVL, CVS и CVD обычно используются оператором
FIELD для чтения упакованных чисел из файла прямого доступа.
Они обратны функциям MKI$, MKL$, MKS$, и MKD$.
CVI$
CVL$
cvs$
CVD$
Преобразует 2-байтную строку в целое число
Преобразует 4-байтную строку в длинное целое число
Преобразует 4-байтную строку в число обычной точности
Преобразует 8-байтную строку в число двойной точности
MKI$, MKL$, MKS$, MKD$
MKI$, MKL$, MKS$, MKD$ — функции, интерпретирую-
щие числа как символьные переменные.
290
МК1$ (целое_выражение)
MKS$ (выражение_обычной_точности)
MKL$ (длинное_целое_выражение)
MKD$ (выражение_двойной_точности)
Эти функции используются с операторами FIELD и PUT для за-
писи числовых значений в файл произвольного доступа. Они преобра-
зуют числа в символьные строки, которые могут размещаться в буфере
оператора FIELD. Функции обратны CVI, CVL, CVS, CVD.
MKIS
MKL$
MKS$
MKD$
Преобразует целое число в 2-байтную строку
Преобразует длинное целое число в 4-байтную строку
Преобразует число обычной точности в 4-байтную строку
Преобразует число двойной точности в 8-байтную строку
Переменные пользовательского типа (записи) предоставляют
более простой и удобный способ чтения и записи файлов произ-
вольного доступа.
Пример. Использования функций MKS$ и CVS:
TYPE Buffer
AccName AS STRING * 25
Check AS STRING * 4
END TYPE
DIM BankBuffer AS Buffer
I****************************************************
'Открытие файла и занесение значений с использованием
'переменный пользовательского типа
¦ ****************************************************
OPEN "ACCOUNT.INF" FOR RANDOM AS #1 LEN = 29
CLS
RESTORE
READ AccName$, Check
i = 0
DO WHILE UCASE$(AccName$) <> "END"
i = i + l
BankBuffer.AccName = AccName$
1 Преобразование числа в символьную переменную
BankBuffer.Check = MKS$(Check)
PUT #1, i, BankBuffer
READ AccName$, Check$
IF AccName$ = "END" THEN EXIT DO
LOOP
CLOSE #1
291
DATA "Роберт", 3 00
DATA "Алиса", 150
DATA "Алексей", 7 5
DATA "Василий", 5 0
DATA "Григорий", 25
DATA "END", 0
1 Открытие файла и обработка значений при помощи
'буфера FIELD, функций MKS$ и CVS
OPEN "ACCOUNT.INF" FOR RANDOM AS #2 LEN =29
FIELD #2, 25 AS AccName$, 4 AS Check$
Format$ = "$$#####.##"
DO
PRINT
DO
INPUT "Введите номер счета: ", Rec%
GET #2, Rec%
PRINT "Этот счет открыл "; AccName$
INPUT "Нужно изменить Y/N "; R$
LOOP WHILE UCASE$(MID$(R$, 1, 1)) о "Y"
1 Преобразование символьной переменной в число.
Checkamt! = CVS(Check$)
PRINT
PRINT "Входящее сальдо по этому счету равно";
PRINT USING Format$; Checkamt!
PRINT "Введите приход и расход по этому счету."
PRINT "По завершению введите 0."
DO
INPUT Check!
Checkamt! = Checkamt! + Check!
LOOP UNTIL Check! = 0
PRINT
PRINT "Исходящее сальдо по этому счету равно";
PRINT USING Format$; Checkamt!
'Преобразование числа в символьную переменную.
LSET Check$ = MKS$(Checkamt!)
PUT #2, Rec%
INPUT "Изменить следующий Y/N "; R$
LOOP UNTIL UCASE$(MID$(R$, 1, 1)) <> "Y"
CLOSE #2
END
Результат:
Введите номер счета: 3
Этот счет открыл Алексей
Нужно изменить Y/N ? у
Входящее сальдо по этому счету равно $300.00
Введите приход и расход по этому счету.
По завершению введите 0.
292
? 560
? -180
? 0
Исходящее сальдо по этому счету равно $680.00
Изменить следующий Y/N ? п
Функции обработки символьных строк
LCASE$
LCASE$ — символьная функция, возвращающая символьную
строку, в которой все латинские буквы преобразованы в строчные.
LCASE$(символьное_выражение)
• символьноевыражение — символьная строка, может быть пе-
ременной или фиксированной длины.
Пример:
CLS
READ Word$
PRINT LCASE$(Word$);
DATA "THIS IS THE STRING in lower case."
this is the string in lower case.
Данная функция не преобразует символы кириллицы. При-
мер, приведенный далее при описании функции UCASE, иллюс-
трирует, как можно этого избежать.
UCASE$
UCASES — символьная функция, возвращающая символьное
значение, в котором все латинские буквы — заглавные.
UCASE$(символьное_выражение)
Функция UCASES может работать со строками фиксированной
и переменной длины. Она не преобразует символы кириллицы.
293
Пример. Использование функции UCASERus$ вместо UCASE$
снимает ограничение на работу с символами кириллицы:
DECLARE FUNCTION UCASERus$ (text$)
DEFINT A-Z
CLS
INPUT First$
PRINT
PRINT UCASERus${First$)
END
FUNCTION UCASERus$ (text$)
CONST Urus$ = "ЙЦУКЕНГШЩЗХФЫВАПРОЛДЖЭЯЧСМИТЬВЮЪ"
CONST Lrus$ = "йцукенлшцзхфывапролджэячсмитьбюъ"
1 длина входной переменной
kolvo = LEN(text$)
1 вспомогательная переменная
temp$ = ""
FOR i = 1 TO kolvo
1 берем по одному символу из входной строки
symbol$ = MID$(text$, i, 1)
'если это русские буквы, то ...
IF symbol$ >= CHR$A28) THEN
'если они маленькие - меняем на большие
place = INSTR(Lrus$, symbol$)
IF place > 0 THEN symbol$ = MID$(Urus$, place, 1)
ELSE
1 ... пользуемся UCASES
symbo1$ = UCASE$(symbo1$)
END IF
1 накапливаем значение во вспомогательной переменной
temp$ = temp$ + symbols
NEXT i
'присваиваем значение функции
UCASERus$ = temp$
END FUNCTION
Результат:
? Штирлиц вошел в лес и увидел ...
ШТИРЛИЦ ВОШЕЛ В ЛЕС И УВИДЕЛ ...
LTRIM$
LTRIM$ — символьная функция, возвращающая копию
строки с удаленными начальными пробелами.
294
LTRIM$(символьное_выражение)
пример: копирование текстового файла с удалением на-
чальных и конечных пробелов.
INPUT "Введите имя исходного файла: ", InFile$
INPUT "Введите имя получаемого файла: ", OutFile$
OPEN InFile$ FOR INPUT AS #1
OPEN OutFile$ FOR OUTPUT AS #2
' Чтение, обработка и запись каждой строки
DO WHILE NOT EOF(l)
LINE INPUT #1, Lineln$
Lineln$ = LTRIM$(RTRIM$(LineIn$))
PRINT #2, Lineln$
LOOP
CLOSE #1, #2
END
RTRIM$
RTRIM$ — символьная функция, которая возвращает сим-
вольную строку с удаленными правыми пробелами.
RTRIM$(символьное_выражение)
См. пример к функции LTRIM$.
SPACES
SPACES — символьная функция, возвращает строку пробе-
лов длиной п.
SPACE$(n)
• п — числовое выражение в пределах 0—32767, количество
пробелов в строке.
Пример:
CLS
FOR i = 1 ТО 5
Х$ = SPACE$(i): PRINT X$; I
NEXT i
Вывод:_
1
2
3
4
5
295
STRINGS
STRINGS — символьная функция, возвращает строку запол-
ненную символами данного ASCII-кода или данным символом.
STRINGS(m,n)
STRINGS(—m, символьное_выражение)
• m — числовое выражение, длина строки;
• п — числовое выражение в пределах 0—255, ASCII-код симво-
ла-заполнителя строки;
• символьное_выражение — указывает строку, первый символ
которой используется для заполнения строки.
Пример: Построение линейного графика.
CLS
PRINT " Рост удоев на ферме г.Нью-Васюки"
PRINT
FOR Month = 1 ТО 12 STEP 2
READ Month$, Temp
296
'Вывод Temp-3 5 звездочек.
PRINT Month$; " +"; STRING$(Temp - 35, "*")
PRINT " I"
NEXT Month
'Вывод горизонтальной линии.
PRINT " +";
FOR X = 1 TO 7
PRINT " +";
NEXT X
PRINT
1 Вывод шкалы высоких удоев.
FOR X = 4 ТО 39 STEP 5
PRINT TAB(X); X + 31;
NEXT X
PRINT
DATA Янвр, 70, Март, 60, Май , 50
DATA Июль, 45, Сент, 50, Нояб, 40
1NSTR
INSTR — символьная функция, возвращающая позицию
первого вхождения подстроки в указанной строке.
INSTR([начало,]строка1,строка2)
• начало — условное смещение от начала строки, устанавливающее
позицию начала поиска. Число в пределах 1—32767. Если не зада-
но, функция INSTR начинает поиск с первого символа строки1;
• строка 1 — строка, в которой производится поиск;
• строка2 — искомая подстрока.
Значение, возвращаемое INSTR зависит от следующих условий:
Условие
строка2 найдена в строке 1
начало больше длины строки 1
строка 1 — пустая строка
строка2 не найдена
строка2 — пустая строка
Значение
позиция, с которой строка2 на-
чинается в строке1
0
0
0
начало (если есть), иначе I
297
Пример: определить, пол человека, если дано полное
английское написание фамилии.
CLS
DO
INPUT "Введите имя: ", Nm$
LOOP UNTIL LEN(Nm$) >= 3
Nm$ = UCASE$(Nm$)
1 Ищем MS, MRS, или MR для установки Sex$.
IF INSTR(Nm$, "MS") > 0 OR INSTR(Nm$, "MRS") > 0 THEN
Sex$ = "W"
ELSEIF INSTR(Nm$, "MR") > 0 THEN
Sex$ = "M"
ELSE
' Невозможно определить, лучше спросим.
DO
INPUT "Введите пол (M/W): ", Sex$
Sex$ = UCASE$(Sex$)
LOOP WHILE Sex$ <> "M" AND Sex$ <> "W" END IF
IF Sex$ = "M" THEN PRINT "Джентльмен" ELSE PRINT "Леди"
Вывод:
Введите имя: Mrs. Higgins
Леди
Введите имя: Col. Pickering
Введите пол (M/W): М
Джентльмен
LEFTS
LEFTS — символьная функция, возвращающая строку, со-
держащую п левых символов исходной строки.
LEFT$(символьное_выражение, п)
• символьное_выражение — исходная строка;
• п — числовое выражение в пределах 0—32767.
Если п = 0, возвращается пустая строка.
Пример:
CLS
А$ = "QuickBASIC Forever ! "
В$ = LEFT$(A$, 5)
PRINT B$
Вывод:
Quick
298
299
RIGHTS
RIGHTS — символьная функция, возвращающая правые п
символов символьной строки.
RIGHT$(символьное_выражение, п)
• символьное_выражение — исходная строка;
• п — числовое выражение от 0 до 32767, указывающее сколько
символов справа требуется взять. Если п = 0, возвращается пу-
стая строка.
Пример: преобразование имени вида "Имя Фамилия* в
форму "Фамилия, Имя".
CLS
LINE INPUT "Имя: "; Nm$
Sppos = INSTRfl, Nm$, » »)
IF Sppos = 0 THEN
PRINT Nm$ 'Введена только фамилия.
ELSE
Lastname$ = RIGHT$(Nm$, LEN(Nm$) - Sppos)
Firstname$ = LEFT$(Nm$, Sppos - 1)
PRINT Lastname$; " ,"; Firstname$
END IF
END
Результат:
Имя: Билл Гейтс
Гейтс, Вилл
МЮ$ (функция)
МШ$ — символьная функция, возвращающая фрагмент ука-
занной строки.
MID$(символьное_выражение,начало[,длина])
• символьное_выражение — исходная строка;
• начало — числовое выражение от 1 до 32767, начальная сим-
вольная позиция фрагмента данной строки;
• длина — длина фрагмента.
Если длина опущена или количество символов от начала до
конца строки меньше длины, то функция МГО$ возвращает
фрагмент от начала до конца строки. Если начало больше, чем
длина символьного выражения, MID$ возвращает пустую строку.
Пример: использование MID$ для преобразования двоич-
ного числа в десятичную форму.
CLS
INPUT "Введите двоичное число =", Binary$
Length = LEN(Binary$)
Decimal = 0
FOR k = 1 TO Length
1 Извлечение единиц и нулей.
Digit$ = MID$(Binary$, k, 1)
IF Digit$ = " OR Digit$ = " THEN
1 Преобразование в десятичное число.
Decimal = 2 * Decimal + VAL(Digit$)
ELSE
PRINT "Неверно введено число: "; Digit$
EXIT FOR
END IF
NEXT k
PRINT "Десятичное число = "; Decimal
Вывод:
Введите двоичное число = 10110
Десятичное число =22
МЮ$ (оператор)
MID$ — символьный оператор, заменяющий фрагмент стро-
ки на содержимое другой строки.
MID$(строка, начало[,длина]) = символьное_выражение
• строка — символьная переменная, в которой требуется произ-
вести изменения;
• начало — числовое выражение, определяющее начальную по-
зицию в исходной строке, с которой производится замена;
• длина — количество символов из символьного выражения;
• символьное_выражение — представляет новые символы.
Аргументы начало и длина — целые выражения. Аргумент
строка должен быть только символьной переменной, но сим-
300
вольное выражение может быть переменной, константой или вы-
ражением.
Если длина опущена, то производится замена полным со-
держимым символьного выражения. Если длина задана, то про-
изводится замена указанным количеством символов слева из
символьного выражения. Заменяемый фрагмент не может превы-
сить текущей длины переменной.
Пример:
CLS
Test$ = "Париж, Франция "
PRINT Test$
MID$(Test$, 7, 8)= "шт.Техас"
PRINT Test$
Paris, Франция
Paris, шт.Техас
НЕХ$
НЕХ$ — символьная функция, возвращающая шестнадцате-
ричное представление десятичного аргумента.
НЕХ$(выражение)
• выражение — любое выражение, имеющее десятичное значение.
CLS
INPUT X
А$ = НЕХ$(Х)
PRINT X; "в десятичной форме — это"; А$; " в шестнадцате-
ричной"
Вывод:
? 32
32 в десятичной форме - это 20 в шестнадцатеричной
ост$
ОСТ$ — символьная функция, возвращающая символьное
представление восьмеричного значения аргумента.
301
ОСТ$(числовое_выражение)
• числовое_выражение — может быть любого типа.
STR$
STR$ — символьная функция, возвращает символьное пред-
ставление числа или числового выражения.
STR$(числовое_выражение)
Если числовое выражение положительно, строка возвращается
с начальным пробелом. Превращение числа в символьное выра-
жение позволяет производить над ним те же действия, что и с
символьной строкой: складывать, выделять фрагменты числа, за-
менять, форматировать и т. д.
Пример:
CLS
Profit% = 50000
PRINT "Прибыль составила" + STR$(Profit%) + ".00 рублей"
Результат:
Прибыль составила 50000.00 рублей
LEN
LEN — символьная функция, возвращающая количество
символов данной строки или количество байт, занимаемых пере-
менной.
п = ЬЕЫ(символьное_выражение) n = LEN(переменная)
• символьное_выражение — строка символов;
• переменная — объект любого типа, для которого требуется уз-
нать занимаемый объем памяти.
Пример: определение длины переменных различных типов
(байт).
TYPE EmpRec
EmpName AS STRING * 2
EmpNum AS INTEGER
END TYPE
302
DIM A AS INTEGER, В AS LONG, С AS SINGLE, D AS DOUBLE
DIM E AS EmpRec
PRINT "Строка символов: "; LEN("Строка")
PRINT "Целое число: "; LEN(A)
PRINT "Длинное целое: "; LEN(В)
PRINT "Обычной точности: "; LEN(С)
PRINT "Двойной точности: "; LEN(D)
PRINT "Запись типа EmpRec: "; LEN(E)
END
Вывод:
Строка символов: б
Целое число: 2
Длинное целое: 4
Обычной точности: 4
Двойной точности: 8
Запись типа EmpRec: 22
От Издательства
Данная книга, изданная впервые в 1994
году для широкого круга профессионалов
и любителей языка QuickBASIC 4.5,
приобрела большую популярность в
ВУЗах, колледжах, школах и лицеях
страны. Не будучи изначально кано-
ническим учебником, она переиздается в
качестве пособия ввиду острой пот-
ребности учебных заведений в литературе
по языкам программирования.
Издательство, заинтересованое в усовер-
шенствовании книги, с благодарностью
примет все критические замечания, советы
и пожелания педагогов и учащихся.
Доступ
к абсолютным адресам (*)
DEF SEG
DEF SEG — оператор управления памятью, устанавливаю-
щий текущий сегментный адрес для выполнения операторов
PEEK, BLOAD, BSAVE, CALL ABSOLUTE, POKE.
DEF SEG [= адрес]
• адрес — целое выражение в интервале от 0 до 65535, указыва-
ющее сегментный адрес.
После выполнения оператора DEF SEG = адрес, необходимо
выполнить оператор DEF SEG без параметров, для установления
текущего сегментного адреса самого языка. Иначе продолжение
выполнения программы будет просто диверсией против работы
BASIC:
DEF SEG = О
DEF SEG
PEEK
PEEK — функция памяти, возвращающая байт, размещен-
ный в памяти по указанному адресу.
РЕЕК(адрес)
• адрес — числовое выражение от 0 до 65535, смещение относи-
тельно текущего сегмента памяти, установленного оператором
DEF SEG.
Пример использования оператора РЕЕК приведен ниже, в
разделе "Доступ к клавишам-переключателям и модификаторам".
РОНЕ
РОКЕ — оператор памяти, записывающий байт по данному
адресу.
РОКЕ адрес, байт
• адрес — числовое выражение от 0 до 65535, смещение относи-
тельно текущего сегмента памяти, установленного оператором
DEF SEG;
• байт — числовое целое выражение от 0 до 255, данные, запи-
сываемые по данному адресу памяти.
Пример использования оператора РОКЕ приведен ниже, в
разделе "Доступ к клавишам-переключателям и модификаторам".
SADD
SADD — функция памяти, возвращающая адрес указанной
символьной переменной. Часто используется для передачи пара-
метров в процедуру, написанную на другом языке, или для вызо-
ва процедуры в машинных кодах, записанной в символьную
строку.
SADD(символьная_переменная)
• символьнаяпеременная — указывает символьную перемен-
ную, размещение в памяти которой требуется узнать.
Функция SADD возвращает адрес символьной строки как
смещение (ближняя адресация) от текущего сегмента данных.
Это двухбайтовое целое число. SADD часто используется в про-
граммировании на разных языках.
Аргумент может быть символьной переменной или элемен-
тов символьного массива. Нельзя использовать строки фиксиро-
ванной длины.
306
Вызывайте функцию осторожно, так как строки могут пере-
мещаться в пределах памяти при выполнении символьных опера-
торов и функций.
Не добавляйте символов в начало или конец строки, переда-
ваемой функциям SADD и LEN — это может вызвать ошибку
при работе программы.
SETMEM
SETMEM — функция памяти, изменяющая размер памяти,
используемой дальними объектами — динамическими массивами
и внешними таблицами.
SETMEM(числовое_выражение)
• числовое_выражение — имеет значение большее, меньшее
или равное нулю. Оно указывает, на сколько байт увеличить
или уменьшить дальнюю память.
Если числовое выражение отрицательно, SETMEM уменьша-
ет используемую память на указанное количество байт, а если
положительно, то SETMEM пытается увеличить используемую
память на указанное количество байт
SETMEM возвращает общее число байт дальней памяти. Ес-
ли числовое выражение равно нулю, он возвращает текущее зна-
чение памяти.
Если SETMEM не может изменить дальнюю память на ука-
занное количество байт, он добавляет или отнимает столько байт,
сколько возможно.
SETMEM может использоваться в смешанном программиро-
вании для уменьшения дальней памяти, если другому языку тре-
буется динамически разместить переменные в этой памяти.
Первый запуск SETMEM не увеличит дальнюю память, так
как программы выделяют всю память для дальних объектов при
запуске.
VARPTR и VARSEG
VARPTR и VARSEG — функции памяти, возвращающие ад-
рес переменной.
VARPTR(переменная)
VARSEG(переменная)
307
• переменная — может быть любого типа, включая записи или
элементы записей.
Функция VARSEG возвращает сегментный адрес переменной
в виде целого числа без знака. Функция VARPTR возвращает
смещение относительно сегментного адреса как целое число без
знака.
Если переменная не была определена до вызова VARPTR
или VARSEG, она создается и возвращается ее адрес. Если пере-
менная является символьной, функции VARPTR и VARSEG воз-
вращают адрес первого байта описателя.
Не используйте значения, возвращенные VARPTR и
VARSEG после выполнения операторов и вызовов функций, так
как многие операторы BASIC изменяют местоположение пере-
менных в памяти.
VARPTR и VARSEG часто используются с BLOAD, BSAVE,
CALL ABSOLUTE, CALL INTERRUPT, PEEK, POKE или для
передачи адресов массивов в процедуры, написанные на других
языках.
Для получения адреса массива задавайте в качестве аргумента
функций его первый элемент. Его адрес — это адрес начала раз-
мещения массива в памяти:
DIM AA50)
ArrAddress = VARPTR(AA))
вы должны вызвать обе функции для получения полного ад-
реса переменной, особенно, если она может иметь дальний адрес,
так как одна VARPTR выдает адреса переменных, размещенных
только в DGROUP (ближние адреса — в пределах 64К сегмента
данных).
VARPTR$
VARPTRS — функция памяти, возвращающая символьное
представление адреса переменной для использования в операто-
рах DRAW и PLAY.
VARPTR$(переменная)
• переменная — имя переменной для операторов DRAW и PLAY
Если переменная является элементом массива, он должен
быть определен до вызова VARPTRS как символьный, перемен-
ной длины.
308
Так как многие операторы языка QuickBASIC изменяют мес-
тоположение переменных в памяти, не используйте значения,
возвращенные VARPTRS после выполнения символьных опера-
торов и вызовов функций.
Пример: использование VARPTRS в операторе PLAY.
SCALE$ = "CDEFGAB"
PLAY "oO X" + VARPTR$(SCALE$)
FOR l = 1 TO б
PLAY ">X" + VARPTR$(SCALE$)
NEXT l
PLAY "Об X" + VARPTR$(SCALE$)
FOR l = 1 TO 6
PLAY "<X" + VARPTR$(SCALE$)
NEXT I
Доступ к клавишам-переключателям и модификаторам
При помощи операторов DEF SEG, РЕЕК и РОКЕ можно
программным образом определять и изменять состояние клавиш-
переключателей ({NUM LOCK}, {CAPS LOCK}, {SCROLL LOCK}
и {INSERT}) и клавиш-модификаторов ({ALT}, {CTRL} и
{SHIFT}). Для этого необходимо прочитать два байта памяти с
адресами &Н417 и &Н418. После этого необходимо сразу же вос-
становить текущий сегментный адрес BASIC, выполнив оператор
DEF SEG без параметров:
DEF SEG = О
с = РЕЕК(&Н417)
d = РЕЕК(&Н418)
DEF SEG
Если условие
IF с AND a THEN ...
истинно, то мы можем "разветвиться" в зависимости от значения
переменной а:
128 — включен режим INSERT;
64 — включен режим CAPS LOCK;
32 — включен режим NUM LOCK;
16 — включен режим SCROLL LOCK;
309
8 — в данный момент нажата клавиша {ALT};
4 — в данный момент нажата клавиша {CTRL};
2 — в данный момент нажата левая клавиша {SHIFT};
1 — в данный момент нажата правая клавиша {SHIFT}.
Если же истинно условие
IF d AND a THEN ...
то, в зависимости от значения переменной а:
128 — в данный момент нажата клавиша {INSERT};
64 — в данный момент нажата клавиша {CAPS LOCK};
32 — в данный момент нажата клавиша {NUM LOCK};
16 — в данный момент нажата клавиша {SCROLL LOCK}.
В программе можно предусмотреть изменение состояния
ключевых клавиш. Для этого надо считать значение байта &Н417,
изменить его и вновь передать в память:1
1 Включение режима
DEF SEG = О
POKE &H417, РЕЕК(&Н417) OR a
DEF SEG
1 Выключение режима
DEF SEG = О
POKE &H417, РЕЕК(&Н417) AND f
DEF SEG
Значение переменных а и f показаны ниже:
Клавиша a f
{INSERT} 128 127
{CAPS LOCK} 64 191
1 У компьютеров класса XT связь клавиатуры с системным блоком односто-
ронняя, поэтому при изменении состояния ключей {CAPS LOCK}, {NUM
LOCK} или {SCROLL LOCK} в программе, лампочки этих клавиш не загорают-
ся. У компьютеров класса AT и выше — связь двусторонняя, и лампочки всегда
показывают правильное состояние соответствующего ключа, в независимости от
того, изменялось или оно в программе или просто нажатием на клавишу
310
{NUM LOCK} 32 223
{SCROLL LOCK} 16 239
Пример. Использование операторов DEF SEG, PEEK и POKE
для программного управления клавишами-переключателями.
DEFINT A-Z
CLS
PRINT "Клавиша Num Lock включена"
DEF SEG = 0
POKE &H417, PEEK(&H417) OR 32
DEF SEG
DO: LOOP WHILE INKEY$ =
PRINT "Клавиша Num Lock выключена": PRINT
DEF SEG = 0
POKE &H417, PEEK(&H417) AND 223
DEF SEG
DO: LOOP WHILE INKEY$ = ""
PRINT "Клавиша Caps Lock включена"
DEF SEG = 0
POKE &H417, PEEK(&H417) OR 64
DEF SEG
DO: LOOP WHILE INKEY$ =
PRINT "Клавиша Caps Lock выключена": PRINT
DEF SEG = 0
POKE &H417, PEEK(&H417) AND 191
DEF SEG
DO: LOOP WHILE INKEY$ =
PRINT "Клавиша Scroll Lock включена"
DEF SEG = 0
POKE &H417, PEEK(&H417) OR 16
DEF SEG
DO: LOOP WHILE INKEY$ = ""
PRINT "Клавиша Scroll Lock выключена": PRINT
PRINT DEF SEG = 0
POKE &H417, PEEK(&H417) AND 239
DEF SEG
DO: LOOP WHILE INKEY$ = ""
311
От Издательства
Данная книга, изданная впервые в 1994
году для широкого круга профессионалов
и любителей языка QuickBASIC 4.5,
приобрела большую популярность в
ВУЗах, колледжах, школах и лицеях
страны. Не будучи изначально кано-
ническим учебником, она переиздается в
качестве пособия ввиду острой пот-
ребности учебных заведений в литературе
по языкам программирования.
Издательство, заинтересованое в усовер-
шенствовании книги, с благодарностью
примет все критические замечания, советы
и пожелания педагогов и учащихся.
10
ОТСЛЕЖИВАНИЕ СОБЫТИЙ,
ОБРАБОТКА ОШИБОК
И ТРАССИРОВКА (*)
Отслеживание событий
ON COM(n)
ON COM(n) — оператор отслеживания событий, передаю-
щий управление подпрограмме при получении символов через
коммуникационный порт п.
ON COM(n) GOSUB метка
• п — числовое выражение, номер коммуникационного порта;
• метка — первая строка подпрограммы обработки события.
Если ваша программа получает данные через асинхронный
коммуникационный адаптер, то используйте опцию /С при за-
пуске QuickBASIC или компиляции для установления размера
буфера данных.
СОМ(п)
СОМ(п) — оператор отслеживания событий, который вклю-
чает, выключает или приостанавливает отслеживание коммуни-
кационной активности порта ввода/вывода.
COM(n) ON COM(n) OFF COM(n) STOP
• n — номер коммуникационного порта, 1 или 2.
COM ON включает отслеживание порта. Если символ при-
бывает в СОМ-порт, выполняется подпрограмма, указанная опе-
ратором ON COM. COM OFF выключает отслеживание.
COM STOP приостанавливает отслеживание порта до вы-
полнения оператора COM ON. Все события запоминаются в бу-
фере и обрабатываются после следующего оператора COM ON.
ON KEY(n)
ON KEY(n) — оператор отслеживания событий, передающий
управление подпрограмме при нажатии клавиши п.
ON KEY(n) GOSUB метка
• п — целое выражение, номер функциональной или пользова-
тельской клавиши;
• метка — первая строка подпрограммы обработки данного со-
бытия.
Клавиши обрабатываются в следующем порядке:
1. Клавиши переключения вывода на принтер.
2. Функциональные и клавиши управления курсором.
3. Клавиши, определенные пользователем.
Оператор ON KEY может обрабатывать любую клавишу, за
исключением {CTRL-BREAK} или {CTRL-ALT-DEL}.
Старайтесь не использовать оператор ON KEY (и другие опе-
раторы отслеживания событий) без особой необходимости. Дело в
том, что при компиляции программы, в которой содержится от-
слеживание событий, BASIC расставляет запрос к своей внутрен-
ней процедуре отслеживания после каждого оператора программы,
что приводит к значительному замедлению работы программы,
увеличению размеров .ЕХЕ файла, и, при большом размере исход-
ного текста может не всегда правильно срабатывать.
В большинстве случаев применения отслеживания событий
связано к контролем нажатия клавиш управления (функци-
314
ональных, клавиш управления курсором и прочих), что значи-
тельно проще и удобнее может быть реализовано с помощью
оператора INKEY$ в режиме опроса клавиатуры.
Пример 1: Отслеживание нажатия клавиши {F1} с помощью
оператора ON KEY. Если вы хотите, чтобы Ваша програм-
ма выполнялась быстро и безошибочно, избегайте таких
приемов.
DEFINT A-Z
'Устанавливаем отслеживания
ON KEY(l) GOSUB Keytrap
'Разрешаем его
KEYA) ON
CLS
PRINT "Для выхода нажмите клавишу F10"
DO:
DO: a$ = INKEY$: LOOP WHILE a$ = " "
IF LEN(a$) > 1 THEN
kod = ASC(RIGHT$(a$, 1))
END IF
LOOP WHILE kod о 68
END
Keytrap:
BEEP: PRINT "Обработка клавиши Fl"
RETURN
Пример 2: Отслеживание нажатия клавиши {Fl} с помощью
оператора INKEY$. Выделяйте фрагмент, отвечающий за
чтение кода нажатой клавиши, в отдельную процедуру.
DEFINT A-Z
DECLARE SUB ink (kod%)
CLS
PRINT "Для выхода нажмите клавишу F10"
DO
'процедура чтения кода клавиши
ink kod
IF kod = 59 THEN BEEP: PRINT "Отработка клавиши Fl"
IF kod =68 THEN EXIT DO
LOOP
END
SUB ink (kod)
DO
DO: a$ = INKEY$: LOOP WHILE a$ = ""
IF LEN(a$) > 1 THEN
kod = ASC(RIGHT$(a$, 1)): EXIT SUB
END IF
LOOP
END SUB
315
KEY
KEY — оператор ввода/вывода, присваивающий символьные
строки функциональным клавишам, а также показывающий те-
кущий статус функциональных клавиш.
KEY LIST
Выводит значения F-клавиш.
KEY {ON I OFF}
Включает/выключает строку статуса F-клавиш внизу экрана.
KEY n, строка
Присваивает значение F-клавише.
• п — номер функциональной клавиши, выбираемый из списка:
1-10 Функциональные F1-F10
11 Стрелка вверх
12 Стрелка влево
13 Стрелка вправо на расширенной клавиатуре
14 Стрелка вниз
15-25 Пользовательские
30-31 Функциональные F11-F12
• строка — для всех п, исключая 15—25, это строка, вводимая
программой при нажатии данной клавиши. До 15 символов.
Для п = 15—25, строка имеет следующий вид:
СШ$(флаг) + CHR$ (скан-код)
Присвоение пустой строки клавише выключает ее. Мож-
но посмотреть значения клавиш путем KEY ON, KEY OFF и
KEY LIST:
316
Опе-
ратор
KEY
ON
KEY
OFF
KEY
LIST
Действие
Показывает 6 первых символов значений F-клавиш в
нижней строке экрана
Стирает демонстрацию F-клавиш из нижней строки,
делая ее свободной для использования. Не стирает зна-
чения клавиш
Показывает 15 символов всех определенных операто-
ром KEY клавиш
Если подобная клавиша нажата, эффект от нее такой же, как
и от набора данной строки с клавиатуры. Их могут читать опера-
торы INPUTS, INPUT и INKEYS.
Пример:
' Присвоение значений программируемым клавишам.
CLS
KEY 4, "MENU" + CHR$A3) 'Присвоение F4
KEY LIST KEY 4, "" 'Отмена F4. KEY LIST
'Присвоение клавишам Fl - F3 значений опций меню.
CLS
DIM KeyText$C)
DATA Добавить, Стереть, Выход
FOR i = 1 TO 3
READ KeyText$(i)
KEY i, KeyText$(i) + CHR$A3)
NEXT I
1 Вывод меню.
PRINT " Главное Меню" : PRINT
PRINT " Добавить (Fl)"
PRINT " Стереть (F2)"
PRINT " Выход (F3)" : PRINT
'Выбор опции из меню.
DO
LOCATE 7,1 : PRINT SPACE$E0)
LOCATE 7,1 : INPUT " Ваш выбор: ", R$
SELECT CASE R$
CASE "Добавить", "Стереть"
LOCATE 10,1 : PRINT SPACE$A5);
LOCATE 10,1 : PRINT R$;
CASE "Выход"
EXIT DO
CASE ELSE
LOCATE 10,1
PRINT "Введите слово или нажмите клавишу."
END SELECT
LOOP
317
KEY(n)
KEY(n) — оператор отслеживания операций, включающий,
выключающий или останавливающий отслеживание указанной F-
клавиши.
KEY(n) ON
KEY(n) OFF
KEY(n) STOP
• KEY(n) ON — включает отслеживание клавиши оператором
ON KEY;
• KEY(n) OFF — выключает отслеживание. Если клавиша была
уже нажата, она не запоминается;
• KEY(n) STOP — приостанавливает отслеживание. Если кла-
виша была нажата, она запоминается, и после включения опе-
ратором KEY(n) ON выполняется действие, связанное с дан-
ной клавишей оператором ON KEY.
Аргумент п описан выше, в комментарии к оператору KEY.
Здесь дано описание флагов клавиатуры и скан-кодов, необходи-
мых для отслеживания клавиш, определенных пользователем.
Флаги клавиатуры имеют следующие значения:
&Н00 нет флага
&Н01-&Н03 SHIFT
&Н04 CTRL
&Н08 ALT
&Н20 NUMLOCK
&H40 CAPSLOCK
&H80 добавочные клавиши расширенной клавиатуры
Можно сложить значения флагов для одновременно нажатых
клавиш. Значение флага &Н12 означает, что будет тестироваться
нажатие CTRL+ALT.
Так как отслеживание клавиш подразумевает, что левый и
правый SHIFT — это одно и то же, можно использовать флаги
&Н01, &Н02 или &Н03 для указания клавиши SHIFT.
318
Пример: отслеживание клавиши "Стрелка вниз" и комбинации
{CTRL-s}
i = О
CLS
PRINT "Клавиша {DOWN} - конец работы "
KEY 15, CHR$(&H04) + CHR$(&Hlf)
KEYA5) ON 'Отслеживание CTRL+s.
KEYA4) ON 'Отслеживание DOWN.
ON KEYA5) GOSUB Keytrap
ON KEYA4) GOSUB Endprog
DO: LOOP 'Бесконечный цикл
Keytrap: 'Подсчет числа нажатий {CTRL-s}
i = i + 1
RETURN
Endprog:
PRINT "Клавиша {CTRL-s} нажата"; i; "раз"
END
RETURN
ON PEN
ON PEN — оператор отслеживания событий, передающий управ-
ление подпрограмме при получении сигнала от светового пера.
ON PEN GOSUB метка
• метка — первая строка подпрограммы обработки события.
PEN ON, PEN OFF, PEN STOP
PEN ON, PEN OFF, PEN STOP — операторы отслеживания
событий, включающие, выключающие и приостанавливающие
отслеживание светового пера.
• Оператор PEN ON включает отслеживание светового пера коман-
дой ON PEN. По умолчанию перо выключено. Событие происхо-
дит при нажатии пером экрана или нажатии специального кольца
на световом пере. Оператор PEN ON должен быть выполнен пе-
ред всеми вызовами функций чтения пера, иначе возникает
ошибка "Illegal function call" (Неверный вызов функции);
319
• Оператор PEN OFF выключает отслеживание светового пера;
• Оператор PEN STOP приостанавливает отслеживание; при
этом все, что касается светового пера запоминается и выпол-
няется при включении отслеживания.
Для ускорения выполнения программы световое перо должно
быть выключено оператором PEN OFF, если не нужно его отсле-
живание. Световое перо требует, как минимум, адаптера IBM
CGA. В настоящее время световое перо практически не использу-
ется в связи с повсеместным распространением "мышей" и трек-
болов1 . См. Глава 12, раздел "Интерфейс с драйвером мыши".
ON PLAY(n)
ON PLAY(n) — оператор отслеживания событий, передаю-
щий управление подпрограмме по окончании звучания нот.
ON PLAY(лимит) GOSUB метка
• лимит — целое выражение, минимальное количество нот, зву-
чащих в фоновом режиме (от 1 до 32);
• метка — первая строка подпрограммы, принимающей управление.
Учтите следующие моменты:
1. Обработка не производится, если фоновое исполнение музыки
не закончилось;
2. Если лимит — достаточно большое число, это замедляет прог-
рамму.
PLAY
PLAY — оператор отслеживания событий, возвращающий
число нот, находящихся в фоновом музыкальном буфере.
PLAY(n)
• п — любой числовой параметр.
1 "Мышь", лежащая на спине, с большим шариком, который двигают рука-
ми.
320
PLAY(n) возвращает 0, если музыка исполняется в основном
(не фоновом) режиме.
PLAY ON, PLAY OFF, PLAY STOP
PLAY ON, PLAY OFF, PLAY STOP — операторы отслежива-
ния событий, включающие, выключающие и приостанавлива-
ющие отслеживание звучания музыки.
• PLAY ON — включает отслеживание оператором ON PLAY;
• PLAY OFF — выключает отслеживание. Если событие насту-
пило, оно не запоминается;
• PLAY STOP — приостанавливает отслеживание. Если событие
наступило, оно запоминается, и оператор ON PLAY выполня-
ется при включении отслеживания оператором PLAY ON.
Эти операторы используются совместно с оператором ON
PLAY для отслеживания событий музыкального буфера.
При возникновении события выполняется подпрограмма,
указанная оператором ON PLAY; при этом автоматически отсле-
живание приостанавливается во избежание рекурсивного вызова
подпрограммы-обработчика (что не должно иметь места). При
выходе из подпрограммы путем RETURN, отслеживание возоб-
новляется.
Пример: программа играет музыку вызывая подпрограмму
обработки события. Событие наступает, когда в музы-
кальном буфере осталось менее 3 нот.
ON PLAYC) GOSUB Background
1 Включение отслеживания.
PLAY ON
1 Строка, содержащая мелодию.
Lizzie$ = "оЗ L8 Е D+ Е D+ Е о2 В оЗ D С L2 о2 А"
1 Мелодия играется в первый раз.
PLAY "MB X" + VARPTR$(Lizzie$)
' Продолжать до нажатия клавиши.
LOCATE 2,1: PRINT "Нажмите клавишу для остановки"
DO WHILE INKEY$ = "": LOOP
END
' Подпрограмма.
Background:
' Счетчик вызова подпрограммы.
Count% = Count% + 1
LOCATE 1, 1
321
PRINT "Подпрограмма вызвана "; Count%; "раз"
1 Исполнить музыку еще раз как фоновую.
PLAY "MB X" + VARPTR$(Lizzie$)
RETURN
ON STRIG(n)
ON STRIG(n) — оператор отслеживания событий, указыва-
ющий на подпрограмму обработки нажатия кнопки джойстика с
триггером п.
ON STRIG(n) GOSUB метка
• n — номер триггера:
О = нижняя кнопка 1-го джойстика
2 = нижняя кнопка 2-го джойстика
4 = верхняя кнопка 1-го джойстика
6 = верхняя кнопка 2-го джойстика
• метка — первая строка подпрограммы обработки нажатия кно-
пки джойстика.
ON TIMER(n)
ON TIMER(n) — оператор отслеживания событий. Указывает
на подпрограмму, которая выполняется по прошествии п секунд.
ON TIMER(n) GOSUB метка
• n — числовое выражение от 1 до 86400 — число секунд интер-
вала времени;
• метка — первая строка подпрограммы обработки временного
события.
TIMER ON, TIMER OFF, TIMER STOP
TIMER ON, TIMER OFF, TIMER STOP - операторы отсле-
живания событий, включающие, выключающие, приостанавли-
вающие отслеживание таймера.
• TIMER ON — включает отслеживание таймера оператором
ON TIMER. Пока отслеживание включено, проверка наступ-
ления указанного времени делается после каждого оператора.
322
Если время наступило, выполняется подпрограмма обработки
события, указанная оператором ON TIMER;
• TIMER OFF — выключает отслеживание. Если событие имело
место, оно не запоминается для оператора TIMER ON;
• TIMER STOP — приостанавливает отслеживание. Если собы-
тие произошло, то оно запоминается, и оператор ON TIMER
запускает свою подпрограмму при включении отслеживания
оператором TIMER ON.
Пример: программа рисует случайным образом выбранную
ломаную линию каждые 3 секунды.
SCREEN 9
DEFINT A-Z
DIM Х(б), YF)
TIMER ON 'Включение отслеживания
ON TIMERC) GOSUB Drawpoly
PRINT "Нажмите любую клавишу для остановки"
INPUT "Нажмите {ENTER} для начала ...",Test$
DO: LOOP WHILE INKEY$ = ""
END
Drawpoly:
CLS
n = INTE * RND + 2)'Случайное число от 2 до б.
FOR i = О ТО п
X(i) = INT(RND * 649)'Координаты вершин ломаной
линии.
Y(i) = INT(RND * 349)
NEXT
PSET (X(n), Y(n))
FOR i = 0 TO n
LINE -(X(i), Y(i)), 15
NEXT
RETURN
ON UEVENT
ON UEVENT — оператор отслеживания событий, указываю-
щий на обработчик пользовательского события.
ON UEVENT GOSUB метка
• метка — первая строка подпрограммы обработки пользова-
тельского события.
323
Обычно пользовательским событием служит аппаратное пре-
рывание. Это дает событиям, определенным пользователем, те же
возможности, что и событиям типа COM, KEY, и др. Если эти
события определены оператором ON, они обрабатываются как
прерывания. Поэтому программе не обязательно следить за каж-
дым своим шагом: при возникновении подобного события она
передает управление подпрограмме-обработчику.
Необходимо вставить в программу три фрагмента для уста-
новки пользовательского события:
1. Процедуру сервиса прерывания.
2. Процедуру инициализации для установки адреса сервисной
процедуры в таблице векторов прерываний.
3. Подпрограмму обработки данных, собранных сервисной про-
цедурой.
Если процедура инициализации перехватит прерывание, ис-
пользуемое другой сервисной процедурой, ее адрес должен быть
восстановлен перед завершением Вашей программы.
Обычно эти процедуры пишутся на языке ассемблера. Мож-
но использовать другие языки, позволяющие генерировать сер-
висные процедуры для обработки прерываний.
Таким образом, существует четыре шага для генерации
пользовательского события:
1. Написать подпрограмму обработки события на BASIC.
2. Выполнить оператор ON UEVENT GOSUB для определения
подпрограммы-обработчика.
3. Выполнить оператор UEVENT ON для включения отслеживания.
4. Вызвать процедуру инициализации прерывания для установки
адреса сервисной процедуры в таблице векторов прерываний.
При возникновении прерывания управление передается сер-
висной процедуре, которая собирает и размещает необходимые
данные в памяти. Далее эта процедура вызывает процедуру
SetUEvent, которая устанавливает флаг, распознаваемый про-
граммой перед переходом к следующему оператору (или метке,
если программа компилирована с ключом /W, а не /V). Когда
флаг установлен, управление передается подпрограмме-обработ-
чику, определенному ON EVENT GOSUB.
Процедура SetUEvent является частью BASIC и автоматичес-
ки включается в компилируемые модули или при запуске Quick
BASIC с опцией /L в командной строке. Сервисная процедура
324
должна вызвать SetUEvent; это единственный способ, позволяю-
щий вашей программе обработать событие.
SetUEvent — не функция; она не возвращает значения в BASIC.
UEVENT ON, UEVENT OFF, UEVENT STOP
UEVENT ON, UEVENT OFF, UEVENT STOP - операторы от-
слеживания событий, включающие, выключающие и приостанавли-
вающие отслеживание события, определенного пользователем.
Действия операторов UEVENT аналогичны действиям других
операторов отслеживания событий. При выполнении UEVENT
ON отслеживание включается и при возникновении события уп-
равление передается подпрограмме-обработчику. При выпол-
нении UEVENT OFF отслеживание выключается и все события
игнорируются. При выполнении UEVENT STOP отслеживание
приостанавливается. Все события запоминаются и обрабатыва-
ются подпрограммой при выполнении оператора UEVENT ON.
Пример:
ON UEVENT GOSUB Event1
UEVENT ON
INPUT "Введите число "; a
IF a = 5 THEN CALL SetUevent
END
Event1:
PRINT "Обработка события"
RETURN
Обработка ошибок и трассировка
ON ERROR
ON ERROR — оператор обработки ошибок, указывающий
начало подпрограммы обработки ошибок, включающий отслежи-
вание ошибок и передающий управление подпрограмме при их
возникновении.
ON ERROR GOTO метка I RESUME NEXT
• метка — первая строка подпрограммы обработки ошибок;
• RESUME NEXT — указывает, что при возникновении ошибок
управление передается на следующий оператор.
325
Если обработчик не найден, выдается сообщение об ошибке
и программа останавливается. Сообщение об ошибке зависит от
типа ошибки. Коды ошибок приведены в Приложении 5 "ASCII-
коды, скан-коды и коды ошибок".
Метка 0 выключает отслеживание ошибок. Обработчик ошибок
не может быть процедурой SUB или FUNCTION или функцией
DEF FN, а только обычным блоком с меткой.
Пример: реакция на ошибки при чтении файла.
ON ERROR GOTO Handler
OpenFile:
INPUT "Введите имя файла"; FileSpec$
IF FileSpec$ = "" THEN END
OPEN FileSpec$ FOR INPUT AS #1
PRINT "Первые 5 строк файла "; FileSpec$;" :" : PRINT
FOR I = 1 TO 5
LINE INPUT #1, Temp$
PRINT Temp$
NEXT
PRINT : INPUT "Это правильный файл Y/N "; R$
1 Установим ошибку 200 при ответе N.
IF UCASE$(R$) <> "Y" THEN ERROR 200
END
Handler:
Number = ERR
1 Если программа генерирует ошибку "файл не най-
ден" ,
1 выводим специальное сообщение.
IF Number =53 THEN
CLOSE #1
PRINT "Файл не найден."
PRINT "Введите новое имя или нажмите"
PRINT "{ENTER}, чтобы закончить программу."
RESUME OpenFile
' Реакция на ответ N.
ELSEIF Number = 200 THEN
CLOSE #1
RESUME OpenFile
ELSE
' Другая ошибка. Остановка программы.
ERROR Number
ON ERROR GOTO 0
END IF
326
ERDEV и ERDEV$
ERDEV и ERDEV$ — функции обработки ошибок, выдающие
информацию об устройстве, в котором произошла ошибка.
ERDEV
ERDEV$
• ERDEV — целая функция, возвращающая код ошибки с пос-
леднего устройства, в котором произошла ошибка;
• ERDEV$ — символьная функция, возвращающая имя устрой-
ства, в котором произошла ошибка.
Если ошибка произошла на именованном устройстве (напри-
мер принтер), то ERDEVS содержит 8-байтовое имя устройства.
Если устройство не имеет имени, то 2-байтовое имя блока (А:, В:
и т. д.).
Значение ERDEV содержит информацию DOS об ошибке.
Нижние 8 бит (первый байт) содержат код ошибки DOS, от 0 до
12. Верхние 8 бит (второй байт) содержат биты 15, 14, 13, XX, 3,
2, 1 и 0, являющиеся атрибутом устройства. XX указывает, что
биты всегда нулевые.
Пример: попытка чтения несуществующего файла или чте-
ния файла с отсутствующего диска.
DEFINT A-Z
' Указание на обработчик.
ON ERROR GOTO ErrorHandler
1 Открытие файла, которого нет.
OPEN "A:JUNK.DAT" FOR INPUT AS #1
END
' Блок обработки ошибок.
' Выводит значения ERDEV и ERDEV$.
' Производится остановка программы.
ErrorHandler:
PRINT "ERDEV = "; ERDEV
PRINT "Устройство "; ERDEV$
ON ERROR GOTO 0
Вывод: при отсутствии диска А.
327
ERDEV = 2
Устройство А:
ERL и ERR
ERL и ERR — функции обработки ошибок, возвращающие
информацию о возникшей ошибке.
ERR
ERL
• ERR —функция, возвращающая код ошибки A — 255);
• ERL — функция, возвращающая номер строки, где возникла
ошибка.
Функция ERL возвращает только номер строки, а не ее мет-
ку. Если программа не имеет номеров строк, ERL возвратит 0.
ERROR
ERROR — оператор обработки ошибок, симулирующий воз-
никновение ошибки и позволяющий пользователю тестировать
программу путем задания ошибки по ее коду.
ERROR целое_выражение
• целое_выражение между 1 и 255 — код ошибки.
Обработчик ошибок должен находится в главном модуле ва-
шей программы1. Если вам нужно отрабатывать собственные
коды ошибок, то используйте значения большие чем 255.
RESUME
RESUME — оператор обработки ошибок, продолжающий
выполнение программы после обработки ошибочной ситуации.
RESUME [0]
RESUME NEXT
1 В Microsoft BASIC PDS 7 1 возможно также и отслеживание локальных
ошибок при помощи оператора ON LOCAL ERROR GOTO .. При этот обработ-
чик ошибок размещается в процедуре или функции.
328
RESUME метка
Оператор
RESUME [0]
RESUME
NEXT
RESUME
метка
Действие
Передает управление тому оператору, который
вызвал ошибку. Оператор должен находиться в
главном модуле, там же где и обработчик ошибок
На следующий оператор после вызвавшего
ошибку
На оператор с данной меткой.
Оператор RESUME, находящийся не в подпрограмме обра-
ботки ошибок, вызывает ошибку "RESUME without error" (RE-
SUME без ошибки). Если обработчик не имеет в конце RESUME,
то выдается сообщение "No RESUME" (Нет RESUME).
Пример: обработка наличия отрицательного аргумента
при вызове функции извлечения квадратного корня SQR.
CLS
ON ERROR GOTO Handler
FOR i = 4 TO -2 STEP -1
PRINT l, SQR(i)
NEXT
END
Handler:
PRINT "Аргумент отрицательный"
RESUME NEXT
Вывод:
4 2
3 1.7320509
2 1.4142136
1 1
0 0
-1 Аргумент отрицательный
-2 Аргумент отрицательный
TRON и TROFF
TRON и TROFF — операторы трассировки выполнения
программы.
329
TRON
TROFF
В среде QuickBASIC выполнение оператора TRON имеет та-
кой же эффект, как выбор опции "Trace On" ("Трассировка
включена") из МЕНЮ "DEBUG" (ОТЛАДКА) - каждый опера-
тор высвечивается на экране. Оператор TROFF выключает трас-
сировку.
Операторы TRON и TROFF показывают номера строк в том
случае, если программа скомпилирована с опцией Debug (/D).
11
СВЯЗЬ С DOS (*)
Передача управления другой программе
CHAIN
CHAIN — оператор, передающий управление другой про-
грамме ("по цепочке").
CHAIN имя_файла
• имя_файла — символьное выражение, имя программы, кото-
рой передается управление. Может включать путь длиной до
127 символов.
Программы, работающие внутри среды QB должны иметь
расширение .BAS (по умолчанию). Нельзя передавать управление
файлам типов .СОМ и .ЕХЕ;
Программы, имеющие расширение ЕХЕ могут передавать
управление файлам .СОМ и .ЕХЕ, но не исходным файлам на
BASIC (с расширением .BAS).
Вы можете переслать переменные между программами, ис-
пользуя оператор COMMON. Если вы компилируете программу
вне среды QB в автономный ЕХЕ файл, то полученная программа
не будет поддерживать передачу значений переменных при по-
мощи COMMON.
Существует три способа переслать переменные между "це-
почными" программами вне среды QB:
1. Компилировать программу с опцией "Requiring BRUN45.EXE"
(Требуется BRUN45.EXE);
2. Передавать параметры через временный дисковый файл;
3. Использовать межпрограмный 16-байтный буфер. Этот буфер
специально предназначен для обмена сообщениями между
программами:
'Файл programl.bas посылает сообщение Messages
DIM Message$ AS STRING * 16
Message$ = "Тестовая строка"
DEF SEG = 0
FOR i = 0 TO 15
POKE &H4F0 + i, ASC(MID$ (message$, i + 1. D)
NEXT i
DEF SEG
CHAIN "program2"
END
'Файл program2.bas считывает сообщение Message$:
DIM Message$ AS STRING * 16
DEF SEG = 0
FOR i = 0 TO 15
MID$(messages, i + 1, 1) = CHR$(PEEK(&H4F0 + i))
NEXT i
DEF SEG
END
Действие CHAIN и RUN в основном идентично. Отличия в
том, что RUN закрывает все открытые файлы и не поддерживает
блоки COMMON. Если программы скомпилированы как авто-
номные ЕХЕ файлы, то открытые файлы перед вызовом другой
программы должны быть закрыты оператором CLOSE.
SHELL
SHELL — оператор связи с DOS, применяемый для выхода
из программы, запуска файла типа *.СОМ, *.ЕХЕ, *.ВАТ или ко-
манды DOS, и возвращения в программу (временный выход в
DOS).
SHELL [команда]
• если все аргументы опущены, DOS загрузит новую копию
C0MMAND.COM, и можно вводить команды на приглаше-
ние DOS;
332
• команда — символьное выражение, содержащее имя про-
граммы для ее запуска или команду DOS, включая все необ-
ходимые параметры.
Любые файлы типа *.СОМ, *.ЕХЕ, *.ВАТ или функции DOS
могут быть исполнены при вызове оператора SHELL, так как он со-
здает "порожденный процесс". Такой процесс выполняется путем
загрузки новой копии COMMAND.COM с опцией /С. Эта опция
позволяет передать порожденному процессу значение командной
строки. Она также позволяет переопределить стандартный ввод или
вывод при выполнении таких команд, как DIR, PATH и SORT.
Если в командной строке нет расширений файла, COM-
MAND.COM ищет сначала файл типа *.СОМ, затем *.ЕХЕ, а по-
том *.ВАТ. Если сам файл COMMAND.COM не найден, SHELL
выдаст сообщение об ошибке "File not found" (Файл не найден).
Но если C0MMAND.COM не найдет файл, указанный в команд-
ной строке, то BASIC не выведет сообщения об ошибке.
Любой текст, отделенный от имени программы хотя бы од-
ним пробелом, воспринимается как строка параметров, пересы-
лаемых программе.
BASIC не освобождает память при исполнении порожденно-
го процесса. При завершении процесса основная программа про-
должается.
Не загружайте таким образом резидентные программы. При
возврате в среду QB область памяти, занятая резидентной про-
граммой окажется занятой, что может привести к фрагментации
оперативной памяти, ее нехватке, и сбоям в работе самого
BASIC. Для возврата в программу введите команду EXIT.
Пример: простой оператор SHELL подгружает новую копию
командного процессора C0MMAND.COM.
SHELL
Novell DOS 7
Copyright (с) 1976, 1993 Novell, Inc.
All rights reserved.
C:\QB45>_
RUN
RUN — оператор связи с DOS, перезапускающий программу,
находящуюся в памяти или исполняющий указанную программу.
333
RUN [номер_строки I файл]
• номер_строки — числовая метка, указывающая строку, с ко-
торой начинается перезапуск. Если номер строки не указан,
исполнение начинается с первой строки;
• файл — символьное выражение, указывающее программу, ко-
торую надо загрузить и запустить. Текущая программа удаля-
ется из памяти.
Строка, с которой начинается перезапуск, должна находить-
ся на модульном уровне. Поэтому, оператор RUN в процедурах
SUB или FUNCTION должен указывать на номер строки в мо-
дульном коде.
Если строка не указана, перезапуск начинается с первой ис-
полняемой строки в главном модуле. Номер строки может быть
только числовой меткой.
Вы можете опустить расширение файла, если нужно загру-
зить программу. В среде QB по умолчанию загружается файл
.BAS, а в откомпилированной программе — файл .ЕХЕ, но не
обязательно написанный на языке BASIC.
Если вызванная программа закончила работу, управление не
передается в исходную программу. В среде QB управление пе-
редается среде, а в DOS — операционной системе.
RUN закрывает все файлы и очищает память перед загрузкой
программы. Используйте оператор CHAIN, если вы хотите оста-
вить файлы открытыми.
Пример:
10 А = 9
20 В = 7
30 С = 5
40 D = 4
50 PRINT А, В, С, D
60 IF A = 0 THEN 70 ELSE RUN 20
70 IF В = 0 THEN 80 ELSE RUN 30
80 IF С = 0 THEN 90 ELSE RUN 40
90 IF D = 0 THEN END ELSE RUN 50
Вывод:
9
0
0
0
0
7
7
0
0
0
5
5
5
0
0
4
4
4
4
0
334
Работа с датой и временем
DATES (функция)
DATES — функция, возвращающая строку, содержащую те-
кущую системную дату.
DATE$
• возвращается 10-символьная строка в форме ММ-ДД-ГГТТ
ММ - месяц @1-12)
ДД - день @1-31)
ГГГГ - год A980-2099)
Пример:
PRINT DATE$
10-30-1967
DATES (оператор)
DATES — оператор, устанавливающий текущую систем-
ную дату.
DATE$ = символьное_выражение
• символьноевыражение может иметь одну из следующих форм:
мм-дд-гг
ММ-ДД-ГГГГ
мм/дд/гг, мм/дд/гггг
где:
• ММ — месяц
• ДД — день
• ГГ или ГГГГ — год
335
Пример:
PRINT "Введите дату (по умолчанию 1994 год)."
INPUT " Месяц: ",Month$
INPUT " Дата: ",Day$
INPUT " Год: ",Year$
IF Year$ = "" THEN Year$ = "94"
DATE$ = Month$ + "-" + Day$ + "-" + Year$
TIMES (функция)
TIMES — функция, возвращающая текущее системное время.
Т1МЕ$
• возвращается 8-символьная строка в форме ЧЧ:ММ:СС
ЧЧ - часы @0-23)
ММ - минуты @0-59)
СС - секунды @0-59)
Пример: преобразование 24-часового представления вре-
мени в 12-часовое.
Т$ = Т1МЕ$
Hr = VAL(T$)
IF Hr < 12 THEN Ampm$ = " AM" ELSE Arapm$ = " PM"
IF Hr > 12 THEN Hr = Hr - 12
PRINT "Текущее время "; STR$(Hr); RIGHT$(T$,6); Ampm$
Текущее время 11:26:31 AM
TIME$ (оператор)
TIMES — оператор, устанавливающий текущее системное
время.
Т1МЕ$ = символьное_выражение
• символьное_выражение — может иметь одну из форм:
ЧЧ
ЧЧ:ММ
ЧЧ:ММ:СС
336
где:
• ЧЧ — часы
• ММ — минуты
• СС — секунды
Пример: установка текущего времени 8:00.
Т1МЕ$ = 8:00:00"
TIMER
TIMER — функция, возвращающая число секунд, прошед-
ших с полуночи.
TIMER
Обычно используется с оператором RANDOMIZE для уста-
новки начального значения генератора случайных чисел.
Пример: поиск первых простых чисел от 3 до 10000. Ис-
пользуется принцип "Решето Эратосфена". Функция TIMER
применяется для подсчета времени, затраченного на по-
иск .
DEFINT A-Z
CONST Markit = -1
DIM Mark(lOOOO)
CLS
Start! = TIMER
Num = 0
FOR n = 3 TO 10000 STEP 2
IF NOT Mark(n) THEN
'Если вам нужно вывести числа, удалите комментарий
'PRINT n.
Delta = 2 - п
FOR i = 3 - n TO 10000 STEP Delta
Mark(i) = Markit
NEXT
Num = Num + 1
END IF
NEXT
Finish! = TIMER
PRINT
PRINT "Поиск продолжался"/Finish! - Start!;
PRINT "сек. Найдено"; Num; "чисел."
END
Вывод:
Поиск продолжался .109375 сек. Найдено 1228 чисел.
337
Работа с файловой системой
CHDIR
CHDIR — оператор, использующий DOS для смены текущей
директории.
CHDIR имя_пути
• имя_пути — символьное выражение, определяющее директо-
рию, которая должна стать текущей по умолчанию. Имя пути
не должно превышать 64 символов.
Например:
[диск:][\]директория[Хдиректория]...
CHDIR отличается от команды DOS CHDIR:
• оператор не может быть сокращен до CD;
• нет форм оператора, возвращающих значение текущей дирек-
тории1 .
CHDIR меняет директорию, но не меняет диск.
Примеры:
' Переход в директорию \QB\BAS на текущем диске.
CHDIR "\QB\BAS"
' Смена текущей директории на диске В.
' Переход на диск В не осуществляется.
CHDIR "В:USERS"
1 Операторы работы с файловой системой значительно расширены в Microsoft
BASIC PDS. В нем значительно проще стало переходить на другой диск
(CHDRIVE), получать имя текущего каталога (CURDIRS) и список файлов за-
данного каталога (DIRS).
338
MKDIR
MKDIR — оператор, использующий DOS для создания но-
вой директории.
MKDIR путь
• путь — символьное выражение, указывающее имя и местопо-
ложение создаваемой директории. Его длина не должна пре-
вышать 128 символов.
Данный оператор работает аналогично команде DOS MKDIR,
но не допускается сокращать его до MD.
Пример:
CLS
PRINT "Эта программа создает директорию MONTHS,"
PRINT "а затем создает файл в этой директории."
PRINT
MKDIR "MONTHS"
INPUT "Файл "; File$
IF File$ = "" THEN END
OPEN "MONTHSV + File$ FOR OUTPUT AS #1
PRINT "Создан файл "; File$; " в директории MONTHS."
CLOSE #1
RMDIR
RMDIR — оператор связи с DOS, удаляющий существующую
директорию.
RMDIR путь
• путь — символьное выражение, определяющее удаляемую ди-
ректорию, не более 128 символов.
Удаляемая директория должна быть пустой и существовать,
иначе выдаются сообщения об ошибке "Path not found" (Путь не
найден) или "Path/File access error" (Ошибка доступа к пути/
файлу).
339
RMDIR аналогичен команде DOS. Однако, его нельзя сокра-
тить до RD как в DOS.
Пример:
CHDIR "C:\SALES\TEMP" 'Переходим в данную директорию
KILL " * . * " 'Стираем все файлы
CHDIR " . . " 'Переходим в старшую директорию
RMDIR "TEMP" 'Стираем данную директорию
FILES
FILES — оператор связи с DOS, выдающий на экран имена
файлов на указанном диске в указанной директории.
FILES [спецификация]
• спецификация — символьная переменная или константа, со-
держащая имя файла, путь, диск. Можно использовать шабло-
ны DOS (? или *).
Если аргумент опущен, то на экран дисплея выдается список
файлов текущей директории.
Примеры:
'Показывает все файлы в текущей директории.
FILES
1 Показывает все файлы с расширением BAS.
FILES "*.BAS"
'Показывает все файлы на диске В.
FILES "В:*.*"
1 Эквивалентно "В:*.*".
FILES "В:11
'Показывает все файлы .BAS, имена которых имеют
'пять букв и начинаются символами "TEST".
FILES "TEST?.BAS"
'Если SALES — директория, то показывает все
1 файлы в' этой директории.
'Если SALES — имя файла в текущей директории,
'показывает только файл SALES.
FILES "\SALES"
340
KILL
KILL — оператор, использующий DOS для стирания файла.
KILL файл
• файл — символьное выражение, указывающее файл, который
нужно стереть. Может содержать путь.
Соответствует команде DOS ERASE (DEL). Используется для
всех типов файлов (кроме скрытых и только для чтения). Сим-
вольное выражение может содержать шаблоны DOS: ? или *.
Для стирания директорий используйте команду RMDIR. По-
пытка стереть открытый файл приведет к ошибке и сообщению
"File already open" (Файл уже открыт).
Пример: стирание файлов.
'Стирает все файлы .DAT, имена которых состоят
1 из 6 букв и начинаются символами DATA1.
KILL "DATA17.DAT"
'То же, но стираются файлы с любыми расширениями.
KILL "DATA1.*"
'Стирает все файлы .DAT в директории GREG.
KILL "\GREG\*.DAT"
NAME
NAME — оператор, использующий DOS для изменения име-
ни файла.
NAME старое_имя AS новое_имя
• старое_имя — символьное выражение, имя существующего
файла;
• новоеимя — символьное выражение, имя еще не существую-
щего файла.
Эти аргументы могут содержать путь. Если оба аргумента
имеют разные пути, данный оператор перемещает файл и пере-
именовывает его. Оба файла должны находиться на одном диске,
341
в противном случае выдается сообщение об ошибке "Rename
across disks" (Перемещение между дисками).
Оператор соответствует команде DOS RENAME. NAME мо-
жет переместить файл в другую директорию, но не может пере-
местить всю директорию.
Использование NAME для открытого файла приведет к со-
общению об ошибке "File already open" (Файл уже открыт).
Пример: переименование файла README.DOC.
CLS
'Переименование README.DOC в READMINE.DOC
NAME "README.DOC" AS "READMINE.DOC"
FILES
PRINT
PRINT "README.DOC переименован в READMINE.DOC"
PRINT "Нажмите любую клавишу"
DO: LOOP WHILE INKEY$ = ""
1 Переименование обратно в README.DOC
NAME "READMINE.DOC" AS "README.DOC"
FILES
PRINT
PRINT "README.DOC восстановлен"
Работа с окружением DOS
COMMANDS
COMMANDS — функция, возвращающая значение команд-
ной строки DOS, заданной при запуске программы.
COMMAND$
Функция COMMANDS возвращает полную командную строку,
введенную после имени вашей программы, включая параметры оп-
ций. COMMANDS удаляет все начальные пробелы из данной строки
и преобразует все буквы в заглавные (верхний регистр).
COMMANDS может быть использована .ЕХЕ-файлами, а в
среде QB она может быть задана опцией /CMD при запуске
BASIC или путем выбора из МЕНЮ "RUN" (ЗАПУСК) пункта
меню "Modify COMMANDS" (Изменить переменную COM-
MANDS).
342
Пример: Включение музыкальной заставки, если програм-
ма запущена с ключом "/М".
CommandString$ = COMMAND$
IF INSTR(CommandString$,"/M") > 0 THEN
PLAY "mbt200o215cl7el7g>14c<18g>12c"
END IF
ENVIRON
ENVIRON — оператор связи с DOS для изменения парамет-
ра в таблиЦе окружения DOS.
ENVIRON символьное_выражение
• символьноевыражение может иметь вид:
• параметр=текст
• параметр текст
Все, что находится слева от знака равенства или пробела,
воспринимается как параметр, все, что справа — как текст.
Если параметр до выполнения оператора не существовал в
таблице окружения, он добавляется в конец таблицы. Если он
существовал, то его значение заменяется на данный текст, сам
параметр ставится в конец таблицы.
Если текст параметра — пустая строка ("") или точка с запя-
той ( ; ), то существующий параметр удаляется из таблицы окру-
жения, а сама таблица сжимается.
DOS восстанавливает таблицу окружения после завершения
программы до ее исходного состояния.
Вы можете применить этот оператор для изменения пара-
метра PATH для порожденного процесса (программы или коман-
ды, выполняемой оператором SHELL) или для пересылки пара-
метров этому процессу путем создания нового параметра таблицы
окружения.
Пример: изменение переменной PATH.
ENVIRON "РАТН=С:\SALES;С:\ACCOUNT"
343
ENVIRONS
ENVIRONS — функция связи с DOS, возвращающая строку
параметра из таблицы окружения DOS.
ENVIRONS (имя_параметра)
ENVIRONS (n)
• имя_параметра — символьная переменная или константа, со-
держащая имя параметра из таблицы окружения DOS;
• п — номер параметра в таблице окружения.
Если вы указали имя параметра или номер, которого нет в
таблице, возвращается пустая строка. Если параметр присутству-
ет, то возвращается его значение.
Пример: вывод текущего содержимого таблицы окружения.
CLS
i = l
DO WHILE ENVIRONS(i) <> ""
PRINT ENVIRONS(i)
i = i + 1
LOOP
Вывод: (аналогичен команде DOS SET)
COMSPEC=C:\COMMAND.COM
PROMPT=$P$G
OS=NWDOS
VER=7
PATH=C:;С:\NWDOS;С:\NORTON;С:\BC7\BIN;С:\UTILS;D:\LEXICON
INCLUDE=C:\BC7\INCLUDE
BIN=C:\BC7\BIN
LIB=C:\BC7\LIB
HELP=C:\BC7\HELP
VC=C:\NORTON
TEMP=C:\NWDOS\TMP
LEXTEMP=C:\NWDOS\TMP
344
12
РАСШИРЕНИЕ
ВОЗМОЖНОСТЕЙ
QuickBASIC 4.5(*)
Работа с системными прерываниями
в QuickBASIC
Исторически сложилось так, что многие стандартные функ-
ции управления устройствами компьютера (памятью, дисковода-
ми, монитором, клавиатурой) были реализованы по принципу
прерываний (interrupt). Часть из них закодирована в постоянной
памяти — BIOS, часть — обеспечивается операционной системой.
Прерывания используются для переключения процессора на об-
служивание того или иного устройства или процесса. Все произ-
водители микросхем BIOS и разработчики DOS придерживаются
определенных стандартов, то есть функционально управление ус-
тройствами компьютеров одинаково.
Программисты чаще всего используют следующие прерывания:
INT 10h Видеосервис;
INT llh Информация об оборудов^нии;
INT 13h Дисковый ввод/вывод;
INT 14h Обслуживание последовательного порта;
INT 16h Сервис клавиатуры;
INT 17h Управление принтером ;
INT lAh Сервис таймера;
INT 21h Сервис DOS;
INT 27h Оставляет программу резидентной;
INT 33h Сервис мыши.
Получив доступ к этим средствам, вы получаете доступ не-
посредственно к оборудованию, вы пересылаете в регистры про-
цессора нужные параметры, а контроллер прерываний переклю-
чает процессор на обслуживание требуемого устройства.
Большинство прерываний имеют свои функции, которые
конкретизируют их действия (номер функции необходимо пере-
слать в регистр процессора АН).
Программисту проще вызвать нужное прерывание, чем пи-
сать сложный модуль обработки состояния какого-либо оборудо-
вания. В справочниках и руководствах1 обычно подробно описа-
ны функции BIOS и DOS, какие данные необходимо переслать в
регистры процессора, и что из этого получается.
Для доступа к системным прерываниям необходимо загру-
зить библиотеку QB.QLB:
C:>QB45>qb program /L QB.QLB
QB.QLB — библиотека, которая загружается по умолчанию,
поэтому при вызове среды QB ее имя можно не указывать, огра-
ничившись указанием ключа /L:
C:>QB45>qb program /L
Библиотека QB.QLB содержит 4 процедуры, работающие с
прерываниями, разрешенными BIOS и DOS:
Процедуры
INTERRUPT
INTERRUPTX
INT86OLD2
INT86XOLD**
Вызов
CALL INTERRUPT (параметры)
CALL INTERRUPTX (параметры)
CALL INT86OLD (параметры)
CALL INT86XOLD (параметры)
Для пересылки параметров в процедуры INTERRUPT и IN-
TERRUPTX используется пользовательский тип данных RegType.
В нем каждый элемент соответствует регистру процессора. Ре-
1 Рекомендую: Р. Джордейн. Справочник программиста персональных компью-
теров типа IBM PC, XT и AT. Москва, "Финансы и статистика", 1991
2 Отличие данных процедур от двух предыдущих в том, что данные передают-
ся и принимаются с помощью двух целых одномерных массивов, длиной 8 и 10
элементов соответственно. Они оставлены для совместимости со старыми верси-
ями языка BASIC.
346
гистры процессора, в которые разрешено пересылать данные сле-
дующие:
АХ
вх
сх
DX
ВР
SI
DI
DS
ES
(АН,
(ВН,
(СН
(DH
AL)
BL)
CL)
, DL)
аккумулятор
базовый регистр
счетчик
регистр данных
указатель базы
индекс источника
индекс приемника
флаговый регистр
указатель сегмента данных
указатель дополнительного сегмента
Процедура INTERRUPT не использует значения в регистрах
DS и ES, поэтому чаще всего она и применяется.
Если вы вызываете процедуру INTERRUPTX и вам требуется
использовать текущие значения в регистрах DS и ES, установите
элементы DS и ES переменной типа RegType равными -1.
Для обеспечения доступа к системным прерываниям создай-
те включаемый (INCLUDE) файл INTERUPT.BI, в котором со-
держатся все необходимые объявления:
1 В этом включаемом файле определены типы и описания
' процедур, необходимых для доступа к системным прерываниям:
1 Interrupt, InterruptX, Int86Old, и Int86XOld.
i****************************************************
'все переменные целые
DEFINT A-Z
'Типы данных, необходимые для процедуры Interrupt
TYPE RegType
ах AS INTEGER
bx AS INTEGER
ex AS INTEGER
dx AS INTEGER
bp AS INTEGER
si AS INTEGER
di AS INTEGER
flags AS INTEGER
END TYPE
347
DIM SHARED inreg AS RegType, outreg AS RegType
'Типы данных, необходимые для процедуры InterruptX
TYPE RegTypeX
ax AS INTEGER
bx AS INTEGER
ex 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
DIM SHARED inregx AS RegTypeX, outregx AS RegTypeX
'объявления процедур
DECLARE SUB Interrupt (intnum AS INTEGER, inreg AS_
RegType, outreg AS RegType)
DECLARE SUB InterruptX (intnum AS INTEGER, inregx AS_
RegTypeX, outregx AS RegTypeX)
DECLARE SUB Int86Old (intnum AS INTEGER, inarrayO AS_
INTEGER, outarrayO AS INTEGER)
DECLARE SUB Int86XOld (intnum AS INTEGER, inarrayO AS_
INTEGER, outarrayO AS INTEGER)
Включите этот INCLUDE-файл в начало вашей программы:
'$INCLUDE: 'interupt.bi'
Обратите особое внимание на следующее обстоятельство: все
переменные, пересылаемые в процедуру INTERRUPT должны быть
целыми! Пересылка нецелых значений приведет к зависанию систе-
мы. Вот почему в начале файла INTERUPT.BI стоит оператор
DEFINT, объявляющий целыми все переменные программы.
Дальше приведены несколько примеров, иллюстрирующих
работу с системными прерываниями в QuickBASIC.
Ввод малой русской буквы "р"
Как уже упоминалось в главе второй "ОСНОВЫ ЯЗЫКА
BASIC" стандартными средствами языка BASIC невозможно вве-
сти символ с кодом 224 — это малая русская буква "р" в Альтер-
нативной кодировке.
Исправить положение помогает процедура Char$, которая
использует прерывание BIOS INT 16H, функцию 0 — "Чтение
символа".
348
'$INCLUDE: 'interupt.bi'
DECLARE SUB Char (c$)
' Вызов процедуры CHAR, печать всех вводимых символов
1 ESC - конец работы программы
DO
CALL Char(a$): PRINT a$;
IF a$ = CHR$B7) THEN EXIT DO
LOOP
END
SUB Char (c$)
*****************************************************
' Данная процедура корректно обрабатывает ввод всех
' символов ASCII, включая малую русскую букву "р"
' используя прерывание BIOS 16h, функция 0.
' Вызов: CALL Char (variable$)
' Аналог:
' DO: variable$ = INKEY$: LOOP WHILE variable$ = ""
*****************************************************
n = &H16: ' прерывание 16h
inreg.ax =0: ' функция О
CALL Interrupt(n, inreg, outreg)
nah = outreg.ax \ 256: nal = outreg.ax MOD 256
c$ = CHR$(nal): IF nal = 0 THEN c$ = c$ + CHR$(nah)
END SUB
Прокрутка текстового экрана
Для организации оконного интерфейса требуется "прокрут-
ка" (скроллинг) фрагмента экрана. Перепечатка занимает слиш-
ком много времени, так как BASIC утомительно медлителен в
своих манипуляциях с экраном.
Решением проблемы может стать использование прерывания
BIOS ЮН, функция 6 — "Прокрутка экрана вверх" и 7 — "Про-
крутка экрана вниз".
Приведенная ниже программа рисует окно-список и прокру-
чивает его в окне на экране. Для прокрутки используется проце-
дура Scroll().
'$INCLUDE: 'interupt.bi'
DECLARE SUB Scroll (x%, y%, xl%, yl, lines%, back%, dir%)
349
DECLARE SUB WaitKey (kod%)
CONST UP% = 72, DOWN% = 80, ESC% = 27, ENTER% = 13
CONST TRUE% = -1, FALSE% = 0, шах = 100
'заполняем вектор Test$() значениями
REDIM test$(max)
FOR i = 1 TO max
test$(i) = STRING$D0, CHR$(i +47))
NEXT i
'рисуем рамку
COLOR 0, 3: CLS : COLOR 0, 7
LOCATE 3, 18: PRINT " r" + STRING$D2, "-") + "-, "
FOR i = 4 TO 21
LOCATE i, 18
PRINT "| " + test$(i - 3) + " II"
NEXT i
LOCATE 22, 18: PRINT "L» + STRING$D2, "-") + "-J "
COLOR 0, 3: LOCATE 23, 20: PRINT STRING$D3, "¦")
COLOR 0, 7
1 locator - позиция на экране
'nomer - начальный номер в векторе test$()
locator = 1: nomer = 1
'основной цикл
DO
LOCATE 4 + locator - 1, 20, 1, 6, 13
'ждем нажатия клавиши
CALL WaitKey(kod)
SELECT CASE kod
CASE IS = DOWN "клавиша {DOWN}
IF locator < 18 THEN
'перемещаемся на экране
locator = locator + 1
1 изменяем номер в векторе
nomer = nomer + 1
ELSEIF nomer < max THEN
1 вызываем прокрутку окна с координатами
'4,18,21,59 на одну строку, освободившуюся
1 строку выводим белым цветом G), прокрутка
'экрана вверх F)
CALL ScrollD, 18, 21, 59, 1, 7, 6)
'изменяем номер в векторе
nomer = nomer + 1
'выводим строку Nomer из вектора test$()
LOCATE 21, 20: PRINT test$(nomer)
END IF
CASE IS = UP
350
IF locator > 1 THEN
locator = locator - 1
noraer = nomer - 1
ELSEIF nomer > 1 THEN
1 вызываем прокрутку окна с координатами
'4,18,21,59 на одну строку, освободившуюся
'строку выводим белым цветом G) , прокрутка
1 экрана внизG)
CALL ScrollD, 18, 21, 59, 1, 7, 7)
'изменяем номер в векторе
nomer = nomer - 1
'выводим строку Nomer из вектора test$()
LOCATE 4, 20: PRINT test$(nomer)
END IF
CASE IS = ESC
LOCATE 24, 25: PRINT "вы отказались от выбора..."
EXIT DO
CASE IS = ENTER
LOCATE 24, 14
PRINT "Элемент N"; nomer; " "; CHR$C4);_
test$(nomer); CHR$C4)
EXIT DO
END SELECT
LOOP
DO: LOOP WHILE INKEY$ = ""
COLOR 0, 7: CLS : END
SUB Scroll (x, y, xl, yl, lines, back, dir)
' Эта процедура производит прокрутку фрагмента экрана
1 используя прерывание BIOS 10h, функцию 6 или 7.
1 х,у - строка и столбец верхнего левого угла
' xl, yl - строка и столбец нижнего правого угол
' lines - на сколько строк опустить/поднять
1 back - каким заполнить цветом
' dir - направление: 6 - вниз, 7 - вверх
••а*************************************************
n = &H10: 'прерывание 10h
inreg.ах = dir * 256 + lines: 'функция 6 или 7
inreg.bx = 4096 * back: 'заполнение фоном
inreg.сх = (х-1) *256+у+1: 'верхний левый угол
mreg.dx = (xl - 1) * 256 + yl - 1: 'нижний правый угол
CALL interrupt(n, inreg, outreg)
END SUB
SUB WaitKey (kod)
351
I************************************************
1 Эта процедура возвращает код клавиши:
1 ESC, ENTER, DOWN, UP
1 код - код клавиши
1 очищаем буфер клавиатуры
DO: LOOP WHILE INKEY$ <> "»
DO
'ждем нажатия какого-нибудь символа
а$ = "»: DO: a$ = INKEY$: LOOP WHILE a$ = ""
IF LEN(a$) = 1 THEN
'если нажата обычная клавиша и если это ENTER или ESC,
'то выходим из цикла DO... LOOP и из процедуры
IF a$ = CHR$(ENTER) THEN kod = ENTER: EXIT DO
IF a$ = CHR$(ESC) THEN kod = ESC: EXIT DO
ELSE
1 если нажата функциональная клавиша, то берем ее
'скан-код и проверяем, не равен ли он коду клавиш
'UP или DOWN
kod = ASC(RIGHT$(a$, 1))
IF kod = UP OR kod = DOWN OR kod = LEFT OR _
kod = RIGHT THEN
EXIT DO
END IF
LOOP
END SUB
Вывод:
352
Интерфейс с драйвером мыши
Использование манипулятора "мышь", по глубокому моему
убеждению, оправдано только в графических программах, кото-
рые, в свою очередь, имеют очень узкую область применения:
картография, проектирование, рисование, еще может быть игры.
Большинство же программ — от сложных коммерческих па-
кетов до математических задач ориентированы, конечно, на тек-
стовый режим экрана. А использование мыши в текстовых про-
граммах — явное излишество. В хорошо продуманных програм-
мах всегда быстрее работать, используя клавиатуру1, нежели
мышь, а программе с запутанным и неудобным интерфейсом ни
одна мышь не поможет. Но не буду навязывать свою точку зре-
ния. На Ваш суд предлагается процедура MOUSE, использующая
прерывание INT ЗЗН: и позволяющая управлять мышью из про-
граммы на BASIC2:
'$INCLUDE: 'interupt.bi'
DECLARE SUB MOUSE (Gl%, G2%, G3%, G4%)
DEFINT A-Z
SUB MOUSE (ml, m2, m3, m4)
' Эта процедура обеспечивает интерфейс с драйвером мыши
1 ml, m2, m3, т4 - параметры, передаваемые в драйвер мыши
' и возвращаемые оттуда. Они соответствуют регистрам
1 процессора АХ, ВХ, СХ, DX
i
*****************************************************
n = &H3 3: ' прерывание 33h
inreg.ax = ml ' входные регистры
inreg.bx = m2
inreg.cx = m3
inreg.dx = m4
CALL interrupt(n, inreg, outreg)
ml = outreg.ax ' выходные регистры
m2 = outreg.bx
rr\3 = outreg. ex
1 Обратимся к классике- всеми нами любимый Norton Commander поддержи-
вает мышь, но многие ли ею там пользуются7
2 Интерфейс с драйвером мыши подразумевает как минимум ее наличие и то,
что драйвер мыши загружен до вызова BASIC. Как гласил рекламный плакат
фирмы GENIUS на выставке "Комтек-91" — "Мышьёнок Жениус ест лучший
мышьёнок для вашего компьютеру" (орфография сохранена).
12 Зах.2105 353
m4 = outreg.dx
END SUB
Основные функции прерывания ЗЗН, и примеры к ним при-
ведены ниже:
Функция 0: Текущее состояние драйвера мыши
Функция 0 показывает текущее состояние драйвера мыши.
На входе:
• Gl%=0
На выходе:
• Gl% = статус драйвера мыши (-1: установлен, 0: не установлен);
• G2% = число кнопок мыши B или 3 кнопки)
Пример:
'Определение состояния драйвера мыши
Gl% = 0 : G2% = 0
CALL MOUSE ( Gl%, G2%, G3%, G4% )
IF G2% AND 2 THEN PRINT "Двухкнопочная мышь"
IF G2% AND 3 THEN PRINT "Трехкнопочная мышь"
IF NOT Gl% THEN PRINT "Драйвер мыши не установлен"
Функция 1: Включить курсор мыши
Функция 1 вызывает появление курсора мыши на экране.
На входе:
• Gl% = 1
На выходе:
• Ничего.
Пример:
'Включить курсор мыши
Gl% = 1
CALL MOUSE ( Gl%, G2%, G3%, G4% )
Функция 2: Погасить курсор мыши
Функция 2 удаляет курсор 'мыши с экрана дисплея. Хотя
курсор мыши и не виден, драйвер продолжает его отслеживание.
354
вы должны вызвать эту функцию перед любыми манипуля-
циями с экраном. Это поможет избежать раздвоения курсора. Для
включения курсора вызовите функцию 1.
На входе:
. Gl% = 2
На выходе:
• Ничего.
Пример:
1 Выключить курсор мыши
Gl% = 2
CALL MOUSE ( Gl%, G2%, G3%, G4% )
Функция З: Прочитать координаты курсора и статус кнопок
Функция 3 читает статус кнопок мыши и координаты курсора.
На входе:
• Gl% = 3
На выходе:
• G2% = статус кнопок;
• G3% = горизонтальная координата курсора;
• G4% = вертикальная координата курсора. =
Пример:
1 Прочитать координаты курсора и статус кнопок
DO
Gl% = 3
CALL MOUSE(Gl%, G2%, G3%, G4%)
LOCATE 1, 1
PRINT "Координаты мыши : X ="; G3%; " Y =";G4%; " "
IF G2% AND 1 THEN LOCATE 3, 1: PRINT "Левая кнопка "
IF G2% AND 2 THEN LOCATE 3, 1: PRINT "Правая кнопка "
IF G2% AND 4 THEN LOCATE 3, 1: PRINT "Средняя кнопка"
LOOP
Функция 4: Установить координаты курсора мыши
Функция 4 устанавливает новую текущую позицию курсо-
ра мыши. Разрешение зависит от экранного режима, и может
округляться при необходимости. Обратите внимание — драй-
вер мыши работает с разрешением 640 х 200 в текстовом ре-
355
жиме (SCREEN 0). Эта функции необходимо передать следую-
щие параметры:
• Gl%=4;
• G3% = новая горизонтальная координата X;
• G4% = новая вертикальная координата Y
На выходе:
• Ничего.
Экранный режим Разрешение
0 640 х 200
1 640 х 200
2 640 х 200
7 640 х 200
8 640 х 200
9 640 х 350
Ю 640 х 350
11 640 х 480
12 640 х 480
13 640 х 200
Пример:
1 Установить курсор мыши в верхнем левом углу экрана
Gl% = 4: G3% = 0 : G4% = 0
CALL MOUSE ( Gl%, G2%, G3%, G4% )
Функция 5: Прочитать статус нажатой кнопки
Функция 5 определяет, какая кнопка была нажата и ее коорди-
наты.
На входе:
• Gl% = 5;
• G2% = статус кнопки (левая = 0, правая = 1, средняя = 2).
На выходе:
• Gl% = статус кнопки;
• G2% = номер нажатой кнопки ;
• G3% = горизонтальная координата курсора в момент послед-
него нажатия;
• G4% = вертикальная координата курсора в момент последне-
го нажатия.
356
Пример:
' Прочитать координату нажатой левой кнопки
DO
Gl% = 5: G2% = 0: CALL MOUSE(G1%, G2%, G3%, G4%)
IF Gl% AND 1 THEN LOCATE 1, 1: PRINT "Нажата левая_
кнопка X = "; G3%; " "
LOOP
Функция 6: Прочитать статус отпущенной кнопки
Функция 6 определяет, какая кнопка была отпущена и ее
координаты.
На входе:
• Gl% = 6;
• G2% = статус кнопки (левая = 0, правая = 1, средняя — 1).
На выходе:
• Gl% = статус кнопки;
• G2% = номер отпущенной кнопки;
• G3% = горизонтальная координата отпущенной кнопки;
• G4% = вертикальная координата отпущенной кнопки.
Пример:
' Прочитать координату отпущенной левой кнопки
DO
Gl% = 6: G2% = 0: CALL MOUSE(Gl%, G2%, G3%, G4%)
IF NOT Gl% THEN LOCATE 1, 1: PRINT "Отпущена_
левая кнопка X = "; G3%; " "
LOOP
Функция 7: Ограничить горизонтальное (X)
перемещение курсора
Функция 7 определяет зону, ограничивающую горизонталь-
ное перемещение курсора. Если в момент вызова функции кур-
сор находился вне этой зоны, то он перемещается внутрь ее.
На входе:
• Gl% = 7
• G3% = минимальная горизонтальная координата курсора;
• G4% = максимальная горизонтальная координата курсора.
На выходе:
357
• Ничего.
Пример:
' Ограничить горизонтальное перемещение курсора между 100
и 200
Gl% = 7
G2% = 100: G3% = 200
CALL MOUSE(Gl%, G2%, G3%, G4%)
Функция 8: Ограничить вертикальное (Y)
перемещение курсора
Функция 8 определяет зону, ограничивающую вертикальное
перемещение курсора Если в момент вызова функции курсор на-
ходился вне этой зоны, то он перемещается внутрь ее.
На входе:
• Gl% = 8;
• G2% = минимальная вертикальная координата курсора;
• G3% = максимальная вертикальная координата курсора.
На выходе:
• Ничего.
Пример:
' Ограничить вертикальное перемещение курсора
1 между 100 и 200
Gl% = 8: G2% = 100 : G3% = 200
CALL MOUSE ( Gl%, G2%, G3%, G4% )
ПРИЛОЖЕНИЯ
ПРИЛОЖЕНИЕ 1
Описание Главного Меню
QuickBASIC 4.5
Для входа в главное меню нажмите клавишу {ALT}. Затем
необходимо нажать подсвеченную букву выбранного меню. Так,
например, для входа в меню FILE (файлы), нажмите {ALT-F}.
Выбор нужного пункта меню также можно производить по под-
свеченной букве. Так, для выбора пункта "Load File" (Загрузить
файл) достаточно нажать {ALT-F, L}.
Чтобы выбрать пункт из меню можно воспользоваться мы-
шью, хотя это и не так удобно: подведите курсор мыши к назва-
нию нужного пункта в линейке меню и нажмите на левую кла-
вишу мыши, затем выберите нужный пункт и нажмите еще раз
на левую клавишу мыши.
Если пункт меню оканчивается троеточием "...", то это зна-
чит, что при выборе этого пункта возникнет диалоговое окно с
дополнительными вопросами.
Ниже приведено подробное описание каждого пункта меню:
МЕНЮ FILE (ФАЙЛЫ)
Используется для:
• создания новой программы;
• загрузки и сохранения программ или частей программ;
• печати файлов или частей файлов;
• использования команд DOS;
• выхода из QuickBASIC.
New Program
Open Program.
Merge...
Save
Save As...
Save All
Create File...
Load File...
Unload File...
Print...
DOS Shell
Exit
Новая программа
Открыть программу...
Объединить...
Сохранить
Сохранить как...
Сохранить всё
Создать файл...
Загрузить файл...
Выгрузить файл...
Печать...
Временный выход в DOS
Выход
NEW PROGRAM (Новая программа)
Используется для очистки памяти перед началом новой
программы. Если программа уже находится в памяти, то может
появиться диалоговое окно. Тогда:
• выберите <Yes> для записи программы;
• выберите <No> для очистки без записи;
• выберите <Cancel> для отмены очистки.
Выбор может осуществляться как клавишей {TAB}, так и
курсором мыши.
OPEN PROGRAM (Открыть программу)
360
Используется для очистки памяти и загрузки программы с
диска, после чего ее можно запускать или вносить изменения.
Вместо этого пункта меню можно использовать "Load File"
(Загрузить файл)
MERGE (Объединение)
Используется для вставки содержимого файла, записанного в
текстовом формате в текущий загруженный файл. Файл, запи-
санный в формате QuickBASIC не может быть объединен с заг-
руженным файлом. В таком случае его надо преобразовать в тек-
стовый формат. Компилировать готовую программу (пункт "Маке
ЕХЕ" из меню RUN), лучше всего также в текстовом виде.
SAVE (Запись)
Используется для записи содержимого файла, находяще-
гося в рабочем окне, на диск. Если файл не имеет имени, то
будет запрошено его имя и формат. В случае, если на диске
уже существует файл с таким именем, то он будет перезапи-
сан. Для записи файла удобнее всего использовать комбина-
цию клавиш {ALT-F, L}.
361
SAVE AS (Записать как...)
Используется для записи файла в рабочем окне на диск.
Файл остается в памяти. С помощью пункта "Save As" вы сможе-
те сделать несколько копий файла с различными изменениями,
сохранив при этом оригинальную версию.
SAVE ALL (Записать все)
Используется для записи всех изменившихся модулей про-
граммы. Новая программа получит имя и формат главного моду-
ля. Пункт "Save All" создает и использует специальный файл, с
именем главного модуля и расширением .МАК. Файл .МАК со-
держит имена всех остальных модулей программы. При последу-
ющей загрузке главного модуля QuickBASIC автоматически под-
грузит все остальные модули.
CREATE FILE (Создать файл )
Используется для ввода нового модуля в многомодульной
программе. Он может быть:
362
программным модулем;
включаемым файлом;
файлом типа документ.
Новый файл становится частью текущей загруженной про-
граммы. Пункт "Create File" может быть использован, когда
программа еще не загружена, вместо "New Program" для создания
нового главного модуля.
FILE LOAD (Загрузить файл)
Используется для загрузки программы с диска, а также для:
• построения многомодульной программы;
• загрузки и редактирования служебных текстовых файлов;
• подготовки Quick library.
Для быстрой загрузки файла можно использовать комбина-
цию клавиш {ALT-F, L}
363
FILE UNLOAD (Выгрузить файл)
Используется при создании
многомодульных программ, чтобы
выгрузить ненужный модуль из
памяти, оставив его записанным в
виде файла на диске. QuickBASIC
выведет список загруженных мо-
дулей. Выберите тот, который вы
хотите выгрузить, подведите к не-
му выделенную строку и нажмите
клавишу {ENTER}. Если выгружа-
емый модуль изменялся, то Quick-
BASIC спросит вас, нужно ли его
сохранять.
PRINT (Печать)
Используется для распечатки текста, находящегося в памяти.
С помощью этого пункта меню вы можете распечатать:
Текст посылается на печать через порт DOS LPT1'.
DOS SHELL (Временный выход в DOS)
Используется для временного выхода из QuickBASIC и вы-
полнения команд DOS2. Для этого необходимо следующее:
1 В дополнение к LPT1 в среде Microsoft BASIC PDS 7.1 выделенный текст
можно послать на LPT2, LPT3 или в файл.
2 В Microsoft BASIC PDS 7.1 имеется меню "UTILITY" (УТИЛИТЫ), где
имеется пункт "Run DOS Command" (Запустить команду DOS). При возврате в
среду вводить "exit" нет необходимости.
364
• выделенный текст;
• содержание активного окна;
• текущий модуль (включая и про-
цедуры);
• все модули в многомодульной
программе.
1. выберите пункт DOS Shell в МЕНЮ FILE.
2. выполняйте команды DOS , но не стирайте те файлы, кото-
рые нужны QuickBASIC (загруженные файлы, библиотеки).
3. чтобы вернуться в QuickBASIC введите "exit" в ответ на приг-
лашение DOS.
EXIT (Выход)
Используется для выхода из среды QuickBASIC. Если файл
не назван, либо не сохранены последние изменения, то может
появится диалоговое окно:
• выберите <Yes> для записи изменений.
• выберите <No> для отмены изменений.
• выберите <Cancel> для отмены выхода.
МЕНЮ EDIT (РЕДАКТИРОВАНИЕ)
Undo Alt+Backspace
Cut Shift+Del
Copy Ctrl+Ins
Paste Shift+Ins
Clear Del
New SUB...
New FUNCTION...
Отмена Alt+Backspace
Вырезать Shift+Del
Скопировать Ctrl+Ins
В буфер Shift+Ins
Очистить Del
Новая процедура SUB...
Новая процедура FUNCTION
Используется для:
стирания (или удаления в буфер) текста;
копирования текста;
передвижения (удаления и вставки через буфер) текста;
отмены последних изменений в тексте;
стирания текста без запоминания в буфере;
создания новой процедуры (SUB) или функции (FUNCTION)
365
UNDO (Отменить)
Используется для отмены всех изменений в текущей строке,
пока курсор находится на ней. Для отмены изменений возможно
применение комбинации клавиш {ALT-BACKSPACE}. Однако
следует учитывать, что отмена изменений возможна до тех пор,
пока курсор находится на текущей строке1.
CUT (Вырезать)
Используйте команду Cut или нажмите {SHIFT-DEL} для
удаления выбранного текста из активного окна и помещения его
в буфер.
Затем вы можете использовать команду Paste {SHIFT-
INS},чтобы вставить текст в активное окно. Чтобы начать выде-
ление текста, поставьте курсор в нужное место и нажимайте кла-
виши {SHIFT} и нужную клавишу-стрелку. Для стирания текста
без запоминания его в буфере нажмите клавишу {DEL}.
Пример: иллюстрирует действие команд Cut и Paste:
Текст
Буфер
1
Выделите текст,
{SHIFT}+ стрел-
ки
2
Выберите ко-
манду Cut или
нажмите
{SHIFT-DEL}
3
Переместите
курсор и выбери-
те команду Paste
{SHIFT-INS}
-^ " -'
Вырезанный текст остается в буфере и может быть скопиро-
ван в другое место программы.
1 В Microsoft BASIC 7 I это ограничение снято В нем вы можете отменить до
20 последних изменений (UNDO) Кроме того, там появился режим
"восстановления отмененных изменений" (REDO)
366
COPY (Копировать)
Используйте команду Сору или нажмите {CTRL-INS} для
копирования выбранного текста из активного окна в буфер
Оригинальный блок текста остается без изменения.
Затем вы можете использовать команду Paste {SHIFT-INS},
чтобы вставить текст в активное окно.
Пример: иллюстрирует действие команд Сору и Paste:
Текст
Буфер
1
Выделите
текст,
{SHIFT}+
стрелки
2
Выберите команду
Сору или нажми-
те {CTRL-INS}
3
Переместите кур-
сор и выберите
команду Paste
{SHIFT-INS}
_ .
-
Вырезанный текст остается в буфере и может быть скопиро-
ван в другое место программы.
PASTE (Вставить через буфер)
Используйте Paste или нажмите {SHIFT-INS} чтобы скопи-
ровать блок текста из буфера в любое место активного окна.
Позиция, куда будет вставлен текст определяется:
1 выделенным текстом; он стирается и текст из буфера
копируется на его место.
2. позицией курсора, если нет выделенного текста; тогда.
— меньше, чем одна строка копируется слева от курсора;
— больше, чем одна строка копируется выше курсора
367
CLEAR (Очистить)
Используйте команду Clear (или нажмите {DEL}, чтобы сте-
реть выделенный текст из активного окна без запоминания в бу-
фере. Содержимое буфера остается без изменения.
NEW SUB (Новая процедура SUB)
Используйте New SUB чтобы создать новую процедуру как
часть программы или модуля в рабочем окне. Появится окно ди-
алога для ввода имени про-
цедуры. QuickBASIC очис-
тит рабочее окно и сгенери-
рует требуемые операторы
SUB и END SUB, так что
вы сможете начать вводить
текст. Процедура может
быть определена только один раз во всей программе.
Когда вы вводите текст внутри новой процедуры, используй-
те команду SUBs из МЕНЮ VIEW (ПРОСМОТР), или нажмите
{F2}, чтобы вернуться в программу. Ваша процедура появится в
списке процедур команды SUBs.
Вы можете начать вводить процедуру и без использования
меню. Для этого введите ключевое слово QuickBASIC SUB и имя
процедуры.
NEW FUNCTION (Новая процедура SUB)
Используется для ввода
определения функции в ра-
бочем окне. Функция в
QuickBASIC — это проце-
дура, которая возвращает
значение в Вашу програм-
му. Каждая функция может
быть определена только один раз во всей программе.
368
МЕНЮ VIEW (ПРОСМОТР)
SUBs...
Next SUB
Split
F2
Shift+F2
Next Statement
Output Screen
F4
Included File
Included Lines
Процедуры... F2
Следующая процедура Sh
Разделение
Следующий оператор
Выходной экран F4
Включенный файл
Включенные строки
Используется для просмотра:
процедур (SUB) и функций (FUNCTION);
включенных файлов;
выходного экрана.
SUBs (Процедуры)
Используется для просмотра различных частей загруженной
программы. Для вызова этого пункта меню можно воспользовать-
ся клавишей {F2}. вы сможете:
• просмотреть содержимое рабочего окна;
• разделить рабочее окно для просмотра различных частей од-
ной программы или двух программ одновременно;
• стереть процедуру или модуль;
• передвинуть процедуру между модулями.
369
NEXT SUB (Следующая процедура)
Используйте эту команду (или нажмите {SHIFT-F2}), когда вы
хотите перейти к следующей процедуре.
QB передвигается от процедуры к
процедуре в алфавитном порядке.
{SHIFT-F2} вызывает переход от А к В,
следующее нажатие вызывает переход к
процедуре С.
{CTRL-F2} осуществляет перемеще-
ние в обратном порядке.
Если в программе много процедур, то
быстрее воспользоваться командой SUBs
(процедуры) или нажать клавишу {F2}.
SPLIT (Разделение)
Используется для работы с двумя частями программы или с
двумя программами одновременно. Выбор этого пункта делит ра-
бочее окно горизонтально. Используйте клавиши {F6} и {SHIFT-
F6} для передвижения между окнами на экране:
• {F6} — передвигает курсор в нижнее окно;
• {SHIFT-F6} — передвигает курсор в верхнее окно;
Для того, чтобы восстановить первоначальное состояние ок-
на, выберите пункт Split снова.
Активное окно содержит курсор, вы можете управлять раз-
мерами этого окна с клавиатуры:
• ALT+PLUS(+) увеличивает на одну строку;
• ALT+MINUS(-) уменьшает на одну строку;
• CTRL+F10 Распахивает окно на весь экран или возвращает
его первоначальный размер.
NEXT STATEMENT (Следующий оператор)
Помещает курсор на выполнимый оператор, следующий за
тем местом, где программа была приостановлена, вы можете про-
должить:
370
• командой Continue (продолжить) , или нажав {F5};
• нажав {F8} чтобы исполнить следующий оператор;
• использовать команду Set Next Statement (установить следу-
ющий оператор), в МЕНЮ DEBUG (ОТЛАДКА), чтобы сме-
нить место, с которого программа будет продолжена.
OUTPUT SCREEN (Выходной экран)
Используется для переключения между средой QuickBASIC и
выходным экраном Вашей программы. Также можно пользовать-
ся клавишей {F4}.
INCLUDED FILE (Включенный файл)
Эта команда используется только в том случае, если загру-
женная программа имеет одну или более метакоманд SINCLUDE.
Используется для загрузки включенного файла в рабочее ок-
но и для его редактирования:
1. поместите курсор на метакоманду SINCLUDE с именем того
файла, который вы хотите редактировать;
2. выберите команду Included File;
3. редактируйте файл в рабочем окне, затем выберите пункт
"Save As" (Записать как) из меню FILE (ФАЙЛЫ), или от-
ладьте программу со включенным файлом и запишите файл
позднее, как часть программы.
Чтобы просмотреть текст программы в то время когда вы ра-
ботаете со включенным файлом:
1. разделите рабочее окно при помощи пункта Split (Разделение)
из меню VIEW (ПРОСМОТР).
2. выберите пункт "Load File" (Загрузить файл) из меню FILE
(ФАЙЛЫ) чтобы загрузить включенный файл.
3. вернитесь к тексту программы. Этим вы сделаете окно с
программой активным. Теперь вы можете запускать прог-
рамму.
371
INCLUDED LINES (Включенные строки)
Используется для того чтобы включить или выключить ре-
жим показа строк текста включенного файла. Если режим вклю-
чен, то в меню появляется точка.
Используйте эту команду только в том случае, если Ваша
программа содержит метакоманду SINCLUDE.
Когда режим включен, то текст включенного файла показы-
вается другим цветом следом за метакомандой SINCLUDE с
именем включенного файла. Эти строки только для чтения, вы
должны загрузить включенный файл в свое окно, для того, чтобы
редактировать его.
МЕНЮ SEARCH (ПОИСК)
Find...
Selected Text Ctrl+\
Repeat Last Find F3
Change...
Label...
Найти...
Выделенный т^кст Ctrl+\
Повторить последний поиск F3
Заменить...
Метка...
Используется для поиска текста:
• только в активном окне;
• в текущем модуле;
• во всех загруженных модулях.
FIND (Поиск)
Используется для поиска текстовой строки:
• в активном окне;
• в текущем модуле;
• во всех загруженных модулях.
372
вы можете выбрать как точный образец ( с учетом регистра),
так и целое слово. Для того чтобы заменить строку, используйте
команду Change (Замена).
Используйте команду Selected Text (Выделенный текст) для
поиска короткой строки в активном окне.
SELECTED TEXT (Выделенный текст)
Используется для поиска образца, размером в одну строку
или меньше, который предварительно был выделен в рабочем
окне. Также можно использовать клавишу {CTRL-\}. Для других
ситуаций используйте пункт Find.
Для работы с выделенным текстом:
1. выделите текст используя клавиши {SHIFT} и стрелки;
2. выберите Selected Text или нажмите {CTRL+\}. QuickBASIC
выделит подсветкой следующее вхождение образца.
REPEAT LAST FIND (Повторить последний поиск)
Используется для повторения последнего поиска (может
быть нажата клавиша {F3}, команды Find (Поиск) или Change
(Замена).
Если с момента запуска QuickBASIC команды Find (Поиск)
или Change (Замена) не выполнялись, то будет найдено:
• слово, на которое указывает курсор;
• если курсор не указывает на слово, то будет найдено слово
слева от курсора.
373
CHANGE (Замена)
Используется для поиска текстовой строки и замены на ее на
другую.
вы можете заменить строку:
• в активном окне;
• в текущем модуле;
• во всех загруженных модулях
Можно выбрать, необходимо ли вам:
• показ места, где будет произведена замена;
• поиск с учетом регистра или нет.
LABEL (Метка)
Используется аналогично опции Find (Поиск). QuickBASIC
ищет строку, оканчивающуюся двоеточием.
Когда вы вводите в текстовое окно Find What (Найти что)
метку, то двоеточие после метки вводить НЕ надо. Дело в том,
что метки могут быть и целочисленными, а такие метки не окан-
чиваются двоеточием.
374
МЕНЮ RUN (ЗАПУСК)
Start Shift+F5
Restart
Continue F5
Modify COMMANDS.
Make EXE File...
Make Library...
Set Main Module...
Запуск Shift+F5
Перезапуск
Продолжение F5
Изменить переменную COMMANDS..
Сделать EXE файл...
Сделать библиотеку. ..
Установить главный модуль...
Используется для:
• исполнения загруженной программы;
• продолжения выполнения прерванной программы;
• очистки переменных в памяти перед выполнением;
• создания исполняемого (.ЕХЕ) файла;
• определения главного модуля в многомодульной программе.
START (Запуск)
Используется для очистки памяти и запуска программы на
исполнение, начиная с первого исполняемого оператора в глав-
ном модуле.
Команда Start может использоваться после останова про-
граммы нажатием {CTRL-BREAK}, для того, чтобы запустить
программу с начала. Для исполнения команды Start можно также
нажать {SHIFT-F5}. Вместо {CTRL-BREAK} можно пользоваться
375
точками прерывания и точками наблюдения (СМ. МЕНЮ
DEBUG (ОТЛАДКА).
RESTART (Перезапуск)
Restart очищает память и продолжает выполнение с первого
исполняемого оператора.
Используйте клавишу {F8} для выполнения одного операто-
ра, вы можете переопределить, какой оператор будет выполнятся
следующим через опцию Set Next Statement (Установить следую-
щий оператор) из меню DEBUG (ОТЛАДКА).
CONTINUE (Продолжить)
Используйте опцию Continue после того, как программа бы-
ла остановлена, для того, чтобы продолжить ее выполнение.
Эта команда часто используется для продолжения выполне-
ния программы, остановленной на точке прерывания или точке
наблюдения, после того как вы проверили значения переменных
или просмотрели выходной экран.
Для исполнения команды Continue можно также нажать кла-
вишу {F5}.
MODIFY COMMANDS
(Изменить переменную COMMANDS)
Используется для отладки QuickBASIC программы, которая
использует функцию COMMANDS. COMMANDS передает ин-
формацию из ко-
мандной строки
DOS. Команда ме-
ню Modify COM-
MANDS позволит
вам отладить Вашу
программу с новой
командной стро-
кой, не переключаясь между QuickBASIC и DOS. Так, например,
если вы хотите, чтобы у программы была музыкальная заставка,
но чтобы ее можно было отключить, используя ключ "/N0"
376
Пример: Отключение музыкальной заставки по ключу,
указанному в командной строке.
CommandString$ = COMMAND$
IF INSTR(CommandString$, "/NO") = 0 THEN
PLAY "mbt200o215-cl7el7g>14c<18g>12c"
END IF
MAKE EXE FILE {Сделать EXE файл)
Используется для построения .ЕХЕ (исполнимой) версии
Вашей работающей QuickBASIC программы. Эта версия может
исполняться прямо из командной строки DOS без загрузки среды
QuickBASIC.
Если вы хотите, чтобы Ваша программы выполнялась авто-
номно, выберите пункт "Stand-Alone EXE File" (Автономный ис-
полняемый файл). В противном случае, для работы Вашей про-
граммы будет необходимо наличие библиотеки времени выпол-
нения BRUN45.EXE в текущем каталоге, или в одном из катало-
гов, перечисленных в PATH.
MAKE LIBRARY (Сделать библиотеку)
Используется для сборки программных модулей в Quick биб-
лиотеку или добавления в существующую библиотеку.
377
Quick library используется, когда у вас есть набор процедур,
которые вы хотите использовать в нескольких программах. Про-
цедуры и функции, которые находятся в Quick библиотеке стано-
вятся расширением самого языка BASIC. При запуске QB.EXE не-
обходимо указать ключ "/L" и имя библиотеки. После этого бу-
дет построено два файла библиотек:
• .QLB — необходима для работы в среде QB;
• LIB — необходима для компиляции в .ЕХЕ файл.
SET MAIN MODULE (Установить главный модуль)
Используется в многомодуль-
ных программах для смены глав-
ного модуля. При написании
программ применяется для отлад-
ки каждого модуля Кроме этого,
если вы выгружаете из программы
главный модуль, то QuickBASIC
спросит вас, какой модуль из ос-
тавшихся будет главным. Не за-
будьте, что именно главный мо-
дуль содержит точку входа, с кото-
рой начинается выполнение про-
граммы.
МЕНЮ DEBUG (ОТЛАДКА)
Add Watch...
Instant Watch ..Shift+F9
Watchpoint. .
Delete Watch..
Delete All Watch
Trace On
History On
Toggle BreakpointF9
Clear All Breakpoints
Break on Errors
Set Next Statement
Добавить наблюдение
Установить Ha6flKweHHeShift+F9
Точка наблюдения ..
Убрать наблюдение. .
Убрать все наблюдения
Трассировка включена
История включена
Точка прерывания F9
Убрать все точки прерывания
Обрыв на ошибках
Установить следующий оператор
378
Используется для настройки работы программы путем:
• открытия окон наблюдения, которые показывают, как пере-
менные изменяются при работе программы;
• установки точек прерывания, которые прерывают выполне-
ние программы для того, чтобы вы смогли просмотреть зна-
чения переменных.
После останова программы можно подвести курсор к любой
переменной и нажать {SHIFT-F9}, чтобы узнать ее значение. Для
установки точки прерывания подведите курсор к нужной строке
и нажмите {F9}.
ADD WATCH (Добавить наблюдение)
Используется для контроля за значением переменной или
значением (-1 "ДА"(Тше) или О "НЕТ" (False)) выражения при
исполнении программы.
Эти значения появляются в Окне отладки в верхней части
экрана.
Сообщение "Not watchable" (Определить невозможно) появ-
ляется в Окне в том случае, если QuickBASIC не может получить
доступ к значению переменной или выражения. Чаще всего это
379
происходит, когда выполнение программы прервано не в той
процедуре или модуле, в котором устанавливали наблюдение.
INSTANT WATCH (Установить наблюдение)
Используется, когда прервано исполнение программы для
того, чтобы показать:
• значение переменной;
• условие выражения (True или False) ;
Чтобы показать значение переменной:
1. подведите курсор к имени переменной;
2. выберите Instant Watch (или нажмите {SHIFT-F9});
Чтобы показать значение выражения:
1. выберите (подсветкой) выражение в рабочем окне или подведите
курсор к выраже-
нию (QuickBASIC
отличает перемен-
ную от выражения);
2. выберите Instant
Watch (или на-
жмите {SHIFT-F9};
3. если выражение
верно, то в окне
высвечивается -1, если же оно ложно, то 0.
Значения появляются в окне диалога. С помощью этого же
окна можно добавить переменную или выражение в Окно отлад-
ки. При использовании мыши можно установить окно, поместив
курсор мыши на переменную, либо выбрав выражение, затем од-
новременно нажав {SHIFT} и правую кнопку мыши.
WATCHPOINT (Точка наблюдения).
Используется для остановки программы в случае, если за-
данное Вами условие станет верным. Это условие может быть:
380
• именем переменной;
• оператором отношения.
Оператор отношения использует операторы: =, О, >, <, >=,
или <=. В про-
стейшем случае,
если вы просто
вводите имя пе-
ременной или вы-
ражение, Quick-
BASIC подразуме-
вает отношение
<> 0. Например ввод X + Y означает выражение X + Y О 0.
Сравнение "Add Watch" и "Watch Point":
"Add Watch" (Добавить наблюдение):
• высвечивает значения переменных, показывая как они изме-
нились при выполнении программы;
• не обрывает выполнение программы.
"Watch Point" (Точка наблюдения):
• не высвечивает значения переменных;
• обрывает программу в случае, если введенное выражение ста-
нет верным.
DELETE WATCH (Стереть наблюдение)
Используется для сти-
рания только одного наблю-
дения из окна отладки. Если
же вы хотите полностью
удалить все наблюдения, то
для этого вам необходимо
воспользоваться пунктом
меню "Delete All Watch"
(Стереть все наблюдения).
381
TRACE ON (Включить трассировку)
Используйте этот переключатель, если вы хотите:
• запустить Вашу программу в замедленном режиме, высвечивая
каждый оператор, в момент его выполнения;
• запомнить, как выполнялись последние 20 строк программы
перед остановкой.
Это позволит проследить за выполнением программы. Ис-
пользуйте Trace On совместно с окнами наблюдения, точками
прерывания или {CTRL-BREAK} для периодического приоста-
новления выполнения программы. Затем используйте {SHIFT-F8}
и {SHIFT-F10} для передвижения вперед и назад в пределах 20
строк программы.
HISTORY ON (История включена)
Используйте этот переключатель, когда вы хотите:
• запустить Вашу программу со скоростью, близкой к нормаль-
ной;
• запомнить, как выполнялись последние 20 строк программы
перед остановкой.
После этого, используйте клавиши {SHIFT-F8} и {SHIFT-
F10} для изучения последовательности выполнения операторов,
включая проверку ветвления и другие действия программы в пре-
делах 20 строк кода программы, которые были записаны пунктом
"History On". Когда этот пункт включен, то в меню напротив
TOGGLE BREAKPOINT (Точка прерывания)
Используется для установки/снятия точек прерывания (мест,
где программа останавливается).
382
Чтобы установить точку прерывания необходимо проделать
следующее:
1. поместите курсор на строку, где вы хотите установить точку
прерывания;
2. выберите "Toggle Breakpoint" (или нажмите {F9}). Quick-
BASIC выделит строку другим цветом.
Чтобы снять точку прерывания:
1. поместите курсор на выделенную строку;
2. выберите "Toggle Breakpoint" (или нажмите {F9}).
Используйте точку прерывания для приостановки Вашей
программы в том месте, где вы предполагаете наличие ошибок, а
затем:
• протестируйте значения переменной в окне для немедленного
выполнения или с помощью опции "Instant Watch" (Ус-
тановить наблюдение);
• добавьте переменные в Окно наблюдения и продолжайте по-
шаговое выполнение программы, начиная с точки прерывания.
CLEAR ALL BREAKPOINTS
(Стереть все точки прерывания)
Используется для удаления всех точек прерывания из Вашей
программы. Для индивидуального удаления точек прерывания
используйте "Toggle Breakpoint" (Точка прерывания) или нажми-
те F9.
BREAK ON ERRORS (Обрыв на ошибках)
Эта опция используется для отладки программы, содержа-
щую процедуру обработки ошибок.
"Break On Errors" (Если опция включена, то в меню появля-
ется точка) приостанавливает выполнение программы на проце-
дуре обработки ошибок. Включение "Break On Errors" также
включает "History On" (История включена), так что будет запи-
сана последовательность выполнения 20 последних операторов
383
программы. Используя {SHIFT-F8} вы можете вернуться на опе-
ратор, вызвавший ошибку. Дальнейшее нажатия покажут вам
операторы, предшествующие ошибке.
SET NEXT STATEMENT
(Установить следующий оператор)
Используется для изменения естественного порядка выпол-
нения операторов и исполнения того оператора, на котором сто-
ит курсор.
МЕНЮ CALLS (ВЫЗОВЫ)
Меню CALLs показывает последовательность вызова проце-
дур из других процедур (стек вложенных процедур). Если про-
грамма не использует вызовы процедур из других процедур, то в
меню CALLs выводится только имя главного модуля программы
и имя текущей вызываемой процедуры. На рисунке показано, как
может выглядеть меню CALLs при останове выполнения про-
граммы DEMO3.BAS в процедуре Siren.
Siren
DEMO3.BAS
Процедура Siren
Вызвана из DEMO3.BAS
Управление можно передать в любую процедуру из стека
вложенных процедур, выбрав ее, и нажав клавишу {F7} (испол-
нить до курсора). Меню CALLs выводит до 8 вызовов в стеке.
МЕНЮ OPTIONS (ОПЦИИ)
Display...
Set Paths...
Right Mouse...
' Syntax Checking
• Full Menus
Экран...
Установить пути...
Правая кнопка мыши.
> Проверка синтаксиса
> Режим полного меню
Используется для:
• настройки цветов экрана;
• установки путей для поиска служебных файлов;
384
• переопределения правой кнопки мыши;
• включения/выключения режимов Full Menus (Полное меню)
и Syntax Checking (Проверка синтаксиса)
Сделанные Вами установки автоматически запоминаются и
используются при дальнейших вызовах QuickBASIC.
DISPLAY (Экран)
Опция Display используется для установки:
экранных цветов;
линеек прокрутки в окнах и списках;
числа пробелов выдаваемых клавишей {TAB}.
SET PATHS (Установить пути)
Используется для установки путей, по которым QuickBASIC
будет осуществлять поиск:
• исполнимых файлов (.ЕХЕ и .СОМ );
• включаемых файлов (.BI и .BAS );
• библиотечных файлов (.LIB и .QLB );
• файлов помощи (.HLP).
385
RIGHT MOUSE (Правая кнопка мыши).
Используется для изменения действий от однократного на-
жатия правой кнопки мыши:
выдать информацию об
элементе на который
указывает курсор (по
умолчанию);
исполнить программу
от начала до строки, на
которой стоит курсор.
Right douse
On right Mouse button click:
(•) Context-sensitive Help
( ) Execute up to this line
ОК
< Cancel > < Help >
SYNTAX CHECKING
(Проверка синтаксиса)
Эта команда включает/выключает Интеллектуальный Редак-
тор QuickBASIC, который:
1. проверяет строку на наличие синтаксических ошибок;
2. форматирует строку;
3. в случае, если синтаксис строке правилен, то переводит стро-
ку в исполнимую форму, при этом операторы языка Quick-
BASIC становятся написанными заглавными буквами.
386
Выключение отменяет эти функции и превращает Интеллек-
туальный Редактор в обычный текстовый. Когда "Syntax
Checking" включена, то рядом с этим пунктом в меню появляется
Интеллектуальный Редактор действует в режимах:
• "New Program" (Новая программа) или "Open Program" (Отк-
рыть программу);
• "Create File" (Создать файл) или "Load File" (Загрузить
файл), в случае если не выбран пункт "Document". Если же
выбран пункт "Document", то в режимах "Create File" или
"Load File" Интеллектуальный Редактор отключается, и вы
можете использовать QuickBASIC как обычный редактор для
ввода текста.
FULL MENUS (Режим полного меню)
Используется для переключения между полной (FULL) и со-
кращенной формой меню QuickBASIC. При выборе опции Full
Menus, рядом с ней в меню появляется точка.
Сокращенное меню содержит команды, достаточные для
предварительного знакомства со средой QuickBASIC. После пер-
воначального освоения более удобно разрабатывать программы в
режиме полного меню, которое содержит ряд дополнительных
команд и дополнительное меню (МЕНЮ CALLs ).
МЕНЮ HELP (ПОМОЩЬ)
Индекс
Содержание
Описание: F1
Справка о noMoiuHShift+Fl
Используется для получения:
• справки по ключевым словам языка BASIC;
• информации по языку программирования QuickBASIC;
• контекстно-зависимой помощи, основанной на местораспо-
ложении курсора;
• дополнительных инструкций по получению помощи.
387
HELP INDEX (Индекс помощи)
Help index — это алфавитный список тем, содержащихся в фай-
лах помощи, включая ключевые слова BASIC. Каждая тема снабже-
на дополняющими подразделами. Для получения помощи:
• выберите пункт Index из меню HELP.
• нажмите клавишу, соответствующую первой букве нужной темы;
• укажите курсором подраздел, по которому вы хотите получить
помощь и нажмите клавишу {F1}.
HELP TABLE of CONTENTS
(Таблица содержания файлов помощи)
Обеспечивает доступ ко всем подразделам помощи
QuickBASIC. Для получения помощи в Table of Contents:
• выберите команду Contents из меню HELP;
• нажмите клавишу, соответствующую первой букве нужного
описания;
• нажмите {F1}.
388
HELP TOPIC (Описание)
При выборе этой опции высвечивается информация о пере-
менной, операторе или выражения, на которой находится курсор.
Выбор этой опции также может осуществляться путем нажатия
клавиши {F1}. При использовании мыши нажмите на ее правую
кнопку.
HELP on HELP (Справка о помощи)
Справка о помощи описывает как получить помощь, исполь-
зуя мышь или клавиатуру.
ПРИЛОЖЕНИЕ 2
Запуск, редактирование
и отладка программы
Ключи запуска среды QB из командной строки DOS
Полный синтаксис командой строки QB :
QB [/RUN [имя_программы]] [/В] [/G] [/H] [/NOHI]
[/С:размер_буфера] [/L [имя_библиотеки]] [MBF]
[/АН] [/СУЮстрока_команды]
Ключ
/RUN
[имяпрограммы]
/в
/G
Описание
Загрузить и выполнить программу, не пока-
зывая ее исходного текста. Имя_програм-
мы — имя файла .BAS.
Позволяет использовать монохромный мо-
нитор с цветным адаптером (CGA/EGA-
mono).
Для машин с адаптером CGA.
389
/н
/NOHI
/С:размер_буфера
/Цимя_библиотеки]
/MBF
/АН
/CMDctpo-
какоманды
Запускает среду QB в режиме 43 строки на
EGA-мониторе и 50 строк на VGA.
Позволяет использовать монитор, где нет
цветов повышенной яркости.
Устанавливает размер буфера обмена данными
для коммуникационной карты. По умолча-
нию — 512 байт, максимально — 32767 байт.
Загружает Quick-библиотека с данным име-
нем. Если имя опущено, то загружается
библиотека QB.QLB.
Позволяет функциям преобразования дан-
ных рассматривать числа IEEE-формата как
числа Microsoft Binary формата.
Позволяет использовать динамические мас-
сивы, превышающие 64К.
Передает строку функции COMMANDS. Этот
ключ должен быть последним в командной
строке1.
Клавиши редактирования
Редактор QuickBASIC совместим по командам с другими ре-
дакторами фирмы Microsoft, такими как EDIT (из MS DOS 5.x
или 6.x), Microsoft Word, а также с остальными интегрированны-
ми Quick-средами (QuickAssembler, QuickPascal, QuickC)
Символ влево
Символ вправо
Слово влево
Слово вправо
Строка вверх
Строка вниз
LEFT
RIGHT
CTRL+LEFT
CTRL+RIGHT
UP
DOWN
1 Для передачи значения функции COMMANDS удобнее использовать пункт
"Modify COMMAND" (Изменить COMMANDS) из меню "RUN" (ЗАПУСК). Это
позволяет передавать функции COMMANDS значения командной строки, не
выходя из среды QB.
390
Первая позиция текущей строки
Начало следующей строки
Конец строки
Начало модуля/процедуры
Конец модуля/процедуры
Установить маркер места номер "п"
(где п = 0-3)
Перейти к маркеру номер "п"
Строка вверх
Строка вниз
Страница вверх
Страница вниз
НОМЕ
CTRL+ENTER
END
CTRL+HOME
CTRL+END
CTRL+K+n
CTRL+Q+n
Клавиши прокрутки текста
CTRL+UP
CTRL+DOWN
PGUP
PGDN
Влево на одно окно
Вправо на одно окно
CTRL+PGUP
CTRL+PGDN
Символ влево
Символ вправо
Слово влево
Слово вправо
Текущая строка и ниже
Строка выше
Страница выше
Страница ниже
До начала модуля/процедуры
До конца модуля/процедуры
Клавиши выбора текста
SHIFT+LEFT
SHIFT+RIGHT
SHIFT+CTRL+LEFT
SHIFT+CTRL+RIGHT
SHIFT+DOWN
SHIFT+UP
SHIFT+PGUP
SHIFT+PGDN
SHIFT+CTRL+HOME
SHIFT+CTRL+END
391
Вставка, копирование и стирание текста
Переключение вставка/замещение
Копировать выбранный текст в карман
Стереть текст и скопировать в карман
Стереть строку и скопировать в карман
Вставить содержимое кармана
Вставить пустую строку ниже текущей
Стереть символ слева от курсора
Стереть текущий символ
Стереть выбранный текст
INS
CTRL+INS
SHIFT+DEL
CTRL+Y
SHIFT+INS
END ENTER
BACKSPACE
DEL
DEL
Стереть начальные пробелы в выбранных SHIFT+TAB
строках
Клавиши просмотра
Посмотреть окно вывода
F4
Вывести список загруженных модулей и файлов F21
Перейти к следующей процедуре SHIFT+F2
Перейти к предыдущей процедуре CTRL+F2
Сделать следующее окно активным
Сделать предыдущее окно активным
Развернуть активное окно на весь экран
Увеличить размер активного окна
Уменьшить размер активного окна
F6
SHIFT+F6
CTRL+F10
ALT+PLUS
ALT+MINUS
1 Если при редактировании программы подвести курсор к имени процедуры или
функции и нажать {F2}, то в выводимом списке загруженных модулей и (файлов курсор
будет указывать на имя этой процедуры или функции. Нажмите {ENTER} и откроется
окно для ее редактирования
392
Клавиши поиска
Искать выбранный (подсвеченный) текст Ctrl+\
Повторить поиск F3
Запустить программу с начала
Продолжить выполнение после остановки
Выполнить программу до данной позиции
Выполнить один следующий оператор
Пошаговое выполнение
Трассировка назад
Трассировка вперед
Включить/выключить точку прерывания
Включить точку наблюдения
Помощь по контексту
Клавиши запуска и отладки
SHIFT+F5
F5
F7
F8
F10
SHIFT+F8
SHIFT+F10
F9
SHIFT+F91
Клавиши помощи
FF
Стереть экран помощи ESC
Смотреть Help on Help SHIFT+F1
Смотреть помощь через команды меню Help ALT+H
Курсор — к следующему ключевому слову TAB
Курсор — к предыдущему ключевому слову SHIFT+TAB
К следующему ключевому слову с данной буквы буква
1 С мышью наблюдение включается: {SHIFT} + правая кнопка мыши.
2 Или правая кнопка мыши.
393
К предыдущему ключевому слову с данной буквы SHIFT+буква
К предыдущему окну помощи (до 20 раз) ALT+F1
К предыдущему окну помощи в Help-файле
SHIFT+CTRL+F1
ПРИЛОЖЕНИЕ 3
Коды ошибок
№№
3
4
5
6
7
9
11
14
16
19
20
24
25
27
39
40
50
51
Ошибка
RETURN without GOSUB
Out of DATA
Illegal function call
Overflow
Out of memory
Subscript out of range
Division by zero
Out of string space
String formula too complex
No RESUME
RESUME without error
Device timeout
Device fault
Out of paper
CASE ELSE expected
Variable required
FIELD overflow
Internal error
Перевод
RETURN без GOSUB
Конец данных в операторе
DATA
Неверный вызов функции
Переполнение
Исчерпана оперативная па-
мять
Индекс вне диапазона
Деление на ноль
Нет места для строк
Слишком сложная формула
Нет RESUME
RESUME при отсутствии
ошибки
Тайм-аут устройства
Сбой на устройстве
Нет бумаги на принтере
Требуется CASE ELSE
Обязательна переменная
Переполнение FIELD
Внешняя ошибка
394
№№
52
53
54
55
56
57
58
59
61
62
63
64
67
68
69
70
71
72
73
74
75
76
Ошибка
Bad file name or 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 of file
Bad record number
Bad file name
Too many files
Device unavailable
Communication-buffer
overflow
Permission denied
Disk not ready
Disk-media error
Advanced feature unavailable
Rename across disks
Path/File access error
Path not found
Перевод
Неверное имя или номер
файла
Файл не найден
Неверный тип файла
Файл уже открыт
Оператор FIELD активен
Ошибка ввода/вывода
Файл уже существует
Неверная длина записи
На диске нет места
Ввод после конца файла
Неверный номер записи
Неверное имя файла
Слишком много файлов
Устройство отсутствует
Переполнение коммуника-
ционного буфера
Доступ запрещен
Диск не готов
Физическое повреждение
диска
Расширенное средство не
доступно
Переименование между дис-
ками
Ошибка доступа/пути к
файлу
Путь не найден
395
ПРИЛОЖЕНИЕ 4
Ограничения QuickBASIC
Имена, символьные строки и числа
Ограничение
Длина имени переменной,
символов
Длина символьной строки,
символов
Целые числа
Длинные целые числа
Числа обычной точности (>0)
Числа обычной точности (<0)
Числа двойной точности (>0)
Числа двойной точности (<0)
Максимум
40
32767
32767
2147483647
3.402823 Е+38
-1.401298 Е-45
1.797693 D+308
4.940656 D-324
Минимум
1
0
-32768
-2147483648
1.401298 Е-45
3.402823 Е+38
4.94066 D-324
1.79769 D+308
Массивы
Ограничение
Максимум
Минимум
Размер (все элементы):
Static
Dynamic
Число размерностей
Значение индекса1
65535 F4 К)
Свободная
оперативная
память
8
32767
1
1
1
-32768
Максимальный диапазон между индексами = 32767
396
Процедуры и файлы
Ограничение
Размер процедуры, байт
Число аргументов процедуры
Вложение INCLUDE-файлов
Размер модуля, байт
Количество файлов
Количество записей в файле
Размер записи файла, байт
Размер файла
Путь файла, символов
Сообщения об ошибках
Максимум
65535 F4 К)
60
5 уровней
65535 F4 К)
255
2147483647
32767 C2 К)
Свободное место
на диске
127
255
Минимум
0
0
0
0
1
1
1
п
1
1
Редактирование
Ограничение
Поиск текста, символов
Замена текста, символов
Маркеры позиции курсора
Точки наблюдения
Число строк в окне
Immediate
Количество символов
в одной строке:
Длина строки COMMANDS,
символов
Максимум
79
39
4
8
10
255
124
Минимум
1
0
0
0
0
0
0
397
ПРИЛОЖЕНИЕ 5
ASCII-коды, Скан-коды
ASCII-коди
Основная ASCII-таблица (символы с кодами 0-127):
000
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
(mil)
(soh)
(stx)
(etx)
(eot)
(enq)
(ack)
(bel)
(bs)
(tab)
(If)
(vt)
(np)
(cr)
(so)
(si)
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
(die)
(del)
(dc2)
(dc3)
(dc4)
(nak)
(syn)
(etb)
(can)
(em)
(eof)
(esc)
(fs)
(gs)
(rs)
(us)
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
sp
i
ii
#
$
%
&
'
(
)
*
+
-
.
/
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
0
1
2
3
4
5
6
7
8
9
:
<
=
>
064
065
066
067
068
069
070
071
@
A
В
С
D
E
F
G
080
081
082
083
084
085
086
087
P
Q
R
S
T
U
V
W
096
097
098
099
100
101
102
103
a
b
с
d
e
f
g
112
113
114
115
116
117
118
119
P
q
r
s
t
u
V
w
398
072
073
074
075
076
077
078
079
Н
I
J
К
L
M
N
0
088
089
090
091
092
093
094
095
X
Y
Z
[
\
]
Л
104
105
106
107
108
109
110
111
h
i
j
к
1
m
n
о
120
121
122
123
124
125
126
127
X
У
z
{
1
}
~
V
Расширенная ASCII-таблица (символы с кодами 0-127):
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
А
Б
В
Г
д
Е
Ж
3
И
Й
К
л
м
н
О
п
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
Р
С
т
У
ф
X
ц
ч
ш
щ
ъ
ы
ь
э
ю
я
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
а
б
в
г
д
е
ж
3
и
й
к
л
м
н
о
п
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
щ
Щ
1
i
н
{
41
=1
J
II
J)
J
J
1
192
193
194
195
196
197
198
L
±
T
-
+
r
208
209
210
211
212
213
214
JL
T
T
1
1=
p
IT
224
225
226
227
228
229
230
P
с
T
У
Ф
X
Ц
240
241
242
243
244
245
246
>
<
f
J
199
200
201
202
203
204
205
206
207
It
It
If
JL
ТГ
If
=
¦
215
216
217
218
219
220
221
222
223
*
J
Г
1
H
1
1
¦
231
232
233
234
235
236
237
238
239
ч
ш
Щ
ъ
Ы
ь
э
ю
я
247 «
248
249
250
251 V
252
253 2
254 ¦
255
Символы псевдографики
для рисования рамок и таблиц
Для ввода этих символов нажмите клавишу {ALT} и, не от-
пуская ее, введите нужный код на цифровой клавиатуре, а затем
отпустите клавишу {ALT}. Чтобы ввести символы с кодами
меньше, чем 32 (управляющие коды), введите с клавиатуры ком-
бинацию клавиш АР (нажмите клавишу {CTRL} и, не отпуская
ее, клавишу с латинской буквой Р, и отпустите обе клавиши), а
затем нужный управляющий код, как обычный символ через кла-
вишу {ALT}.
218
г
195
192
L
179
1
Одинарная
линия
194
т
197
т
193
X
196
191
п
180
i1
217
j
201
If
204
If
200
Ik
186
II
Двойная
линия
203
тг
206
+
202
205
187
И
185
i
188
176
219
1
220
¦
16
>
Символы-
шаблоны
177
221
1
223
17
<
178
1
222
1
254
¦
400
Скан-коды клавиатуры
Клавиша
ESC
! или 1
@ или 2
# или 3
$ или 4
% или 5
Л или 6
& или 7
* или 8
( или 9
) или 0
_ или -
+ или =
LEFT
TAB
Q
W
E
R
T
Y
U
I
0
P
{ или [
} или ]
RETURN
Hex-
КОД
01
02
03
04
05
06
07
08
09
0A
OB
ОС
0D
0E
OF
10
11
12
13
14
15
16
17
18
19
1A
IB
1С
Клавиша
CTRL
A
S
D
F
G
H
J
К
L
: или ;
" или '
~ или
LEFT SHIFT
1 или \
Z
X
С
V
В
N
M
< или
> или .
? или /
RIGHT
SHIFT
PRTSC или
*
ALT
Hex-
код
ID
IE
IF
20
21
22
23
24
25
26
27
28
29
2A
2B
2C
2D
2E
2F
30
31
32
33
34
35
36
37
38
Клавиша
SPACEBAR
CAPSLOCK
Fl
F2
F3
F4
F5
F6
F7
F8
F9
F10
NUMLOCK
SCROLLOCK
HCME или 7
UP или 8
PGUP или 9
-
LEFT или 4
5
RIGHT или 6
+
END или 1
DCWN или 2
PGDN или 3
INS или 0
DEL или .
Hex-
КОД
39
ЗА
3B
ЗС
3D
3E
3F
40
41
42
43
44
45
46
47
48
49
4A
4B
4C
4D
4E
4F
50
51
52
53
ПРИЛОЖЕНИЕ 6
Типы дисплеев и экранные режимы
Описание экранных режимов SCREEN
Ниже перечислено подробное описание каждого экранного
режима, задаваемого оператором SCREEN для видеоадаптеров1:
• IBM Color Graphics адаптер (CGA)
• IBM Enhanced Graphics адаптер (EGA)
• IBM Video Graphics Array (VGA)
• IBM Multicolor Graphics Array (MCGA).
• Hercules Graphics Card (HGC), Graphics Card Plus (GCP)
SCREEN 0
Это текстовый режим. Поддерживается адаптерами MDPA,
CGA, EGA, VGA.
• Формат текста 40x25, 40x43, 40x50, 80x25, 80x43, 80x50 с раз-
мером символа 8x8 (CGA), 8x14, 9x14, 9x16 (EGA или VGA)
точек;
• 16 цветов, присваиваемых 2 атрибутам (MDPA);
• 16 цветов, присваиваемых 16 атрибутам (CGA, EGA с 64К);
• 64 цветов, присваиваемых 16 атрибутам (EGA, VGA).
SCREEN 1
Это графический режим с разрешением 320x200. Поддержи-
вается адаптерами CGA, EGA, VGA, MCGA.
• Формат текста 40 х 25, размер символа 8x8 точек;
• 16 фоновых цветов и одна из двух 3-цветовых палитр для ос-
новного цвета (CGA);
• 16 цветов, присваиваемых 4 атрибутам (EGA, VGA).
' Многие режимы поддерживают несколько комбинаций числа строк и стол-
бцов на экране. Подробности — в описании оператора WIDTH.
402
SCREEN 2
Это графический режим с разрешением 640x200. Поддержи-
вается адаптерами: CGA, EGA, VGA, MCGA.
Формат текста 80x25 с размером символа 8x8 точек.
16 цветов, присваиваемых 2 атрибутам (EGA, VGA).
SCREEN 3
Это графический режим с разрешением 720x348. Для него
требуется адаптер Hercules и монохромный монитор.
• Формат текста 80x25, 9x14 точек размер символа;
• 2 экранные страницы A страница, если есть второй дисплей-
ный адаптер);
• Оператор PALETTE не поддерживается.
SCREEN 4
Это графический режим с разрешением 640x400. Для него
требуется адаптер Hercules и монохромный монитор.
• Поддерживает компьютеры Olivetti М24, М240, М28, М280,
М380, М380/С, М380/Т и AT&T 6300;
• Формат текста 80x25, 8x16 точек размер символа;
• 1 из 16 цветов — основной (выбирает оператор COLOR), фо-
новый всегда черный.
SCREEN 7
Это графический режим с разрешением 320x200. Для него
требуется адаптер EGA или VGA.
• 40 х 25 текстовый формат, размер символа 8x8 точек;
• 32К — размер страницы, номера страниц зависят от экранной
памяти: 0-1 F4К), 0-3 A28К), 0-7 B56К);
• 16 цветов присваиваются 16 атрибутам.
SCREEN 8
Это графический режим с разрешением 640x200. Для него
требуется адаптер EGA или VGA.
• 80 х 25 текстовый формат, размер символа 8x8 точек;
403
• 64К — размер страницы, номера: О F4К), 0-1 A28К), 0-3
B56К);
• 16 цветов присваиваются 16 атрибутам.
SCREEN 9
Это графический режим с разрешением 640x350. Для него
требуется адаптер EGA или VGA.
• 80x25 или 80x43 текстовые форматы, соответственно 8x14 или
8x8 точек — размер символа;
• 64К — размер страницы, номер 0 F4К память адаптера),
128К;
• размер страницы, номера: 0 A28К) или 0-1 B56К);
• 16 цветов для 4 атрибутов F4К память адаптера);
• 64 цветов для 16 атрибутов (более 64К памяти адаптера).
SCREEN 10
Это графический режим с разрешением 640x350. Для него
требуется адаптер EGA или VGA и монохромный монитор.
• 80x25 или 80x43 текстовые форматы, соответственно 8x14 или
8x8 точек — размер символа;
• 128К — размер страницы, номера: 0 A28К) или 0-1 B56К).
До 9 оттенков серого для 4 атрибутов.
SCREEN 11
Это графический режим с разрешением 640 х 480. Для него
требуется адаптер VGA или MCGA.
• 80x30 или 80x60 текстовые форматы, соответственно 8x16 или
8x8 точек — размер символа.
• До 256К цветов для 2 атрибутов.
SCREEN 12
Это графический режим с разрешением 640 х 480. Для него
требуется адаптер VGA.
• 80 х 30 или 80 х 60 текстовые форматы, соответственно 8x16
или 8x8 точек — размер символа.
До 256К цветов для 2 атрибутов.
•
404
SCREEN 13
Это графический режим с разрешением 320x200. Для него
требуется адаптер VGA или MCGA.
• 40x25 формат текста, размер символа 8x8 точек.
• До 256К цветов для 256 атрибутов.
ПРИЛОЖЕНИЕ 7
Словарь зарезервированных слов
В этом приложении приведена таблица, содержащая список
зарезервированных слов QuickBASIC. Эти слова не могут быть
использованы в качестве меток или имен переменных или проце-
дур. Список включает ключевые слова языка, а также служебные
инструкции, которые обрабатываются средой QB и компилято-
ром ВС. Во второй графе таблицы приведена краткая расшиф-
ровка наименование ключевого слова языка BASIC и дается при-
близительный перевод.
ABS
ACCESS
ALIAS
AND
ANY
APPEND
AS
ASC
ATN
BASE
BEEP
BINARY
BLOAD
BSAVE
ABSOLUTE — абсолютное значение
доступ
замена
и
любой
добавление в конец (файла)
как
ASCii code — код из таблицы ASCII
арктангенс
точка отсчета
сигнал
двоичный (файл)
Binary LOAD — загрузка образа (памяти)
Binary SAVE — запись образа (памяти)
405
BYVAL
CALL
CALLS
CASE
CDBL
CDECL
CHAIN
CHDIR
CHR$
CINT
CIRCLE
CLEAR
CLNG
CLOSE
CLS
COLOR
COM
COMMANDS
COMMON
CONST
COS
CSNG
CSRLIN
CVD
CVDMBF
BY VALue — (передача) по значению
вызов (BASIC-процедуры)
вызов (не BASIC-процедуры)
случай
Conversion number to DouBLe — преобразование
числа к типу удвоенной точности
C-language DECLare — объявить процедуру, ис-
пользующую передачу параметров по правилам
языка С
передать управление (файлу)
CHange DIRectory — сменить директорию
CHaracteR — символ •
Conversion number to INTeger — преобразование
числа к целому типу
окружность
обнулять
Conversion to LoNG — преобразовать к длин-
ному целому числу
закрыть (файл)
CLear Screen — очистигь экран
цвет
COMmunicate port — параллельный порт
командная строка
общая (переменная/группа переменных)
CONSTant — константа
косинус
Conversion to SiNGle — преобразовать к длин-
ному целому числу
CurSoR LINE — строка, на которой находится
курсор
ConVert string to Double — представить строку
как число удвоенной точности
ConVert Double in Microsoft Binary Format —
представить строку в формате Microsoft Binary
406
CVI
CVL
CVS
CVSMBF
DATA
DATES
DECLARE
DEF
DEFDBL
DEFINT
DEFLNG
DEFSNG
DEFSTR
DIM
DO
DOUBLE
DRAW
ELSE
ELSEIF
как число удвоенной точности1
ConVert string to Integer — представить строку
как целое число
ConVert string to Long — представить строку как
длинное целое число
ConVert string to Single — представить строку
как число обычной точности
ConVert Single in Microsoft Binary Format —
представить строку в формате Microsoft Binary
как число обычной точности1
Данные
Текущая дата (ММ-ДД-ГГГГ)
Объявить (процедуру/функцию)
DEefine Fn function — определить функцию FN
DEFine DouBLe — определить тип данных уд-
военной точности
DEFine INTeger — определить целый тип дан-
ных
DEFine LoNG — определить длинный целый
тип данных
DEFine SiNGle — определить тип данных
обычной точности
DEFine STRing — определить символьный тип
данных
DIMension — резервирование места (для масси-
ва/переменной)
делать
двойной точности (переменная)
рисовать
иначе
ELSE IF — иначе, если ...
1 Этот оператор оставлен в языке для совместимости с предыдущими версия-
ми языка BASIC. Для его использования требуется загрузить среду QB с ключом
MBF (Microsoft Binary Format): C:\QB45>qb /MBF
407
END
ENDIF
ENVIRON
ENVIRONS
EOF
EQV
ERASE
ERDEV
ERDEV$
ERL
ERR
ERROR
EXIT
EXP
FIELD
FILEATTR
FILES
FIX
FOR
FRE
FREEFILE
FUNCTION
GET
GOSUB
Конец (программы/процедуры/функции или
управляющей конструкции)
END IF — конец условия IF
ENVIRONment dos change — изменить пере-
менную окружения DOS
ENVIRONment dos get — получить значение
переменной окружения DOS
End of File — конец файла
EQuiValence — эквивалентность
стереть содержимое или уничтожить массив
Error on DEVice code — код внешнего устрой-
ства, вызвавшего ошибку
Error on DEVice name — название внешнего ус-
тройства, вызвавшего ошибку
ERror Line — номер строки которая вызвала
ошибку
ERRor code — код ошибки
ошибка
выход (из процедуры/функции, управляющей
конструкции)
экспонента
поле (файла прямого доступа)
FILE ATTRibute — атрибут файла
файлы
FIXed — округление
для
FREe memory — свободная область памяти
FREE FILE number — свободный номер файла
функция
взять
GO SUBroutine — перейти к подпрограмме
408
GOTO
HEX$
IF
IMP
INKEY$
INP
INPUT
INPUTS
INSTR
INT
INTEGER
IOCTL
IOCTL$
IS
KEY
KILL
LBOUND
LCASE$
LEFTS
LEN
LET
LINE
LIST
GO TO2 — перейти к
HEXadecimal string — шестнадцатеричная строка
если
IMPlication — импликация
INput KEY — ввести символ
INput from Port — прочитать байт из порта вво-
да/вывода
ввести (переменную)
INPUT string — ввести строку символов
IN STRing position — позиция в строке
INTeger —целое (число)
целое (тип данных)
Input/Output ConTroL data string to device
driver — послать управляющую строку драйверу
устройства
Input/Output ConTroL data string from device
driver — принять управляющую строку от драй-
вера устройства
если
клавиша
уничтожить (файл)
Lower BOUND — нижняя граница (массива)
Lower-CASE string — строка в нижнем регистре
слева
длина
пусть будет3
линия
список (функциональных клавиш)
2 Старайтесь не использовать оператор GOTO для прямой передачи управле-
ния. Вместо этого используйте управляющие конструкции SELECT...END
SELECT, DO...LOOP, WHILE...WEND, FOR. NEXT. Подробности см. в Главе 2
"Основы языка BASIC", раздел "Избегайте устаревших конструкций"
3 Этот оператор может опускаться при написании программы. Помните, как
как пели "Beatles": Let it be... (Пусть будет...)
409
LOC
LOCAL
LOCATE
LOCK
LOF
LOG
LONG
LOOP
LPOS
LPRINT
LSET
LTRIM$
MID$
MKD$
MKDIR
MKDMBF$
MKI$
MKL$
MKS$
MKSMBF$
Location Of Current Position — место текущей
позиции (в файле)
местный4
разместить
заблокировать (файл)
Len Of File — длина файла
логарифм
Длинное целое (тип данных)
пока
Line Printer's head position — позиция печатаю-
щей головки принтера
Line printer PRINT — печатать на принтер
Left SET — присвоить слева (для файлов пря-
мого доступа)
Left TRIM — подровнять (убрать пробелы) слева
MIDdle — середина
МаКе Double to string — превратить число удво-
енной точности в строку
МаКе DIRectory — сделать директорию
МаКе Double to string in Microsoft Binary
Format — превратить число удвоенной точности
в строку в формате Microsoft Binary5
МаКе Integer to string — превратить целое число в
строку
МаКе Long to string — превратить длинное це-
лое число в строку
МаКе Single to string — превратить число обыч-
ной точности в строку
МаКе Single to string in Microsoft Binary
Format — превратить число удвоенной точности
в строку в формате Microsoft Binary
4 В QuickBASIC 4.5 это ключевое слово не используется — зарезервировано
для будущего использования. Оно задействовано в Microsoft BASIC PDS 7.1. В
нем можно отлавливать ошибки времени выполнения на уровне процедуры опе-
ратором ON LOCAL ERROR GOTO ErrorHandler.
410
MOD
NAME
NEXT
NOT
OCT$
OFF
ON
OPEN
OPTION
OR
OUT
OUTPUT
PAINT
PALETTE
PCOPY
PEEK
PEN
PLAY
PMAP
POINT
POKE
POS
PRESET
PRINT
PSET
PUT
RANDOM
RANDOMIZE
READ
модуль
имя
следующий
нет
OCTal — восьмеричный
выключить (отслеживание событий или строку
функциональных клавиш
включить (отслеживание событий или строку
функциональных клавиш
открыть (файл или устройство)
начало (точки отсчета
или
считать байт из порта ввода/вывода
вывести
закрасить
палитра
Page COPY — скопировать экранную страницу
прочесть байт по машинному адресу
световое перо
играть (ноты)
Point MAP — преобразование физических коор-
динат экрана в логические и наоборот
точка
записать байт по машинному адресу
POSition — позиция
Point RESET — стереть точку
напечатать
Point SET — вывести точку
поместить
прямой (доступ к файлу)
случайный
считать
411
REDIM
REM
RESET
RESTORE
RESUME
RETURN
RIGHTS
RMDIR
RND
RSET
RTRIM$
RUN
SADD
SCREEN
SEEK
SEG
SELECT
SETMEM
SHARED
SHELL
SIGNAL
SIN
SINGLE
SLEEP
SOUND
SPACES
REDIMension — повторно определить размер-
ность
REMark — комментарий
закрыть (все открытые файлы)
восстановить
продолжить
возвращение
справа
ReMove DIRrectory — удалить директорию
RaNDom — случайным образом
Right SET — присвоить слева (для файлов пря-
мого доступа)
Right TRIM — подровнять (убрать пробелы)
справа
запустить
String ADDress — адрес строки (в памяти)
экран
установить позицию (в файле)
SEGment — сегмент (памяти)
выбрать
SET MEMory — установить размер динамичес-
кой области память
разделяемый
временный выход
сигнал6
синус
обычной точности (тип данных)
задержка
звук
SPACE string — строка пробелов
6 В QuickBASIC 4.5 это ключевое слово не используется — зарезервировано
для будущего использования. Оно задействовано в Microsoft BASIC PDS 7 1 и
используется для отслеживания событий в среде OS/2.
412
SPC
SQR
STATIC
STEP
STICK
STOP
STR$
STRIG
STRING
STRINGS
SUB
SWAP
SYSTEM
TAB
TAN
THEN
TIMES
TO
TROFF
TRON
TYPE
UBOUND
UCASE$
UNLOCK
UNTIL
USING
VAL
VARPTR
VARPTRS
VARSEG
Skip sPaCes — пропустить пробелы
квадратный корень
локальная (переменная)
шаг
Specified joySTICK — управления джойстиком
стоп
STRing — строка
Specified joystick TRIgger — нажатие кнопки
джойстика
символьное (тип данных)
строка символов
процедура
обмен
система (выход в DOS)
табулятор
тангенс
тогда
время
до
TRace OFF — выключить трассировку
TRace ON — включить трассировку
тип
Upper BOUND — верхняя граница (массива)
Upper-CASE string — строка в верхнем регистре
разблокировать (файл)
до тех пор, пока
используются
VALue — значение
вычисление адреса переменной
строковое представление адреса переменной
вычисление сегмента адреса переменной
413
VIEW
WAIT
WEND
WHILE
WIDTH
WINDOW
WRITE
XOR
обзор
ждать
конец цикла
пока
ширина
окно
вывести
неэквивалентность
ПРИЛОЖЕНИЕ 8
Метакоманды
Метакоманды — это инструкции, предназначенные для об-
работки текста компилятором. Они начинаются со знака $ и вво-
дятся как обычные комментарии. В одном комментарии может
размещаться несколько метакоманд, отделяемых пробелами. Но
для удобочитаемости текста программы лучше каждую метако-
манду помещать на отдельной строке.
Метакоманды, имеющие аргумент, содержат двоеточие меж-
ду самой метакомандой и аргументом:
REM $METACOMMAND [:аргумент]
Символьные аргументы заключаются в апострофы (').
Пробелы между элементами метакоманды игнорируются ком-
пилятором. Формы записи метакоманд могут быть следую-
щими:
REM $STATIC $INCLUDE: 'datadefs.bi'
REM $STATIC $INCLUDE : 'datadefs.bi'
¦$STATIC $INCLUDE: 'datadefs.bi'
¦$STATIC $INCLUDE : 'datadefs.bi'
1 $STATIC
"$INCLUDE : 'datadefs.bi'
Между знаком $ и именем метакоманды не должно быть
пробела. Если вы хотите обозначить метакоманду просто как
414
комментарий, поместите какой-нибудь символ перед знаком $.
Такая строка будет обрабатываться как комментарий:
REM x$STATIC $INCLUDE: 'datadefs.bi'
Метакоманды $STATIC и $DYNAMIC
$STATIC и $DYNAMIC — это метакоманды, управляющие
размещением массивов, объявленных операторами DIM и
REDIM.
REM $STATIC
или
1 $STATIC
REM $DYNAMIC
или
' $DYNAMIC
Эти метакоманды указывают компилятору как распределять
память для массивов. Аргументов для них не требуется.
SSTATIC устанавливает объем памяти во время компиляции.
Оператор ERASE обнуляет элементы числовых массивов, а сим-
вольным — присваивает значение пустой строки (""). Сами мас-
сивы не уничтожаются. Оператор REDIM не влияет на такие
массивы.
SDYNAMIC устанавливает объем памяти при выполнении
программы. Это значит, что оператор ERASE удаляет массивы и
освобождает память для дальнейшего использования. Оператор
REDIM изменяет размеры динамических массивов.
Метакоманды SSTATIC и SDYNAMIC влияют на все масси-
вы, кроме тех, которые не описаны оператором DIM, которые
всегда размещаются как статические.
Метакоманда SINCLUDE
SINCLUDE — метакоманда, позволяющая QuickBASIC чи-
тать и компилировать другой исходный файл на языке BASIC в
определенное место текущей программы.
REM $INCLUDE: 'файл'
или
1 $INCLUDE: 'файл'
4.15
Метакоманда $ INCLUDE указывает компилятору переклю-
читься с обработки одного файла на другой, указанный в аргу-
менте. Когда компилятор дойдет до конца этого файла, он воз-
вратится к исходному файлу. Метакоманда SINCLUDE должна
быть последней в строке:
DEFINT I-N ' $INCLUDE: 'COMMON.BAS'
Существует ограничение на включаемые файлы — они не
должны содержать процедур SUB и FUNCTION, а также опера-
торов GOTO.
ПРИЛОЖЕНИЕ 9
Что почитать о языке BASIC
БИБЛИОГРАФИЯ
статей, опубликованных в 1988-1993 гг.
В эту библиографию не включены материалы постоянной
рубрики "MS BASIC" журнала "Монитор", который ведется А. А.
Колесовым, начиная с номера 2'93.
Журнал "Монитор"
4.93 Стр.72-78
В. Очков
"Двенадцать программ с дублями и эпиграфами, или три триа-
ды программирования, а точнее третий лишний, а второй непра-
вильный "
В статье приводятся 12 листингов программ, реализующих
различные алгоритмические конструкции, а также комментарии
к этим программам.
Журнал "Мир ПК"
В мире персональных компьютеров 2'88 Стр. 54-76
Дейвид Уилльямз.
"Программирование на Quick Basic"
416
В статье рассказывается, как использовать новые эффектив-
ные средства Quick Basic, а также описаны некоторые возможно-
сти, не упомянутые в руководстве.
"Управление окнами "
Краткое описание библиотеки управления окнами Quick
Windows.
"Усовершенствования QuickBASIC"
Краткий обзор новых возможностей Quick Basic версии 4.0.
Джон Вулфскилл.
"Работа а адаптером EGA на Бейсике "
Рассматривается один из приемов программирования — за-
пись образа экрана на диск.
Джон Вулфскилл.
"Волшебные клавиши"
Рассматривается программа AUTOMAC.BAS, которая позво-
ляет выполнить ряд программ или команд DOS, нажав одну кла-
вишу.
Джон Вулфскилл.
"Горизонтальная прокрутка "
Рассматривается программа HSCROLL, предназначенная для
горизонтальной прокрутки.
Роджер Олфорд.
"Разные стороны быстродействия "
В статье рассказывается о возможностях повышения быстро-
действия.
Грег Перри.
"Повышение скорости выполнения программ на Бейсике"
Рассматриваются некоторые очевидные приемы, использова-
ние которых может повысить скорость выполнения программ.
Дейвид Литхозер.
" Ставьте в программах ловушки ошибок."
Рассматривается программа-ловушка ошибок ERRTRAP.BAS,
которая фиксирует 99% ошибок, связанных с факторами, вне-
шними по отношению к программе, такими как переполнение
диска или не готовность принтера.
Д. Уинфри.
"Если вы задали время, мы запишем Ваш файл "
417
Рассматривается программа PROG.BAS, позволяющая сохра-
нить на диске последнюю версию программы.
"Переназначение вывода "
Рассказывается о том, как можно так переназначить вывод,
что выдаваемые программой данные будут поступать и в файл на
диске, и на экран.
Дж. Володзко.
"Подавление ошибок "
Приводится подпрограмма, которая во время выполнения
программы, создающей различные файлы данных, проверяет,
сколько свободного пространства осталось на диске.
"Обращение к DOS из программы на Бейсике "
Рассказывается о команде SHELL, которая позволяет временно
приостановить работу программы для выполнения команд DOS.
Мир ПК 1/90 Стр. 42
Ричард Лэндри
"Бейсик — надежда и опора "
Рассматриваются тенденции развития языка Бейсик в на-
правлении создания единого макроязыка.
Мир ПК 4/91 Стр. 14-18
В. П. Дьяконов
"От простого Бейсика к быстрому"
Краткий обзор и опыт применения различных языков семей-
ства Basic: GW-BASIC, QBASIC, QuickBASIC 4.0 и 4.5, BASIC
Professional.
Мир ПК 7'91
А. А. Колесов, О. Р. Павлова
"SURFER — пакет инженерной графики "
Если вы имеете дело с данными, представленными в виде
двумерной функции F(x,y) — экстраполяция, графический вывод
и пр., — а также, если вас интересует масштабный вывод вектор-
ных графических изображений, — вам надо прочитать эту статью.
Мир ПК Г92
А. А. Колесов, О. Р. Павлова
"Для тех, кто не хочет расставаться с ФОРТРАН'ом "
418
Подробно рассматриваются проблемы смешанного програм-
мирования (стыковки) QuickBASIC — FORTRAN. Практические
советы, программные примеры. Все сказанное здесь во многом
это годиться и для QB — С, QB — PASCAL).
Мир ПК, 5'92
A. А. Колесов, О. Р. Павлова
"Бейсик: от "быстрого " к "профессиональному "
О системе Microsoft BASIC Professional Development System
v.7.1 Что появилось нового по сравнению с QB 4.5, мнение авто-
ров о целесообразности перехода Quick -> PDS и пр.
Журнал "Компьютер Пресс"
Компьютер Пресс 8'90 Стр. 37-47
B. Яковлев
"Бейсик — язык для начинающих или для профессионалов?"
Обзор программных продуктов — GW-BASIC, BASICA,
QuickBASIC 4.5, Microsoft BASIC 6.0 , TrueBASIC , Turbo Basic,
PopBASIC 3.0, Thoroughbred BASIC 7.4, BBx Progression, 387BA-
SIC, Watcom BASIC. Обзор библиотек для языка BASIC — уни-
версальные библиотеки, а также специальные библиотеки, пред-
назначенные для передачи данных, управления базой данных,
для научных расчетов, графики и т. д. Кроме того, в статье рас-
сматриваются специальные вопросы — вызов функций из
Microsoft BASIC 6.0 и использование машинного кода в Бейсике.
Компьютер Пресс, 3'91
А. А. Колесов
"QuickBASIC — это то, что вам нужно "
Обсуждаются преимущества работы в среде QB, приводится
краткое описание библиотек, разработанных автором.
Компьютер Пресс, 5'91
А. А. Колесов
"Опыт разработки специализированных баз данных"
Обсуждаются проблемы создания систем накопления и обра-
ботки геоэкологических данных, детально показаны возможности
использования библиотеки работы с .DBF-файлами для
QuickBASIC.
419
Компьютер Пресс, 2'92, 3'92
А. А. Колесов, М. Коновалов
"Как повысить скорость графического вывода на экран при ра-
боте на QuickBASIC"
Кроме некоторого общего анализа, дается ряд конкретных
рекомендаций и тексты процедур на ассемблере.
Ф. Зубанов
"Microsoft Visual BASIC: первые шаги в программировании для
Windows"
Статья знакомит с новым пакетом Visual Basic, в ней можно по-
лучить первые навыки программирования в среде Windows, а также
узнать о некоторых способах расширения возможностей пакета.
Кроме того, приводится англо-русский словарь новых терминов.
Компьютер Пресс, 5'92
А. А. Колесов
"Полезные программные конструкции для QuickBASIC"
Полезные конструкции и тексты программ (создание окон,
преобразование данных и некоторые другие штучки).
Компьютер Пресс 6'93 Стр. 33-34
А. Федоров
"Визуальное программирование: Microsoft Visual Basic 2.0"
Краткий обзор новинок Visual Basic версии 2.0. Оценка этого
пакета автором.
Компьютер Пресс 10'93 Стр. 32
А. Федоров
"Visual Basic 3.0"
Краткий обзор новых возможностей версии 3.0: поддержка раз-
личных СУБД и протокола создания составных документов OLE 2.0,
а также утилита для создания программ установки SetupWizard.
Журнал "Персональные программы"
N2.1 2.2, 1992
Ю. Е. Купцевич
"Программирование ПЭВМ типа IBM PC/XT/AT в среде
QuickBASIC 4.5"
420
Газета "СофтМаркет"
СофтМаркет 6/1991 Стр. 6
Д. С. Аглицкий
"С новой силой "
Краткий обзор новых возможностей и история развития
Power Basic версии 2.10.
СофтМаркет, N 13G7), апрель 1993 Стр. 3
"Усовершенствование Visual Basic упрощает программирование
под Windows"
Краткий обзор новых возможностей и существенных изме-
нений новой версии пакета Visual Basic for Windows 2.0 по срав-
нению с предыдущей.
"ComputerWorld" N 24, 23.06.93
А. А. Колесов
"Как купить продукты Microsoft"
Проблемы легального приобретение программ, цели и задачи Ас-
социации пользователей MS BASIC (АПМБ), взаимоотношения
АПМБ с московским Microsoft, краткое мнение автора о перспективах
использования разных вариантов языка — Quick, PDS, Visual.
"ComputerWorld" N 31(91), август 25, 1993 Стр.28-30
Роберт Дельросси
"Версия 2.0знаменует зрелость Visual Basic"
Детальный анализ отличий и усовершенствований версии 2.0
по всем параметрам: рабочие характеристики и среда программи-
рования, язык, производительность, документация, простота ис-
пользования и освоения, поддержка.
"ComputerWorld" N 31(91), август 25, 1993 Стр. 5
Kelley Damore
"Visual Basic готов выступить в роли общего макроязыка "
Анонс нового продукта корпорации Microsoft — макроязыка
Visual Basic, Applications Edition, который будет входить в состав
пакетов Excel 5.0 и Microsoft Project 4.0.
"ComputerWorld" N 46A06), декабрь 8, 1993 Стр. 1
Michael Vizard
"Язык Visual Basic: пока все в порядке "
421
Анонс языка прикладного программирования Microsoft Visual
Basic Applications (VBA). Приводятся отзывы пользователей бета-
версии языка.
Книги издательства "ABF"
Хачатур Арушанов
"Visual BASIC 3.0/4.0"
Книга представляет собой перевод на русский язык справоч-
ной системы Visual BASIC. Полезна для начинающих пользовате-
лей, не вполне владеющих английским языком.
Григорий Зельднер
"Microsoft BASIC Professional Development System 7.1"
В книге рассказывается о языке программирования Microsoft
BASIC 7.1. Microsoft BASIC является продолжением линии Quick-
BASIC — стандарта de facto для всех компиляторов языка BASIC.
Новые языковые расширения делают Microsoft BASIC идеальным
инструментом для разработки программ различного назначения.
Григорий Зельднер
"Библиотеки языка BASIC"
В книге продолжается рассказ о языке программирования
Microsoft BASIC Professional Development System, практически
неизвестном в нашей стране широкому кругу любителей BASIC.
Выпустив на рынок этот замечательный пакет для професси-
онального разработчика, фирма Microsoft позаботилась о включе-
нии в него разнообразных библиотек (add-on libraries), охватыва-
ющих практически все запросы BASIC-программиста.
Индекс
$ DYNAMIC, 411
SINCLUDE, 411
SSTATIC, 411
ASC, 287
ATN, 277
BEEP, 255
BLOAD, 196
BSAVE, 194
CDBL, 286
CHAIN, 327
CHR$, 286
CINT, 285
CIRCLE, 229
CLEAR, 271
CLNG, 285
CLOSE, 185
CLS, 219
COLOR, 220-2
COM(n), 309
COMMANDS, 338
COMMON, 129, 327
CONST, 121
COS, 277
CSNG, 285
CSRLIN, 179
CVC, 288
DATA, 133
DATES (оператор), 331
DATES (функция), 331
DEF FN, 97, 155
DEF SEG, 302
DEFran, 122
DIM, 123
DO. LOOP, 82, 143
DRAW, 234
END, 165
ENVIRON, 339
ENVIRONS , 340
EOF, 197
ERASE, 270
ERDEV, 323
ERDEVS, 323
ERL, 324
ERR, 324
ERROR, 324
EXIT, 166, 329
EXP, 274
FIELD, 198
FILEATTR, 202
FILES, 336
FIX, 284
FOR...NEXT, 81, 136
FREEFILE, 203
FUNCTION...
END FUNCTION, 157
GET, 186, 239
GOSUB...RETURN, 154
GOTO, 83
HEXS, 299
Huge-массивы, 69
IF...THEN...ELSE, 83, 148
Index, 23
IN KEYS, 172
INP, 211
INPUT, 89, 169
INPUT #, 189
INPUTS, 171, 191
INSTR, 295
INT, 284
IOCTL, 204
KEY, 312
KEY(n), 314
KILL, 337
LBOUND, 127
LCASES, 291
LEFTS, 296
LEN, 300
LINE, 231
LINE INPUT, 171
LINE INPUT #, 190
LINE INPUT:, 90
LOC, 205
LOCATE, 178
LOCK, 205
LOF, 198
LOG, 275
LPOS, 210
LPRINT, 92, 210
LPRINT USING, 92, 210
LSET, 201
LTRIMS, 292
MID$, 297, 298
MKDIR, 335
MKS$, 288
MOD, 275
NAME, 337
ОСИ, 299
ON ERROR, 321
ON COM(n), 309
ON KEY(n), 310
ON PEN, 315
ON PLAY(n), 316
ON STRIG(n), 318
ON TIMER(n), 318
ON UEVENT, 319
OPEN, 182
OPEN COM, 212
OPTION BASE, 129
OUT, 212
PAINT, 236
PALETTE, 223
PALETTE USING, 223
PCOPY, 225
PEEK, 302
PEN OFF, 315
PEN ON, 315
PEN STOP ,315
PLAY, 255
PLAYOFF, 317
PLAY ON, 317
PLAY STOP ,317
PLAY , 316
PMAP, 244
POINT, 242
POKE, 303
POS, 179
PRESET, 233
PRINT, 91, 173
PRINT #,192
PRINT # USING, 192
PRINT USING, 92, 174
PSET, 233
PUT, 188, 240
RANDOMIZE, 281
READ, 133
REDIM, 125
RESET, 185
RESTORE, 134
RESUME, 324
RIGHTS, 297
RMDIR, 335
RND, 282
RSET, 201
RTRIMS, 293
RUN, 329
SADD, 303
SCREEN, 226
SEEK, 207, 208
424
SELECT CASE, 150
SELECT..END SELECT, 83
SETMEM , 304
SGN, 275
SHELL, 328
SIN, 278
SLEEP, 267
SOUND, 262
SPACES, 293
SPC,180
SQR, 275
STICK, 216
STOP, 167
STRS, 300
STRIG, 217
STRINGS, 294
SWAP , 269
SYSTEM, 167
TAB, 180
TAN, 279
TIMES, 332
TIMER, 333
TIMER OFF, 318
TIMER ON, 318
TIMER STOP ,318
TROFF, 325
TRON, 325
TYPE, 128
UBOUND, 128
UCASES, 291
UEVENTOFF, 321
UEVENTON, 321
UEVENTSTOP, 321
UNLOCK, 205
VARPTR, 304
VARPTRS, 305
VARSEG, 304
VIEW, 227
VIEW PRINT, 227
WAIT, 218
WHILE...WEND, 82, 140
WIDTH, 181
WINDOW, 228
WRITE, 177
WRITE #, 193
Бланк-заказ на книги издательства "ABF"
Вырежьте табличку, вложите в конверт или наклейте на открытку
и отправьте по адресу: 117331 МОСКВА а/я 143
И для оптовых покупателей: @95) 935-26-79
ПРОШУ ВЫСЛАТЬ МНЕ ПЕРЕЧИСЛЕННЫЕ ИЗДАНИЯ
НАЛОЖЕННЫМ ПЛАТЕЖОМ. ОПЛАТУ ГАРАНТИРУЮ.
Автор
И Книжный
Е. Козловский
Э. Берлинер и др.
Г. Зельднер и др.
Л. Лопатников
В. Дьяконов
Г. Зельднер
Г. Зельднер
Ю. Шаров
С. Каратыгин и др.
В. Жельников
Ю. Шафрин
Е. Козловский
Книга
Norton Commander 5.0
Norton Utilities 7-8.0 C
тома)
Windows-95. Русская версия.
B-е дополненное издание)
Компьютер на связи!
Словарь современной
экономики.
Популярная энциклопедия
мультимедиа
Библиотеки BASIC 7.1
Лексикон
Введение в базы данных
Базы данных B тома)
Криптография.
Основы компьютерной
технологии (учебное
пособие для 7-11 кл.)
Диск-доктор.
Кол-во
Какие книги Вы хотели бы видеть изданными?
Фамилия (название
организации),
адрес и телефон
заказчика
Ю. Шафрин
ОСНОВЫ КОМПЬЮТЕРНОЙ
ТЕХНОЛОГИИ.
Учебное пособие для 7-11 классов по курсу
"Информатика и вычислительная техника"
Данное учебное пособие представляет собой
систематическое изложение основ современной
информационной технологии на базе компьюте-
ров IBM PC и объективно-ориентированного
подхода корпорации Microsoft.
Центральное место отведено изучению при-
ложений Windows.
Книга может быть использована как учебник
для старших классов общеобразовательных
школ, гимназий, лицеев по курсу "Основы ин-
форматики и вычислительной техники", а также
как пособие по самообразованию для начинаю-
щих пользователей.
Ждем Ваших заявок:
117331, Москва, а/я 143,
тел. 935-26- 79 (для оптовых покупателей).
Г. Зелъднер
ЭНЦИКЛОПЕДИЯ
ЯЗЫКА BASIC
Автор рассказывает о всех современных реа-
лизациях BASIC фирмы Microcoft: QuickBASIC,
Microcoft BASIC Professional Development System
и Visual BASIC. Это первое издание, ставящее
своей целью познакомить читателя со всеми ос-
новными версиями языка BASIC.
Спектр языков программирования BASIC,
описанных в этом издании, охватывает все ос-
новные компьютерные платформы: DOS, OS/2,
Windows. В книге в легкой и увлекательной ма-
нере дано описание всех операторов и функций
языка, дается понятие о том, что такое хороший
стиль программирования и как стать настоящим
приверженцем языка BASIC.
Ждем Ваших заявок:
117331, Москва, а/я 143,
тел. 935-26-79 (для оптовых покупателей).
В.М. Кирюхин
А. В. Лапунов
СМ. Окулов
ЗАДА ЧМ
МЕЖДУНАРОДНЫХ ОЛИМПИАД
ПО ИНФОРМАТИКЕ
В книге собраны все задачи I-VIII междуна-
родных олимпиад по информатике, проводив-
шихся в 1989-1996 гг.
Даны решения всех задач.
Книга знакомит так же с историей олимпиад
и порядком их проведения, и будет интересна
студентам, преподавателям информатики, подго-
товленным школьникам, а так же всем, кто ув-
лекается программированием.
Ждем Ваших заявок:
117331, Москва, а/я 143,
тел. 935-26-79 (для оптовых покупателей).
Э. Берлинер
Б. Глазырин
И. Глазырина
WINDOWS 95
Русская версия. Microsoft Plus.
(Издание 1996г. Переработанное и дополненное)
Книга написана как учебное пособие и посвящена ло-
кализованной версии нашумевшего продукта. Достаточно
подробно рассматриваются основные концепции и прави-
ла работы с WINDOWS 95. Значительное внимание уделе-
но работе с файловой системой, составлению и редактиро-
ванию документа с помощью текстового процессора Word-
Pad, графического редактора Paint, использованию муль-
тимедиа, установке и конфигурированию программного и
аппаратного обеспечения, работе в сети. Для читателей и
пользующихся американской версией WINDOWS 95 наря-
ду с названиями диалоговых окон и их элементов на рус-
ском языке приводятся их обозначения на английском
языке. Описаны также возможности предоставляемые па-
кетом Microsoft Plus!
Материал рассчитан как на начинающих пользовате-
гей персональных компьютеров, не имеющих опыта рабо-
ты с операционной системой WINDOWS, так и на тех, кто
уже знаком с WINDOWS 3.x.
Ждем Ваших заявок:
117331, Москва, а/я 143,
тел. 935-26- 79 (для оптовых покупателей).
От Издательства
Данная книга, изданная впервые в 1994
году для широкого круга профессионалов
и любителей языка QuickBASIC 4.5,
приобрела большую популярность в
ВУЗах, колледжах, школах и лицеях
страны. Не будучи изначально кано-
ническим учебником, она переиздается в
качестве пособия ввиду острой пот-
ребности учебных заведений в литературе
по языкам программирования.
Издательство, заинтересованое в усовер-
шенствовании книги, с благодарностью
примет все критические замечания, советы
и пожелания педагогов и учащихся.
Учебное издание
Зельднер Григорий Алексеевич
"Программируем на QuickBASIC 4.5"
Учебное пособие по курсам
"Основы программирования",
"Информатика и вычислительная техника"
М: ABF, 1996, ил., 432 с.
Набор и верстка выполнены автором
Ответственный редактор Е.А. Вайнер
Оформление обложки В.М. Монетов
Подписано к печати 10.Х.96
Формат 60x90 1/16. Бумага офсетная.
Печать офсетная. Усл.-печ. л. 27,0
Тираж 11000. Зак.2Ю5
Издательство "ABF", 117331, Москва, а/я 143
тел. 935-26-79; факс @95I38-18-62
Лицензия ЛР № 062931 от 18.08.93
Отпечатано с готовых диапозитивов
в^полиграфической фирме "Красный пролетарий"
103473, Москва, Краснопролетарская, 16