Оператор INPUT список_переменных принимает числовые или текстовые значения с клавиатуры и присваивает их переменным из списка. Программа, дойдя до оператора INPUT, выводит на дисплей знак вопроса и ждет ввода с клавиатуры. Для общения с клавиатурой используется небольшая область памяти (буфер клавиатуры). При нажатии клавиши соответствующий символ (точнее, его код) попадает в буфер клавиатуры, оператор INPUT
забирает его оттуда и отображает на экране. Ввод заканчивается при нажатии клавиши Enter.
Имена переменных, предназначенных для хранения текстовых значений, должны заканчиваться знаком $. Имена переменных, хранящих числовые значения , могут в зависимости от типа значения заканчиваться знаком !, # или &. При отсутствии этих знаков в имени переменной считается, что она имеет тип, соответствующий восклицательному знаку. (Подробнее о типах данных рассказано в соответствующем разделе.)
Примеры:
А) В программе |
INPUT x, y |
|
PRINT x, y |
|
|
На дисплее |
? 30, 47
ї |
|
30 47 |
В результате переменная “x” получит значение 30, а переменная “y” - значение 47.
Если повторно запустить программу и ввести только одно значение, например, 30 , то Quick Basic предложит повторить ввод - выдаст сообщение “Redo from start”. То же самое сообщение мы получим, если захотим ввести значений больше, чем переменных в списке оператора INPUT.
Б) В программе |
INPUT word$ |
|
PRINT word$ |
|
|
На дисплее |
? Антон
ї |
|
Антон |
В результате переменная word$ будет содержать слово “Антон”. Обратите внимание, что вводимое слово в кавычки не берется, хотя в операторе присваивания word$ = “Антон” они обязательны!
Запустим программу повторно и наберем на клавиатуре слово “Сергей”. К нашему удивлению, буква “р” не появляется на экране, хотя мы изо всех сил жмем ее на клавиатуре. Увы! Стандартными средствами языка ввести с клавиатуры строчную русскую “р” невозможно. (Мы вернемся к этой проблеме в разделе “Дополнительные возможности”.)
Можно ли ввести число в переменную word$? Давайте в ответ на приглашение введем число 12. Программа “ответит” тем же значением, т.е. переменная word$ содержит сейчас текстовое (но не числовое!) значение “12”. Операции над текстовыми значениями (строками символов) выполняются совсем по другому, чем над числовыми. Выполним, например, программу:
n = 12 + 3
n$ = “12” + “3”
PRINT n, n$
|
На дисплей будут выведены два значения: 15 и 123. Но если первое значение - число, полученное в результате арифметической операции сложения, то второе - текстовая константа “123”, которая получена в результата особой операции “склеивания” двух строк.
Из строки символов можно выделить любую ее часть с помощью функции MID$:
часть = MID$(строка, начальная_позиция, количество_символов)
Оператор INPUT$(число) вводит заданное число символов без их отображения на экране. Нажимать Enter после ввода не требуется.
Этот оператор удобно использовать при вводе пароля. Пример:
‘Запрос пароля
password$ = INPUT$(4)
IF password$ <> “aq” + CHR$(8) + CHR$(27) THEN STOP
‘Основная программа
...
|
Чтобы запустить основную программу, нужно нажать две буквенных клавиши - “a” и ”q”. затем клавиши Backspace и Esc, коды которых (8 и 27) преобразуются функцией CHR$ в символы.
С помощью операторов INPUT и INPUT$ нельзя обработать нажатие ряда клавиш: функциональных, клавиш управления курсором, Home, End, PageUp, PageDn и некоторых других. Для этого используется функция INKEY$. Эта функция берет символы из буфера клавиатуры (если он не пуст!), но не ждет нажатия клавиши. Если буфер пуст, INKEY$ возвращает значение “пустая строка” - две кавычки, между которыми ничего нет.
При нажатии клавиши в буфер клавиатуры помещается одно или два числа - код клавиши. Если код клавиши состоит из двух чисел, то первое число обязательно равно 0. Коды некоторых клавиш приведены в таблице.
Клавиша |
BS |
Enter |
Esc |
пробел |
+ |
2 |
G |
g |
я |
Код |
8 |
13 |
27 |
32 |
43 |
50 |
71 |
103 |
239 |
Клавиша |
F1 |
F2 |
Home |
й |
PageUp |
з |
и |
к |
Ins |
Код |
0; 59 |
0; 60 |
0; 71 |
0; 72 |
0; 73 |
0; 75 |
0; 77 |
0; 80 |
0; 82 |
Функция INKEY$ возвращает символ, соответствующий коду в буфере клавиатуры. Если она обнаруживает 0 в буфере клавиатуры, то возвращается “склейка” двух символов - CHR$(0) и следующего за ним.
Клавиши Alt, Shift и Ctrl являются клавишами-модификаторами: они изменяют код нажатой одновременно с ними клавиши, но сами не имеют кода. Например, клавиша F2, нажатая с клавишей Shift, генерирует код 0; 85, с клавишей Ctrl - 0; 95, с клавишей Alt - 0; 105.
Задача . Написать программу, которая выводит на экран код нажатой клавиши. Выход из программы - по клавише Esc.
Решение. Для ввода символа воспользуемся уже известной нам функцией INKEY$. а для перевода символа в код - функцией ASC:
код = ASC(символ).
Запишем алгоритм работы программы:
- Ждем нажатия клавиши.
- Выделяем первый символ полученной (из буфера клавиатуры) строки и выводим его код на печать.
- Если первый символ строки равен CHR$(27), то заканчиваем работу.
- Если первый символ строки равен CHR$(0), то выделяем и печатаем код второго символа.
- Переходим к пункту 1.
‘------------------Программа ------------------
‘Ждем нажатия клавиши
10 s$ = INKEY$: IF s$ = "" THEN GOTO 10
‘Выделяем и печатаем первый символ
first$ = MID$(s$, 1, 1)
PRINT ASC(first$)
‘Анализируем первый символ
IF first$ = CHR$(27) THEN STOP
‘Выделяем и печатаем второй символ
IF first$ = CHR$(0) THEN
next$ = MID$(s$, 2, 1)
PRINT ASC(next$)
END IF
GOTO 10
|
10. Анализ нажатой клавиши
Во многих программах взаимодействие пользователя с программой происходит с помощью клавиш-стрелок влево, вправо, вверх, вниз. Запишем строки, возвращаемые функцией INKEY$ при нажатии этих клавиш, в переменные LF$ (от английского left - влево), RT$ (от английского right - вправо), UP$ (от английского up - вверх), DN$ (от английского down - вниз).
LF$ = CHR$(0) + CHR$(75)
RT$ = CHR$(0) + CHR$(77)
UP$ = CHR$(0) + CHR$(72)
DN$ = CHR$(0) + CHR$(80)
|
Пусть в переменной s$ находится значение, полученное от функции INKEY$. Проанализируем ее содержимое с помощью нескольких IF:
IF s$ = LF$ THEN
‘Операторы, выполняемые по нажатию стрелки влево
...
ELSE IF s$ = RT$ THEN
‘Операторы, выполняемые по нажатию стрелки вправо
...
ELSE IF s$ = UP$ THEN
‘Операторы, выполняемые по нажатию стрелки вверх
...
ELSE IF s$ = DN$ THEN
‘Операторы, выполняемые по нажатию стрелки вниз
...
ELSE
‘Была нажата какая-то другая клавиша
...
END IF
|
Более компактно эти же проверки можно сделать с помощью оператора SELECT CASE (выбрать вариант):
SELECT CASE выражение |
- “заголовок” оператора выбора |
CASE значение_1 : действие_1 |
- выполняется, если выражение = значение_1 |
CASE значение_2 : действие_2 |
- выполняется, если выражение = значение_2 |
CASE ELSE : иное_действие |
- выполняется, если значение выражения не совпадает ни с одним из перечисленных значений
|
END SELECT |
- конец оператора выбора |
Задача . При нажатии любой из клавиш-стрелок, напечатать сообщение, какая стрелка нажата, при нажатии на Esc выйти из программы.
Решение. Напишем сначала алгоритм:
- Задаем константы.
Кроме констант LF$, RT$, UP$ и DN$ зададим еще Esc$ = CHR$(27).
- Ждем нажатия клавиши.
- Анализируем полученную символьную строку и выполняем заданное действие (печать сообщения или останов).
- Чтобы не запускать программу каждый раз заново, переходим к пункту 2.
‘---------Программа-----------
‘Задаем константы
LF$ = CHR$(0) + CHR$(75)
RT$ = CHR$(0) + CHR$(77)
UP$ = CHR$(0) + CHR$(72)
DN$ = CHR$(0) + CHR$(80)
Esc$ = CHR$(27)
‘Ждем нажатия клавиши
10 s$ = INKEY$: IF s$ = “” THEN GOTO 10
‘Анализируем строку s$
SELECT CASE s$
CASE LF$: PRINT “Нажата стрелка влево”
CASE RT$: PRINT “Нажата стрелка вправо”
CASE UP$: PRINT “Нажата стрелка вверх”
CASE DN$: PRINT “Нажата стрелка вниз”
CASE Esc$: STOP
CASE ELSE: GOTO 10
END SELECT
GOTO 10
|
Последний оператор GOTO 10 “зацикливает” программу, оставляя ей единственный выход - по клавише Esc. При такой организации программы у нас есть возможность проверить реакцию на каждую из клавиш-стрелок, не запуская каждый раз программу заново. Оператор GOTO 10 в CASE ELSE выполняет другую важную функцию: не позволяет программе выйти из оператора SELECT до тех пор, пока не будет нажата одна из нужных клавиш. Нажатия на другие клавиши (кроме аварийного останова по Ctrl+Break) будут игнорироваться.
Задание . Записать программу под именем ARROW.BAS. Добавить в оператор выбора анализ двух-трех других клавиш (“+”, “-”, “1”, “2”, “F1” и т.д.).
Указание. Для клавиш с обычными символами нет необходимости знать их код. Нужно просто указать этот символ в кавычках после CASE.
11. Управление окружностью
Нарисуем на экране некоторую фигуру, например, окружность. Как заставить ее двигаться при нажатии на клавишу-стрелку? Предположим, что мы нажали на стрелку влево. Сотрем на старом месте окружность и нарисуем такую же, но смещенную на несколько пикселей влево. Если была нажата стрелка вправо, то смещенную окружность будем рисовать на несколько пикселей вправо и т.д.
Для хранения параметров “старой” и “новой” окружности введем переменные:
x0, y0 - координаты центра “старой” окружности; r0 - ее радиус.
x, y - координаты центра “новой” окружности; r - ее радиус.
Приведем алгоритм решения.
- Задаем начальные значения переменных.
- Рисуем окружность
.
Ждем нажатия клавиши.
Вычисляем координаты центра “новой” окружности.
Стираем “старую” и рисуем “новую” окружность.
(Чтобы стереть окружность, нужно нарисовать ее цветом фона!)
Заменяем параметры “старой” окружности новыми значениями и переходим к пункту 3.
В пункте 6 алгоритма происходит обновление переменных x0, y0, r0. Им присваиваются значения x, y, r, и с этого момента окружность становится “старой”. При следующем проходе программа будет оперировать с новыми значениями параметров “старой” окружности.
(Возможен вариант:
5’. Стираем “старую” окружность.
6’. Заменяем координаты центра “старой” окружности новыми значениями и переходим к пункту 2.)
Программу “Управление окружностью” напишем на основе ARROW.BAS.
‘-------- Программа “Управление окружностью” --------
‘Задаем константы
LF$ = CHR$(0) + CHR$(75)
RT$ = CHR$(0) + CHR$(77)
UP$ = CHR$(0) + CHR$(72)
DN$ = CHR$(0) + CHR$(80)
Esc$ = CHR$(27)
‘Задаем начальные значения переменных
SCREEN 7
x0 = 160: y0 = 100: r0 = 10
‘Рисуем окружность
CIRCLE (x0, y0), r0
‘Ждем нажатия клавиши
10 s$ = INKEY$: IF s$ = “” THEN GOTO 10
‘Анализируем строку s$ и вычисляем параметры “новой” окружности
SELECT CASE s$
CASE LF$: x = x0 - 5: y = y0: r = r0
CASE RT$: x = x0 + 5: y = y0: r = r0
CASE UP$: x = x0: y = y0 - 5: r = r0
CASE DN$: x = x0: y = y0 + 5: r = r0
CASE Esc$: STOP
CASE ELSE: GOTO 10
END SELECT
‘Стираем “старую” и рисуем “новую” окружность
CIRCLE (x0, y0), r0, 0
CIRCLE (x, y), r
‘Заменяем параметры “старой” окружности новыми значениями
x0 = x: y0 = y: r0 = r
GOTO 10
|
Запишем программу под именем CIRCLES.BAS, убедимся, что она работает, и попробуем ее улучшить. Во-первых, нерационально повторять в каждом CASE одинаковые присваивания x = x0, y = y0, r = r0. Удобнее сделать все три присваивания перед оператором выбора, а в каждом варианте вычислять только тот параметр, который действительно изменялся. Во-вторых, мы заложили в программу возможность изменения радиуса окружности, но не воспользовались этим. Назначим клавишу “>” для увеличения, а клавишу “<” - для уменьшения радиуса. Наконец, если “стирать” окружность не цветом фона, а любым другим, на экране будет оставаться след - узор из окружностей.
Задание . Реализуйте все улучшения программы. Придумайте, как изменять цвет оставляемого окружностью следа и шаг перемещения окружности.
12. Операторы GET и PUT
Оператор GET позволяет запомнить часть графического экрана в некотором массиве, а оператор PUT - вывести запомненное изображение на экран. Синтаксис оператора GET:
GET (x1, y1)-(x2, y2), массив - запомнить прямоугольную область.
Точки (x1, y1) и (x2, y2) - две вершины прямоугольника, лежащие на одной из его диагоналей. Размеры прямоугольника и его содержимое запоминаются в массиве.
Синтаксис оператора PUT:
PUT (x, y), массив [, способ_вывода] - вывести на экран картинку из массива заданным способом.

Поскольку в массиве хранятся и размеры картинки, в операторе PUT указывается только одна точка - верхний левый угол прямоугольной области для вывода картинки.
12.1. Понятие массива
Проиллюстрируем наглядно понятия простой переменной и массива. Простую переменную можно представить в виде ящичка, на котором написано имя переменной (в нашем случае - A). В ящичек можно положить любое число - значение переменной (в нашем случае - 5).
Массив можно представить как ящик с перегородками. В каждый из получившихся “отсеков” можно положить свое число. Отсеки пронумерованы, поэтому имя каждого отсека состоит из двух частей: общего имени ящика и номера отсека. Но такие обозначения как A 0, A1, A2 используются в математике, в языках программирования элемент массива обозначается A(0), A(1), A(2) и т.д.
Каждый массив должен быть описан в операторе DIM (от английского dimentions - размеры):
DIM имя_массива(номер_последнего_элемента)
Поскольку нумерация элементов массива в Quick Basic начинается с нуля, то количество элементов массива (длина массива) оказывается на единицу больше номера последнего элемента. Например, DIM A(7) описывает массив из восьми элементов. Иногда, для удобства работы, мы будем “забывать” о нулевом элементе и указывать в описании массива его длину.
Элементы массива должны иметь значения одного и того же типа. Для указания типа элементов к имени массива добавляется знак $, если элементы массива суть строки символов, или знак %, если все элементы массива - целые числа. (Подробнее о типах данных поговорим в соответствующем разделе.)
Указатели типа являются частью имени как обычной переменной так и массива, поэтому A% и A$ - это имена разных переменных!
В операторах GET и PUT будем использовать только массивы целых чисел. Размер массива должен быть достаточно большим, чтобы в него поместилась необходимая информация (сохранилась нужная картинка с экрана). В литературе [1] приводятся точные формулы, но можно пользоваться более простой приближенной формулой
размер_массива = 0.3*dx*dy,
где dx = x2 - x1 + 1, dy = y2 - y1 +1 - размеры (в пикселях) прямоугольной области, полностью закрывающую интересующую нас картинку, по горизонтали и вертикали. Если размер массива, вычисленный по приближенной формуле, окажется недостаточным, Quick Basic выдаст предупреждение “Illegal function call” (“Неверный вызов функции”) и остановит выполнение программы на строке с оператором GET. В этом случае следует несколько увеличить размер массива и запустить программу еще раз.
‘---------------- Программа ------------------
‘----“Копирование прямоугольника” ---
SCREEN 7
DIM a%( ) ‘Размер массива укажем позже
LINE (20, 20)-(79, 69), 5, BF
GET (20, 20)-(79, 69), a%
SLEEP 1
PUT (120, 20), a%
|
Программа выводит на экран закрашенный прямоугольник, для которого dx=60, dy=50. Вычисляя по приближенной формуле размер массива, получим значение 900 (точная формула дает значение 802). Укажем теперь размер массива и запустим программу. На экране появится фиолетовый прямоугольник, а ровно через одну секунду ( SLEEP n дает задержку в n секунд) рядом появится его дубликат.
Задание. Запишите программу под именем GETPUT.BAS. Измените положение второго прямоугольника на экране. Что получится, если прямоугольники будут пересекаться?
12.2. Способы вывода оператором PUT
Если в программе “Копирование прямоугольника” в последней строке поставить PUT (30, 30), a% , то на экране появится такая вот картинка.
Мы видим, что в результате наложения двух прямоугольников одного цвета образовалось черное пятно. Это произошло потому, что при выводе картинки оператором PUT над цветом точки экрана и цветом точки картинки, попадающей на это место, производится логическая операция “исключающее или” (краткое обозначение - XOR). Особенность ее состоит в том, что для любого числа n выполняется равенство: n XOR n = 0. Следовательно, наложение точек одинакового цвета даст цвет 0, т.е. цвет фона.
Способ вывода XOR принят в операторе PUT по умолчанию, т.е. если не указан другой способ вывода.Способы вывода определяются последним параметром.
PSET - вывод картинки без изменения ее цвета. В этом случае никакие операции над цветами картинки и экрана не производятся.
PRESET - замена цветов картинки на дополнительные. Дополнительный цвет вычисляется по формуле: цвет = 15 - исходный_цвет.
OR - цвет картинки определяется результатом логической операции “или”.
AND - цвет картинки определяется результатом логической операции “и”.
Задание . Замените в программе “Копирование прямоугольника” последнюю строку циклом
FOR x = 30 TO 130 STEP 10
PUT (x, x), a%
NEXT x
|
Нарисуйте границу исходного прямоугольника другим цветом. Измените способ вывода в операторе PUT.
“Связку” операторов GET и PUT можно использовать для создания периодического узора. Для этого рисуем небольшой прямоугольный фрагмент узора, а затем заполняем фрагментами экран.
‘----------- Программа “Узор” -----------
SCREEN 7
DIM a%(130)
‘Рисуем и запоминаем фрагмент узора
FOR r = 0 TO 10 STEP 2
LINE (10 - r, 10 - r)- (10 + r, 10 + r), r, B
NEXT r
GET (0, 0)-(20, 20), a%
‘Размножаем фрагмент
CLS
FOR x = 50 TO 250 STEP 20
FOR y = 40 TO 140 STEP 20
PUT (x, y), a%, PSET
NEXT y
NEXT x
|
|