Г Л А В А 4
----------------------------------------------------------------
ТУРБО БЕЙСИК : Язык
----------------------------------------------------------------
Структура программы
----------------------------------------------------------------
Программы ТБ состоят из одной или более строк исходного текста,
каждая из которых имеет следующий формат:
[linenumber] statement [:statement] ... ['comment]
[номер-строки] оператор [:оператор] ... ['комментарий]
или
label:
метка :
или
$метаоператор
$metastatement
Linenumber - это целое число в интервале от 0 до 65535, ко-
торое может произвольно обозначать строки программы. ТУРБО БЕЙ-
СИК весьма "просто" относится к номерам строк. Они могут переме-
жаться метками, использоваться в одних частях программы и не
использоваться в других. Фактически они могут и не следовать в
обычной последовательности, хотя две строки не могут иметь оди-
наковый номер. Ни одна строка не может одновременно иметь и мет-
ку и номер. Фактически номера строк и есть метки.
Statements - это "строительные кирпичики", составляющие
программу. В ТБ около 100 типов операторов (см. Глава 5, где да-
ется весь список). В строке может не быть ни одного оператора,
либо один или несколько, отделенные двоеточием.
Ниже приведены все допустимые строки ТБ:
Start : 'только метки
10 'только номер строки
$INCLUDE "CONST.TBS" 'метаоператор
20 а = а+1 'номер строки + оператор
а = а+1 : b = b+1 'два оператора
30 а = а+1 : b = b+1 : с = а+b 'номер строки, три оператора
Единственным ограничетелем количества операторов, могущих поя-
виться в строке, является ее размер, составляющий в ТБ 249 коло-
нок. В отличие от интерпретируемого Бейсика, в ТБ пробелы, ком-
ментарии и чистые строчки компилятор игнорирует.
Не рекомендуется писать строки шире дисплейного окна редак-
тора, имеющего 80 колонок (несмотря на шикарную возможность
горизонтальной прокрутки, имеющуюся в редакторе). Выдя за пре-
делы 80 колонок при редактировании, вы не сможете увидеть на
дисплее строку целиком, да и при распечатке выглядеть это будет
не очень красиво.
В тех случаях, когда требования синтаксиса вынуждают вас
создавать строку длиной более 80 символов, ставьте символ под-
черкивания (_) в конце строки. Это позволяет рассматривать ТБ
следующую строку как продолжение первой. Эта строка может быть
таким же образом продолжена. Например:
FIELD #1,30 AS name$, 30 AS address1$, 30 AS address2$,_
15 AS city$, 2 AS state$, 5 AS zip$,_
30 AS comments$
С точки зрения компилятора - это одна длинная строка, начи-
нающаяся с FIELD и заканчивающаяся comments$, без единого
символа подчеркивания.
Comment - это любой текст, добавляемый в конце строки и от-
деляемый от собствено программы апострофом ('). Апостроф (')
можно использовать вместо REM (комментарий) для разделения ком-
ментария и оператора на строке, если только это не оператор DATA
(DATA посчитает его частью данных). В отличии от REM, не нужно
отделять комментарий с апострофом еще и двоеточием от соседнего
оператора. Приведенные ниже примеры абсолютно одинаковы для
компилятора:
area = radius^2*3.14159 'вычисление площади
area = radius^2*3.14159 :REM вычисление площади
Label (метка) должна стоять на строке одна (хотя может сопровож-
даться комментарием); она служит для идентификации непосредс-
твенно следующего за ней оператора. Метка начинается с буквы и
может содержать любое количество букв и цифр. Регистр не важен:
THISLABEL и ThisLabel эквивалентны. После метки ставится двоето-
чие, а операторы, относящиеся к этой метке (например, GOSUB) не
должны включать двоеточий.
Например
SortInvoices :
GOSUB SortInvoices 'обращается к метке
ExitPoint : a = a + I 'недопустимо; метка должна быть на строке
$metastatements - это операторы,работающие на другом уровне,
чем обычные операторы. Называемые директивами компилятора, они
всегда начинаются с символа доллара ($). Стандартные операторы
управляют компьютером программ; метаоператоры как режимы вариан-
тного меню управляют компьютером во время компиляции.
Примером служит метаоператор $INCLUDE, заставляющий компь-
ютер ввести содержимое другого файла на указанное место в теку-
щий файл. Заметьте, что метаоператоры ТБ не появляются в
ремарках (REM) как метаоператоры некоторых других компиляторов
БЕЙСИК. На строке может быть только один метаоператор.
Набор сиволов ТУРБО БЕЙСИК
- - - - - - - - - - - - - -
Буквы от A до Z или от a до z и цифры от 0 до 9 могут быть
использованы для формирования идентификаторов (меток, парамет-
ров, процедур и имен функций).
Цифры от 0 до 9; символы . + - ; а также буквы E, e, D и d
можно использовать для создания числовых констант.
Следующие символы имеют особое значение в ТБ:
----------------------------------------------------------------
Символ Описание / функция
----------------------------------------------------------------
= Знак равенства (оператор назначения, сравнения)
+ Знак плюс (сложение и оператор конкатенации строк)
- Знак минус (вычитание и оператор отрицания)
* Звездочка (оператор умножения)
/ Черта дроби (оператор деления)
\ Наклонная черта влево (оператор деления целых чисел)
^ Каре (оператор возведения в степень)
% Процент (целочисленный символ-определитель)
& Символ "и" (символ-определитель длинных целых чисел и
дескриптор недесятичных оснований)
! Восклицательный знак (символ-определитель с одинар-
ной точностью)
# Номер (символ-определитель с двойной точностью)
$ Символ "доллар" (символ-определитель строки, префикс
метаоператора)
() Скобки (фактические параметры функции/процедуры, мас-
сивы, расположение выражений по приоритету)
[] Квадратные скобки (действительны только для массивов)
Пробел (разделитель)
, Запятая (многоцелевой отделитель)
. Точка (десятичная точка, отделитель расширения файла)
' Апостроф (отделитель комментария/ремарки)
; Точка с запятой (многоцелевой отделитель)
: Двоеточие (отделитель оператора)
? Знак вопроса (заменитель команды ПЕЧАТАТЬ/PRINT)
< Меньше (оператор сравнения)
> Больше (оператор сравнения)
" Кавычки (отделитель цепочки/строки)
_ Символ подчеркивания (символ продолжения строки)
----------------------------------------------------------------
Резервируемые слова
- - - - - - - - - -
ТУРБО БЕЙСИК резервирует использование нескольких слов для опре-
деленных синтаксических целей. Эти служебные слова нельзя ис-
пользовать в качестве меток, параметров, именованных констант
или названий процедур или функций, хотя ваши идентификаторы и
могут содержать их (см. Таблицу 4-1).
Например END (Конец) - недопустимое имя переменной, т.к. оно
противоречит служебному слову END. Однако ENDHERE и FRIEND при-
емлемы. Начинать идентификатор с FN также нельзя, поскольку это
противоречит синтаксису функций, определяемых пользователем.
Попытка использования служебного слова в качестве идентифи-
катора вызовет синтаксическую ошибку компиляции.
Таблица 4-1 Служеные слова ТУРБО БЕЙСИКа
----------------------------------------------------------------
$COM1 CLOSE ERR LOC POKE STRING$
$COM2 CLS ERROR LOCAL POS SUB
$DEBUG COLOR EXIT LOCATE PRESET SWAP
$DYNAMIC COM EXP LOF PRINT SYSTEM
$ELSE COMMAND EXP10 LOG PRINT # TAB
$ENDIF COMMON EXP2 LOG10 PSET TAN
$EVENT COS FIELD LOG2 PUT THEN
$IF CSNG FILES LOOP PUT$ TIME$
$INCLUDE CSRLIN FIX LPOS RANDOM TIMER
$INLINE CVD FN LPRINT RANDOMIZE TO
$LISTNE CVI FOR LPRINT # READ TROFF
$OPTION CVL FRE LSET REG TRON
$SEGMENT CVMD GET MEMSET REM UBOUND
$SOUND CVMS GET$ MID$ RESET UCASE$
$STACK CVS GOSUB MKDIR RESTORE UNTIL
$STATIC DATA GOTO MKD$ RESUME USING
ABS DATA$ HEX$ MKI$ RETURN USR
ABSOLUTE DECR IF MKL$ RIGHTS USR0
AND DEF IMP MKMD$ RMDIR USR1
APPEND DEFDBL INCR MKMS$ RND USR2
AS DEFINT INCEY$ MKS$ RSET USR3
ASC DEFLNG INLINE MOD RUNT USR4
AT DEFSNG INP MTIMER SAVE USR5
ATN DEFSTR INPUT NAME SCREEN USR6
BASE DELAY INPUT # NEXT SEEK USR7
BEEP DIM INPUT$ NOT SEG USR8
BIN$ DO INSTAT OCT$ SELECT USR9
BINARY DRAW INSTR OFF SERVICE VAL
BLOAD DYNAMIC INT ON SGN VARPTR
BSAVE ELSE INTERRUPT OPEN SHARED VARPTR$
CALL ELSEIF IOCTL OPTION SHELL VARSEG
CASE END IOCTL$ OR SIN VIEW
COBL ENDMEM KEY OUT SOUND WAIT
CEIL ENVIRON KILL OUTPUT SPACE$ WEND
CHAIN ENVIRON$ LBOUND PAINT SPC WHILE
CHDIR EOF LCASE$ PALETTE SQR WIDTH
CHR$ EQV LEFT$ PALETTE STATIC WINDOW
CINT ERADR LEN PEEK STEP WRITE
CIRCLE ERASE LET PEN STICK WRITE #
CLEAR ERDEV LINE PLAY STOP XOR
CLNG ERDEV$ LIST PMAP STR$
ERL POINT STRIG
----------------------------------------------------------------
Числа в ТУРБО БЕЙСИКе
----------------------------------------------------------------
Осторожное обращение и загрузка числовых данных составляет важ-
ную часть любой системы программирования. ТУРБО БЕЙСИК в соот-
ветствии с традициями БЕЙСИК был разраьотан так, чтобы вы могли
в значительной мере игнорировать технические моменты внутренней
обработки числовой информации. Если вы никогда не задумывались о
таких вещах, как скорость вычислений, точность и требования к
памяти, ваши программы, возможно, будут работать, как вы и ожи-
дали. Однако, знание основополагающих моментов поможет вам пи-
сать программы более быстрые, более точные и требующие меньшего
объема памяти.
Для большей эффективности ТУРБО БЕЙСИК хранит и обрабатывает
числа четырьмя различными способами; т.е. обеспечивает четыре
уникальных числовых "типа" данных: целые числа, длинные целые
числа, с одинарной точностью с плавающей запятой и с двойной
точностью с плавающей запятой.
Целые числа
- - - - - -
Самые простые числа, с которыми ТУРБО БЕЙСИК "живо спрвляется" в
своих встроенных программах - целые числа. Для ТУРБО БЕЙСИКа це-
лое число - это число без десятичной в интервале от -32768 до
32767. Эти значения основываются на шестнадцатиричном изображе-
нии целых чисел: 32768 это 2^15.
Хотя этот дапазон и ограничивает использование целых чисел,
наверняка большинство параметров в каждой написанной вами прог-
рамме (такие, как счетчики в циклах FOR/NEXT) будут нормально
работать в этих границах. Если это так, использование целых
чисел позволяет создавать быстрые и компактные программы. Ваш
компьютер прекрасно приспособлен для произведения арифметических
действий с целыми числами (например, производит их быстро), а
каждая цифра занимает только 2 байта памяти.
Переключатель режима "Переполнение"(Overflow) в Вариантном
(OPTIONS) меню позволяет создавать программы, в которых случаи
переполнения целочисленных переменных автоматически регистриру-
ются и сообщаются.
Длинные целые числа
- - - - - - - - - -
Значительно расширив возможности интерпретирующего БЕЙСИКа, ТУР-
БО БЕЙСИК обеспечивает цифровой тип известный как длинные целые
числа. Для того, чтобы избежать ошибок округления, длинные целые
числа являются идеальными для бухгалтерских расчетов. Как и
обычные целые числа, длинные целые числа не должны содержать де-
сятичных запятых. Они занимают диапазон от -2147483648 до
+2147483647 (-2^31 до 2^31-1 или от -2 млрд. до +2 млрд.). Для
хранения таких чисел требуется 4 байта и расчеты выполняются
несколько медленнее, чем с целыми числами.
Длинные целые числа достаточно эффективны и безусловно зас-
луживают более близкого рассмотрения, особенно в компьютерах, не
оборудованных сопроцессором 8087. В зависимости от применения
вашего компьютера, десятичные точки могут иметь гораздо меньшее
значение, чем вы полагаете. Например, суммы денег можно выражать
в центах, а для отображения долларов делить на 100. Таким обра-
зом, можно выразить суммы до 20 млн. долларов.
Числа с одинарной точностью с плавающей запятой
- - - - - - - - - - - - - - - - - - - - - - - -
"С одинарной точностью с плавающей запятой" (или просто с оди-
нарной точностью) - вероятно, самый универсальный числовой тип в
ТУРБО БЕЙСИКе. Такие значения могут содержать десятичные запятые
и имеют диапазон от 10^-38 до 10^38, как отрицательный, так и
положительный. Скорость счета,правда, не так высока,как в расче-
тах с длинными целыми числами,и для каждого числа нужно 4 байта.
Недостаток чисел с одинарной точностью в том, что они не
пригодны там, где требуется точность более, чем до шестого зна-
ка. Например, одинарная точность хороша для таких чисел, как
$451.21 и $6411.92, но число $671421.62 не может быть представ-
лено точно, так как содержит слишком много цифр, равно как и
числа 234.56789 или 0.00123456789; одинарная точность представ-
ления даст не более шести цифр: $671421 или 234.568 или
0.00123457. В зависимости от применения вашего компьютера это
округление может быть несущественным либо критическим для вас.
С двойной точностью с плавающей запятой
- - - - - - - - - - - - - - - - - - - -
Двойная точность соотносится с одинарной так же, как длинные це-
лые числа с целыми. Они занимают вдвое больше места в памяти (8
байт вместо 4) и, следовательно, требуют больше времени для вы-
числений, имеют больший диапазон (10^308) и точность (16 знаков
против 6 при одинарной точности).
Требование по записи с двойной точностью становится особенно
важным, когда мы имеем дело с массивами. При двойной точности
для хранения массива, содержащего 5000 элементов, требуется
40000 байт. Целочисленный массив с таким же числом элементов за-
нимает всего 10000 байт.
Обратите внимание: в ТУРБО БЕЙСИКе используется станарт ИИЭР
(Институт инжененров по электротехнике и радиоэлектронике) для
арифметических действий с плавающей запятой, а не патентованный
формат Microsoft, используемый в Интерпретируемом БЕЙСИКе . Поэ-
тому необходимо использовать специальные трансляционные функции
Майкрософт/ИИЭР (CVMS,CVMD,MKMS$ и MKMD$) для считывания и запи-
си данных с плавающей запятой, содержащихся в файлах прямого
доступа, создаваемом в Интерпретируемом Бейсике. (Более подробно
об этом см. раздел "Файлы прямого доступа" данной главы).
Если вы еще не решили, какой тип с плавающей запятой исполь-
зовать, мы советуем - с двойной точностью. По существу цифровой
"движок" ТУРБО БЕЙСИКа лучше всего работает на горючем двойной
точности. Его трансцендентные функции, такие как COS и LOG (ко-
синус и логарифм), дают результаты с двойной точностью. Все-таки
одинарная точность, вероятно, будет лучше для больших массивов,
там, где будет более очевидно ее "размерное" преимущество.
Расчеты и 8087
- - - - - - - -
Сопроцессор 8087 (80287 на компьютерах AT-типа) значительно сок-
ращает разницу в скорости счета между различными типами числовых
данных. Поскольку 8087 ведет все расчеты с двойной точностью не-
зависимо от типа, это делает двойную точность еще более привле-
кательной. В отличие от Интерпретируемого БЕЙСИКа ТУРБО БЕЙСИК
не всегда округляет дробные части чисел в большую сторону, а
каждый раз рассматривает особым образом каждое число, содержащее
5 в дробной части: число округляется в сторону ближайшего четно-
го числа. Например число 0.5 будет округлено в меньшую сторону
до 0 - ближайшего четного числа. И число 9.005 тоже будет округ-
лено в меньшую сторону, т.е. в данном случа до 9.000.
Поскольку наиболее широко употребляемые методы округления
чисел всегда округляют в большую сторону,ТУРБО БЕЙСИК фактичеки
обеспечивает более равное распределение.
Константы и переменные
----------------------------------------------------------------
Программы ТУРБО БЕЙСИКа обрабатывают два четко определенных
класса данных: константы и переменные. Переменная может изменять
свое значение во время выполнения программы. Значение константы
фиксируется при компиляции и не может изменяться во время выпол-
нения программы. ТУРБО БЕЙСИК обеспечивает три типа констант:
строковые, числовые константы и, в дополнение к Интерпретируемо-
му Бейсику, особая форма целочисленной константы - именные
константы.
Строковые константы
- - - - - - - - - -
Строковые константы - это просто группы символов: взятых в ка-
вычки, например:
"Это строка"
"3.14159"
"Тим Джоунс. Адвокат"
Если строковая константа стоит последней на строке, закры-
вать кавычки не обязательно:
PRINT "Это небрежно, но допустимо.
Числовые константы
- - - - - - - - - -
Числовые константы представляют числовые величины и состоят в
основном из цифр от 0 до 9 и десятичной запятой. Впереди отрица-
тельных констант должен ставиться знак минус (-); знак плюс (+)
для положительных констант не обязателен. Величина точности, со-
общаемая вами, определяет внутреннее представление (целое число,
длинное целое число, с одинарной точностью, с двойной точ-
ностью), которым будет пользоваться ТУРБО БЕЙСИК в обработке
этой константы.
Если величина не содержит десятичной запятой и находится в
интервале от -32768 до 32767 - ТУРБО БЕЙСИК использует свой це-
лочисленный тип.
Если величина - целое число от -2^31 до 2^31-1 включительно
(приблизительно от -2 млрд. до +2 млрд.), но вне диапазона
целочисленных констант, - ТУРБО БЕЙСИК использует свой длинный
целочисленный тип.
Если величина содержит десятичную запятую и до шести цифр -
ТУРБО БЕЙСИК использует тип с одинарной точностью и плавающей
запятой.
Числовая константа с десятичной запятой, состоящая более чем
из шести цифр, или целое число слишком большое для длинного це-
лочисленного формата, сохраняется в формате двойной точности с
плавающей запятой. Например:
345.1 С одинарной точностью
1.10321 С одинарной точностью
1.103213 С двойной точностью
3453212*1234 С двойной точностью
Идентификация целочисленных констант в других основаниях
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Иногда удобнее выражать целые числа в иных основаниях, чем деся-
тичные. Это особенно актуально при выражении информации бинарной
по своей природе, например, машинных адресов. ТУРБО БЕЙСИК поз-
воляет специфицировать целочисленные данные в шестнадцатиричной
(основание 16), восьмиричной (основание 8) и двоичной (основание
2) записи. Заметьте, что длинные целые числа не могут быть
представлены в альтернативной записи.
Шестнадцатиричные константы состоят максимально из четырех
знаков, причем, каждый символ из интервала 0-9 и A-F, перед
константой пишется &H.
Восьмиричные константы содержат только цифры от 0 до 7, мак-
симально могут состоять из 6 цифр и перед ними пишется &Q (или
&O или просто &).
Двойчные константы содержат только нули и единицы, могут
состоять максимально из шестнадцати цифр и перед ними мишется &B.
Каждая из следующих констант представляет целое число, деся-
тичное 256 :
256 , &H100 , &O400 , &400 , &B100000000
Именные константы
- - - - - - - - -
ТУРБО БЕЙСИК позволяет называть целочисленные константы по име-
нам. Это несолько похоже на функцию CONST Паскаля. Только целые
числа можно именовать таким образом.
Для того, чтобы назвать целочисленную константу , предварите
ее идентификатор знаком (процент) % и назначьте ему целочислен-
ную константу. В отличие от переменных можно использовать имен-
ную константу в левой части оператора присваивания единожды, и
только постоянное значение (не переменная или выражение) может
быть присвоено ей. Например:
%debug = -1 ' именная константа, значение -1
debug% = 112409 ' целочисленная переменная
PRINT %debug , debug% ' это отдельные объекты
Используйте именные константы для флагов условной трансляции
(см. метаоператоры в Главе 5) и для повышения "читаемости" ваших
программ. (Можно также использовать именные константы для сниже-
ния вероятности появления "магических чисел" в ваших программах.
Магические числа - это мистичесике величины, имеющие какое-то
значение для вас в момент написания программы, но не через пол-
года, когда вы к ней возвращаетесь).
Переменные
- - - - - -
Переменная - это идентификатор, представляющий числовое или
строковое значение. B отличие от констант значение переменной
может меняться при выполнении программы. Как и метки, имена пе-
ременных должны начинаться с буквы и могут содержать любое коли-
чество букв и цифр. Не скупитесь при именовании важных перемен-
ных. В отличие от Интерпретатора Бейсика длинные имена
переменных в ТБ не занимают память в иомент выполнения. Перемен-
ные EndOfMonthTotals (ИтогНаКонецМесяца) и emt занимают ровно по
четыре байта памяти в момент выполнения.
ТУРБО БЕЙСИК поддерживает пять типов переменных: строковую,
целочисленную, длинную целочисленную, с одинарной точностью и
двойной точностью. Имя переменной определяет ее тип. Обычно имя
переменной заканчивается символом описания типа.
Строковые переменные заканчиваются знаком "доллар" ($):
a$="ТУРБО БЕЙСИК"
В целочисленных переменных используется знак "процент (%):
a% = 15
В длинных целочисленных использован знак "амперсанд" (&):
a& = 7000
В переменных с одинарной точностью с плавающей запятой ис-
пользован восклицательный знак (!):
a! = 1.1
Переменные с двойной точностью с плавающей запятой оканчива-
ются на знак "номер" (#):
a# = 1.031
Если вы не укажете символ описания типа переменной, ТУРБО
БЕЙСИК использует по умолчанию тип с одинарной точностью. Для
назначения другого типа "по умолчанию" испотльзуйте оператор
"DEFтип". Например:
a# = 1.031 'a# - переменная с двойной точностью
b =16.5 'b - с одинарной точностью
a% = 3 'a% - целочисленная переменная: a# - отдельная
' переменная
DEFINT m 'тип "по умолчанию" для переменных, начинающихся
' с m теперь целочисленный
m = 16 'm - целое число
Обратите внимание на то, что a%, a#, a&, a$ и a! - это пять
различных переменных.
Массивы
----------------------------------------------------------------
Массив - это группа строковых или числовых данных, имющих одно
имя переменной. Отдельные значения, составляющие массив, называ-
ются элементами. Элемент массива можно использовать в операторе
или выражении, где обычно используются обычные строковые или
числовые переменные. Другими словами, каждый элемент массива -
сам по себе переменная.
При запуске программы каждый элемент каждого числового или
строкового массива устанавливается в нулевую величину или пустую
строку (""). DIM- оператор (установка размерности) динамического
массива также очищает каждый элемент. Если программа затем
запускается оператором RUN, эта инициализация повторяется.
Описать имя и тип массива, а также число и организацию его
элементов, можно с помощью оператора DIM (установка размернос-
ти). Например:
DIM payments(55)
создает переменную массива "payments" (выплаты), состоящего из
56 элементов с одинарной точностью, нумеруемых от 0 до 56. Мас-
сив payments и переменная с одинарной точностью, также названная
payments - это раличные переменные.
Индексы
- - - -
Отдельные элементы массива помечаются индексами, целочисленными
выражениями в скобках справа от имени переменной массива. Напри-
мер, payments(3) и payments(44) - это два элемента из 56 элемен-
тов массива "payments". Обычно первый элемент массива получает
значение индекса, равное 0, хотя это можно изменить, используя
операторы DIM или OPTION BASE: например:
'Данный оператор DIM описывает 56-элементный массив с индексными
'границами от 0 до 55.
DIM payments(55)
OPTION BASE 1
'Данный оператор DIM описывает 55-элементный массив с индексными
'границами от 0 до 55 вследствие применения оператора OPTION
'BASE.
DIM payments(55)
Если массив используется в программе без установки размер-
ности (DIM), ТУРБО БЕЙСИК работает так, словно описан массив с
одинадцатью элементами (индексы от 0 до 10). Тем не менее мы
настоятельно советуем вам заняться четкой установкой размерности
каждого массива, используемого вашей программой.
В дополнение к функциям Интерпретируемого Бейсика по манипу-
лированию массивами, ТУРБО БЕЙСИК позволяет определять диапазон
значений индексов, а не просто верхнюю границу. Например, опера-
тор DIM
DIM b(50:60)
создает массив b, состоящий из одиннадцати элементов с одинарной
точностью, с номерами от 50 до 60.
Оператор:
DIM c(50:60,25:45)
создает двумерный массив c, содержащий 231 (11*21) элемент.
Возможность описать диапазоны индексов в ТУРБО БЕЙСИК позво-
ляет моделировать структуру программных данных наиболее опти-
мально для текущей задачи.
Рассмотрим, например, программу, прослеживающую статистику
рождаемости (birth) в 19 веке. Структура основных данных прог-
раммы представляет собой массив с одинарной точностью, состоящий
из 100 элементов, содержащих количество детей, рожденных каждый
год прошлого века. В идеале следует создать массив, в котором
будут использованы значения индексов, равные году учета рождае-
мости (например, рождаемость(1851) представляет, сколько детей
рождено в 1851 году), и поэтому отрывок программы
DIM births(1899)
.
.
.
FOR n = 1800 nj 1899
PRINT "Всего было" births(n) "рождений в" n
NEXT n
будет предельно прост.
К сожалению, DIM births(1899) создает
1900-элементный массив, в котором первые 1800 элементов беспо-
лезны. Обычно программисты, работающие в Бейсике, решают эту
проблему "обыгрывая" индексы и описывая массив как
DIM births(99)
.
.
.
FOR n = 1800 TO 1899
PRINT "Всего было" births(n-1800) "рождений в" n
NEXT n
Хотя это и срабатывает, но усложняет и замедляет программу,
поскольку неожиданно возникает проблема выполнения 100 вычита-
ний, которых ранее не было.
Соответствующий оператор OPTION BASE также можно использо-
вать для определения низшего элмента массива, хотя механизм раз-
бивки на диапазоны более действенный и предпочтительный.
Строковые массивы
- - - - - - - - -
Элементы строковых массивов хранят строки, а не числа. Длина
строки может быть различной:от 0 до 32767 знаков. Обычный стро-
ковый объем для строк и строковых массивов составляет 64К.
Например:
DIM a$(50) ' создает последовательность
' из 51 независимых
' строковых переменных:
a$(0)= "Строка средней длины" 'строка из 20 знаков
a$(1)= "" 'пустая строка (по умолчанию)
a$(0)= SPACE$(20000) 'строка из 20000 знаков
.
.
.
a$(50)="The last one" 'строка из 21 знака
Многомерные массивы
- - - - - - - - - -
Массивы могут иметь одну или несколько размерностей, максимально
- 8. Одномерный массив, например, payments - это просто список
значений. Двумерный массив представляет собой таблицу чисел с
рядами и колонками данных. Возможны также и многомерные массивы.
DIM a(15) (одномерный список)
DIM b(15,20) (двумерная таблица)
DIM c(5,5,10,20,3) (пятимерный массив)
Максимальное число элементов на каждую размерность - 32768.
Проверка связей массива
- - - - - - - - - - - -
ТУРБО БЕЙСИК делает все возможное, чтобы избавить вас от непри-
ятностей, связанных с неверными индексами (т.е. индексами либо
слишком большими, либо слищком малыми для данного массива). И
компилятор немедленно сообщает о неверном индексе:
DIM a(50)
a(51) = 33
Эта программа не будет транслироваться, т.к. ТУРБО БЕЙСИК
сознательно не будет генерировать команду доступа к 52-му эле-
менту 51-элементного массива. Однако, если в качестве индексов
использовать переменные, компилятор не обнаружит ошибки:
DIM a(50)
n = 51
a(n) = 33
И хотя данная программа будет компилироваться без ошибки,
все же можно поймать внедиапазонный индекс в 3-ей строке при вы-
полнении программы путем ее компиляции с включенным режимом "От-
ладка связей" (По проверке индексов см. раздел "Команды Вариан-
тов" в Главе 3).
Требования к хранению массивов
- - - - - - - - - - - - - - - -
По техническим причинам, связанным с быстродействием и эффек-
тивным использованием объема программ, ТУРБО БЕЙСИК ограничивает
размер каждого отдельного массива до 64 Килобайт, хотя в прог-
рамме может содержаться столько 64-килобайтовых массивов, сколь-
ко позволяет ЗУ. Максимальное число элементов в массиве зависит
от его типа, как показано ниже:
----------------------------------------------------------
Тип Требования к объему памяти
----------------------------------------------------------
Целочисленный 2байта на элемент (32768 на 64 К)
Длинный целочисленный 4байта на элемент (16384 на 64 К)
С одинарной точностью 4байта на элемент (16384 на 64 К)
С двойной точностью 8байт на элемент (8102 на 64 К)
Строковый 4байта на элемент (16384 на 64 К)
----------------------------------------------------------
Внимание: В элементе строкового массива содержится только
информация по указателям и длине. Собственно строковые данные
хранятся в строковом пространстве и занимают столько байт,
сколько знаков в строке. Пространство строки максимально может
содержать 64К знаков.
Динамическое распределение
- - - - - - - - - - - - - -
ТУРБО БЕЙСИК обеспечивает динамическое распределение памяти. Ди-
намическое распределение означает создание массивов изменяющейся
величины при выполнении, а не определение фиксированных (стати-
ческих) структур при компилировании.
Это позволяет создавать массивы точно таких размеров, кото-
рые необходимы для обработки данных, задаваемых программе при
выполнении. После завершения их функций память, отведенная дина-
мическим массивам, может быть возвращена и вновь использована.
Для создания динамического массива просто используйте пер-
менные аргументы в операторе DIM; если есть место в ЗУ - массив
будет создан. Когда программа завершила использование этого мас-
сива, примените опреатор ERASE (Стереть) для того, чтобы изба-
виться от него и использовать память для других целей.
Например:
'выяснить, сколько записей в каталоговом файле,
'затем установить размеры динамических массивов и загрузить их
OPEN "PARTS.DTA" AS #1 LEN = 56
count = LOF(1)/56
DIM partNo(count), desc$(count), quan(couny), cost(count)
GOSUB LoadArrays
GOSUB UseArrays
ERASE partNo, desc$, quan, cost
Чтобы воспользоваться преимуществами динамических массивов
ТУРБО БЕЙСИКа, нужно лишь сделать оценочный опрос каждого масси-
ва вашей программы: статический или динамический? Имеет ли он
фиксированный размер в соответствии с конфигурацией программы,
или это зависит от некоего параметра, величина которого неиз-
вестна до выполнения программы? Например, массив births из ранее
приведенного примера лучше всего создавать как статическую
структуру - его величина всегда будет составлять 100 элементов.
Небольшим неудобством динамических массивов является тот
факт, что иногда можно безуспешно пытаться установить размер-
ность большого массива DIM-оператором при выполнении программы,
но для выполнения этой функции просто не будет достаточного ко-
личества свободной памяти. Если же в программе только статичес-
кие массивы и достаточно памяти для запуска - то память не будет
исчерпана; массивы такой программы создаются еще до того, как
начинается ее выполнение.
В связи с этим программа, использующая динамические массивы,
должна знать, что при выполнении может оказаться недостаточно
свободной памяти для описания требуемых массивов. Прежде чем ус-
тановить размерность динамического массиа DIM-оператором, вос-
пользуйтесь функцией FRE(-1), чтобы проверить, достаточно ли
места для него.
Описание статических или динамических массивов
- - - - - - - - - - - - - - - - - - - - - - - -
Метаоператоры $DYNAMIC и $STATIC управляют типом задания масси-
вов в программе по умолчанию. Обычно в программе содержится
только один из этих метаоператоров. По умолчанию компилятор под-
разумевает атрибут $STATIC.
Массивы считаются динамическими в следующих случаях:
- Если они описаны после употребления метаоператора $DYNAMIC:
$DYNAMIC
DIM A(10)
- Если явно заданы как динамические:
DIM DYNAMIC A(10)
- Если в операторе DIM использована переменная:
X% = 10
DIM A(X%)
- Если массив включен в оператор COMMON:
DIM A(10)
COMMON A(1)
- Если есть два или более операторов DIM для олного и того же
идентификатора массива:
DIM A(10)
A(0) = 10
DIM A(10)
- Если массив описывается как локальный в процедуре или функ-
ции:
DEF FNTest%
LOCAL A()
DIM A(10)
FNTest = A(10)
END DEF
Класс хранения массива также может быть задан атрибутами
STATIC и DYNAMIC в DIM-операторе. Кроме того, массив всегда ди-
намический, если в соответствующем DIM-операторе используется
выражение. Например:
$STATIC 'отсюда и далее считать все массивы стати-
'ческими
DIM a(40), b(20,20) 'поэтому a и b оба статические массивы
DIM DYNAMIC c(20) 'атрибут DYNAMIC отменяет примененный по
'умолчанию $STATIC
DIM d(n) 'использование переменной в DIM также ус-
танавливает атрибут DINAMIC
$DYNAMIC 'отсюда и далее компилятор считает массивы
динамическими
DIM e(50) 'поэтому e - массив динамический
"Избавиться" от динамических массивов можно с помощью опера-
тора ERASE: удаление статических массивов с помощью ERASE не
восстанавливает память, но устанавливает их элементы на 0 (в
строковых массивах в нулевую строку).
Выражения
----------------------------------------------------------------
Выражение состоит из операций и операндов, осуществляющих оп-
ределенные операции при вычислении выражения. В ТУРБО БЕЙСИКе
существует два основных типа выражений: строковые и числовые.
Строковое выражение состоит из строковых констант, строковых
переменных и строковых функций (тех, которые оканчиваются на $),
соединенные, где это необходимо, конкатенационной операцией -
знаком плюс (+). Строковые выражения упрощают до строки; т.е. до
последовательности символов ASCII известной длины. Среди приме-
ров строковых выражений следующие:
"Cats and dogs"
a$
a$ + z$
LEFT$(a$ + z$)
a$ = MID$("Cats and dogs",6,3)
RIGHT$(MID$(a$ + z$,1,6),3)
Числовые выражения состоят из числовых констант, переменных
и функций, разделяемых, где необходимо, числовыми операциями.
Числовые выражения всегда упрощаются в соответствии со значением
одного из четырех числовых типов (целочисленному, длинному цело-
численному, со динарной точностью, с двойной точностью). Примеры
числовых выражений включают:
37
37/15
a
37/a
SQR(37/a)
SQR((c + d)/a) * SIN(37/a)
При формировании числовых выражений следует иметь в виду,
что определенные операции будут произведены первыми. Ниже приве-
ден порядок вычисления выражения. Возведение в степнь имеет выс-
ший приоритет; IMP(импликация) - низший.
- Возведение в степень (^)
- Унарный минус (-)
- Умножение, Деление с плавающей запятой (*,/)
- Целочисленное деление (\)
- По модулю (MOD)
- Сложение, Вычитание (+,-)
- Операции сравнения (<,<=,=,>,>=,<>)
- Отрицание (NOT)
- И (AND)
- ИЛИ, Исключающее ИЛИ (OR, XOR)
- Эквивалентность (EQV)
- Импликация (IMP)
Например значение выражения 3 + 6/3 равно 5, а не 3. Пос-
кольку приоритет деления выше, чем вычитания, операция деления
(6/3) производится первой.
При проведении операций с одинаковым приоритетом ТУРБО БЕЙ-
СИК производит их слева направо. Например, в выражении 4 - 3 + 6
вычитание (4-3) производится перед сложением (3 + 6), что дает
промежуточное выражение 1 + 6.
Операции в скобках имеют высший приоритет и всегда произво-
дятся первыми; внутри скобок действуют общие правила.
Арифметические операции
- - - - - - - - - - - -
Арифметические операции производят обычные математические опера-
ции. В Таблице 4-2 перечислены арифметические операции ТУРБО
БЕЙСИК в порядке возрастания приоритетов.
Таблица 4-2. Арифметические операции
----------------------------------------------------------
Операция Действие Пример
----------------------------------------------------------
^ Возведение в степень 10^4
- Унарный минус -16
*, / Умножение, Деление с плаваю- 45 * 19, 45 / 19
щей запятой
\ Целочисленное деление 45 \ 19
MOD По модулю 45 MOD 19
+,- Сложение, Вычитание 45 + 19, 45 - 19
-----------------------------------------------------------
Некоторые из этих операций заслуживают краткого пояснения.
Обратная черта дроби (\) представляет целочисленное деление. Це-
лочисленное деление округляет свои операнды до целых чисел и да-
ет округленное частное без остатка; например, 5 \ 2 равняется 2,
а 9 \ 10 равно 0.
Остаток целочисленного деления можно определить с помощью
операции MOD (заметьте, что операция MOD действительна только с
короткими целыми числами). Операция MOD похожа на операцию цело-
численного деления, только она показывает остаток деления, а не
частное; например, 5 MOD 2 равно 1 , а 9 MOD 10 равно 9.
Операции сравнения
- - - - - - - - - -
Операции сравнения позволяют сравнивать значения двух строк или
двух чисел (но не строки с числами) для получения булева резуль-
тата: ВЕРНО (TRUE) или НЕВЕРНО (FALSE). Результату сравнения
присваивается целочисленное значение "-1", если отношение верно,
и "0" - если неверно. Например:
PRINT 5 > 6, 5 < 6, (5 < 6)*15
выдает 0,-1 и -15. Хотя полученные численные результаты можно
использовать в любом числовом выражении (например, a = (b*c)
/13), числовые результаты, получаемые в операциях сравнения, как
правило, используются в IF (ЕСЛИ) или других операторах принятия
решения для определения направления дальнейшего выполнения прог-
раммы. В Таблице 4-3 приведены операции сравнения.
Таблица 4-3. Операции сравнения
---------------------------------------------------
Операция Сравнение Пример
---------------------------------------------------
= Равенство x = y
<> Неравенство x <> y
< Меньше, чем x < y
> Больше, чем x > y
<= Меньше или равно x <= y
>= Больше или равно x >= y
----------------------------------------------------
Если арифметические операции и операции сравнения сведены
в одном выражении, арифметические операции всегда выполняются
первыми. Например, 4 + 5 < 4*3 дает всегда результат "-1"(ВЕР-
НО), поскольку операция сравнения в конце проверяет правильность
утверждения 9 < 12.
Логические операции
- - - - - - - - - -
Логические операции выполняют булевы действия с целыми числами.
При использовании с операциями сравнения они позволяют проводмть
такие комплексные тесты, как
IF day > 29 AND month = 2 THEN PRINT "Error in date"
ЕСЛИ день > 29 И месяц = 2 ТО ПЕЧАТАТЬ "Ошибка в дате"
Этот оператор производит логичекое И с целочисленными ре-
зультатами, полученными в двух операциях сравнения. (Оператор И
(AND) имеет более низкий приоритет, чем операторы сравнения ">"
и "=", поэтому скобки не нужны). Например, если день = 29 и ме-
сяц = 2, обе операции сравнения дают результат ВЕРНО (-1). Лежа-
щее в основе бинарное представление целых чисел таково, что
"-1" имеет величину &HFFFF (все биты включены); "0" - &H0000,
все биты выключены.
Затем оператор И производит операцию логического умножения
этих двух ВЕРНЫХ результатов:
1111 1111 1111 1111 (-1)
AND 1111 1111 1111 1111 (-1)
------------------------
1111 1111 1111 1111 (-1)
давая ВЕРНЫЙ (ненулевой) результат.
Операция ИЛИ (OR) (иногда называемая включающее ИЛИ) дает
ответ ВЕРНО, если один или оба ее аргумента ВЕРНЫ; и дает ответ
НЕВЕРНО только если оба аргумента НЕВЕРНЫ.
Например:
-1 OR 0 это ВЕРНО (TRUE)
0 OR 0 это НЕВЕРНО (FALSE)
5 > 6 OR 6 < 7 это ВЕРНО (TRUE)
Операция Исключающее ИЛИ (XOR) дает ответ ВЕРНО, если прове-
ряемые величины разные, и ответ - НЕВЕРНО, если они равны.
-1 XOR 0 это ВЕРНО (TRUE)
-1 XOR -1 это НЕВЕРНО (FALSE)
5 > 6 XOR 6 < 7 это ВЕРНО (TRUE)
Функция Эквивалентно (EQV) противоположна XOR. Она дает от-
вет ВЕРНО, если исследуемые две логические величины одинаковы, и
ответ НЕВЕРНО, если они неодинаковы:
-1 EQV 0 это НЕВЕРНО (FALSE)
-1 EQV -1 это ВЕРНО (TRUE)
5 > 6 EQV 6 < 7 это НЕВЕРНО (FALSE)
Оператор Импликация (IMP) дает ответ НЕВЕРНО только если
первый операнд ВЕРЕН, а второй НЕВЕРЕН:
-1 IMP 0 это НЕВЕРНО (FALSE)
-1 IMP -1 это ВЕРНО (TRUE)
5 > 6 IMP 6 < 7 это ВЕРНО (TRUE)
Обратите внимание, что логичекие операторы производят дейс-
твия только над целыми числами, но не над длинными целыми числа-
ми или числами с плавающей запятой. Если операнды логического
выражения не могут беть преобразованы в целые числа, происходит
переполнение:
x = 500000
IF x OR y THEN GOTO Exit
Такой оператор IF может в результате дать ошибку переполнения,
если x нельзя преобразовать в целое число.
Поразрядные операции
- - - - - - - - - - -
В дополнение к созданию комплексных тестов логические операторы
позволяют управлять базовыми двоичными кодами их целочисленных
операндов. Самые известные операции - AND-, OR-, XOR-маскирова-
ние.
Маски И используются для установки в 0 выбранных битов цело-
численного значения, не затрагивая остальных битов. Например,
для обнуления старших 2 битов целочисленной величины &H9700 ис-
пользуйте И с маской &H3FFF,т.е. в маске содержатся все единицы,
кроме тех позиций битов, которые вы желаете обнулить:
1001 0111 0000 0000 &H9700
И(AND) 0011 1111 1111 1111 &H3FFF (маска)
--------------------------
0001 0111 0000 0000 &H1700 (результат)
Маска ИЛИ устанавливает в 1 выбранные биты целого числа, не
влияя на остальные. Для установок в 1 двух старших битов в
&H9700 используйте ИЛИ с маской &HC000; т.е. маска содержит
нули, за исключением позиций тех битов, которые вы желаете уста-
новить в 1:
1001 0111 0000 0000 &H9700
ИЛИ(OR) 1100 0000 0000 0000 &HC000 (маска)
--------------------------
1101 0111 0000 0000 &H9700 (результат)
Маска ИсклИЛИ инвертирует выбранные биты, не влияя на другие
биты. Например, чтобы инвертировать 2 старших бита в &H9700
используйте ИсклИЛИ (XOR) с маской &C0000; т.е. все нули, кроме
позиций, которые нужно инвертировать.
1001 0111 0000 0000 &H9700
ИсклИЛИ(XOR) 1100 0000 0000 0000 &HC000 (маска)
--------------------------
0101 0111 0000 0000 &H9700 (результат)
Операции ИсклИЛИ (XOR) часто используются в графике, пос-
кольку позволяют перемещать объект без помех на сложном фоне.
Используйте ИсклИЛИ один раз, чтобы нарисовать объект на ка-
ком-либо фоне, а затем еще раз на этом объекте в том же месте,
чтобы стереть его, возвращая фон в его первоначальное состояние.
Строковые операции и операци сравнения
- - - - - - - - - - - - - - - - - - - -
ТУРБО БЕЙСИК позволяет сравнивать строковые данные. Строковые
выражения можно проверять на эквивалентность,а также алфавитное
упорядоченное "больше чем" и "меньше чем".
Два строковых выражения равны тогда и только тогда, когда
они содержат абсолютно одинаковые символы в одинаковой последо-
вательности. Например:
a$ = "CAT"
PRINT a$ = "CAT", a$ = "CATS", a$ = "cat"
Строковое упорядочение основано на двух критериях и в данном
порядке: (1) значения ASCII содержащихся знаков, и (2) длина.
Например, "A" меньше "B", т.к. ASCII код для A - 65 меньше кода
для B - 66. Заметьте, однако, что "B" меньше "a", т.к. код каж-
дой строчной буквы больше кода соответствующей прописной (ровно
на 32). При cортировке смешанной строчно-прописной информации
можно использовать функции UCASE$ или LCASE$ для того, чтобы вы-
бор регистров не влиял на сортировку.
Длина имеет значение только если обе строки идентичны вплоть
до длины короткой строки; в этом случае более короткая строка
оценивается как меньшая, чем длинная; например, "CAT" меньше,
чем "CATS".