Г Л А В А   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".