Элементы языка QBASIC

Алгоритм решения практически любой задачи можно трансформировать в компьютерную программу. Такую программу в общем случае можно рассматривать как последовательность некоторых слов и специальных символов. Слова и символы образуют более сложные конструкции, которые должны формироваться по определенным правилам. В отличие от естественных, в языках программирования эти правила должны соблюдаться более строго: даже забытая запятая может привести к тому, что программа либо будет работать не корректно, либо вовсе не сможет выполняться. Набор правил для написания программ называется синтаксисом языка программирования.

Ключевые слова

Некоторые слова, используемые в программах, имеют особый смысл и поэтому называются ключевыми (или зарезервированными) . Интерпретация или компиляция ключевого слова всегда вызывает вполне определенное действие компьютера. Например, ключевое слово PRINT задает вывод информации на экран.

Синтаксические соглашения

Имеются различные способы описания синтаксиса языковых конструкций. По понятным причинам для описания элементов языка QBASIC мы будем пользоваться той же формой описания синтаксиса, что и в Help-системе QBASIC. Следующая таблица дает представление о применяемых обозначениях.

 
Элемент
Значение
Ключевое слово Ключевые слова QBASIC всегда записываются большими (заглавными) буквами
Метка-заполнитель Выражение
[ ] Необязательный параметр
{А1|А2} Выбор одного из альтернативных значений
: Три точки, следующие одна за другой, обозначают, что предшествующий элемент может повторяться
Ключевое слово1
.
.
.
Ключевое слово2
Три точки одна под другой обозначают несущественный в данном контексте фрагмент программы.

Комментарии

Включенные в программу комментарии QBASIC просто игнорирует. Использование комментариев позволяет включать в программу любой текст, не нарушая ее семантики. Комментарии используются для объяснения тех или иных действий в программе. Если Вы вернетесь к своей программе через несколько недель (месяцев или даже лет), они помогут Вам быстрее в ней освоится. В QBASIC начало комментария обозначается знаком ' (одинарная кавычка). Остаток строки нельзя переносить в начало следующей строки, содержащей оператор.


Пример:
'Это комментарий
'PRINT без дополнений выводит на экран пустую строку
PRINT
PRINT 'За каждым оператором следует комментарий
PRINT
'Вывод пустой строки 
PRINT
 
Примечание: Вся последняя строка интерпретируется QBASIC как комментарий, т.е.  включенный в эту строку оператор PRINT не выполняется. Теперь перейдем к рассмотрению арифметических выражений.

 

Арифметические выражения. 

Арифметическое выражение — это комбинация чисел, арифметических констант и некоторых функций, которые связаны между собой знаками арифметических операций. Числа — простейшая форма арифметических выражений. Число состоит из цифр "О...9" и специальных знаков "- + . D". Обратите внимание, что вместо запятой ",", отделяющей целую часть от дробной, используется точка ".".


Примеры:
4.23
вместо
4,23
9.23D+78
вместо
9,23*1078
-2.77
вместо
-2,77
-1.34D-23
вместо
-1,34*10 -23

Сложные арифметические выражения можно получить, если связать в программе числа друг с другом, например, для вычислений. Символы, с помощью которых числа вступают друг с другом в некоторые отношения, называют знаками операций. Эти знаки имеют следующие значения:
 
Знак
Значение
*
умножение
/
деление
+
сложение
-
вычитание
(
открывающая скобка
)
закрывающая скобка
^
возведение в степень
Примечание: В QBASIC операции "*", "/", "^" имеют больший риоритет, чем операции "+","-". Впрочем на последовательность вычислений можно влиять, применяя в нужных местах круглые скобки.

 
Новое представление оператора PRINT дает возможность работать с арифметическими выражениями.


PRINT [Выражение] 
Выражение - Арифметическое выражение. Значение выражения выводится на экран.
Так как в операторе PRINT выражение — необязательный параметр, то c его помощью можно выводить на экран пустую строку.
Пример:
'Пример программы для применения оператора PRINT
'Для начала выведем простые числа
PRINT 12
PRINT 23.34
PRINT-345.454
PRINT 'Вывод пустых строк
PRINT
PRINT
'Вывод арифметических выражений
PRINT 12-4
PRINT+6+56-6
PRINT 3*4-4* (4+1)
PRINT 3+2^3
'Конец программы
 
 

Строковые выражения

Строковое выражение — это комбинация текстов, текстовых констант, текстовых переменных и определенных функций, которые связаны операцией "+". Простейшая строка — это текст, заключенный в кавычки ("), состоящий из произвольных комбинаций букв, цифр и специальных знаков. Тексты используются, например, чтобы выводить на экран заглавия, комментарии или примечания.


Примеры: 
" Задайте высоту" 
" 2345,34" 
" Программа окончена? (Y/N)" 
" Эта программа вычисляет объем бруса" 
 
Примечание: Так как кавычка является ограничивающим текст знаком, то его нельзя применять в качестве элемента самого текста (например, "Введите "Y/N"). Чтобы включить кавычку в текст, используйте функцию CHR$ (см. главу "Обработка строк")


Объединяя отдельные тексты оператором "+", можно получать более длинные строковые выражения. Эта операция называется конкатенацией.


Пример: 
" Сегодня" + " хорошая" + " погода", в результате получим "Сегодня хорошая погода".
Теперь расширим синтаксическое описание оператора PRINT, чтобы иметь возможность работать со строковыми выражениями.
PRINT [Выражение]
Выражение - Числовое или строковое выражение. Значение выражения выводится на экран.
Пример:
'Вывод выражений с помощью оператора PRINT
PRINT "Вывод чисел:"
PRINT 23.4
PRINT-10.2
PRINT
PRINT
PRINT "Вычислим (10+4) - 4*(2-3'^2)"
PRINT (10 + 4)-4* (2-3^2)
PRINT
PRINT "В заключение объединим отдельные"
PRINT
PRINT "слова в текст:"
PRINT "Сегодня" + " " + "хорошая" + " погода"
'Конец программы
 
 

Типы данных

Как правило, любой программе необходимы данные, которые каким-то образом обрабатываются программой. Эти данные могут быть совершенно различными. Так, в простейшем случае различают два типа данных: числовые и строковые. В QBASIC разные типы данных должны иметь четкие различия и признаки.

Стандартные типы данных. 

В QBASIC можно объявить следующие стандартные типы данных:

 
Тип
Символ
Содержание
INTEGER
%
целые числа в интервале от -32 768 до +32 768
LONG
&
целые числа в интервале от -2 147483648 до +2 147483648
SINGLE
!
числа с плавающей запятой в интервале от ±8,43*10-37 до ± 3,З7*1038
DOUBLE
#
числа с плавающей запятой в интервале от ±4,19*10-307 до ±1,67*10308
STRING
$
любые тексты с максимальной длиной 32 767 знаков
Примечание: Обработка данных типа INTEGER производится значительно быстрее, чем данных типа DOUBLE.
 

Константы и переменные.

Константы.

Константы определяют в начале программы. После определения они могут использоваться во всей программе.


CONST Имя_константы = Выражение [, Имя_константы "Выражение]...
Имя_константы - Имя константы содержит максимум 40 символов и должно начинаться с буквы. Допустимые символы: "A...Z","0...9" и точка".". Причем несущественно, строчные или заглавные буквы составляют имя константы. Последним должен быть один из символов, идентифицирующих тот или иной стандартный тип (! # % $ ). По умолчанию QBASIC сам присвоит тип SINGLE. Следует следить за тем, чтобы не присвоить константе ключевое слово в качестве имени. Выражение - Значение, которое должно храниться в константе. Это значение может быть просто числом, другой константой, текстом или арифметическим выражением (не применять операцию"^").
Пример:
'Работа с константами 
CONST р1!-3.14 
CONST mwst% - 14
 
 

Переменные.

Так же, как и константы, переменные определяют в самом начале программы. В отличие от констант, значения переменных могут меняться в процессе выполнения программы.
 
 
Примечание: BASIC часто критикуют за то, что переменные не обязательно объявлять в начале программы. Если во время работы программы необходима переменная,ее можно просто применять. В других языках программирования (Паскаль, Си, Кобол и др.) переменные объявляются в начале программы. В своих собственных интересах программисту следует привыкать к объявлению переменных в начале программы, так как в этом случае значительно повышается наглядность программы. Кроме того, легче будет осваивать другие языки программирования.
 
Объявление переменных выглядит так:


DIM [SHARED] Имя_переменной [, Имя_переменной ]...
SHARED - Указание на то, что переменную можно использовать во всех функциях и процедурах программы.
Имя_переменной - Его максимальная длина 40 символов. Имя переменной подчиняется тем же правилам, что и имя константы.

Примеры:
DIM SHARED height!
DIM breadth!
DIM height!, length!, okl$, telefon$
 
 
Примечание: Следите за тем, чтобы имена переменных и констант соответствовали их содержанию. С переменными height!, telefon$, length! сразу ассоциируется их применение. 

 

Присвоение значений переменным.

Присвоить некоторое значение переменной можно следующим образом:


Имя_переменной = {Строковое_выражение | Арифметическое_выражение}
При присвоении значения необходимо следить за тем, чтобы тип переменной соответствовал типу выражения, расположенного справа от знака равенства. Если Вы попробуете присвоить строковое выражение арифметической переменной или наоборот, то получите ошибку несоответствия типов. Необходимо также точно соблюдать соответствие между типом числовой переменной и типом арифметического выражения, чтобы избежать ошибок при вычислениях.

Следует следить за тем, чтобы при вычислениях не было переполнения значения переменной.

Конструкции, в которых переменная находится слева и справа от знака равенства, применяются очень часто. Интерпретация такого выражения достаточно проста. Сначала вычисляется значение выражения, стоящего справа от знака равенства с учетом текущих значений переменных, и только после этого происходит присвоение значение переменной, расположенной слева от знака равенства. 

Ввод/вывод.

В этой главе Вы познакомитесь с операторами и функциями, которые реализуют вывод на экран и ввод с клавиатуры.

Вывод на экран.

Оператор PRINT позволяет выводить данные на экран. Синтаксис оператора PRINT:


PRINT [Выражение] [{;|,} Выражение]...[{;|,} ]
Выражение - Арифметическое или строковое выражение. Значение выражения выводится на экран.
{;|,} - Устанавливает начало последующего вывода:
;: — значение очередного выражения следует непосредственно за значением предыдущего,
, — значение очередного выражения размещается в начале следующей области вывода. Область вывода — блок из 14 символов.
Если в конце PRINT-выражения нет ни знака ";", ни ",", то выполняется перевод строки, и вывод следующего значения начинается с новой строки.
 
 
Примечание: Оператор LPRINT выводит данные на печатающее устройство (принтер). В остальном синтаксис LPRINT идентичен синтаксису оператора  PRINT.

 

Очистка экрана.

Оператор CLS очищает экран и используется без параметров. Следующий оператор вывода начинает размещение данных в левом верхнем углу экрана (первая строка, первый столбец).
Пример:
'В данной программе демонстрируется очистка экрана
CLS
'Экран очищен
PRINT "Вывод в левый верхний угол, ";
PRINT "остальное поле экрана свободно" 
'Конец программы
 
 

Ввод с клавиатуры.

Описанный далее оператор INPUT дает возможность вводить данные во время выполнения программы, после чего эти данные обрабатываются программой. Появление на экране вопросительного знака означает запрос ввода. Ввод данных завершается нажатием клавиши  , и введенное значение сохраняется в заданной переменной.


INPUT [Текст{;|,}] Имя_переменной [, Имя_переменной].
Текст- Текст, который будет выведен на экран перед тем, как пользователь осуществит ввод.
{;|,} - Точка с запятой обозначает, что после текста выводится знак вопроса для обозначения необходимости ввода данных. Если вместо точки с запятой стоит запятая, знак вопроса после текста не появится. 
Имя_переменной - Переменные, в которых сохраняются вводимые данные. Объявление переменных должно быть выполнено в начале программы. 
Пример 1:
В приведенной ниже программе вводятся значения трех переменных — height!, breadth!, length!. Результат вычислений выводится на экран.
'Пример 1
DIM height!, breadth!, length!
CLS
INPUT height!
INPUT breadth!
INPUT length!
PRINT
PRINT "Результат "; height! * breadth! * length!
'Конец программы
 
 

Пример 2: 
Предыдущая программа имеет очевидный недостаток, так как на экране не видно, что собственно требуется вводить. Однако в операторе INPUT имеется возможность перед каждым вводом данных выводить на экран текст. 
'Пример 2
 DIM height!, breadth!, length!
CLS
INPUT "Введите, пожалуйста, высоту :"; height! 
INPUT "Введите, пожалуйста, ширину :"; breadth! 
INPUT "Введите, пожалуйста, длину :"; length!
PRINT
PRINT "Результат V="; height! * breadth! * length!
'Конец программы
 
 

Применение точки с запятой приводит к тому, что после вывода текста на экране появляется знак вопроса, вывод которого можно отменить, если точку с запятой заменить запятой. Предложение INPUT будет выглядеть так:
INPUT "Введите, пожалуйста, высоту :", height!
 
 
Примечание: Оператор INPUT проверяет, соответствует ли тип вводимой величины типу указанной переменной. Если число с плавающей запятой записать в переменную типа INTEGER, то вводимая величина будет округлена до ближайшего большего целого числа. Если текст вводится в числовую переменную, QBASIC отказывается воспринимать данные и выдает сообщение об ошибке — "Redo from start" (Начните еще раз).

 

 

Форматированный вывод на экран.

Следующий оператор служит для форматированного вывода данных на экран. Он очень похож на оператор PRINT.


PRINT USING Шаблон Выражение [;]
Шаблон- Определяет вид, в котором выводятся выражения.
Выражение- Арифметическое или строковое выражение.
Значение выражения появляется на экране, преобразованное шаблоном.
Как и в операторе PRINT, точка с запятой подавляет перевод строки. Шаблон в операторе PRINT USING всегда заключен в двойные кавычки (""). Внутри кавычек находятся символы, определяющие формат вывода.
Символы для вывода чисел
#      Вывод одного цифрового разряда. Если выводимое значение короче, чем количество цифровых знаков в шаблоне, то число выравнивается по правому краю и лишние (свободные) позиции слева заполняется пробелами.
+      Вывод знака. Выводит в явном виде знак "+". Вывод пробела, если выводимое значение положительно.
-       Вывод пробела, если выводимое значение положительно, и знака "-", если значение отрицательно.
**     Ведущие пробелы заменяются звездочками
$$     Ведущие пробелы заменяются знаком доллара
Символы шаблона для вывода строк
&     Указание на вывод всего строкового выражения
!      Указание на вывод лишь первого символа строкового выражения
\\     Указывает на вывод строки определенной длины. Количество выведенных символов определяется интервалом между двумя знаками "косая черта". Причем, считаются как ог- раничители (знак "косая черта"), так и пробелы между ними.
Специальные символы внутри шаблона.
Текст Реализуется возможность вводить текст в шаблон
_ Вывод следующего символа в непосредственном виде

Пример 1: 
Демонстрирует принципиальное различие между операторами PRINT и PRINT USING.
'Пример вывода с помощью оператора PRINT USING
CLS
PRINT "Сначала несколько арифметических шаблонов
PRINT
PRINT "Вывод с шаблоном:"
PRINT USING "#####" 112
PRINT USING "#####" 10
PRINT USING "#####" 1123
PRINT "Вывод без шаблона:" 'Для сравнения
PRINT 34
PRINT 123
PRINT 1123
PRINT
PRINT "Вывод с шаблоном:"
PRINT USING "###.##"; 34
PRINT USING "#*#.*#"; 45.2
PRINT USING "###.*#"; 123.23
PRINT "Вывод без шаблона:" 'Для сравнения
PRINT 23 "Для сравнения
PRINT 345.34
 
 

Позиционирование курсора.

Для перемещения курсора в требуемую позицию экрана, как правило, применяют оператор LOCATE. Это очень удобно, например, для создания сложных форм вывода на экран. 


LOCATE [Строка] [, [Столбец][,[Курсор] [,Старт[,[Стоп] ]]]
Строка - Строка экрана (1-25), на которую должен переместиться курсор.
Столбец - Столбец экрана (1-80), к которому должен переместиться курсор.
Курсор - Указывает, в каком состоянии находится курсор при выводе. 0— выключен, 1 — включен.
Старт, Стоп - Числа от 1 до 31, которые задают высоту курсора.
Синтаксически команда выглядит достаточно сложной, но ситуацию упрощает то, что большинство параметров необязательны.
Пример 1: 
После очистки первый вывод на экран должен быть в десятой строке.

'Вывод в десятую строку после CLS
CLS
LOCATE 10
PRINT "Вывод появляется в десятой строке экрана"
'Конец программы
 
 

Вывод пробелов.

Функция SPC в сочетании с оператором PRINT может выводить на экран пробелы. Это полезно, например, при оформлении вывода информации на экран.


SPC (Значение)
Значение - Арифметическое выражение типа INTEGER в диапазоне значений от 0 до 32767.

Пример:
CLS 
PRINT "Text Г; SPC(10); "Text 2"
 
 

Функция табуляции.

Функция TAB так же, как функция SPC, применяется в операторе PRINT. Позволяет начать вывод данных текущей строки с определенной позиции.


TAB (Столбец)Столбец - Переменная типа INTEGER, задает номер столбца вывода данных текущей строки.
Функция TAB очень полезна в случаях, когда с помощью оператора LPRINT требуется оформить наглядный листинг.

Остановка программы.

В основном любой алгоритм должен как-то заканчиваться, поэтому отсутствие необходимости использовать оператор END в последних версиях QBASICа, считается отрицательным его качеством. Но он всё же существует, и вставлять его в конец программы всё же стоит (потом пригодится). Также если хотите прервать вашу программу в любом её месте то надо использовать оператор


STOP 
Он останавливает выполнение программы на том месте, где стоит. 

Управляющие операторы.

Рассматриваемые до сих пор программы были линейными, т.е. выполнялись последовательно оператор за оператором с начала до конца программы. В таких программах невозможно влиять на последовательность выполнения операторов, когда, например, происходит повторение фрагментов программы или выполнение ряда действий зависит от определенных условий.
В этой главе Вы познакомитесь с операторами, которые позволяют управлять ходом выполнения программы. Группу таких операторов часто объединяют понятием "Управляющие операторы".

Оператор безусловного перехода.

Оператор GOTO позволяет изменить последовательность выполнения шагов программы, но его применение нежелательно, так как увеличивается время выполнения, снижается наглядность и понимаемость программы. В предыдущих версиях BASICa не было возможности отказаться от применения GOTO, так как практически не существовало других языковых элементов для управления программой.


GOTO Метка_перехода
Метка_перехода Объявленная в программе метка. Метка объявляется произвольным именем, заканчивающимся двоеточием.
Пример 1: 
В приведенной ниже программе происходит переход к последнему оператору PRINT, В результате на экране получаем сообщение "Хелло, Долли!".

'Оператор GOTO
CLS
PRINT "Хелло, "
GOTO weiter
PRINT "Здесь проявляется GOTO";
Welter: ‘Метка перехода 
PRINT "Долли!" 
'Конец программы

Если указать в операторе GOTO метку, не объявленную в программе, то при запуске программы, появится соответствующее сообщение об ошибке. Если одну метку объявить в программе дважды, тоже появится сообщение об ошибке.


Пример 2:
В этом примере представлена "бесконечная" (зациклившаяся) программа, которая всегда возвращается к своему началу.

'Зациклившаяся программа (прервать нажатием клавиш "CTRL" + "Pause")
anfang:
PRINT 234.23
GOTO anfang 'Недосягаемый конец программы
 
 

Пример 3: 
Последний пример показывает, насколько плохую услугу при конструировании программ оказывает оператор GOTO.

'Как не надо писать программы 
anfang:
GOTO schritti 
schritt4:
PRINT "совсем непонятная "
GOTO schritt5 
schritt6:
GOTO ende
 schritti:
CLS
GOTO schritt2
schrin3:
PRINT "простая, но "
GOTO schritt4
 schritt2:
PRINT "Это очень"
GOTO schrin3 
Schritt5:
PRINT "программа."
GOTO schritt6
PRINT "Здесь работает Goto-"
ende:
PRINT "Наконец готово!"
'Конец программы
 
 

Условия .

Результат сравнения может принимать только два значения: "истина", когда высказы- вание справедливо, или "ложь" — в противном случае. Говорят также, что истинность таких выражений либо "true" (t)(-1), либо "false" (f)(0).
Конструкция логических выражений в QBASIC довольно проста. В качестве сравниваемых значений (сравниваемых операндов) могут участвовать строки, числа, константы, переменные, арифметические и строковые выражения. Используют следующие операции сравнения:

 
Операция
Значение
>
больше
<
меньше
>=
больше или равно
<=
меньше или равно
=
равно
<>
Не равно

Схематически условие можно представить следующим образом:
Выражение_1 Операция_сравнения Выражение_2
Для того чтобы сравнить строки (т.е. применить операторы ">" или "<" к строковым данным), необходимо учитывать порядок расположения символов в таблице кодов ASCII: "О" < "1" <„.< "9 "< "А ",...< "Z" < "а" <... "z".

Итак, Строка_1 больше (меньше) Строки_2, если при посимвольном сравнении строк код первого несовпадающего символа из Строки_1 больше (меньше) кода соответствующего символа из Строки_2.
Числовые переменные(константы) сравниваются обычным образом.

Также в QВasic можно использовать переменные типа Boolean, т.е. переменные которым можно присвоить какое-то логическое выражение, и значение этой переменной будет зависеть от истинности или ложности определяющего выражения. Если значение выражения ложно, то переменной будет присвоено значение 0, а если истинно, то -1. 

Пример
'Использование логических выражений
А=2>5
B=6<=6
C=8<>9
PRINT A
PRINT B
PRINT C
END
'Конец программы
 

В результате на экране вы увидите:
0
-1
-1
 
 

Также в логических выражениях можно использовать логические операции AND(и), OR(или), NOT(не), XOR(исключающее или, либо). Приведём таблицу истинности и приоритет операций.


Выражение А
Выражение В
A AND B
A OR B
NOT A
A XOR B
0
0
0
0
1
0
0
1
0
1
1
1
1
0
0
1
0
1
1
1
1
1
0
0

Приоритет
В первую очередь вычисляется значение функции под операцией NOT, потом AND, и в конце OR, XOR. 

Пример
'Использование в логических выражениях логические операции
А=((2>5) AND (6<=6)) OR (NOT(8<>9))
PRINT A
END
'Конец программы
В результате на экране вы увидите:
0
 
 

Оператор условного перехода в программе.

Этот оператор позволяет изменять порядок выполнения операторов в программе в зависимости от определенных условий. Синтаксис оператора:


IF Условие THEN 
[Оператор 1-1]
[Оператор 1-n]
[ELSE
[Оператор 2-1] 
[Оператор 2-m] 
END IF 
Как видно из синтаксического описания, оператор IF состоит из THEN-ветви с операторами 1-1 ... 1-n и из ELSE-ветви, которая содержит операторы 2-1 ... 2-m. Если условие, заданное в операторе IF истинно, то выполняется THEN-ветвь, т.е. последовательно выполняются операторы 1-1 ... 1-n. В противном случае выполняются операторы 2-1... 2-m ELSE-ветви. После выполнения одной из ветвей работа программы продолжается с оператора, следующего за END IF, если ход выполнения программы не изменяется оператором GOTO.

Если отсутствует ELSE-ветвь и условие в операторе IF ложно, то работа программы всегда продолжается с оператора, следующего за END IF. В отличие от ELSE ключевое слово THEN пропускать нельзя. В прежних версиях BASIC часто незаменимой была конструкция условного перехода, т.е. комбинация операторов IF и GOTO.

Цикл WHILE.

С помощью конструкции WHILE … WEND можно реализовать выполнение ряда операторов до тех пор, пока выполняется определенное условие. Последовательность операторов, выполнение которых повторяется циклически, называется циклом.


WHILE Условие
[Оператор_1] 



[Оператор_n] 
WEND 
До тех пор пока соблюдается условие, последовательно выполняются операторы от 1 до n. Ключевое слово WEND закрывает конструкцию по аналогии с командой END IF. Если условие цикла больше не соблюдается, то выполнение программы продолжается, начиная с оператора, следующего за WEND.Если условие цикла WHILE не выполняется с самого начала, то управление сразу же передается оператору, расположенному за WEND.

Следите за тем, чтобы действия внутри цикла влияли на WHILE-условие. В данном примере показано, что произойдет, если эту рекомендацию не выполнить.
'Конструкция цикла WHILE с подвохом
DIM i%
i%=1
WHILE i%=1
PRINT "1-ый оператор в While-цикле" 
PRINT "2-ой оператор в While-цикле"
WEND
'Конец программы
 
 
Примечание: Если Вы используете цикл WHILE ... WEND, следите за тем, чтобы к моменту первой проверки логического условия переменные,  входящие в него, были установлены соответствующим образом.

Цикл DO.

Конструкция DO...LOOP очень похожа на WHILE...WEND. Здесь также имеется последовательность операторов, повторное выполнение которых зависит от некоторых условий. 


Вариант 1: 
DO 
[Оператор_1] 
        . 
        . 
        . 
[Оператор_n]
[EXIT DO] 
LOOP [{WHILE I UNTIL} Условие ]
Вариант 2:
DO [{WHILE I UNTIL} Условие]
[Оператор_1] 
        . 
        . 
        . 
[Оператор_n] 
[EXIT DO] 
LOOP 
{WHILE I UNTIL} - Ключевыми словами WHILE или UNTIL определяется способ проверки условий. При использовании WHILE цикл выполняется до тех пор, пока соблюдается условие (значение логического выражения истинно). И, наоборот, при использовании UNTIL цикл выполняется только тогда, когда условие не соблюдается (значение логического выражения ложно).
EXIT DO - Оператор EXIT DO преждевременно прерывает выполнение цикла. 
DO...LOOP- Работа программы продолжается с оператора, следующего за LOOP.

В первом варианте цикл выполняется по крайней мере один раз, так как проверка условия находится в конце цикла. А во втором варианте цикл может вообще не выполняться, если соответствующее условие с самого начала не позволяет входить в него. Этот вариант очень похож на цикл WHILE...WEND. Как видно из синтаксического описания, DO...LOOP может работать без проверки условий. В этом случае из бесконечного цикла можно выйти с помощью оператора EXIT DO.
Используя оператор FOR...NEXT, можно программировать циклы, количество прохождений которых зависит от значения счетчика.
FOR Счетчик = Нач_значение ТО Кон_значение [STEP Шаг]
[Оператор_1] 
        . 
        . 
        . 
[Оператор_n]
[EXIT FOR] 
NEXT Счетчик 
Счетчик - Арифметическая переменная, которая изменяется при повторении цикла. Ее часто называют управляющей переменной цикла.
Нач значение - Арифметическое выражение, задающее начальное значение счетчика.
Кон значение - Арифметическое выражение, задающее конечное значение счетчика. 
Шаг - Арифметическое выражение, задающее приращение счетчика при каждом прохождении цикла. Если эта опция пропущена, значение шага по умолчанию принимается равным +1
EXIT FOR- Прерывает выполнение цикла. Программа продолжает работу с оператора, следующего за NEXT FOR.

Операторы между FOR и NEXT повторяются до тех пор, пока управляющая переменная цикла не превысит конечное значение. После каждого прохождения цикла переменная цикла изменяется на величину шага. Если шаг — положительное число, то начальное значение переменной цикла должно быть меньше конечного значения, иначе цикл ни разу не выполнится, и, наоборот, если шаг отрицательный, то начальное значение переменной цикла должно быть больше конечного, иначе опять-таки цикл ни разу не отработает. В остальных случаях количество прохождений цикла с шагом — это ближайшее большее целое от выражения: "( конечное значение — начальное значение+1) / шаг", если шаг положительный, и "(конечное значение—начальное значение-1) / шаг", если шаг отрицательный.

Оператор выбора SELECT CASE.

SELECT CASE предназначен для выполнения одного из альтернативных действий, перечисленных в нем. Выбор определяется значением управляющей переменной. Начнем с представления синтаксиса: 


SELECT CASE Переменная 
CASE Сравнение_1 
[Операторы_1] 
[CASE Сравнение_2 
[Операторы_2] ]... 
[CASE ELSE 
[Операторы] ] 
END SELECT 
Сначала выполняется Сравнение_1. Если результат истинен, выполняются Операторы_1, после чего выполнение программы продолжается с оператора, следующего за END SELECT. Если результат Сравнения_1 ложен, то проверяется условие следующей ветви CASE. В итоге выполняются операторы той CASE-ветви, для которой выполняется условие сравнения. Если же ни для одной ветви результатом сравнения не является истина, то выполняются операторы ветви CASE ELSE.
 
Примечание: Применение CASE ELSE не обязательно. Однако эту ветвь все же следует описывать, так какv QBASIC выдает сообщение об ошибке, если ее нет и ни для одного из сравнений не был получен истинный результат.


CASE-сравнение в простейшем случае состоит только из одного выражения (например, из чисел или из переменных). Однако можно включать списки выражений (выражение_1, выражение_2,.„) или даже целые области (выражение_1 ТО выражение_2). Далее значение переменной можно оценивать с помощью операторов сравнения, как в случае с условиями. Для этого после CASE применяется ключевое слово IS, за которым следует операция отношения и выражение. 


Пример I: 
В этом примере вводимое число проверяется на принадлежность к определенному интервалу.
‘ SELECT ... CASE
CONST zehn%= 10
DIM zahl%
CLS
INPUT "Задать число "; zahl%
SELECT CASE zahl%
CASE 1, 2  'список значений
PRINT "Число 1 или 2" 
CASE 3 TO 10  'область значений
PRINT "Число в диапазоне от 3 до 10"
CASE IS = 11 'сравнение с IS и оператор
PRINT "Число 11"
'Разумеется, выражение для сравнения может быть и посложнее 
CASE IS < zehn% + 10
PRINT "Число меньше 20" 
CASE ELSE
PRINT "Это все, что я знаю о числе " 
END SELECT 
PRINT "Конец" 
'Конец программы
 
 

Пример 2: 
Иногда важно, в какой последовательности располагаются CASE-ветви. Рассмотрим пример. 
'SELECT...CASE с подвохом 
DIM zahl% 
CLS
INPUT "Ввести число "; zahl% 
SELECT CASE zahl% 
CASE IS < 10
PRINT "Число меньше 10" 
CASE IS < 20
PRINT "Число меньше 20" 
CASE IS < 5
PRINT "Число меньше 5" 
CASE ELSE
PRINT "Решение не встретилось" 
END SELECT 'Конец программы
 
 

Третья CASE-ветвь никогда не будет выполнена, так как число, которое меньше 5, всегда меньше 10, а значит, после первой CASE-ветви выполнение оператора SELECT завершится.

Логические операции.

В программах часто возникает необходимость описывать более сложные логические выражения, чем мы рассматривали. Рассмотрим пример:


'Пример, подводящий читателя к применению более сложных логических условий 
DIM zahl1%, zahl2% 
CLS
INPUT "Ввести число 1, zahl1% 
INPUT "Ввести число 2", zahl2% 
'Конец программы
 
 

Предположим входные данные должны вводится только тогда, когда zahll % больше нуля, и одновременно zahl1% меньше нуля. Как проверить одно из условий, Вы уже знаете. Рассмотрим способ, позволяющий объединить оба условия.

Логическое И (AND) .

AND (И) коньюктивно объединяет логические условия:


Условие_1 AND Условие_2 [AND Условие_3] …
Результат такого объединения лишь тогда истинен, когда истинно каждое отдельное условие.
Таблицу истинности данной операции смотри в главе Условия 
Пример :
DIM zahl1%, zahl2%
CLS
DO
INPUT "Введите число 1> 0", zahl1% 
INPUT "Введите число 2 < 0 ", zahl2%
LOOP UNTIL zahll %>0 AND zahl2% < 0
PRINT "Спасибо за корректный ввод"
'Конец программы
 
 

Только тогда, когда zahl1% > 0 и zahl2%< 0, значение всего логического выражения станет истинно, а значит, выполнение цикла закончится.

Логическое ИЛИ (OR) .

OR (ИЛИ) дизъюнктивно объединяет логические условия:


Условие_1 OR Условие_2 [OR Условие_3...]
Результат такого объединения только тогда ложен, когда ложны все составляющие:
Таблицу истинности данной операции смотри в главе Условия 

Пример:
DIM zahl1%, zahl2% 
CLS
DO
PRINT "Число 1 или число 2 должно быть больше нуля" 
INPUT "Введите число 1", zahl1% 
INPUT "Введите число 2", zahl2% 
LOOP UNTIL zahl1% >0 OR zahl2% >0 
PRINT "Спасибо за корректный ввод"
'Конец программы
 
 

В этом примере выход из LOOP-цикла не произойдет только в том случае, если значение каждого из вводимых чисел будет меньше или равно нулю.

Логическое отрицание (NOT).

NOT инвертирует (меняет на противоположное) значение логического выражения, т.е. то, что было "ложь", становится "истиной" и наоборот:


Таблицу истинности данной операции смотри в главе Условия 

Пример:
DIM zahl%
CLS
INPUT "Введите число " zahl%
IF NOTzahl% > 0 THEN
PRINT "Число не больше нуля" 
       ELSE
PRINT "Число больше нуля" 
END IF 
'Конец программы
 
 

Обработка строк

В этой главе рассмотрим функции, которые осуществляют обработку строк. В QBASIC функция состоит из имени и аргументов, которые заключаются в круглые скобки и располагаются всегда за именем функции. Значения функций обработки строк могут быть или типа STRING, или принадлежать к группе арифметических типов данных. Функции, наряду с переменными и константами, применяют в качестве составляющих оператора или используют при составлении выражений или логических условий. Естественно, зна- чение функции должно быть совместимо с остальными составляющими оператора, например, в арифметическое выражение нельзя встраивать функцию, значение которой является строковым выражением.

Определение длины строки.

Функция LEN выдает длину строки, т.е. количество символов в строковом выражении.


Пример:
DIM a$, 1аеngе%
PRINT LEN("Сегодня понедельник")
INPUT "Ввести текст ";а$
1aenge% = LEN(a$)
PRINT a$; "Длина ";1аеnge," символов "
 
 

Получение символов кода ASCII.

Функция CHR$ преобразует ASCII-код в соответствующий символ (ASCII=American Standard Code for Information Interchange — Американский стандартный код для обмена информацией). Аргумент функции — число типа INTEGER в диапазоне от 0 до 255. 
Соответствие кодов ASCII определенным символам дано в ASCII-таб-лице, размещенной в справочнике (Help) OBASIC и приведенной ниже. Также можно воспользоваться следующей программой:


'ASCII-символьное предложение
DIM ascll%
DO
INPUT "Ввести ASCII-значение ", ascii% 
LOOP UNTIL ascii% > 0 AND ascii% <= 256
PRINT "Код ASCII "; ascll%;" соответствует символу ";CHR$(ascii%)
 
 

Получение ASCII-кода символа.

Функция ASC — обратная по отношению к функции CHR$. Аргумент функции ASC — символ, а значение функции — соответствующий этому символу ASCII-код.
Пример:
PRINT ASC ("А")

Выделение левых крайних символов строки.

Функция LEFT$ выделяет крайние слева символы строки. Вызов функции:


LEFT$ (Строка, Число) 
Строка - Строка, из которой выделяются символы.
Число - Величина типа INTEGER, которая задает количество выделяемых символов.

Пример:
PRINT LEFT$ ("Хелло, QBASIC", 5)

Выделение правых крайних символов строки.

Функция RIGHT$ выделяет крайние справа символы строки. Вызов функции:


RIGHT$ (Строка, Число) . Строка- Строка, из которой выделяются символы.
Число- Значение типа INTEGER, в котором указывается количество выделяемых справа символов. 

Пример:
PRINT RIGHTS ("Хелло, OBASIC, 5)

Выбор подстроки.

Функция MID$ копирует из строки любой ее фрагмент. 


MID$ (Строка, Начало, Длина) 
Строка - Строка, из которой должны выделятся символы.
Начало - Позиция, с которой начинается выбор фрагмента.
Длина - Длина подстроки.
Пример:
' MID$ - функция
DIM A$, i%, j%
А$=" Доброе утро"
1%=3
J%=5
PRINT MID$ ("Хелло, QBASIC",4,4)
PRINT MID$(aS,i%,j%)
 
 

Получение строчных символов.

Функция LCASE$ возвращает заданную строку в виде строчных букв. Пользуясь этой функцией, следует принять во внимание, что аргументы для LCASE$ расположены в подмножестве символов, коды которых лежат в диапазоне от 32 до 127. Следующие 128 символов (от 128 до 256) предназначены для кодирования символов национальных алфавитов, псевдографики, математических и др.
Пример:
‘LCASE$ 
PRINT LCASE$ ("HUT OF BROWN NOW SIT DOWN")

Получение заглавных символов.

Функция UCASE$ противоположна функции LCASE$ и возвращает заданную строку в виде заглавных букв. Следует принимать во внимание тот факт, что аргументом для UCASE$ могут быть лишь символы, коды которых расположены в диапазоне от 32 до 127.
Пример:
‘UCASE$ 
PRINT UCASE$ ("hut of brown now sit down")
 
 

Устранение ведущих пробелов.

Функция LTRIM$ устраняет в строке ведущие пробелы. Возвращенное значение сдвинуто влево.
Пример:
'LTRIM$
DIM wort$, lwort$
wort$ = "     Сдвиг влево"
Iwort$= LTRIM$(wort$)
PRINT wort$
PRINT LEN(wort$)
PRINT
PRINT Iwort$
PRINT LEN(lwort$)

      

Устранение последних пробелов .

Функция RTRIM$ убирает в строке последние пробелы. 
Пример :
‘RTRIM$
DIM wort1$, wort2$
wort1$= "левый
wort2$=" и правый"
PRINT wort1$+wort2$
PRINT PTRIM$(wort1$)+wort2$

Создание строки из пробелов.

Функция SPACE$ создает строку из пробелов. Аргумент функции — длина этой строки.
Пример:
DIM leer$
leer$-SPACES$(45) PRINT LEN(leer$)
 
 

Преобразование строки в число.

Функция VAL преобразует число из строкового представления в числовое. Предполагается, что преобразуемая строка содержит допустимые для представления чисел символы. Если нецифровой знак встречается первым в строке, то преобразование невозможно и значение функции равно нулю.
Пример:
PRINT VAL("234.23) PRINT VAL("Hallo") PRINT VAL("43D12)
 
 

Математические вычисления.

С простыми математическими вычислениями Вы уже познакомились в главе "Элементы языка QBASIC". В этой главе рассмотрим функции, которые позволяют проводить сложные математические расчеты. Без этих функций такие расчеты либо не возможны, либо требуют для реализации значительных затрат.

Абсолютное значение числа.

Функция ABS возвращает абсолютное значение заданного арифметического выражения.
Пример:
'Функция ABS 
DIM wert% 
wert% = 45 PRINT 
ABS(wert%) 
PRINT ABS(-1 * wert%)

      

Тригонометрические функции.

В QBASIC определены следующие тригонометрические функции:
SIN (угол) Функция синус угла
COS(угол) Функция косинус угла
TAN (угол) Функция тангенс угла
ATN (арифм.выраж.) Функция арктангенс угла

Угол следует задавать в радианах. Функция, обратная тангенсу — ATN, возвращает значение угла, выраженное в радианах. Для преобразования значения угла из градусной меры в радианную, и наоборот, можно воспользоваться формулами:
D град = рад* (180 /pi) 
D рад =град* (pi/ 180) где pi =3,14159 
Пример:
'Примеры тригонометрических функций
CONST pi!- 3.14159
CONST bogum! - 180 / pi!
CONST gradum!-pi!/ 180
'Вычисление синуса, косинуса и тангенса угла 17 градусов
PRINT SIN(17*gradum)
PRINT COS(17 * gradum)
PRINT TAN(17*gradum)
'Функция, обратная тангенсу — ATN
'Требуется опять получить 17 градусов
PRINT ATN(TAN(197 * gradum)) * bogum
'Конец программы
 
 

Функция вычисления экспоненты.

Функция ЕХР вычисляет значения функции е в степени х, где е=2,71 — основание натурального логарифма. Результат имеет вещественный тип SINGLE.
Пример:
'Функция :f(x)-- 3*ex+ 2*eзx
DIMx!
CLS
INPUT "Задать аргумент функции ",х!
PRINT "f(";x;")-";
PRINT -3 * EXP(x!) + 2 * EXP(3 * xl) 
'Конец программы
 
 

Вычисление натурального логарифма.

Функция LOG вычисляет значение натурального логарифма, т.е. логарифма с основанием е. Результат имеет вещественный тип SINGLE.
Пример:
'Функция LOG
DIMx!
CLS
INPUT "Задать аргумент функции ",х!
PRINT "ln(";x!;")-"; LOG(x!)
'проверка
PRINT "так как е^"; LOG(x!); "-х- "; EXP(LOG(x!))
 
 

Преобразование к типу INTEGER.

Функция INT возвращает наибольшее целое, не превосходящее значение ее аргумента.
PRINT INT(2.234)
PRINT INT(-2.234)
'Ближайшее меньшее целое число для -2.234 равно -3
 
 

Функцию INT удобно использовать для коммерческих округлений. 
Пример:
'Округление с помощью функции INT 
CONST nkstelle%-10
 'константа для определения количества
'значащих цифр после запятой при округлении 
'nkstelle - 10 — соответствует одной цифре после запятой
 'nkstelle - 100 — соответствует двум цифрам после запятой 
DIM x!, rund! 
CLS
INPUT "Задать число ";х! 
rund!=х! * nkstelle% + 0.5
 rund!= INT(rund!)
 rund! = rund! / nkstelle% 
PRINT х!; " ";rund!
 'Конец программы
 
 

Чтобы разобраться в работе этой программы, составим такую же таблицу значений переменных, как в главе "От задачи — к программе": 
Переменные Действия
х! rund!
0 0 DIM x!, rund!
23.352 0 Ввод 23.352 (INPUT)
23.352 234.2 х! * nkstelle% + .5 = 23.352 * 10 + .5
23.352 234 int(rund!)
23.352 23.4 rund! / nkstelle% = 234 / 10

Выделение целой части числа.

Функция FIX возвращает целую часть арифметического значения аргумента. Результат имеет целочисленный тип (INTEGER).
Пример:
PRINT FIX(2.334) PRINT FIX(-2.334)

Извлечение квадратного корня.

Функция SQR возвращает корень квадратный заданного аргумента. Результат — вещественное число типа SINGLE. Помните, что аргумент обязательно должен быть неотрицательным числом.
Пример:
PRINT SQR(4) 
PRINT SQR(1OO)
 PRINT SQR(234.234)
 'Следующая команда с ошибкой 
PRINT SQR(-4)

Для других дробных степеней в QBASIC нет стандартных функций. В главе "Функции и процедуры, определенные пользователем" Вы познакомитесь с тем, как можно самостоятельно создавать такие функции в QBASIC.

Определение знака числа (функция сигнатуры).

Функция SGN (Signum) возвращает значения -1,0,1, если аргумент соответственно меньше, равен или больше нуля.
Пример:
'Функция SGN 
PRINT SGN(-23.3454)
 PRINT SGN(0)
 PRINT SGN(23.32)

Преобразование числа в строку.

Функция STR$ преобразует числовое значение в цифровую строку и является функцией, обратной VAL.
DIM zeichen$
ZeichenS= "Это "+ STR$(10.234)
PRINT zeichenS

Массивы в QBASIC.

Под массивом понимают объединение переменных одного типа в единую структуру. Обращение к отдельным элементам в массиве осуществляется по индексу. Допустим, в программе необходимо 20 переменных для запоминания стоимостей каких-то товаров artprl,..artpr20. Переменные можно объявить следующим образом:


Dim artpi1!, artpr2!,......artpr20!
Ввод данных выглядит примерно так:
INPUT "Artpri ",artpr1! 
INPUT "Artpr 20 ",anpr20! 
Перечень подобных примеров можно продолжить (вывод наименований товаров, суммирование цен, стирание старых цен и т.п.). Значительно удобнее в подобных случаях вместо 20 отдельных полей данных использовать массив из 20 элементов и отдельный элемент идентифицировать с помощью числового индекса. Причем индекс может изменятся, например, как переменная цикла. Массив объявляется командой DIM:
DIM [SHARED] Переменная [Размерность]
В отличие от объявления простых переменных появляется новая спецификация — размерность. В ней указывается максимальное значение индекса массива.

Пример:
DIM artlkel$(1 T0 20)
 DIM prels%(5 TO 10)
 DIM alter%(18 T0 65)
'20 строковых элементов 1...20
'6 Integer-элементов  5...10 
'48 Integer-элементов 18...65

В программе для выбора элемента из массива используется индекс.
Пример:
PRINT preis%(5) 
'Выбор элемента массива с индексом 5

      
При программировании вышеописанного примера отчетливо видны преимущества применения массивов.
Пример:
'Упражнение с использованием массива
DIM artpr!(1 TO 20) 'массив цен
DIM 1% 'индекс-переменная
CLS
'Ввод цен для 20 наименований товаров
FOR i%-1 T0 20
PRINT "Ввести стоимость "; 1%; "-го товара";
'Ввод в элемемент массива с индексом 1% INPUT "",artpr(l%)
NEXT I %
'Вывод 20 наименований
CLS
'Вывод в строку
'суммы, количества, среднего значения, Max, Min
 
 
До сих пор мы рассматривали одномерные массивы. Но в QBASIC массив может иметь несколько индексов. Например, использование второго индекса позволяет обрабатывать двумерные таблицы. Трехмерный массив можно представить как куб. Можно описать массивы с четырьмя, пятью и более индексами. Максимально допустимое число индексов для одного массива — 255.
Пример:
'Использование трехмерных массивов
 DIM zahl%(1 TO 10, 4 ТО 16, 6 ТО 30)
 zahl%(1,5,23)=13
 PRINTzahl%(1,523)
 
 

Функции и процедуры, определенные пользователем.

Собственные функции.

В предшествующих главах Вы познакомились с некоторыми встроенными функциями QBASIC (например, MID$ или SQR). Теперь рассмотрим составление собственных функций. 
Вернемся к математической функции INT. INT — имя функции. Этим именем определяются некоторые программные действия, невидимые программисту, и которые инициализируются автоматически с появлением в программе имени функции. Иначе говоря, функцию можно понимать как группу операторов в программе, объединенных под именем функции. С помощью заключенного в круглые скобки аргумента (сравни INT (3.34)) в подпрограмму, инициируемую именем функции, передаются конкретные данные. Над этими данными производятся некоторые преобразования, и результат, как правило, возвращается в основную программу.
Чтобы вызвать из программы собственную функцию, нужно указать ее имя. Последний символ имени функции определяет тип возвращаемого значения.


Пример: 
STRICH$()-Возвращаемое значение - строка 
RUNDEN%()-Возвращаемое значение - число типa INTEGER 
WURZEL! ()-Возвращаемое значение — число типа SINGLE 
В QBASIC пользовательские функции объявляются при вводе ключевого слова FUNCTION и следующего за ним имени функции. В этом случае редактор автоматически генерирует новое программное окно, в котором нет ничего, кроме операторов, ограничивающих тело функции:
FUNCTION Имя_функции END FUNCTION
В пространство между ограничивающими ключевыми словами вносят операции QBASIC, обеспечивающие выполнение необходимых действий. Чтобы вернуться в главную программу, надо нажать клавишу  . На экране появляется поле списков со всеми BIBL.BAS и сохраните его под новым именем ("Save as..."). Если Вы будете составлять свою программу в этом файле, из нее можно вызывать все процедуры и функции файла BIBL.BAS.

Покажем создание функции извлечения корня, упомянутой в главе "Математические вычисления", функция должна извлекать из числа корень любой степени. Начнем с главной программы: 
'Главная программа для функции извлечения корня
DIM argument!, wurz%
CLS
DO
INPUT "Ввести аргумент: ", argument!
INPUT "Ввести степень корня: ", wurz%
LOOP WHILE argument! < 0
PRINT
PRINT wurzel!(argument!, wurz%)
'Конец главной программы
 
 

Составим шаблон функции: 
FUNCTION wurzel! (argument!, wurz%) END FUNCTION
Извлечение корня из аргумента можно представить функцией возведения аргумента в степень, обратную степени корня. Функция извлечения корня любой степени имеет следующий вид:

FUNCTION wurzel! (argument!, wurz%)
wurzell = argument! ^ (1 / wurz%)
 END FUNCTION

      
Рассмотрим синтаксис определения функции в программе более детально:
FUNCTION Имя_функции (Параметр_1 [, Параметр_2]...) [STATIC]
[Оператор]... 
Имя_функции = Выражение 
END FUNCTION 
Имя_функции - Имя функции; последний символ обязательно определяет тип возвращаемого значения (%,&,!, #или $).
Параметр - Параметр, который передается функции при вызове.
STATIC - Если в теле функции объявляются локальные переменные, то они сохраняют свои значения в промежутке между вызовами функции. 
Выражение- Возвращаемое значение
Смысл опции STATIC разъясним на небольшом примере. Составим главную программу для вызова функции zlen:
'Главная программа
PRINT "Длина 'test' "; zlen%("test")
PRINT "Длина 'test' "; zlen%("test")
 
 

Функцию zlen объявим следующим образом:

FUNCTION zlen%(text$)
DIMi%
i%-i%+LEN(text$)
zlen%-i% END FUNCTION

      
После запуска программы дважды получим на экране сообщение "Длина 'тест' 4". Изменим заголовок функции:
FUNCTION zlen% (text$) STATIC
После первого запуска программы получаем сначала значение длины 4, затем 8. Так как при объявлении функции используется ключевое слово STATIC, то значение локальной переменной i% сохраняется после окончания выполнения функции. Поэтому при последующих вызовах к значению переменной i% добавляется число 4, и при втором обращении к функции возвращаемое значение уже не 4, а 8.

Собственные процедуры.

В процедурах, как и в функциях, под одним именем процедуры объединяются логически самостоятельные фрагменты программы. Для начала рассмотрим пример:
'Программа, иллюстрирующая понятие процедуры PRINT "A"
PRINT "В"
PRINT "B1"
PRINT "B2"
 PRINT "С"
PRINT "В"
PRINT "B1"
PRINT "B2"
PRINT "erf"
PRINT "B"
PRINT "B1"
PRINT "B2"
 PRINT "ugh" 
'Конец программы
 
 
Программа носит чисто иллюстративный характер, однако полезна для внесения ясности в представление о процедурах. Можно заметить, что некоторые фрагменты программы часто повторяются. 
Такие повторения необоснованно удлиняют программу и затрудняют работу с ней. Процедуры позволяют объединять под одним именем повторяющиеся фрагменты программы. Процедуру, как и функцию, можно вызвать из главной программы.


Задайте в программе команду "SUB beispiel" и получите пустой шаблон процедуры:

SUB beispiel 
END SUB

      
Внесите туда операторы, которые повторяются в главной программе.
SUB beispiel
 PRINT "В" 
PRINT "B1"
 PRINT "B2"
END SUB

      
Теперь достаточно из главной программы вызвать процедуру там, где это требуется. Таким образом, получаем новый вариант программы в таком виде:
beispiel 
PRINT "C"
beispiel
PRINT "erf"
beispiel
PRINT "ugh" 

      

Другие операторы.

Обработка даты компьютера.

С помощью функции DATE$ можно определить текущую системную дату или изменить ее.
Пример:
DIM datS
PRINT DATE$
dat$ = DATE$
DATE$="17-02-1992"
PRINT "Предшествующая дата: "; datS:
 'последующая дата: ";DATES

Обработка компьютерного времени.

С помощью функции ТIМЕ$ можно определить текущее системное время или изменить его.
Пример:
DIMtlmS
PRINT TIME$
Tim$=TIME$
TIME$-"12:12:00""
PRINT "Предшествующее время:"; tlm$;последующее время: ";TIME$
 
 

Обмен значениями.

Оператор SWAP позволяет выполнить обмен значениями между двумя переменными одного типа.
Пример:
'Программа для демонстрации SWAP
DIMa%,b%,aS,bS
а%=1
b%=4
a$= "А"
b$="B"
SWAPa%,b%
SWAP aS, bS
PRINT "a%-"; a%, "b%-"; b%, "aS-"; aS, "bS"; bS
 
 

Опрос клавиатуры.

С помощью функции INKEY$ во время выполнения программы можно узнать, какая клавиша была только что нажата. Эта функция возвращает строковое значение, которое может быть пустой строкой (") либо состоять из одного или двух символов. Если значение функции — пустая строка, то это означает, что никакие клавиши не нажимались; если возвращается один символ, то это символ, только что набранный на клавиатуре.
Пример 1:
'INKEY$ для программных прерываний
CLS
PRINT "Для продолжения нажать любую клавишу"
DO WHILE INKEY$-""
LOOP
PRINT "Спасибо!"
'Конец программы
 
 

Пример 2:
Функция INKEY$ интересна тем, что она может опрашивать специальные и функциональные клавиши. Коды клавиатуры можно узнать либо в справочной системе QBASIC, либо использовать следующую программу:
'Коды клавиш 
DIM taste$
 DO
CLS
PRINT "Нажать любую клавишу"
DO
TASTE$=INKEY$
LOOPWHILEtaste$=""
PRINT "Код клавиши: "; taste$
PRINT "Длина кода клавиши: "; LEN(taste$)
PRINT
PRINT "Опросить еще одну клавишу? (Y)"
DO
Taste$-INKEY$
LOOP WHILEtaste$-"" LOOP UNTIL UCASTS(taste$)< > "Y"
 
 

Из этого примера видно, что специальные клавиши отличаются тем, что их коды состоят из двух символов.

Установка цветов экрана.

Используя оператор COLOR, можно изменять цвет изображения и фон. Оператор COLOR имеет следующий формат:


COLOR [Цвет_фона] [,Цвет_символов]
Цвет_фона- Величина типа INTEGER, обозначающая цвет фона экрана
Цвет_символов- Величина типа INTEGER, обозначающая цвет изображения символов.
Возможны следующие цвета:
Номер Цвет Номер Цвет
0 Черный 8 Темно-серый
1 Синий 9 Светло-синий
2 Зеленый 10 Светло-зеленый
3 Голубой 11 Светло-голубой
4 Красный 12 Светло-красный
5 Фиолетовый 13 Светло-фиолетовый
6 Коричневый 14 Желтый
7 Светло-серый 15 Белый

Стандартное значение установки цвета — COLOR 7,0. Если к коду цвета фона прибавить число 16, то получим мерцающее изображение.
Пример:
'Программа для демонстрации различных цветов изображения
DIM vordergrund%, hlntergrund%
CLS
FOR vordergrund%=O to 31 'цвет символа
FOR hlntergrund%=O to 15 'фон
COLOR vordergrund%, hlntergrund%
PRINT USING "Farbe #*"; vordergrund%;
PRINT ",";
PRINT USING "•»»";hintergrund%
NEXT hlntergrund% NEXT vordergrund% 'Возвращение к стандарту:
COLOR 7,0 
'Конец программы
 
 

Работа с файлами.

Введение и основные функции.

Большинство программ работает с данными, которые можно вводить с клавиатуры и выводить на экран, или с данными, хранящимися в каких-либо файлах на дискетах или жестких дисках. 
Рассмотрим некоторые основные понятия. Прежде всего следует выяснить, что собственно понимают под словом "файл". Это понятие можно определить так: файл — это область на носителе информации, где хранятся некоторые данные. Правда это определение слишком обобщенное, так как, следуя такому определению, файлами можно назвать и такие вещи как: 

 
  • Телефонный справочник (носитель - бумага)
  • Ящик картотеки (носитель - бумага)
  • Сведения об адресах на жестком диске (носитель - жесткий диск).
Нас будут интересовать лишь такие файлы, хранящиеся на носителях, которые можно обрабатывать программами QBASIC. Вернемся к картотеке.
В картотечном ящике, как правило, находится некоторое количество карточек, в противном случае — картотека пуста. Если к картотеке применить понятие файла, то может возникнуть ситуация, когда файл окажется пустым. Однако файл существует, в нем только нет информации. Отдельные карточки картотеки называются записями. Так же, как карточки в ящике картотеки, записи в файле расположены последовательно: есть первая запись файла и последняя. На отдельной карточке картотеки или в отдельной записи может храниться всевозможная информация (например, фамилия, адрес, возраст,...). Эта информация называется полем данных. Объединение отдельных полей составляет логическое целое — запись или предложение файла. Прежде чем создавать или обрабатывать файлы в программе, следует позаботится о том, чтобы нужная информация запоминалась в предложении файла. 
В этой главе попробуем создать небольшой адресный справочник, в котором будут следующие поля данных:
Д Имя (30 позиций)
Д Фамилия (30 позиций) 
Д Улица (30 позиций)
Д Почтовый индекс (6 позиций)
Д Местность (30 позиций)
Д Телефон (16 позиций) 
Д Заглавие (30 позиций) 


Чтобы ввести данные в справочник, необходимо сначала открыть файл данных. Для этого используется оператор OPEN в следующем формате:
OPEN Имя_фаила FOR Режим_работы AS #Номер_файла 
Имя_фаила- Имя файла с расширением и маршрутом
Режим_работы - Устанавливает разрешенный режим доступа к данным, хранящимся в файле: 
APPEND: файл открывается для записи, причем новые предложения записываются в конец файла.
INPUT: файл открывается для чтения.
OUTPUT: файл открывается для записи, причем если файла не существует, то создается новый, а если существует, то ранее существовавшая там информация будет уничтожена, а новая будет записана в начало.
RANDOM: файл состоит из записей фиксированной длины и открыт как для записи, так и для чтения.
Номер_фаила: Целое число между 1 и 255. Обращение к файлу из программы происходит под этим номером.
После того как файл обработан, с помощью команды CLOSE его необходимо закрыть. В программе это выглядит так:
CLOSE #Номер_фаила
Доступ к файлу возможен между командами OPEN и CLOSE, например, командой 
WRITE можно записать предложение в файл.
WRITE Номер_файла, Переменная [, Переменная]...
Следующая программа показывает, как можно вводить данные для файла адресов. В режиме APPEND каждое записываемое предложение помещается в конец файла. Таким образом, программу можно вызывать сколь угодно часто и дописывать данные в файл. Если же режим APPEND изменить на OUTPUT, данные будут каждый раз обновляться.
'*********************************
'** Программа для ввода адресов **
'*********************************
'Объявление полей данных
DIM nachnameS, vorname$, strasseS, plz$, ort$, telefon$, stlchwort$
DIM nocheinS 'Переключатель
'Открыть файл в режиме APPEND
OPEN "adresse.asc" FOR APPEND AS #1
'Ввод данных будет продолжаться до тех пор, пока в поле nocheinS
'будет вводиться "Y" или "у"
DO
CLS
'Ввести поля данных
INPUT "Фамилия : ", nachnameS
INPUT "Имя   . ", vorname$
INPUT "Улица   : ", strasse$
INPUT "Почт.индекс: ", plz$
INPUT "Местность : ", ort$
INPUT "Телефон : ", telefon$
INPUT "Заглавие : ", stichwortS
'Записать предложение
WRITE #1,nachname$,vorname$,strasse$,plz$,ort$,telefon$,stichwort$
PRINT
'Спросить, продолжить ли ввод
INPUT "Следующий адрес? (Y/N)", nocheln$ 
LOOP WHILE UCASE$(nochein$)-"Y" 
'Закрыть файл 
CLOSE #1 
'Конец программы
 
 

Далее необходимо вывести содержимое созданного файла на экран. Это значит, что данные последовательно читаются, и отдельные поля при необходимости появляются на экране. Для распознавания конца файла используется функция EOF.

Функция EOF
Функция EOF (Номер_файла) применяется с аргументом Номер_файла и возвращает логическое значение "истина", если достигнут конец файла, и "ложь" — в противном случае. 

Отдельные записи файла считываются одним из вариантов команды INPUT. Ранее было рассмотрено считывание данных с клавиатуры и запоминание полученной информации в переменных. Для того чтобы читать данные из файла, следует применять оператор INPUT в таком виде:
INPUT #Номер_фаила, Поле_данных_1 [,Поле_данных_2]... [,Поле_данных_n]
'Работа с файлами
'Программа для последовательного чтения адресов
'Объявление полей данных
DIM nachname$, vornameS, strasse$, plz$, ort$, telefon$,stichwort$
'Открыть файл в режиме INPUT
OPEN "adresse.asc FOR INPUT AS #1
CLS
'Читать файл до тех пор, пока функция EOF не примет
'значение "ложь" (0)
DO UNTIL EOF(1) 
'0 до тех пор, пока не достигнут конец файла
'Читать запись
INPUT #1,nachname$,vornamee$,strasse$,plz$,ort$,telefon$, stichworrtS
'Вывести на экран
PRINT nachname$," "; vorname$; " "; strasse$
PRINT plz$; " "; ort$, " ", telefonS; " "; stichwort$
PRINT LOOP
'Закрыть файл CLOSE *1
 
 

Работа с адресами в справочнике.

В данном разделе работу с адресами в справочнике дополним несколькими важными функциями. Прежде всего должны быть разработаны удобные формы представления справочных данных на экране. Не следует обходить вниманием этот раздел, даже если Вас отпугнут несколько пространные примеры. Интенсивная проработка этого раздела несомненно даст Вам ценный материал для собственной практики программирования. У Вас появится возможность повторить основные операции QBASIC. Программа управления адресами должна выполнять 
Д следующие действия:
Д искать адрес изменять адрес 


В главной программе для выбора отдельных действий необходимо создать меню. Из меню программа разветвляется на отдельные процедуры, которые выполняют независимые задачи. Преимущество такой структуры программы в том, что, во-первых, можно достаточно быстро получить доступ к любому фрагменту рабочей программы, а также меню - очень удобный интерфейс любой программы. Для начала попробуем нарисовать некую рамку, в которой и будет находится наша программа. Пример программы представлен ниже.
Пример:
CLS
FOR i = 17 TO 64 
 COLOR 1
 LOCATE 10, i 
  PRINT "="    'Прорисовка 1-й горизонтальной линии
 LOCATE 23, i
  PRINT "="    'Прорисовка 2-й горизонтальной линии
NEXT i
FOR j = 11 TO 22
 LOCATE j, 17
  PRINT ""      'Прорисовка 1-й вертикальной линии
 LOCATE j, 65
  PRINT "¦"     'Прорисовка 2-й вертикальной линии
NEXT j
LOCATE 10, 17  ' Прорисовка уголков
PRINT "?" 
LOCATE 10, 65 
PRINT "?" 
LOCATE 23, 17 
PRINT "?" 
LOCATE 23, 64 
PRINT "?"
COLOR 2
LOCATE 21, 39
 PRINT "OK"
 
 

Ну что теперь мы имеем рамочку в центре экрана и внутри написано ОК. Далее... Во первых нам нужен обработчик клавиш для передвижения по меню, а во вторых требуется составить алгоритм прорисовки экрана после каждого нового перехода от одного пункта к другому. Попробуйте составить программу самостоятельно 

Обработка ошибок.

Рассмотрим следующий пример:
'Программа, при выполнении которой возможна ошибка
DIM a!
INPUT "Введите, пожалуйста, число ",а!
PRINT 5000 / а!
'Конец программы
 
 

Эта программа работает до тех пор, пока в качестве входной информации не будет введен нуль. При вводе "нуля" диагностируется ошибка (Run-time error), так как операция деления на нуль недопустима. Такая ситуация должна быть предупреждена программистом введением контроля над вводимым числом.

'Ошибка нейтрализована
DIM a!
DO
INPUT "Введите, пожалуйста, число ",а1 
UNTIL a!<>0
PRINT 5000 / а!
'Конец программы

      
Однако имеется целый ряд ситуаций, приводящих к ошибкам, которые нельзя устранить, используя контроль вводимых данных. Рассмотрим следующий пример:
'Программа с возможной ошибкой принтера
LPRINT "Druckausgabe 1" 
LPRINT "Druckausgabe 2"
LPRINT "Druckausgabe 3"
'Конец программы

      
Вызовите программу, не включив принтер. Вы получите сообщение об ошибке (Run- time error). To же самое произойдет, если Вы выключите принтер (или установите его в режим "OFFLINE") в то время, когда программа пытается передавать ему данные. Рассмотрим методы, которые позволяют программе реагировать на такие ошибки.
Оператор ON ERROR GOTO
Определяет подпрограмму обработки ошибок и имеет формат:
ON ERROR GOTO Метка
Если в процессе выполнения программы произошла ошибка, то оператор ON ERROR GOTO передаст управление на определенную метку. При этом стандартный метод обработки ошибок выполнения QBASIC блокируется. Подпрограмма обработки ошибок всегда должна завершаться оператором RESUME NEXT. Точное значение этого оператора будет объяснено ниже.
'Программа с ошибкой деления
ON ERROR GOTO FehlerHandler
PRINT "Вывод проведенных вычислений"
'строка-провокатор
PRINT 1000/0
END 'здесь основная программа кончается
'Конец программы
'начало собственной программы обработки ошибок
FehlerHandler:
PRINT "Найдена ошибка"
PRINT RESUME NEXT
 
 

При обнаружении ошибки выполнение основной программы не прекращается и программа выполняется до конца, в отличие от стандартного метода обработки ошибок. Обходится только строка, в которой была обнаружена некорректность. Более эффективно обработать ошибку можно, если знать причину ее появления. Необходимая информация об ошибке хранится в следующих переменных:
ERDEV Последний код ошибки устройства
ERDEV$ Соответствующее имя устройства 
ERR Код ошибки выполнения 
Значение этих переменных можно анализировать в собственной программе обработки ошибок:
'Программа с ошибкой деления
ON ERROR GOTO FehlerHandler
PRINT "Вывод проведенных вычислений"
'строка с возможной ошибкой
PRINT 1000/0
END 'здесь кончается основная программа
'Конец программы
'начало собственной программы обработки ошибок
FehlerHandler
PRINT
PRINT" ———————————————"
PRINT "Найдена ошибка 
PRINT "код ошибки устройства:" ; ERDEV 
PRINT "устройство     " , ERDEV$ 
PRINT "Код ошибки выполнения:" ; ERR 
PRINT "———————————————"
PRINT RESUME NEXT
 
 

В справочно-информационной системе (Help) QBASICa имеется список всех возможных ошибок выполнения (Run-time error). В приведенной ниже таблице собраны наиболее часто встречающиеся сообщения об ошибках и их коды: 
Код Ошибка
11 Деление на нуль
24 Прерывание устройств по времени (Time out)
25 Общая ошибка устройства
27 Конец бумаги
52 Недопустимое имя или номер файла
53 Файл не найден
54 Ошибочный режим файла
55 Файл уже открыт
57 Ошибка устройства ввода/вывода
58 Файл уже существует
61 Переполнение диска
64 Недопустимое имя файла
68 Устройство недоступно
70 Доступ запрещен
71 Диск не готов
72 Ошибка носителя
75 Ошибка доступа
76 Путь не найден
Прежде чем заняться дальнейшим усовершенствованием программы обработки ошибок, рассмотрим оператор RESUME. Его можно применять в следующих вариантах:
*) RESUME 
*) RESUME Метка_перехода 
*) RESUME NEXT 
RESUME NEXT продолжает программу со строки, следующей за предложением, в котором обнаружена ошибка. С помощью оператора RESUME Метка_перехода можно перейти в любую точку программы, a RESUME без дополнений вызывает повторное выполнение ошибочного фрагмента. Для оценки кода ошибки выполнения лучше всего использовать оператор SELECT...CASE .
'обработка ошибок
ON ERROR GOTO FehlerHandler
PRINT "Вывод вычислений"
PRINT 1000 / О"
LPRINT "Вывод на печать"
OPEN "GIBTESNI.CHT" FOR INPUT AS #1
END 'здесь основная программа кончается'
'начало собственной программы обработки ошибок
FehlerHandler:
PRINT"—————————————"
PRINT "Найдена ошибка          " 
SELECT CASE ERR 
CASE ERR=11 'деление на ноль
PRINT "при программировании можно усложнить
RESUME NEXT CASE ERR=27 'конец бумаги
PRINT "Вставьте бумагу"
PRINT "Нажмите любую клавишу"
DO WHILE INKKEY$=""
LOOP
RESUME CASEERR=25 AND MID$(ERDEV$,1,3)-"LPT"
'ошибка принтера
PRINT "Подготовьте принтер"
PRINT "Нажмите любую клавишу"
DO WHILE INKEY$=""
LOOP
RESUME CASE ELSE
CLS
PRINT "Код ошибки :" ; err
PRINT "Придется прервать программу"
END  SELECT
 
 

Приведенная подпрограмма реагирует на ошибку, вызванную делением на нуль, обходом ошибочной строки (RESUME NEXT). При этом выдается сообщение об ошибке. Если обнаружена ошибка принтера, выдается рекомендация по ее устранению. Если прозойдет ошибка, код которой не анализируется ветвями CASE ERR, то становится активной ветвь CASE ELSE, программа выводит код ошибки и прерывает работу. В предложенном примере это произойдет при попытке открыть несуществующий файл "GIBTESNI.CHT".

Графические возможности Basica

При программировании на BASICе вы можете задействовать графику, благодаря чему можете наглядно смодулировать некоторые процессы (напимер движение). BASIC иммет обычные процедуры, гафического режима, присущие большинству я зыков программирования. Опишем их.

Переход в графический режим экрана

Для того, чтобы начать работать с графикой, сначала надо перейти в графисеский режим. Для этого существует оператор SCREEN, его синтаксис: 


SCREEN [mode] [,[apage]] [,[vpage]]
mode-Это режим в котором находитмя экран при выводе графики. Режим устанавливает разрешение экрана, его цветовую гамму.
apage,vpage - это номера страниц экрана, где apage-это страница активная в данный момент (Вы её видите), а vpage-это скрытая страница экрана.
Колличество страниц в каждом графическом режиме различно и звиси от обёма видео памяти, поэтому следует сначала узнать кол-во страниц а потом устанавливать значения переменных.

Параметры некоторых режимов(для VGA мониторов).

Операторы, реализующие графику

Оператор PSET организовывает прорисовку точки на экране.


Cинтаксис:
PSET (x,y) [,color]
(x,y)-координаты точки
color-цвет вывода

Оператор CIRCLE организовывает прорисовку окружности на экране.
Cинтаксис:
CIRCLE (x,y),radius[,color][,[start]][,[end]][,[aspect]]
(x,y)-координаты центра
radius-радиус 
color-цвет вывода
start,end-используются для прорисовки части окружности, задаётся началои конец соответственно
aspect-используются для прорисовки элипса

Оператор LINE организовывает прорисовку линии или закрашенного/незакрашенного прямоугольника на экране.
Cинтаксис:
LINE (x1,y1)-(x2,y2),[,[color][,[B[F]]
(x1,y1)-координаты начала линии
(x2,y2)-координаты конца линии
color-цвет вывода
В-используются для прорисовки незаполненного прямоугольника
BF-используются для прорисовки заполненного прямоугольника

Оператор PAINT заполняет какую-то область экрана заданным цветом 
Cинтаксис:
PAINT (x,y),[paint][,[bordercolor]][,[backgroung]]
(x,y)-координаты точки. Если точка поладает в область какого-нибудь изображения (окружности) то изображение заполняется
bordercolor-цвет линии, ограничивающей область
backgroung-цвет фона

Оператор POINT возаращает цвет точки по координатам
Cинтаксис:
POINT (x,y)
(x,y)-координаты точки.