Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия Последняя версия Следующая версия справа и слева | ||
msx:basic_for_beginners:basic_for_beginners [2019-06-22 13:58] GreyWolf [Урок 3] |
msx:basic_for_beginners:basic_for_beginners [2020-11-25 09:54] GreyWolf |
||
---|---|---|---|
Строка 9: | Строка 9: | ||
Наверное, не стоит читать эту книжку тем, кто что–то уже умеет делать на Бейсике. Эта книжка для начинающих, и к тому же, учеников не очень старших классов. Её главное достоинство — простота ( автор надеется, что это не самообман ). | Наверное, не стоит читать эту книжку тем, кто что–то уже умеет делать на Бейсике. Эта книжка для начинающих, и к тому же, учеников не очень старших классов. Её главное достоинство — простота ( автор надеется, что это не самообман ). | ||
- | Чтобы привыкнуть к Бейсику, знать его как свой собственный язык, недостаточно только читать эту книжку. Нужно каждый приведённый в ней пример в рамочке тотчас же опробовать на компьютере [[msx:msx]]. Обязательно выполняйте упражнения, стоящие после знака █ ! Если не выполнять чего-то своего после ознакомления с чужой программой, то и не станешь самостоятельным программистом! | + | Чтобы привыкнуть к Бейсику, знать его как свой собственный язык, недостаточно только читать эту книжку. Нужно каждый приведённый в ней пример в рамочке тотчас же опробовать на компьютере [[msx:msx]]. Обязательно выполняйте упражнения (выделены серым фоном) ! Если не выполнять чего-то своего после ознакомления с чужой программой, то и не станешь самостоятельным программистом! |
====== Урок 1 ====== | ====== Урок 1 ====== | ||
Строка 45: | Строка 45: | ||
- [ + ], [ - ] — сложение и вычитание. | - [ + ], [ - ] — сложение и вычитание. | ||
- | <WRAP box 60%> | + | <WRAP box> |
Напечатайте результат таких действий: | Напечатайте результат таких действий: | ||
<code> | <code> | ||
Строка 162: | Строка 162: | ||
Выполните упражнения: | Выполните упражнения: | ||
- | <WRAP box 60%> | + | <WRAP box> |
Программа спрашивает радиус окружности у пользователя, а затем печатает длину окружности и площадь круга. | Программа спрашивает радиус окружности у пользователя, а затем печатает длину окружности и площадь круга. | ||
</WRAP> | </WRAP> | ||
Строка 170: | Строка 170: | ||
Бейсик понимает ''SIN'', ''COS'', ''TAN'' (так в Бейсике записывается тангенс), но нужно не забывать, что это — функции, а значит аргументы должны помещаться в скобках. Например, ''SIN(5)''… | Бейсик понимает ''SIN'', ''COS'', ''TAN'' (так в Бейсике записывается тангенс), но нужно не забывать, что это — функции, а значит аргументы должны помещаться в скобках. Например, ''SIN(5)''… | ||
- | <WRAP box 60%> | + | <WRAP box> |
Программа спрашивает длину одной стороны равностороннего треугольника и печатает его периметр и площадь. | Программа спрашивает длину одной стороны равностороннего треугольника и печатает его периметр и площадь. | ||
</WRAP> | </WRAP> | ||
Строка 360: | Строка 360: | ||
====== Урок 4 ====== | ====== Урок 4 ====== | ||
+ | Все примеры, которые мы делали до сих пор, представляли собой линейные программы, то–есть, программы, в которых все команды выполняются подряд, одна за другой. Но часто встречается необходимость изменить порядок следования программы. | ||
+ | |||
+ | Например, нам нужно, чтобы после 40 строки программа перешла сразу в 60–ю, не выполняя 50–й строки. Для этого используется команда перехода ''GOTO''. Например, в программе: | ||
<code> | <code> | ||
- | Все примеры, которые мы делали до сих пор, представляли собой | + | 10 print "Посмотрите: я считаю" |
- | линейные программы, то-есть, программы, в которых все команды | + | 20 goto 40 |
- | выполняются подряд, одна за другой. Но часто встречается | + | 30 print"Лучше вашего калькулятора" |
- | необходимость изменить порядок следования программы. | + | 40 print "2+2=";2+2 |
- | Например, нам нужно, чтобы после 40 строки программа перешла | + | </code> |
- | сразу в 60-ю, не выполняя 50-й строки. Для этого используется | + | строка 30 не выполнится: программа обошла её с помощью ''GOTO''. |
- | команда перехода GOTO. Например, в программе: | + | |
- | ┌────────────────────────────────────┐ | + | |
- | │ 10 print "Посмотрите: я считаю" │ | + | |
- | │ 20 goto 40 │ | + | |
- | │ 30 print"Лучше вашего калькулятора"│ | + | |
- | │ 40 print "2+2=";2+2 │ | + | |
- | └────────────────────────────────────┘ | + | |
- | строка 30 не выполнится: программа обошла ее с помощью GOTO. | + | |
- | GOTO может переводить не только вперед по тексту программы, | + | ''GOTO'' может переводить не только вперёд по тексту программы, но и назад, к уже выполнявшимся строкам: |
- | но и назад, к уже выполнявшимся строкам: | + | <code> |
- | ┌────────────────────────────────────┐ | + | 10 print "Посмотрите: я считаю" |
- | │ 10 print "Посмотрите: я считаю" │ | + | 20 goto 10 |
- | │ 20 goto 10 │ | + | 30 print "2+2=";2+2 |
- | │ 30 print "2+2=";2+2 │ | + | </code> |
- | └────────────────────────────────────┘ | + | В этом случае до строки 30 программа никогда не доберётся: дойдя до 20 строки, она возвращается в 10, затем снова в 20 и 10… Такой участок программы, который повторяется с помощью ''GOTO'', называется бесконечным циклом. Его прервать можно аварийным способом: нажатием одновременно клавиш <key>CTRL</key> и <key>STOP</key>. |
- | В этом случае до строки 30 программа никогда не доберется: | + | |
- | дойдя до 20 строки, она возвращается в 10, затем снова в 20 и | + | |
- | 10 ... Такой участок программы, который повторяется с помощью | + | |
- | GOTO, называется бесконечным циклом. Его прервать можно | + | |
- | аварийным способом: нажатием одновременно клавиш <CTRL> и | + | |
- | <STOP>. | + | |
- | Еще пример бесконечного цикла: | + | |
- | ┌─────────────────────────────────────────────┐ | + | |
- | │ 10 print "У попа была собака. Он ее любил." │ | + | |
- | │ 20 print "Она съела кусок мяса. Он ее убил."│ | + | |
- | │ 30 print "В яму закопал. На камне написал:" │ | + | |
- | │ 40 goto 10 │ | + | |
- | └─────────────────────────────────────────────┘ | + | |
- | При всей на первый взгляд бессмысленности бесконечные циклы | + | Ещё пример бесконечного цикла: |
- | используются очень часто. Они имеют смысл в тех случаях, | + | <code> |
- | когда при повторении действия выполняются не одинаковые. | + | 10 print "У попа была собака. Он ее любил." |
- | Например, когда действия зависят от реакции человека. Так | + | 20 print "Она съела кусок мяса. Он ее убил." |
- | большинство игр представляют собой бесконечный цикл: | + | 30 print "В яму закопал. На камне написал:" |
- | окончившись, начинаются снова. Попробуйте такой пример: | + | 40 goto 10 |
- | ┌────────────────────────────────────────┐ | + | </code> |
- | │ 10 print "купи слона!" │ | + | |
- | │ 20 input otw$ │ | + | При всей на первый взгляд бессмысленности бесконечные циклы используются очень часто. Они имеют смысл в тех случаях, когда при повторении действия выполняются не одинаковые. |
- | │ 30 print "Все говорят ";otw$;", а ты " │ | + | |
- | │ 40 goto 10 │ | + | Например, когда действия зависят от реакции человека. Так большинство игр представляют собой бесконечный цикл: окончившись, начинаются снова. Попробуйте такой пример: |
- | └────────────────────────────────────────┘ | + | <code> |
+ | 10 print "купи слона!" | ||
+ | 20 input otw$ | ||
+ | 30 print "Все говорят ";otw$;", а ты " | ||
+ | 40 goto 10 | ||
+ | </code> | ||
Более сложный пример бесконечного цикла: | Более сложный пример бесконечного цикла: | ||
- | ┌───────────────────────────────────────────────┐ | + | <code> |
- | │ 10 print "Предлагаю научиться считать время." │ | + | 10 print "Предлагаю научиться считать время." |
- | │ 20 print "Я буду считать 50 раз в секунду," │ | + | 20 print "Я буду считать 50 раз в секунду," |
- | │ 30 print "А ты нажмешь клавишу <ВВОД>, когда" │ | + | 30 print "А ты нажмешь клавишу <ВВОД>, когда" |
- | │ 40 print "по-твоему я насчитаю 6000. Понял?" │ | + | 40 print "по-твоему я насчитаю 6000. Понял?" |
- | │ 50 input otw$ │ | + | 50 input otw$60% |
- | │ 60 print "Начинаю считать до 6000. Если го-" │ | + | 60 print "Начинаю считать до 6000. Если го-" |
- | │ 70 print "тов, жми <ВВОД>." │ | + | 70 print "тов, жми <ВВОД>." |
- | │ 80 input otw$ │ | + | 80 input otw$ |
- | │ 90 time=0 │ | + | 90 time=0 |
- | │ 100 input"Для остановки жми <Ввод>";otw$ │ | + | 100 input"Для остановки жми <Ввод>";otw$ |
- | │ 110 print "Насчитал";time │ | + | 110 print "Насчитал";time |
- | │ 120 input "Для продолжения нажми <ВВОД>";otw$ │ | + | 120 input "Для продолжения нажми <ВВОД>";otw$ |
- | │ 130 goto 60 │ | + | 130 goto 60 |
- | └───────────────────────────────────────────────┘ | + | </code> |
- | В этом примере есть кое-что новое. Во-первых, мы | + | В этом примере есть кое–что новое. Вомпервых, мы воспользовались тем, что Бейсик имеет специальную переменную ''TIME'', в которую он (независимо от наших действий) 50 раз в секунду добавляет единицу. Поэтому после нажатия <key>⏎</key> мы печатаем в строке 110 новое значение ''TIME'', накопленное за время ожидания команды INPUT из 100 строки. При повторении мы снова обнуляем в строке 90 переменную ''TIME'' и накопление начинается сначала. |
- | воспользовались тем, что Бейсик имеет специальную переменную | + | Ещё заметим, что в строках 50, 80 и 100 мы в команде ''INPUT'' ожидаем ответа, но никак этот ответ не используем. ''INPUT'' в этом примере служат только для задержки до нажатия клавиши <key>⏎</key>. |
- | TIME, в которую он (независимо от наших действий) 50 раз в | + | |
- | секунду добавляет единицу. Поэтому после нажатия <ВВОД> мы | + | |
- | печатаем в строке 110 новое значение TIME, накопленное за | + | |
- | время ожидания команды INPUT из 100 строки. При повторении мы | + | |
- | снова обнуляем в строке 90 переменную TIME и накопление | + | |
- | начинается сначала. | + | |
- | Еще заметим, что в строках 50, 80 и 100 мы INPUT'ом ожидаем | + | |
- | ответа, но никак этот ответ не используем. INPUT'ы в этом | + | |
- | примере служат только для задержки до нажатия клавиши <ВВОД>. | + | |
- | Конечно, хорошо бы, если бы ответы человека можно было | + | Конечно, хорошо бы, если бы ответы человека можно было использовать. Например, в 120 строке спросить:"Продолжим или нет?", и если пользователь ответит "да", то ''GOTO 60'', а в противном случае закончим программу. Измените в своей программе такие строки: |
- | использовать. Например, в 120 строке спросить:"Продолжим или | + | <code> |
- | нет?", и если пользователь ответит "да", то GOTO 60, а в | + | 120 INPUT "Продолжим (да/нет)";OTW$ |
- | противном случае закончим программу. Измените в своей | + | 130 IF OTW$="да" THEN GOTO 60 ELSE PRINT "Конец!" |
- | программе такие строки: | + | </code> |
- | ┌──────────────────────────────────────────────────┐ | + | Новая команда (проверки условия) состоит из 3–х служебных слов: ''IF'' (если), ''THEN'' (то), ''ELSE'' (иначе). |
- | │ 120 INPUT "Продолжим (да/нет)";OTW$ │ | + | |
- | │ 130 IF OTW$="да" THEN GOTO 60 ELSE PRINT "Конец!"│ | + | |
- | └──────────────────────────────────────────────────┘ | + | |
- | Новая команда (проверки условия) состоит из 3-х служебных | + | |
- | слов: IF (если), THEN (то), ELSE (иначе). | + | |
- | После IF стоит проверяемое условие. Примеры возможных условий: | + | После ''IF'' стоит проверяемое условие. Примеры возможных условий: |
- | IF 2.5=X+Y | + | * ''IF 2.5=X+Y'' |
- | IF X>5+2*Y | + | * ''IF X>5+2*Y'' |
- | IF A+B<=14 ( [ <= ] значит меньше или равно ) | + | * ''IF A+B<=14'' ( [ <= ] значит меньше или равно ) |
- | IF A$="привет" | + | * ''IF A$=%%"привет"%%'' |
- | IF B$<>A$ ( [ <> ] значит не равно ) | + | * ''IF B$<>A$'' ( [ <> ] значит не равно ) |
- | После THEN стоят одно или несколько (через [:]) действий, | + | После ''THEN'' стоят одно или несколько (через [:]) действий, которые будут выполнены, если условие после ''IF'' истинно. Все они должны разместиться в одной строке программы. Если таких действий много, и в этой строке они не помещаются, то можно поставить ''GOTO'' и переслать на строку с нужными действиями. |
- | которые будут выполнены, если условие после IF истинно. Все | + | ( Кстати, вместо ''THEN GOTO 60'' можно написать просто ''THEN 60'' ) |
- | они должны разместиться в одной строке программы. Если таких | + | |
- | действий много, и в этой строке они не помещаются, то можно | + | |
- | поставить GOTO и переслать на строку с нужными действиями. | + | |
- | ( Кстати, вместо THEN GOTO 60 можно написать просто THEN 60 ) | + | |
- | После ELSE находятся те команды, которые должны быть выполне- | + | После ''ELSE'' находятся те команды, которые должны быть выполнены в том случае, когда условие после ''IF'' не истинно. Если все команды в строку не входят, можно тоже употребить ''ELSE GOTO 100'' или просто ''ELSE 100''. |
- | ны в том случае, когда условие после IF не истинно. Если все | + | |
- | команды в строку не входят, можно тоже употребить ELSE GOTO | + | |
- | 100 или просто ELSE 100. | + | |
- | ЗАПОМНИТЕ: слева или справа от слов THEN и ELSE не ставят | + | ЗАПОМНИТЕ: слева или справа от слов ''THEN'' и ''ELSE'' не ставят двоеточия — это не отдельные команды, а части команды ''IF''. |
- | двоеточия - это не отдельные команды, а части команды IF. | + | |
Примеры программ с проверкой условия: | Примеры программ с проверкой условия: | ||
- | ┌────────────────────────────────────────────┐ | + | <code> |
- | │ 10 input "Введите Ваш любимый цвет";c │ | + | 10 input "Введите Ваш любимый цвет";c |
- | │ 20 if c<0 or c>15 then 10 else color 15,c │ | + | 20 if c<0 or c>15 then 10 else color 15,c |
- | └────────────────────────────────────────────┘ | + | </code> |
- | Мы проверили здесь, чтобы введенный номер цвета был в | + | Мы проверили здесь, чтобы введённый номер цвета был в допустимых пределах. |
- | допустимых пределах. | + | <code> |
- | ┌─────────────────────────────────────────────────────────┐ | + | 10 print "Я работаю только со своим программистом!" |
- | │ 10 print "Я работаю только со своим программистом!" │ | + | 20 input "Введите Ваше имя";n$ |
- | │ 20 input "Введите Ваше имя";n$ │ | + | 30 if n$="Виктор" then print "Привет, хозяин!" else print "Вы не мой хозяин":goto 10 |
- | │ 30 if n$="Виктор" then print "Привет, хозяин!" else pri │ | + | </code> |
- | │ nt "Вы не мой хозяин":goto 10 │ | + | Эта программа сработает лишь при точном совпадении ответа с ожидаемым текстом. Программу можно усовершенствовать, если предусмотреть несколько имён. Для этого в строке 30 нужно поменять условие: |
- | └─────────────────────────────────────────────────────────┘ | + | <code> |
- | Эта программа сработает лишь при точном совпадении ответа с | + | 30 if n$="Виктор Алексеевич" or n$="Дима" or n$="Шурик" then print "Привет, хозяин!" else print "Вы не мой хозяин":goto 10 |
- | ожидаемым текстом. Программу можно усовершенствовать, если | + | </code> |
- | предусмотреть несколько имен. Для этого в строке 30 нужно | + | Служебное слово ''OR'' в условии обозначает ИЛИ: условие будет в целом истинным, если выполняется хотя бы одно из условий, соединённых словом ''OR''. |
- | поменять условие: | + | |
- | │ 30 if n$="Виктор Алексеевич" or n$="Дима" or n$="Шурик" │ | + | Обратили ли вы внимание, что в этом примере тоже используется цикл, но он уже не является бесконечным: имеется условие его окончания: когда будет названо правильное имя. |
- | │ then print "Привет, хозяин!" else print "Вы не мой хозя │ | + | |
- | │ ин":goto 10 │ | + | |
- | Служебное слово <OR> в условии обозначает <ИЛИ>: условие | + | <WRAP box> |
- | будет в целом истинным, если выполняется хотя бы одно из | + | Переделайте программу "Купи слона" так, чтобы при каком–то определённом ответе цикл заканчивался. |
- | условий, соединенных словом <OR>. | + | </WRAP> |
- | Обратили ли вы внимание, что в этом примере тоже используется | + | <code> |
- | цикл, но он уже не является бесконечным: имеется условие его | + | 10 'Непедагогичное воспитание |
- | окончания: когда будет названо правильное имя. | + | 20 input"Шлеп! Будешь слушаться (да/нет)";a$ |
- | + | 30 if a$="да" then 60 else if a$="нет" then 40 else 50 | |
- | █ Переделайте программу "Купи слона" так, чтобы при каком-то | + | 40 print "Ах, так!": goto 20 |
- | █ определенном ответе цикл заканчивался. | + | 50 print "Я не понял!":goto 20 |
- | + | 60 print "Вот то-то же!" | |
- | ┌────────────────────────────────────────────────────────┐ | + | </code> |
- | │ 10 'Непедагогичное воспитание │ | + | В этом примере вы увидели, что проверка условия может быть и не простая: если первое условие не выполнилось, мы новым ''IF'' продолжаем проверку другого условия. Следующий пример развивает этот способ: |
- | │ 20 input"Шлеп! Будешь слушаться (да/нет)";a$ │ | + | <code> |
- | │ 30 if a$="да" then 60 else if a$="нет" then 40 else 50 │ | + | 10 'Электронный продавец |
- | │ 40 print "Ах, так!": goto 20 │ | + | 20 S=0:'Начинаем с нулевой суммы |
- | │ 50 print "Я не понял!":goto 20 │ | + | 30 cls:print"СПИСОК ТОВАРОВ:" |
- | │ 60 print "Вот то-то же!" │ | + | 40 print"1. Шашлык свежий - 200 р." |
- | └────────────────────────────────────────────────────────┘ | + | 50 print"2. Хлеб - 5 р." |
- | В этом примере вы увидели, что проверка условия может быть и | + | 60 print"3. Сок гранатовый - 40 р." |
- | не простая: если первое условие не выполнилось, мы новым | + | 70 print"4. Шоколад импортный - 240 р." |
- | IF-ом продолжаем проверку другого условия. Следующий пример | + | 80 print:print:input"Введите выбранный номер";N |
- | развивает этот способ: | + | 90 input"Сколько штук";K |
- | ┌─────────────────────────────────────────────────────────┐ | + | 100 if N=1 then P=200 else if N=2 then P=5 else if N=3 then P=40 else if N=4 then P=240 else 30:'ошибочный N 110 S=S+P*K:'Увеличили общую сумму на стоимость покупки |
- | │ 10 'Электронный продавец │ | + | 120 input"Продолжим (да/нет)";OTW$ |
- | │ 20 S=0:'Начинаем с нулевой суммы │ | + | 130 if OTW$="да" or OTW$="ДА" or OTW$="Да" then 30 |
- | │ 30 cls:print"СПИСОК ТОВАРОВ:" │ | + | 140 print "Заплатите";S;"рублей в кассу" |
- | │ 40 print"1. Шашлык свежий - 200 р." │ | + | </code> |
- | │ 50 print"2. Хлеб - 5 р." │ | + | |
- | │ 60 print"3. Сок гранатовый - 40 р." │ | + | |
- | │ 70 print"4. Шоколад импортный - 240 р." │ | + | |
- | │ 80 print:print:input"Введите выбранный номер";N │ | + | |
- | │ 90 input"Сколько штук";K │ | + | |
- | │ 100 if N=1 then P=200 else if N=2 then P=5 else if N=3 │ | + | |
- | │ then P=40 else if N=4 then P=240 else 30:'ошибочный N │ | + | |
- | │ 110 S=S+P*K:'Увеличили общую сумму на стоимость покупки │ | + | |
- | │ 120 input"Продолжим (да/нет)";OTW$ │ | + | |
- | │ 130 if OTW$="да" or OTW$="ДА" or OTW$="Да" then 30 │ | + | |
- | │ 140 print "Заплатите";S;"рублей в кассу" │ | + | |
- | └─────────────────────────────────────────────────────────┘ | + | |
Здесь нужно остановиться на нескольких моментах: | Здесь нужно остановиться на нескольких моментах: | ||
- | Во-первых, обратите внимание, как накапливается сумма: в 20 | + | Во–первых, обратите внимание, как накапливается сумма: в 0 строчке ей даётся начальное значение 0, а в 110 она увеличивается на стоимость текущей покупки. Поступайте таким способом всегда, когда нужно какую–то величину наращивать от заданного начального значения. |
- | строчке ей дается начальное значение 0, а в 110 она | + | |
- | увеличивается на стоимость текущей покупки. Поступайте таким | + | |
- | способом всегда, когда нужно какую-то величину наращивать от | + | |
- | заданного начального значения. | + | |
- | Во-вторых, такую проверку, как в 130 строке делайте тогда, | + | Во–вторых, такую проверку, как в 130 строке делайте тогда, когда нет уверенности, ответит ли пользователь строчными или заглавными буквами. |
- | когда нет уверенности, ответит ли пользователь строчными или | + | |
- | заглавными буквами. | + | |
- | В-третьих, вы заметили , что в 30 строке при проверке | + | В–третьих, вы заметили, что в 130 строке при проверке отсутствует ''ELSE''. Дело в том, что при проверке ''IF'' можно FIXME |
- | отсутствует ELSE. Дело в том, что при проверке IF-ом можно | + | |
- | </code> | + | |
====== Урок 5 ====== | ====== Урок 5 ====== | ||
+ | Вы уже познакомились с циклом, который организуется с помощью ''GOTO''. Иногда такой цикл бывает бесконечным, но чаще всего в цикле имеется условие, которое проверяется при каждом повторении, и если оно выполнилось, цикл заканчивается, и программа продолжается после цикла. Условия окончания цикла | ||
+ | могут быть разными. Если это условие определяется ответом пользователя, или случайным числом, или другим труднопредсказуемым событием, то ''GOTO'' и ''IF'' — лучший способ для организации такого цикла. Но часто встречаются такие циклы, окончание которых определяется значением переменной, которая при каждом повторении меняется на одну и ту же величину. Поясню на примерах: | ||
+ | |||
+ | Программа печатает квадраты всех чётных чисел от 40 до 76: | ||
<code> | <code> | ||
- | Вы уже познакомились с циклом, который организуется с помощью | + | 10 x=40 |
- | GOTO. Иногда такой цикл бывает бесконечным, но чаще всего в | + | 20 if x > 76 then end else print x^2 |
- | цикле имеется условие, которое проверяется при каждом | + | 30 x=x+2:goto 20 |
- | повторении, и если оно выполнилось, цикл заканчивается, и | + | </code> |
- | программа продолжается после цикла. Условия окончания цикла | + | |
- | могут быть разными. Если это условие определяется ответом | + | |
- | пользователя, или случайным числом, или другим труднопредска- | + | |
- | зуемым событием, то GOTO и IF - лучший способ для организации | + | |
- | такого цикла. Но часто встречаются такие циклы, окончание | + | |
- | которых определяется значением переменной, которая при каждом | + | |
- | повторении меняется на одну и ту же величину. Поясню на | + | |
- | примерах: | + | |
- | Программа печатает квадраты всех четных чисел от 40 до 76: | + | FIXME |
- | ┌──────────────────────────────────────┐ | + | <code> |
- | │ 10 x=40 │ | + | └───────────────────────────────────────────────────────┘ |
- | │ 20 if x > 76 then end else print x^2 │ | + | Единица в скобках после input$ обозначает, что функция закончит работу после первой же нажатой клавиши. Если бы стояло input$(2), то функция ждала бы нажатия второй клавиши, а затем в переменную a$ записала бы оба нажатых символа. |
- | │ 30 x=x+2:goto 20 │ | + | </code> |
- | └─────────────└───────────────────────────────────────────────────────┘ | + | FIXME |
- | Единица в скобках после input$ обозначает, что функция | + | |
- | закончит работу после первой же нажатой клавиши. Если бы | + | |
- | стояло input$(2), то функция ждала бы нажатия второй клавиши, | + | |
- | а затем в переменную a$ записала бы оба нажатых символа. | + | |
- | Следующая программа печатает подряд все числа, пропуская | + | Следующая программа печатает подряд все числа, пропуская кратные 5–ти. Чтобы это проверить, достаточно найти остаток от деления числа на 5. Если он =0, то число кратно 5: |
- | кратные 5-ти. Чтобы это проверить, достаточно найти остаток | + | <code> |
- | от деления числа на 5. Если он =0, то число кратно 5: | + | 10 for m=0 to 200 |
- | ┌─────────────────────────────────────────────────┐ | + | 20 if m mod 5>0 then print m :'Если не кратно 5 |
- | │ 10 for m=0 to 200 │ | + | 30 next |
- | │ 20 if m mod 5>0 then print m :'Если не кратно 5 │ | + | </code> |
- | │ 30 next │ | + | |
- | └─────────────────────────────────────────────────┘ | + | |
- | Если положить сумму в банк с процентной ставкой 20% годовых, | + | Если положить сумму в банк с процентной ставкой 20% годовых, то по истечение года сумма возрастёт на 20%. К концу следующего года УЖЕ НОВАЯ сумма возрастёт на 20% и т.д. |
- | то по истечение года сумма возрастет на 20% . К концу | + | Составим программу, которая запрашивает начальную сумму, процентную ставку и количество лет, а вычисляет конечную сумму. |
- | следующего года УЖЕ НОВАЯ сумма возрастет на 20% и т. д. | + | <code> |
- | Составим программу, которая запрашивает начальную сумму, | + | 10 input"Начальная сумма";s |
- | процентную ставку и количество лет, а вычисляет конечную | + | 20 input"Процентная ставка (%)";n |
- | сумму. | + | 30 n=1+n/100:'Во столько раз возрастает за год |
- | ┌────────────────────────────────────────────────┐ | + | 40 input"На сколько лет";y |
- | │ 10 input"Начальная сумма";s │ | + | 50 for l=1 to y:'Начинаем считать годы |
- | │ 20 input"Процентная ставка (%)";n │ | + | 60 s=s*n:next:print"Сумма=";s |
- | │ 30 n=1+n/100:'Во столько раз возрастает за год │ | + | </code> |
- | │ 40 input"На сколько лет";y │ | + | Поясню, откуда взялась 30 строка: Если процентная ставка 53%, то за год сумма возрастёт на 0.53 от исходной суммы, или, что то же самое — в 1.53 раза = в 1+53/100 раза или в общем |
- | │ 50 for l=1 to y:'Начинаем считать годы │ | + | случае — в 1+n/100 раз. |
- | │ 60 s=s*n:next:print"Сумма=";s │ | + | |
- | └────────────────────────────────────────────────┘ | + | |
- | Поясню, откуда взялась 30 строка: Если процентная ставка 53%, | + | |
- | то за год сумма возрастет на 0.53 от исходной суммы, или, что | + | |
- | то же самое - в 1.53 раза = в 1+53/100 раза или в общем | + | |
- | случае - в 1+n/100 раз. | + | |
- | Кстати, в этом примере можно обойтись вовсе без цикла, если | + | Кстати, в этом примере можно обойтись вовсе без цикла, если увидеть, как возрастает каждый год начальная сумма: |
- | увидеть, как возрастает каждый год начальная сумма: | + | \\ За 1 год — в 1.53 раза |
- | За 1 год - в 1.53 раза | + | \\ За 2 года — в 1.53 * 1.53 |
- | За 2 года - в 1.53 * 1.53 | + | \\ За 3 года — в 1.53 * 1.53 * 1.53 или 1.53^3 |
- | За 3 года - в 1.53 * 1.53 * 1.53 или 1.53^3 | + | \\ И т. д. … |
- | И т. д. ... | + | \\ За Y лет — в 1.53^Y раза или, для общего случая, в (1+n/100)^Y раз — и не нужно цикла: |
- | За Y лет - в 1.53^Y раза или, для общего случая, в | + | <code> |
- | (1+n/100)^Y раз - и не нужно цикла: | + | 10 input"Начальная сумма";s |
- | ┌───────────────────────────────────┐ | + | 20 input"Процентная ставка (%)";n |
- | │ 10 input"Начальная сумма";s │ | + | 30 input"На сколько лет";y |
- | │ 20 input"Процентная ставка (%)";n │ | + | 40 s=s*(1+n/100)^y |
- | │ 30 input"На сколько лет";y │ | + | 50 print"Сумма=";s |
- | │ 40 s=s*(1+n/100)^y │ | + | </code> |
- | │ 50 print"Сумма=";s │ | + | |
- | └───────────────────────────────────┘ | + | |
- | Циклами очень удобно обрабатывать тексты. Рассмотрим такую | + | Циклами очень удобно обрабатывать тексты. Рассмотрим такую программу: Пользователь вводит текст, например, "Победа", а программа печатает сначала все слово, затем без первой буквы, без второй и т. д.: |
- | программу: Пользователь вводит текст, например, "Победа", а | + | <code> |
- | программа печатает сначала все слово, затем без первой буквы, | + | Победа |
- | без второй и т. д.: | + | обеда |
- | Победа | + | беда |
- | обеда | + | еда |
- | беда | + | да |
- | еда | + | а |
- | да | + | </code> |
- | а | + | <code> |
- | ┌─────────────────────────────────────────────┐ | + | 10 input "Введите слово "; A$ |
- | │ 10 input "Введите слово "; A$ │ | + | 20 L=len(A$):' Нашли длину текста |
- | │ 20 L=len(A$):' Нашли длину текста │ | + | 30 for I=0 to L-1:print right$(A$,L-I):next |
- | │ 30 for I=0 to L-1:print right$(A$,L-I):next │ | + | </code> |
- | └─────────────────────────────────────────────┘ | + | В 30–й строчке с помощью ''right$()'' вырезаем правую часть введённого слова, длиной L-I. Например, когда в цикле переменная I дойдёт до 5, будет вырезано L-5 букв, то–есть, от 5–й до L–й (последней в тексте). |
- | В 30-й строчке с помощью right$() вырезаем правую часть | + | |
- | введенного слова, длиной L-I. Например, когда в цикле пере- | + | |
- | менная I дойдет до 5, будет вырезано L-5 букв, то-есть, от | + | |
- | 5-й до L-й (последней в тексте). | + | |
- | Следующая программка отрезает от слова последние буквы: | + | Следующая программка отрезает от слова последние буквы: |
- | ┌────────────────────────────────────────────────┐ | + | <code> |
- | │ 10 input "Введите слово "; A$ │ | + | 10 input "Введите слово "; A$ |
- | │ 20 L=len(A$) │ | + | 20 L=len(A$) |
- | │ 30 for I=L to 1 step -1:print left$(A$,I):next │ | + | 30 for I=L to 1 step -1:print left$(A$,I):next |
- | └────────────────────────────────────────────────┘ | + | </code> |
Нетрудно слово и вовсе разобрать по отдельным буквам: | Нетрудно слово и вовсе разобрать по отдельным буквам: | ||
- | ┌────────────────────────────────────────────────┐ | + | <code> |
- | │ 10 input "Введите слово "; A$ │ | + | 10 input "Введите слово "; A$ |
- | │ 30 for I=1 to len(a$):print mid$(A$,I,1):next │ | + | 30 for I=1 to len(a$):print mid$(A$,I,1):next |
- | └────────────────────────────────────────────────┘ | + | </code> |
- | Внимательно разберитесь с последним примером и не двигайтесь | + | Внимательно разберитесь с последним примером и не двигайтесь дальше, пока не выполните задание: |
- | дальше, пока не выполните задание: | + | |
- | █ Составить программу, получающую слово и печатающую отдельные | + | <WRAP box> |
- | █ буквы этого слова в обратном порядке. | + | Составить программу, получающую слово и печатающую отдельные буквы этого слова __в обратном порядке__. |
- | ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ | + | </WRAP> |
- | Следующий пример такой: программа должна получить слово и | + | |
- | напечатать его задом наперед. Не отдельные буквы, как в | + | |
- | предыдущем примере, а слово! | + | |
- | ┌────────────────────────────────────────────────┐ | + | |
- | │ 10 input "Введите слово "; A$ │ | + | |
- | │ 20 B$="":'Заводим другую текстовую переменную,│ | + | |
- | │ в которую будем накапливать новое слово │ | + | |
- | │ 30 for I=L to 1 step -1:B$=B$+mid$(A$,I,1):next│ | + | |
- | │ 40 print B$ │ | + | |
- | └────────────────────────────────────────────────┘ | + | |
- | Две кавычки, которые использованы в 20-й строке подряд (без | + | |
- | пробела) называются пустым текстом. Мы берем пустой текст в | + | |
- | переменную B$ для того, чтобы приклеивать к нему букву за | + | |
- | буквой, вырезая их из текста A$, начиная с конца. | + | |
- | Пример немного сложнее: Программа должна ввести предложение | ||
- | пользователя и разделить его на отдельные слова. | ||
- | В качестве разделителей между словами могут быть пробел, запя- | ||
- | тая, двоеточие и другие знаки препинания. Программа накапли- | ||
- | вает новое слово, просматривая текст буква за буквой. Когда | ||
- | встретится разделитель, слово напечатается, обнулится и будет | ||
- | снова накапливаться. | ||
- | ┌──────────────────────────────────────────────────────────┐ | ||
- | │ 10 input "Введите текст ";A$: L=len(A$) │ | ||
- | │ 20 B$="":for I=1 to L: K$=mid$(A$,I,1) │ | ||
- | │ 30 if K$=" " or K$="," or K$="." or K$=":" then print B$:│ | ||
- | │ B$="" else B$=B$+K$ │ | ||
- | │ 40 next │ | ||
- | └──────────────────────────────────────────────────────────┘ | ||
- | Хотя явных ошибок в этой программе нет, не если ее запустите, | ||
- | вы увидите, что она работает только тогда, когда в предложе- | ||
- | нии нет знаков препинания. Если встречается запятая, все, что | ||
- | в тексте после запятой, отбрасывается. При этом Бейсик сооб- | ||
- | щает: ?EXTRA IGNORED (лишнее пропускаю). Причина этого - | ||
- | особенности INPUTа. Если после INPUTа имеется не одна, а | ||
- | несколько переменных, INPUT может принять сразу несколько | ||
- | чисел или текстов, разделенных запятой. Например, | ||
- | ┌─────────────────────────────────┐ | ||
- | │ input "Введите два слова ";A$,B$│ вводит два текста. | ||
- | └─────────────────────────────────┘ | ||
- | В предыдущей программе, когда текст включал запятые, они | ||
- | воспринимались INPUTом не как часть текста, а как разделитель | ||
- | между двумя текстами для двух переменных. Этого недостатка | ||
- | лишена другая команда:LINE INPUT (ввод строки). Она беднее | ||
- | INPUTа, так как не принимает чисел, а только текст ( причем, | ||
- | только один!). Зато ей безразличны запятые в этом тексте. | ||
- | Измените 10-ю строку в программе: | ||
- | ┌──────────────────────────────────────────────────────────┐ | ||
- | │ 10 line input "Введите текст ";A$: L=len(A$) │ | ||
- | └──────────────────────────────────────────────────────────┘ | ||
- | Но и измененная программа не лишена недостатка: Если в конце | ||
- | предложения не стоит точка, последнее слово не напечатается | ||
- | (ведь программа печатает слово в момент, когда найден | ||
- | разделитель). Эту ошибку устранить и вовсе легко: если | ||
- | последняя буква не ".", "!" или "?", добавим к тексту пробел. | ||
- | ┌──────────────────────────────────────────────────────────┐ | ||
- | │ 10 line input "Введите текст ";A$:K$=right$(A$,1):if K$<>│ | ||
- | │ "." and K$<>"!" and K$<>"?" then A$=A$+" " │ | ||
- | │ 20 B$="":for I=1 to len(A$): K$=mid$(A$,I,1) │ | ||
- | │ 30 if K$=" " or K$="," or K$="." or K$=":" then print B$:│ | ||
- | │ B$="" else B$=B$+K$ │ | ||
- | │ 40 next │ | ||
- | └──────────────────────────────────────────────────────────┘ | ||
- | У этой программы есть еще недостатки. Всех их устранять мы не | ||
- | будем, но еще один исправим. Обратите внимание: два раза | ||
- | встречается проверка, является ли K$ разделителем. Из-за | ||
- | громоздкости проверки мы не все возможные знаки проверяем. | ||
- | Воспользуемся функцией INSTR(T1$,T2$). Она проверяет, является | ||
- | ли текст T2$ частью текста T1$. Если T2$ не входит в T1$, то | ||
- | функция дает 0, а если входит, то значение функции равно номе- | ||
- | ру позиции, начиная с которой T2$ входит в T1$. Например, | ||
- | ┌────────────────────────────────┐ | ||
- | │ print INSTR("Барабанщик","ба") │ напечатает 5 ( а не 1, так | ||
- | └────────────────────────────────┘ | ||
- | в начале слова - "Б" а не "б"), а | ||
- | ┌────────────────────────────────┐ | ||
- | │ print INSTR("Барабанщик","ва") │ напечатает 0, так как "ва" | ||
- | └────────────────────────────────┘ | ||
- | в слово не входит. | ||
- | В нашей программе мы с помощью INSTR можем проверить, входит | + | Следующий пример такой: программа должна получить слово и напечатать его задом наперёд. Не отдельные буквы, как в предыдущем примере, а слово! |
- | ли K$ (вырезанная буква) в список разделителей: | + | <code> |
- | ┌────────────────────────────────────────────────────┐ | + | 10 input "Введите слово "; A$ |
- | │ 10 line input "Введите текст ";A$:K$=right$(A$,1): │ | + | 20 B$="":'Заводим другую текстовую переменную, в которую будем накапливать новое слово |
- | │ if instr(" ,.!?-:",K$)=0 then A$=A$+" " │ | + | 30 for I=L to 1 step -1:B$=B$+mid$(A$,I,1):next |
- | │ 20 B$="":for I=1 to len(A$): K$=mid$(A$,I,1) │ | + | 40 print B$ |
- | │ 30 if instr(" ,.!?-:",K$) then print B$:B$="" else │ | + | |
- | │ B$=B$+K$ │ | + | |
- | │ 40 next │ | + | |
- | └────────────────────────────────────────────────────┘ | + | |
- | Проверка получилась меньше, а знаков проверили больше. 10-ю | + | |
- | строчку можно еще сократить, если внести RIGHT$ прямо в | + | |
- | аргумент INSTRа: получится функция от функции. Так можно! | + | |
- | ┌──────────────────────────────────────────────────────────┐ | + | |
- | │ 10 line input "Введите текст ";A$:if instr(" ,.!?-:",righ│ | + | |
- | │ t$(a$,1) )=0 then A$=A$+" " │ | + | |
- | └──────────────────────────────────────────────────────────┘ | + | |
- | В 20 и 30 строчках вносить функцию MID$() в функцию INSTR() | + | |
- | не нужно, так как K$ используется не только в INSTR(), но и | + | |
- | дальше. | + | |
- | + | ||
- | Торопливый читатель упрекнет меня, зачем столько времени | + | |
- | доделывать и переделывать одну и ту же программу? Не проще ли | + | |
- | сразу дать готовую в окончательном виде, а потом объяснить? | + | |
- | Ответ: я показываю, как работает программист: большую часть | + | |
- | времени у программиста занимает не написание, а совершенство- | + | |
- | вание программы. | + | |
- | Еще раз напомню: сия книжка - не художественная литература, | + | |
- | которую проглатывают за один раз! Читайте, перечитывайте по | + | |
- | многу раз объяснения, разбирайтесь в примерах, и тогда от | + | |
- | вашей работы будет толк! | + | |
</code> | </code> | ||
+ | Две кавычки, которые использованы в 20–й строке подряд (без пробела) называются пустым текстом. Мы берём пустой текст в переменную B$ для того, чтобы приклеивать к нему букву за буквой, вырезая их из текста A$, начиная с конца. | ||
- | ====== Урок 6 ====== | + | Пример немного сложнее: Программа должна ввести предложение пользователя и разделить его на отдельные слова. |
- | <code> | + | |
- | Много хороших программ можно сделать, если научиться размещать | + | |
- | печатаемый текст в нужном месте экрана. Например, можно | + | |
- | заставить текст ползти по экрану, можно печатать не только | + | |
- | слева направо, но и справа налево, сверху вниз, под углом... | + | |
- | Можно организовать на экране табличку и аккуратно впечатывать | + | |
- | числа или тексты в клетки этой таблицы... Можно, наконец, | + | |
- | делать простенькие игры, в которых движутся не рисунки, | + | |
- | слова. Чтобы этому научиться, нужно разобраться, как | + | |
- | организован экран. | + | |
- | На экране помещаются 24 строки текста. Они пронумерованы: | + | В качестве разделителей между словами могут быть пробел, запятая, двоеточие и другие знаки препинания. |
- | первая имеет номер 0, 24-я - номер 23. Обычно в 23-й строке | + | |
- | находятся подсказки, и ваша программа ею пользоваться не | + | |
- | может. Чтобы убрать подсказки, используют команду KEYOFF, | + | |
- | тогда 23-ю строку можно использовать. Если нужно восстановить | + | |
- | строку с подсказками - команда KEYON. | + | |
- | Сколько помещается в каждой строке символов, зависит от того, | + | |
- | какие установлены экранный режим и ширина экрана. | + | |
- | Экранный режим устанавливается командой SCREEN: | + | |
- | SCREEN 0 - до 80 символов в строке. | + | |
- | SCREEN 1 - до 32 символов в строке. | + | |
- | При включении обычно автоматически устанавливается SCREEN 0. | + | |
- | После установки режима, командой WIDTH можно установить ширину | + | Программа накапливает новое слово, просматривая текст буква за буквой. Когда встретится разделитель, слово напечатается, обнулится и будет снова накапливаться. |
- | экрана. Например, WIDTH 80 устанавливает 80 символов в строке | + | <code> |
- | (мелкий шрифт). Такая команда не сработает в 1-м экранном | + | 10 input "Введите текст ";A$: L=len(A$) |
- | режиме (Максимально WIDTH 32). Команда WIDTH 40 в 0-м режиме | + | 20 B$="":for I=1 to L: K$=mid$(A$,I,1) |
- | установит 40 символов в строке (крупный шрифт). | + | 30 if K$=" " or K$="," or K$="." or K$=":" then print B$:B$="" else B$=B$+K$ |
+ | 40 next | ||
+ | </code> | ||
+ | Хотя явных ошибок в этой программе нет, не если её запустите, вы увидите, что она работает только тогда, когда в предложении нет знаков препинания. Если встречается запятая, все, что в тексте после запятой, отбрасывается. При этом Бейсик сообщает: | ||
+ | <WRAP centeralign>?EXTRA IGNORED (лишнее пропускаю).</WRAP> | ||
+ | Причина этого — особенности ''INPUT''. Если после ''INPUT'' имеется не одна, а несколько переменных, ''INPUT'' может принять сразу несколько чисел или текстов, разделённых запятой. Например, | ||
+ | <code> | ||
+ | input "Введите два слова ";A$,B$ | ||
+ | </code> вводит два текста. | ||
- | Все дальнейшие примеры (если не оговаривается особо) приведе- | + | В предыдущей программе, когда текст включал запятые, они воспринимались ''INPUT'' не как часть текста, а как разделитель между двумя текстами для двух переменных. Этого недостатка лишена другая команда:''LINE INPUT'' (ввод строки). Она беднее ''INPUT'', так как не принимает чисел, а только текст (причём, только один!). Зато ей безразличны запятые в этом тексте. Измените 10–ю строку в программе: |
- | ны из рассчета на 0-й режим, 80-символьный экран и пустую | + | <code> |
- | служебную строку. | + | 10 line input "Введите текст ";A$: L=len(A$) |
+ | </code> | ||
+ | Но и изменённая программа не лишена недостатка: Если в конце предложения не стоит точка, последнее слово не напечатается (ведь программа печатает слово в момент, когда найден разделитель). Эту ошибку устранить и вовсе легко: если последняя буква не ".", "!" или "?", добавим к тексту пробел. | ||
+ | <code> | ||
+ | 10 line input "Введите текст ";A$:K$=right$(A$,1):if K$<>"." and K$<>"!" and K$<>"?" then A$=A$+" " | ||
+ | 20 B$="":for I=1 to len(A$): K$=mid$(A$,I,1) | ||
+ | 30 if K$=" " or K$="," or K$="." or K$=":" then print B$:B$="" else B$=B$+K$ | ||
+ | 40 next | ||
+ | </code> | ||
+ | У этой программы есть ещё недостатки. Всех их устранять мы не будем, но ещё один исправим. Обратите внимание: два раза встречается проверка, является ли K$ разделителем. Из–за громоздкости проверки мы не все возможные знаки проверяем. | ||
- | Команда LOCATE позволяет указать, где будет печатать следующий | + | Воспользуемся функцией INSTR(T1$,T2$). Она проверяет, является ли текст T2$ частью текста T1$. Если T2$ не входит в T1$, то функция даёт 0, а если входит, то значение функции равно номеру позиции, начиная с которой T2$ входит в T1$. Например, |
- | после нее PRINT. Например, | + | <code> |
- | ┌─────────────────────────────┐ | + | print INSTR("Барабанщик","ба") |
- | │ LOCATE 30,12:PRINT "Привет" │ | + | </code> |
- | └─────────────────────────────┘ | + | напечатает 5 ( а не 1, так в начале слова — "Б" а не "б"), а |
- | напечатает "Привет", начиная с 30-й позиции в 12-й строке. | + | <code> |
- | (Вы не забыли, что нумерация идет от 0?) | + | print INSTR("Барабанщик","ва") |
+ | </code> напечатает 0, так как "ва" в слово не входит. | ||
- | Если в LOCATE использовать не числа, а переменные, то можно в | + | В нашей программе мы с помощью ''INSTR'' можем проверить, входит ли K$ (вырезанная буква) в список разделителей: |
- | цикле печатать красивые вещи. Например, напечатаем уголком | + | <code> |
- | слово "привет": | + | 10 line input "Введите текст ";A$:K$=right$(A$,1):if instr(" ,.!?-:",K$)=0 then A$=A$+" " |
- | ┌───────────────────────────────────────────────────────┐ | + | 20 B$="":for I=1 to len(A$): K$=mid$(A$,I,1) |
- | │ 10 for i=0 to 10:locate i,i:print"Привет!":next │ | + | 30 if instr(" ,.!?-:",K$) then print B$:B$="" else B$=B$+K$ |
- | │ 20 for i=0 to 10:locate 10-i,11+i:print"Привет!":next │ | + | 40 next |
- | └───────────────────────────────────────────────────────┘ | + | </code> |
- | Посмотрите, как программка работает. В 10-й строке LOCATE в | + | Проверка получилась меньше, а знаков проверили больше. 10–ю строчку можно ещё сократить, если внести ''RIGHT$'' прямо в аргумент ''INSTR'': получится функция от функции. Так можно! |
- | качестве номера строки и номера позиции использует одно и то | + | <code> |
- | же число (i). В 20-й строке мы хотим, чтобы позиция | + | 10 line input "Введите текст ";A$:if instr(" ,.!?-:",righ t$(a$,1) )=0 then A$=A$+" " |
- | уменьшалась, а номер строки увеличивался. Поэтому рассчитыва- | + | </code> |
- | ем их по-разному. | + | В 20 и 30 строчках вносить функцию ''MID$()'' в функцию ''INSTR()'' не нужно, так как K$ используется не только в ''INSTR()'', но и дальше. |
- | Если хотим растянуть по X в 2 раза, нужно номер позиции | + | |
- | умножить на 2 (а номер строки не умножать): | + | |
- | ┌─────────────────────────────────────────────────────────┐ | + | |
- | │ 10 for i=0 to 10:locate i*2,i:print"Привет!":next │ | + | |
- | │ 20 for i=0 to 10:locate 20-i*2,11+i:print"Привет!":next │ | + | |
- | └─────────────────────────────────────────────────────────┘ | + | |
- | Напечатаем из левого верхнего в правый нижний угол: | + | Торопливый читатель упрекнёт меня, зачем столько времени доделывать и переделывать одну и ту же программу? Не проще ли сразу дать готовую в окончательном виде, а потом объяснить? |
- | ┌────────────────────────────────────────────────────┐ | + | \\ Ответ: я показываю, как работает программист: большую часть времени у программиста занимает не написание, а совершенствование программы. |
- | │ 10 for i=0 to 23:locate i*3.5,i:print"ШШШШШШ":next │ | + | |
- | └────────────────────────────────────────────────────┘ | + | |
- | Выполнив пример, вы заметите, что когда программа допечатает | + | |
- | до низа, весь экран дернется вверх. Одна из причин этого- та, | + | |
- | что Бейсик, окончив программу, печатает "Ok" и при этом | + | |
- | переводит строку, поднимая экран. Чтобы этого не было, | + | |
- | зациклим программу, то-есть, добавим к ней строчку: | + | |
- | ┌─────────────┐ | + | |
- | │ 20 goto 20 │ | + | |
- | └─────────────┘ | + | |
- | Но даже и в этом случае экран дернулся вверх, хотя и меньше, | + | |
- | чем раньше. Виноват print, который после последней строчки | + | |
- | переводит строку. Если вы добавите после ...ШШШ" знак <;>, то | + | |
- | все будет в порядке. | + | |
- | █ Если вы разобрались в этом примере, то попробуйте напечатать | + | Ещё раз напомню: сия книжка — не художественная литература, которую проглатывают за один раз! Читайте, перечитывайте помногу раз объяснения, разбирайтесь в примерах, и тогда от вашей работы будет толк! |
- | █ так же под углом, но снизу вверх. | + | |
- | █ Еще труднее, но вы постараетесь, напечатать текст справа | + | ====== Урок 6 ====== |
- | █ налево сверху вниз. | + | |
- | Сделаем программу, которая пишет текст под каким-нибудь углом, | + | Много хороших программ можно сделать, если научиться размещать печатаемый текст в нужном месте экрана. Например, можно заставить текст ползти по экрану, можно печатать не только слева направо, но и справа налево, сверху вниз, под углом… |
- | и, дойдя до границы экрана, отражается от не УРОК 6 | + | |
- | Много хороших программ можно сделать, если научиться размещать | + | Можно организовать на экране табличку и аккуратно впечатывать числа или тексты в клетки этой таблицы… Можно, наконец, делать простенькие игры, в которых движутся не рисунки, слова. Чтобы этому научиться, нужно разобраться, как организован экран. |
- | печатаемый текст в нужном месте экрана. Например, можно | + | На экране помещаются 24 строки текста. Они пронумерованы: первая имеет номер 0, 24–я — номер 23. Обычно в 23–й строке находятся подсказки, и ваша программа ею пользоваться не может. Чтобы убрать подсказки, используют команду ''KEYOFF'', тогда 23–ю строку можно использовать. Если нужно восстановить |
- | заставить текст ползти по экрану, можно печатать не только | + | строку с подсказками — команда ''KEYON''. |
- | слева направо, но и справа налево, сверху вниз, под углом... | + | Сколько помещается в каждой строке символов, зависит от того, какие установлены экранный режим и ширина экрана. |
- | Можно организовать на экране табличку и аккуратно впечатывать | + | Экранный режим устанавливается командой ''SCREEN'': |
- | числа или тексты в клетки этой таблицы... Можно, наконец, | + | * ''SCREEN 0'' — до 80 символов в строке. |
- | делать простенькие игры, в которых движутся не рисунки, | + | * ''SCREEN 1'' — до 32 символов в строке. |
- | слова. Чтобы этому научиться, нужно разобраться, как | + | При включении обычно автоматически устанавливается ''SCREEN 0''. |
- | организован экран. | + | |
- | На экране помещаются 24 строки текста. Они пронумерованы: | + | После установки режима, командой ''WIDTH'' можно установить ширину экрана. Например, ''WIDTH 80'' устанавливает 80 символов в строке (мелкий шрифт). Такая команда не сработает в 1–м экранном режиме (Максимально ''WIDTH 32''). Команда'' WIDTH 40'' в 0–м режиме установит 40 символов в строке (крупный шрифт). |
- | первая имеет номер 0, 24-я - номер 23. Обычно в 23-й строке | + | |
- | находятся подсказки, и ваша программа ею пользоваться не | + | |
- | может. Чтобы убрать подсказки, используют команду KEYOFF, | + | |
- | тогда 23-ю строку можно использовать. Если нужно восстановить | + | |
- | строку с подсказками - команда KEYON. | + | |
- | Сколько помещается в каждой строке символов, зависит от того, | + | |
- | какие установлены экранный режим и ширина экрана. | + | |
- | Экранный режим устанавливается командой SCREEN: | + | |
- | SCREEN 0 - до 80 символов в строке. | + | |
- | SCREEN 1 - до 32 символов в строке. | + | |
- | При включении обычно автоматически устанавливается SCREEN 0. | + | |
- | После установки режима, командой WIDTH можно установить ширину | + | Все дальнейшие примеры (если не оговаривается особо) приведены из расчёта на 0–й режим, 80–символьный экран и пустую служебную строку. |
- | экрана. Например, WIDTH 80 устанавливает 80 символов в строке | + | |
- | (мелкий шрифт). Такая команда не сработает в 1-м экранном | + | |
- | режиме (Максимально WIDTH 32). Команда WIDTH 40 в 0-м режиме | + | |
- | установит 40 символов в строке (крупный шрифт). | + | |
- | Все дальнейшие примеры (если не оговаривается особо) приведе- | + | Команда ''LOCATE'' позволяет указать, где будет печатать следующий после неё ''PRINT''. Например, |
- | ны из рассчета на 0-й режим, 80-символьный экран и пустую | + | <code> |
- | служебную строку. | + | LOCATE 30,12:PRINT "Привет" |
+ | </code> | ||
+ | напечатает "Привет", начиная с 30–й позиции в 12–й строке. (Вы не забыли, что нумерация идёт от 0?) | ||
- | Команда LOCATE позволяет указать, где будет печатать следующий | + | Если в ''LOCATE'' использовать не числа, а переменные, то можно в цикле печатать красивые вещи. Например, напечатаем уголком слово "привет": |
- | после нее PRINT. Например, | + | <code> |
- | ┌─────────────────────────────┐ | + | 10 for i=0 to 10:locate i,i:print"Привет!":next |
- | │ LOCATE 30,12:PRINT "Привет" │ | + | 20 for i=0 to 10:locate 10-i,11+i:print"Привет!":next |
- | └─────────────────────────────┘ | + | </code> |
- | напечатает "Привет", начиная с 30-й позиции в 12-й строке. | + | Посмотрите, как программка работает. В 10–й строке ''LOCATE'' в качестве номера строки и номера позиции использует одно и то же число (i). В 20–строке мы хотим, чтобы позиция уменьшалась, а номер строки увеличивался. Поэтому рассчитываем их по–разному. |
- | (Вы не забыли, что нумерация идет от 0?) | + | |
- | Если в LOCATE использовать не числа, а переменные, то можно в | + | Если хотим растянуть по X в 2 раза, нужно номер позиции умножить на 2 (а номер строки не умножать): |
- | цикле печатать красивые вещи. Например, напечатаем уголком | + | <code> |
- | слово "привет": | + | 10 for i=0 to 10:locate i*2,i:print"Привет!":next |
- | ┌───────────────────────────────────────────────────────┐ | + | 20 for i=0 to 10:locate 20-i*2,11+i:print"Привет!":next |
- | │ 10 for i=0 to 10:locate i,i:print"Привет!":next │ | + | </code> |
- | │ 20 for i=0 to 10:locate 10-i,11+i:print"Привет!":next │ | + | |
- | └───────────────────────────────────────────────────────┘ | + | |
- | Посмотрите, как программка работает. В 10-й строке LOCATE в | + | |
- | качестве номера строки и номера позиции использует одно и то | + | |
- | же число (i). В 20-й строке мы хотим, чтобы позиция | + | |
- | уменьшалась, а номер строки увеличивался. Поэтому рассчитыва- | + | |
- | ем их по-разному. | + | |
- | Если хотим растянуть по X в 2 раза, нужно номер позиции | + | |
- | умножить на 2 (а номер строки не умножать): | + | |
- | ┌─────────────────────────────────────────────────────────┐ | + | |
- | │ 10 for i=0 to 10:locate i*2,i:print"Привет!":next │ | + | |
- | │ 20 for i=0 to 10:locate 20-i*2,11+i:print"Привет!":next │ | + | |
- | └─────────────────────────────────────────────────────────┘ | + | |
Напечатаем из левого верхнего в правый нижний угол: | Напечатаем из левого верхнего в правый нижний угол: | ||
- | ┌────────────────────────────────────────────────────┐ | + | <code> |
- | │ 10 for i=0 to 23:locate i*3.5,i:print"ШШШШШШ":next │ | + | 10 for i=0 to 23:locate i*3.5,i:print"ШШШШШШ":next |
- | └────────────────────────────────────────────────────┘ | + | </code> |
- | Выполнив пример, вы заметите, что когда программа допечатает | + | Выполнив пример, вы заметите, что когда программа допечатает до низа, весь экран дёрнется вверх. Одна из причин этого — та, что Бейсик, окончив программу, печатает "Ok" и при этом переводит строку, поднимая экран. Чтобы этого не было, зациклим программу, то–есть, добавим к ней строчку: |
- | до низа, весь экран дернется вверх. Одна из причин этого- та, | + | <code> |
- | что Бейсик, окончив программу, печатает "Ok" и при этом | + | 20 goto 20 |
- | переводит строку, поднимая экран. Чтобы этого не было, | + | </code> |
- | зациклим программу, то-есть, добавим к ней строчку: | + | Но даже и в этом случае экран дёрнулся вверх, хотя и меньше, чем раньше. Виноват ''print'', который после последней строчки переводит строку. Если вы добавите после …ШШШ%%"%% знак <;>, то все будет в порядке. |
- | ┌─────────────┐ | + | |
- | │ 20 goto 20 │ | + | |
- | └─────────────┘ | + | |
- | Но даже и в этом случае экран дернулся вверх, хотя и меньше, | + | |
- | чем раньше. Виноват print, который после последней строчки | + | |
- | переводит строку. Если вы добавите после ...ШШШ" знак <;>, то | + | |
- | все будет в порядке. | + | |
- | █ Если вы разобрались в этом примере, то попробуйте напечатать | + | <WRAP box> |
- | █ так же под углом, но снизу вверх. | + | Если вы разобрались в этом примере, то попробуйте напечатать так же под углом, но снизу вверх. |
+ | </WRAP> | ||
- | █ Еще труднее, но вы постараетесь, напечатать текст справа | + | <WRAP box> |
- | █ налево сверху вниз. | + | Ещё труднее, но вы постараетесь, напечатать текст справа налево сверху вниз. |
+ | </WRAP> | ||
- | Сделаем программу, которая пишет текст под каким-нибудь углом, | + | |
- | и, дойдя до границы экрана, отражается от нее, как на рисунке: | + | Сделаем программу, которая пишет текст под каким–нибудь углом, и, дойдя до границы экрана, отражается от не1, как на рисунке: |
+ | <code> | ||
┌────────────────────лл────────────лл┐ | ┌────────────────────лл────────────лл┐ | ||
│ лллл лллл | │ лллл лллл | ||
Строка 955: | Строка 714: | ||
│ лллл лллл │ | │ лллл лллл │ | ||
└───────────лл────────────────лл─────┘ | └───────────лл────────────────лл─────┘ | ||
- | |||
- | Поскольку количество шагов не задано, лучше использовать не | ||
- | цикл FOR, а GOTO, и координаты X и Y для LOCATE рассчитывать | ||
- | независимо друг от друга. Рассмотрим последовательность | ||
- | действий: | ||
- | 1) Заведем переменные X и Y для LOCATE. | ||
- | 2) Заведем переменные DX и DY, которые показывают, на сколько | ||
- | изменяются X и Y в каждом шаге. | ||
- | 3) Напечатаем слово в позиции X,Y | ||
- | 4) Изменим X на DX и проверим, не зашли ли на левый или | ||
- | правый край экрана. Если зашли, нужно поменять DX на -DX, | ||
- | чтобы двигаться в противоположном направлении. | ||
- | 5) Изменим Y на DY и проверим так же верхнюю и нижнюю границы | ||
- | экрана. | ||
- | 6) Для продолжения вернемся к 3) и все повторим. | ||
- | ┌──────────────────────────────────────┐ | ||
- | │ 10 screen 0:keyoff:width 80 │ | ||
- | │ 20 x=10:y=10:dx=1:dy=1 │ | ||
- | │ 30 locate x,y:print"*"; │ | ||
- | │ 40 x=x+dx:if x>78 or x<1 then dx=-dx │ | ||
- | │ 50 y=y+dy:if y>22 or y<1 then dy=-dy │ | ||
- | │ 60 goto 30 │ | ||
- | └──────────────────────────────────────┘ | ||
- | Всем бы хороша эта программа, но через некоторое время в | ||
</code> | </code> | ||
+ | Поскольку количество шагов не задано, лучше использовать не цикл ''FOR'', а ''GOTO'', и координаты X и Y для ''LOCATE'' рассчитывать независимо друг от друга. Рассмотрим последовательность действий: | ||
+ | - Заведём переменные X и Y для ''LOCATE''. | ||
+ | - Заведём переменные DX и DY, которые показывают, на сколько изменяются X и Y в каждом шаге. | ||
+ | - Напечатаем слово в позиции X,Y | ||
+ | - Изменим X на DX и проверим, не зашли ли на левый или правый край экрана. Если зашли, нужно поменять DX на -DX, чтобы двигаться в противоположном направлении. | ||
+ | - Изменим Y на DY и проверим так же верхнюю и нижнюю границы экрана. | ||
+ | - Для продолжения вернёмся к п.3 и все повторим. | ||
+ | <code> | ||
+ | 10 screen 0:keyoff:width 80 | ||
+ | 20 x=10:y=10:dx=1:dy=1 | ||
+ | 30 locate x,y:print"*"; | ||
+ | 40 x=x+dx:if x>78 or x<1 then dx=-dx | ||
+ | 50 y=y+dy:if y>22 or y<1 then dy=-dy | ||
+ | 60 goto 30 | ||
+ | </code> | ||
+ | Всем бы хороша эта программа, но через некоторое время в FIXME | ||
====== Урок 7 ====== | ====== Урок 7 ====== | ||
- | <code> | ||
- | Часто бывает так, что какой-либо цикл нужно повторить нес- | ||
- | колько раз. Для этого его помещают в другой цикл. Получается | ||
- | цикл в цикле или вложенные циклы. | ||
- | Например, нужно сделать на экране 5 строк, в каждой из которых | ||
- | имеется десять чисел (1,3,5,... каждое на 2 больше предыдуще- | ||
- | го). | ||
- | ┌────────────────────────────────────────────┐ | ||
- | │ 10 screen0:width80:keyoff │ | ||
- | │ 20 for st=1 to 5 :'Изменяется номер строки │ | ||
- | │ 30 for po=1 to 10:'Изменяем номер позиции │ | ||
- | │ 40 locate po*4,st:print po*2-1; │ | ||
- | │ 50 next:next:'Закрыли оба цикла │ | ||
- | └────────────────────────────────────────────┘ | ||
- | В 40-й строке мы умножили PO на 4 в LOCATE, чтобы цифры | ||
- | располагались не подряд, а через 4 позиции (иначе слепятся). | ||
- | При изменении PO на 1 мы хотим печатать числа, которые | ||
- | отличаются на 2. Поэтому в PRINT'е увеличиваем PO в 2 раза. | ||
- | Но тогда будут числа 2,4,6,... Чтобы были 1,3,5... отнимаем 1. | ||
- | Почти так же делается таблица Пифагора (таблица умножения), в | + | Часто бывает так, что какой–либо цикл нужно повторить несколько раз. Для этого его помещают в другой цикл. Получается цикл в цикле или вложенные циклы. |
- | которой каждое число равно произведению номера строки, на | + | |
- | номер столбца, в котором оно находится. | + | |
- | ┌────────────────────────────────────────────┐ | + | |
- | │ 10 screen0:width80:keyoff │ | + | |
- | │ 20 for st=1 to 9 :'Изменяется номер строки │ | + | |
- | │ 30 for po=1 to 9 :'Изменяем номер столбца │ | + | |
- | │ 40 locate po*4,st:print po*st;:next:next │ | + | |
- | └────────────────────────────────────────────┘ | + | |
- | █ Пора, читатель, делать задания немного посложнее. Сделайте | + | Например, нужно сделать на экране 5 строк, в каждой из которых имеется десять чисел (1,3,5,… каждое на 2 больше предыдущего). |
- | █ программу, которая печатает на экране ту же таблицу | + | <code> |
- | █ Пифагора но с рамкой и заголовками сверху и слева: | + | 10 screen0:width80:keyoff |
- | █ 1 2 3 4 и т.д. | + | 20 for st=1 to 5 :'Изменяется номер строки |
- | █ ┌──────────────── | + | 30 for po=1 to 10:'Изменяем номер позиции |
- | █ 1│ 1 2 3 4 | + | 40 locate po*4,st:print po*2-1; |
- | █ 2│ 2 4 6 8 | + | 50 next:next:'Закрыли оба цикла |
- | █ 3│ 3 6 9 12 | + | </code> |
- | █ 4│ 4 8 12 16 | + | В 40–й строке мы умножили PO на 4 в ''LOCATE'', чтобы цифры располагались не подряд, а через 4 позиции (иначе слепятся). |
- | Если вы справились с этим заданием, то разберетесь в | + | При изменении PO на 1 мы хотим печатать числа, которые отличаются на 2. Поэтому в ''PRINT'' увеличиваем PO в 2 раза. Но тогда будут числа 2,4,6,… Чтобы были 1,3,5… отнимаем 1. |
- | программе, которая двигает звездочку сверху вниз в первой | + | |
- | колонке, затем сверху вниз во второй, ... | + | |
- | ┌─────────────────────────────────────┐ | + | |
- | │ 10 screen0:width80:keyoff:xs=0:ys=0 │ | + | |
- | │ 20 for x=0 to 78:for y=0 to 21 │ | + | |
- | │ 30 locate x,y:print"*";:'нарисовали │ | + | |
- | │ 40 locate xs,ys:print" ";:'стерли │ | + | |
- | │ 50 xs=x:ys=y:next:next │ | + | |
- | └─────────────────────────────────────┘ | + | |
- | В 50-й строке переназначаются xs,ys- координаты места для | + | |
- | стирания. | + | |
- | █ Вы поняли приведенный пример, если вы сумеете его переделать | + | Почти так же делается таблица Пифагора (таблица умножения), в которой каждое число равно произведению номера строки, на номер столбца, в котором оно находится. |
- | █ так, чтобы звездочки двигались горизонтально, сначала вдоль | + | <code> |
- | █ самой верхней строки, потом ниже, ниже... | + | 10 screen0:width80:keyoff |
+ | 20 for st=1 to 9 :'Изменяется номер строки | ||
+ | 30 for po=1 to 9 :'Изменяем номер столбца | ||
+ | 40 locate po*4,st:print po*st;:next:next | ||
+ | </code> | ||
+ | <WRAP box> | ||
+ | Пора, читатель, делать задания немного посложнее. Сделайте программу, которая печатает на экране ту же таблицу Пифагора но с рамкой и заголовками сверху и слева: | ||
+ | 1 2 3 4 и т.д. | ||
+ | ┌──────────────── | ||
+ | 1│ 1 2 3 4 | ||
+ | 2│ 2 4 6 8 | ||
+ | 3│ 3 6 9 12 | ||
+ | 4│ 4 8 12 16 | ||
+ | </WRAP> | ||
- | Несколько труднее сделать, чтобы звездочка сначала двигалась | + | Если вы справились с этим заданием, то разберётесь в программе, которая двигает звёздочку сверху вниз в первой колонке, затем сверху вниз во второй, … |
- | вниз, а в следующем столбце - вверх и т.д. | + | <code> |
- | ┌──────────────────────────────────────────┐ | + | 10 screen0:width80:keyoff:xs=0:ys=0 |
- | │ 10 screen0:width80:y=0:xs=0:ys=0:dy=1 │ | + | 20 for x=0 to 78:for y=0 to 21 |
- | │ 20 for x=0 to 78:for k=0 to 21:y=y+dy │ | + | 30 locate x,y:print"*";:'нарисовали |
- | │ 30 locate x,y:print"*"; │ | + | 40 locate xs,ys:print" ";:'стерли |
- | │ 40 locate xs,ys:print" "; │ | + | 50 xs=x:ys=y:next:next |
- | │ 50 xs=x:ys=y:next:dy=-dy:next │ | + | </code> |
- | └──────────────────────────────────────────┘ | + | В 50–й строке переназначаются xs,ys — координаты места для стирания. |
- | Как видите, в 20 строке К- не координата Y, а просто счетчик. | + | |
- | Y же равен вначале нулю, а в цикле меняется не на 1, как K, а | + | |
- | на DY, который (в конце 50-й строки) принимает значения либо | + | |
- | 1 (вниз), либо -1 (вверх). | + | |
- | █ Считайте, что вы поняли этот пример, а также пример со | + | <WRAP box> |
- | █ змейкой из 6-го урока, если вы сделаете в нем движение не | + | Вы поняли приведённый пример, если вы сумеете его переделать так, чтобы звёздочки двигались горизонтально, сначала вдоль самой верхней строки, потом ниже, ниже… |
- | █ одной звездочки, а змейки из звездочек. | + | </WRAP> |
- | Еще пример на вложенные циклы: Пусть программа печатает в | + | Несколько труднее сделать, чтобы звёздочка сначала двигалась вниз, а в следующем столбце — вверх и т.д. |
- | одной строке ряд чисел: 1,8,15,...,71, в следующей строке - | + | <code> |
- | ряд 2,9,16,...,72, дальше 3,10,17,...,73 и так до строки с | + | 10 screen0:width80:y=0:xs=0:ys=0:dy=1 |
- | рядом 9,16,...,79. | + | 20 for x=0 to 78:for k=0 to 21:y=y+dy |
+ | 30 locate x,y:print"*"; | ||
+ | 40 locate xs,ys:print" "; | ||
+ | 50 xs=x:ys=y:next:dy=-dy:next | ||
+ | </code> | ||
+ | Как видите, в 20 строке К — не координата Y, а просто счётчик. Y же равен вначале нулю, а в цикле меняется не на 1, как K, а на DY, который (в конце 50–й строки) принимает значения либо 1 (вниз), либо -1 (вверх). | ||
- | Первая переменная цикла (A) будет задавать номер строки, а | + | <WRAP box> |
- | тем самым- начальное значение ряда. Вторая (B) будет задавать | + | Считайте, что вы поняли этот пример, а также пример со змейкой из 6–го урока, если вы сделаете в нем движение не одной звёздочки, а змейки из звёздочек. |
- | числа в ряду и изменяться от A до A+70 с шагом 7: | + | </WRAP> |
- | ┌────────────────────────────────────────────────────┐ | + | |
- | │ 10 for a=1 to 9 │ | + | |
- | │ 20 for b=a to A+70 step 7:print b;:next:print:next │ | + | |
- | └────────────────────────────────────────────────────┘ | + | |
- | В 20-й строке пустой PRINT - чтобы перейти на новую строку. | + | |
- | + | ||
- | █ Сделайте подобную программу, чтобы она печатала такие ряды: | + | |
- | █ 1,4,7,...,34 | + | |
- | █ 4,7,10,...,37 | + | |
- | █ 7,10,13,...,40 и т.д. ... до ряда 34,37,40,...,67 | + | |
+ | Ещё пример на вложенные циклы: Пусть программа печатает в одной строке ряд чисел: 1,8,15,…,71, в следующей строке — ряд 2,9,16,…,72, дальше 3,10,17,…,73 и так до строки с рядом 9,16,…,79. | ||
+ | Первая переменная цикла (A) будет задавать номер строки, а тем самым — начальное значение ряда. Вторая (B) будет задавать числа в ряду и изменяться от A до A+70 с шагом 7: | ||
+ | <code> | ||
+ | 10 for a=1 to 9 | ||
+ | 20 for b=a to A+70 step 7:print b;:next:print:next | ||
</code> | </code> | ||
+ | В 20–й строке пустой ''PRINT'' — чтобы перейти на новую строку. | ||
+ | |||
+ | <WRAP box> | ||
+ | Сделайте подобную программу, чтобы она печатала такие ряды: | ||
+ | 1,4,7,…,34 | ||
+ | 4,7,10,…,37 | ||
+ | 7,10,13,…,40 и т.д. … до ряда 34,37,40,…,67 | ||
+ | </WRAP> | ||
====== Урок 8 ====== | ====== Урок 8 ====== | ||
+ | Представьте себе случай, когда одинаковые действия нужно выполнить для множества данных. Например, каждое из 20–ти чисел нужно увеличить в 2 раза. Ясно, что эту работу нужно делать в цикле. Для этого есть несколько способов: | ||
+ | |||
+ | Первый способ очень прост. Мы в цикле запрашиваем данные у пользователя и тут же их обрабатываем. Например, пусть программа сложит 10 чисел, введённых пользователем: | ||
<code> | <code> | ||
+ | 10 S=0:for n=1 to 10 | ||
+ | 20 input"Введите число";a | ||
+ | 30 S=S+a:next | ||
+ | 40 print "Сумма всех чисел =";S | ||
+ | </code> | ||
- | Представьте себе случай, когда одинаковые действия нужно | + | Если данные заранее известны программисту, их удобнее поместить в программу, а не запрашивать командой ''INPUT''. Делают это с помощью команд ''DATA'' (данные) и ''READ'' (читать): |
- | выполнить для множества данных. Например, каждое из 20-ти | + | После слова ''DATA'' размещаются через запятую нужные данные. |
- | чисел нужно увеличить в 2 раза. Ясно, что эту работу нужно | + | После слова ''READ'' стоит имя переменной (или несколько, через запятую), куда нужно занести очередное данное. Не обязательно все данные размещать в одной строке программы. ''DATA'' могут находиться в любом месте программы. Нужно только помнить, что ''READ'' считывают из ''DATA'', начиная с самой первой встреченной в программе и до самой последней подряд. Если команд ''READ'' больше, чем ''DATA'', то будет выдано сообщение об ошибке (OUT OF DATA — ЗА ПРЕДЕЛАМИ ДАННЫХ). Если данные считываются в цикле, то это |
- | делать в цикле. Для этого есть несколько способов: | + | значит, что число повторений больше, чем данных. |
- | Первый способ очень прост. Мы в цикле запрашиваем данные у | + | Посмотрите предыдущий пример с использованием ''READ'' и ''DATA'': |
- | пользователя и тут же их обрабатываем. Например, пусть | + | <code> |
- | программа сложит 10 чисел, введенных пользователем: | + | 10 S=0:for n=1 to 10:read a:S=S+a:next |
- | ┌─────────────────────────────────┐ | + | 20 print "Сумма всех чисел =";S |
- | │ 10 S=0:for n=1 to 10 │ | + | 30 data 1,4,23,11,4,52,4,2,5,2 |
- | │ 20 input"Введите число";a │ | + | </code> |
- | │ 30 S=S+a:next │ | + | |
- | │ 40 print "Сумма всех чисел =";S │ | + | |
- | └─────────────────────────────────┘ | + | |
- | Если данные заранее известны программисту, их удобнее | + | Нередко бывает, что данные нужно обработать вторично. Но ведь после первой обработки ''READ'' установлен на последнюю ''DATA''! |
- | поместить в программу, а не запрашивать INPUT'ом. Делают это с | + | |
- | помощью команд DATA (данные) и READ (читать): | + | |
- | После слова DATA размещаются через запятую нужные данные. | + | |
- | После слова READ стоит имя переменной (или несколько, через | + | |
- | запятую), куда нужно занести очередное данное. Не обязательно | + | |
- | все данные размещать в одной строке программы. DATA могут | + | |
- | находиться в любом месте программы. Нужно только поминить, что | + | |
- | READ'ы считывают из DATA, начиная с самой первой встреченной в | + | |
- | программе и до самой последней подряд. Если READ'ов больше, | + | |
- | чем DATA, то будет выдано сообщение об ошибке (OUT OF DATA - | + | |
- | ЗА ПРЕДЕЛАМИ ДАННЫХ). Если данные считываются в цикле, то это | + | |
- | значит, что число повторений больше, чем данных. | + | |
- | Посмотрите предыдущий пример с использованием READ и DATA: | + | Чтобы его переустановить на начало, используется команда ''RESTORE'' (переустановка). Если нужно повторить обработку данных не с самого начала программы, а с определённой строки, после ''RESTORE'' пишут номер строки, где начинаются нужные данные. |
- | ┌────────────────────────────────────────┐ | + | |
- | │ 10 S=0:for n=1 to 10:read a:S=S+a:next │ | + | |
- | │ 20 print "Сумма всех чисел =";S │ | + | |
- | │ 30 data 1,4,23,11,4,52,4,2,5,2 │ | + | |
- | └────────────────────────────────────────┘ | + | |
- | Нередко бывает, что данные нужно обработать вторично. Но ведь | + | Например, чтобы звёздочка ходила по кругу зададим ей координаты в ''DATA'', а когда опишем полную окружность, сделаем ''RESTORE'': |
- | после первой обработки READ установлен на последнюю DATA! | + | <code> |
- | Чтобы его переустановить на начало, используется команда | + | 10 color15,1,1:screen1:keyoff:xs=0:ys=0 |
- | RESTORE (переустановка). Если нужно повторить обработку данных | + | 20 for i=1 to 21: read xn,yn:locate xn,yn:print"*" |
- | не с самого начала программы, а с определенной строки, после | + | 30 locate xs,ys:print" ";:xs=xn:ys=yn:next |
- | RESTORE пишут номер строки, где начинаются нужные данные. | + | 40 restore:goto20 |
+ | 50 data 29,11, 29,14, 27,17, 25,19, 23,20, 20,21, 17,21 | ||
+ | 60 data 14,20, 12,18, 10,15, 9,12, 9,9, 10,7, 12,4 | ||
+ | 70 data 14,2, 17,1, 20,1, 23,2, 25,3, 27,5, 29,8 | ||
+ | </code> | ||
+ | Здесь одним ''READ'' читаем 2 данных XN и YN. Старые координаты (для стирания) держим в переменных XS,YS. | ||
+ | Кстати, ''SCREEN1'' в этом фрагменте выбран из тех соображений, что в нем каждое знакоместо — квадрат. В ''screen 0'' окружность превращается в эллипс, так как знакоместо заужено по X. | ||
- | Например, чтобы звездочка ходила по кругу зададим ей координа- | + | В качестве следующего примера, где ''READ'' читает не только числовые, но и текстовые величины, приведу программу медленной (буква за буквой) печати текстов, которые записаны в ''DATA'': |
- | ты в DATA, а когда опишем полную окружность, сделаем RESTORE: | + | <code> |
- | ┌────────────────────────────────────────────────────────┐ | + | 10 screen0:width80:keyoff |
- | │ 10 color15,1,1:screen1:keyoff:xs=0:ys=0 │ | + | 20 read n:'Взяли количество строк |
- | │ 20 for i=1 to 21: read xn,yn:locate xn,yn:print"*" │ | + | 30 for i=1 to n:read a$:'Взяли текст строки |
- | │ 30 locate xs,ys:print" ";:xs=xn:ys=yn:next │ | + | 40 for k=1 to len(a$):b$=mid$(a$,k,1):'взяли букву |
- | │ 40 restore:goto20 │ | + | 50 print b$;:fork=0to50:next:'поставили букву и задержались |
- | │ 50 data 29,11, 29,14, 27,17, 25,19, 23,20, 20,21, 17,21│ | + | 60 next:d$=input$(1):'Написали строку. Ждем нажатия клавиши |
- | │ 60 data 14,20, 12,18, 10,15, 9,12, 9,9, 10,7, 12,4 │ | + | 70 print:next:'перевели строку и повторим со следующей |
- | │ 70 data 14,2, 17,1, 20,1, 23,2, 25,3, 27,5, 29,8�│�� | + | 80 print:print"Дo свидания":end:'Закончив, попрощались |
- | └────────────────────────────────────────────────────────┘ | + | 90 '---------------- сам текст ----------------------- |
- | Здесь одним READ'ом читаем 2 данных XN и YN. Старые координаты | + | 100 data 4,"Однажды, в студеную зимнюю пору" |
- | (для стирания) держим в переменных XS,YS. | + | 110 data "Я из лесу вышел, был сильный мороз." |
- | Кстати, SCREEN1 в этом фрагменте выбран из тех соображений, | + | 120 data "Гляжу, поднимается медленно в гору" |
- | что в нем каждое знакоместо- квадрат. В screen 0 окружность | + | 130 data "Лошадка, везущая хворосту воз." |
- | превращается в эллипс, так как знакоместо заужено по X. | + | </code> |
+ | Вы поняли, для чего стоит 4 в 100–й строке? Правильно, для первого ''READ''. | ||
- | В качестве следующего примера, где READ читает не только | + | ''READ'' и ''DATA'' — очень удобны, но лишь в тех нечастых случаях, когда все данные нужно читать и обрабатывать подряд. А как быть, когда надо через одно? А если с конца в начало? |
- | числовые, но и текстовые величины, приведу программу медленной | + | |
- | (буква за буквой) печати текстов, которые записаны в DATA: | + | |
- | ┌────────────────────────────────────────────────────────────┐ | + | |
- | │ 10 screen0:width80:keyoff │ | + | |
- | │ 20 read n:'Взяли количество строк │ | + | |
- | │ 30 for i=1 to n:read a$:'Взяли текст строки │ | + | |
- | │ 40 for k=1 to len(a$):b$=mid$(a$,k,1):'взяли букву │ | + | |
- | │ 50 print b$;:fork=0to50:next:'поставили букву и задержались│ | + | |
- | │ 60 next:d$=input$(1):'Написали строку. Ждем нажатия клавиши│ | + | |
- | │ 70 print:next:'перевели строку и повторим со следующей │ | + | |
- | │ 80 print:print"Дo свидания":end:'Закончив, попрощались │ | + | |
- | │ 90 '---------------- сам текст ----------------------- │ | + | |
- | │ 100 data 4,"Однажды, в студеную зимнюю пору" │ | + | |
- | │ 110 data "Я из лесу вышел, был сильный мороз." │ | + | |
- | │ 120 data "Гляжу, поднимается медленно в гору" │ | + | |
- | │ 130 data "Лошадка, везущая хворосту воз." │ | + | |
- | └────────────────────────────────────────────────────────────┘ | + | |
- | Вы поняли, для чего стоит 4 в 100-й строке?Правильно, для | + | |
- | первого READ'а. | + | |
- | READ и DATA - очень удобны, но лишь в тех нечастых случаях, | + | Во многих задачах вас выручат массивы. Массив — это табличка в памяти, где хранятся пронумерованные данные. У массива есть имя. Например, массив А. Но в отличие от переменной с именем А, в массиве под этим именем хранится не одно число, а несколько. |
- | когда все данные нужно читать и обрабатывать подряд. А как | + | |
- | быть, когда надо через одно? А если с конца в начало? | + | |
- | Во многих задачах вас выручат массивы. Массив - это табличка в | + | По имени массива и номеру можно получить любое данное. Например, если мы хотим напечатать 20–е число из массива WWW, то мы напишем: ''print www(20)'' . Для того, чтобы запомнить число в нужное место массива, нужно как и с переменной использовать присваивание: ''www(20)=62.11''. Номер элемента массива может быть записан не только числом, но и переменной, в которой находится это число. Это позволяет использовать массив в цикле, где индекс (номер в скобках) меняет своё значение. Например, посмотрите, как выполняется такая задача: программа получает от пользователя 10 чисел, а затем печатает их в строку в обратном порядке: |
- | памяти, где хранятся пронумерованные данные. У массива есть | + | <code> |
- | имя. Например, массив А. Но в отличие от переменной с именем А, | + | 10 dim a(9) |
- | в массиве под этим именем хранится не одно число, а несколько. | + | 20 for i=0 to 9:input a(i):next |
- | По имени массива и номеру можно получить любое данное. | + | 30 for i=9 to 0 step -1:print a(i):next |
- | Например, если мы хотим напечатать 20-е число из массива WWW, | + | </code> |
- | то мы напишем: print www(20) . Для того, чтобы запомнить число | + | Как видите, программа несложная. Остаются неясными детали: В 10–й строке стоит команда ''DIM'', которая объявляет номер последнего элемента массива. С этого момента Бейсик зарезервировал 10 (от 0 до 9) элементов и заполнил их нулями. В 20–строке вместо нулей мы ''INPUT'' заносим новые значения, а в |
- | в нужное место массива, нужно как и с переменной использовать | + | 30–й строке печатаем в обратном порядке. |
- | присваивание: www(20)=62.11. Номер элемента массива может быть | + | |
- | записан не только числом, но и переменной, в которой находится | + | |
- | это число. Это позволяет использовать массив в цикле, где | + | |
- | индекс (номер в скобках) меняет свое значение. Например, | + | |
- | посмотрите, как выполняется такая задача: программа получает | + | |
- | от пользователя 10 чисел, а затем печатает их в строку в | + | |
- | обратном порядке: | + | |
- | ┌─────────────────────────────────────────┐ | + | |
- | │ 10 dim a(9) │ | + | |
- | │ 20 for i=0 to 9:input a(i):next │ | + | |
- | │ 30 for i=9 to 0 step -1:print a(i):next │ | + | |
- | └─────────────────────────────────────────┘ | + | |
- | Как видите, программа несложная. Остаются неясными детали: В | + | |
- | 10-й строке стоит команда DIM, которая объявляет номер | + | |
- | последнего элемента массива. С этого момента Бейсик зарезерви- | + | |
- | ровал 10 (от 0 до 9) элементов и заполнил их нулями. В 20-й | + | |
- | строке вместо нулей мы INPUT'ом заносим новые значения, а в | + | |
- | 30-й строке печатаем в обратном порядке. | + | |
- | Если программа попытается использовать элемент массива с номе- | + | Если программа попытается использовать элемент массива с номером, большим, чем объявлено в ''DIM'', то Бейсик сообщит об ошибке: "SUBSCRIPT OUT OF RANGE" или "ИНДЕКС ЗА ПРЕДЕЛАМИ РЯДА". |
- | ром, большим, чем объявлено в DIM, то Бейсик сообщит об | + | |
- | ошибке: "SUBSCRIPT OUT OF RANGE" или "ИНДЕКС ЗА ПРЕДЕЛАМИ РЯДА". | + | |
- | Составим такую программу: программа заносит из DATA в массив | + | Составим такую программу: программа заносит из ''DATA'' в массив 10 чисел и печатает в одну строку на экран, а затем все чётные делит на 2 и снова весь массив печатает на экран одной строкой. |
- | 10 чисел и печатает в одну строку на экран, а затем все четные | + | <code> |
- | делит на 2 и снова весь массив печатает на экран одной строкой. | + | 10 dim a(9) |
- | ┌──────────────────────────────────────────────────┐ | + | 20 for n=0 to 9:read a(n):print a(n);:next |
- | │ 10 dim a(9) │ | + | 30 for n=0 to 9:if a(n) mod 2=0 then a(n)=a(n)/2 |
- | │ 20 for n=0 to 9:read a(n):print a(n);:next │ | + | 40 print a(n);:next |
- | │ 30 for n=0 to 9:if a(n) mod 2=0 then a(n)=a(n)/2 │ | + | 50 data 1,4,23,11,4,52,4,2,5,2 |
- | │ 40 print a(n);:next │ | + | </code> |
- | │ 50 data 1,4,23,11,4,52,4,2,5,2 │ | + | |
- | └──────────────────────────────────────────────────┘ | + | |
- | В 30-й строке проверяется, четное ли число ( для четных | + | В 30–й строке проверяется, чётное ли число (для чётных остаток от деления на 2 равен 0 ). Если чётное, то делим на 2. |
- | остаток от деления на 2 равен 0 ). Если четное, то делим на 2. | + | В 40–й строчке печатается a(n), независимо от того, делили его на 2 или нет. |
- | В 40-й строчке печатается a(n), независимо от того, делили его | + | У вас может возникнуть вопрос: почему в 40–й строке после окончания печати не стоит команда END? Дело в том, что когда окончится цикл, программа перейдёт на последнюю, 50–ю строку, и, ничего не сделав, закончится. (Команда ''DATA'' не выполняет никаких действий. Она просто хранит данные для ''READ''. Поэтому команды ''DATA'' можно размещать в любом месте программы.) |
- | на 2 или нет. | + | |
- | У вас может возникнуть вопрос: почему в 40-й строке после | + | |
- | окончания печати не стоит команда END? Дело в том, что когда | + | |
- | окончится цикл, программа перейдет на последнюю, 50-ю строку, | + | |
- | и, ничего не сделав, закончится. (Команда DATA не выполняет | + | |
- | никаких действий. Она просто хранит данные для READ. Поэтому | + | |
- | DAT'ы можно размещать в любом месте программы.) | + | |
- | Попробуем с помощью массивов улучшить программу, в которой | + | Попробуем с помощью массивов улучшить программу, в которой звёздочка движется по кругу. Занесём координаты в массив. |
- | звездочка движется по кругу. Занесем координаты в массив. | + | Обращение к массиву происходит быстрее, чем ''READ'', поэтому движение ускорится. Кроме того, можно пустить звёздочку в обратном направлении: |
- | Обращение к массиву происходит быстрее, чем READ, поэтому | + | <code> |
- | движение ускорится. Кроме того, можно пустить звездочку в | + | 10 color15,1,1:screen1:keyoff:xs=0:ys=0 |
- | обратном направлении: | + | 20 for i=1 to 21: read x(i),y(i):next |
- | ┌────────────────────────────────────────────────────────┐ | + | 30 for i=21 to 1 step -1:locate x(i),y(i):print"*" |
- | │ 10 color15,1,1:screen1:keyoff:xs=0:ys=0 │ | + | 40 locate xs,ys:print" ";:xs=x(i):ys=y(i):next |
- | │ 20 for i=1 to 21: read x(i),y(i):next │ | + | 50 goto20 |
- | │ 30 for i=21 to 1 step -1:locate x(i),y(i):print"*" │ | + | 60 data 29,11, 29,14, 27,17, 25,19, 23,20, 20,21, 17,21 |
- | │ 40 locate xs,ys:print" ";:xs=x(i):ys=y(i):next │ | + | 70 data 14,20, 12,18, 10,15, 9,12, 9,9, 10,7, 12,4 |
- | │ 50 goto20 │ | + | 80 data 14,2, 17,1, 20,1, 23,2, 25,3, 27,5, 29,8 |
- | │ 60 data 29,11, 29,14, 27,17, 25,19, 23,20, 20,21, 17,21│ | + | </code> |
- | │ 70 data 14,20, 12,18, 10,15, 9,12, 9,9, 10,7, 12,4 │ | + | |
- | │ 80 data 14,2, 17,1, 20,1, 23,2, 25,3, 27,5, 29,8�│�� | + | |
- | └────────────────────────────────────────────────────────┘ | + | |
- | Если обойтись без FOR в 30 строке, сделать цикл по старинке, с | + | Если обойтись без ''FOR'' в 30 строке, сделать цикл по старинке, с помощью ''GOTO'', то можно организовать одновременное движение двух звёздочек по– и против часовой стрелки: |
- | помощью GOTO, то можно организовать одновременное движение | + | <code> |
- | двух звездочек по- и против часовой стрелки: | + | 10 color15,1,1:screen1:keyoff:x1=0:y1=0:x2=0:y2=0 |
- | ┌─────────────────────────────────────────────────────────┐ | + | 20 dim x(21),y(21):for t=1 to 21: read x(t),y(t):next |
- | │ 10 color15,1,1:screen1:keyoff:x1=0:y1=0:x2=0:y2=0 │ | + | 30 t=1:k=21 |
- | │ 20 dim x(21),y(21):for t=1 to 21: read x(t),y(t):next │ | + | 40 locate x(t),y(t):print"*";:locate x1,y1:print" "; |
- | │ 30 t=1:k=21 │ | + | 50 x1=x(t):y1=y(t):t=t+1:if t=22 then t=1 |
- | │ 40 locate x(t),y(t):print"*";:locate x1,y1:print" "; │ | + | 60 locate x(k),y(k):print"Ш";:locate x2,y2:print" "; |
- | │ 50 x1=x(t):y1=y(t):t=t+1:if t=22 then t=1 │ | + | 70 x2=x(k):y2=y(k):k=k-1:if k=1 then k=21 |
- | │ 60 locate x(k),y(k):print"Ш";:locate x2,y2:print" "; │ | + | 80 goto40 |
- | │ 70 x2=x(k):y2=y(k):k=k-1:if k=1 then k=21 │ | + | 90 data 29,11, 29,14, 27,17, 25,19, 23,20, 20,21, 17,21 |
- | │ 80 goto40 │ | + | 100 data 14,20, 12,18, 10,15, 9,12, 9,9, 10,7, 12,4 |
- | │ 90 data 29,11, 29,14, 27,17, 25,19, 23,20, 20,21, 17,21│ | + | 110 data 14,2, 17,1, 20,1, 23,2, 25,3, 27,5, 29,8 |
- | │ 100 data 14,20, 12,18, 10,15, 9,12, 9,9, 10,7, 12,4 │ | + | </code> |
- | │ 110 data 14,2, 17,1, 20,1, 23,2, 25,3, 27,5, 29,8�│�� | + | Надеюсь, без объяснений понятно, как 50–й строке делают, чтобы дойдя до 21 переменная t снова стала =1, а в 70–й строке k, дойдя до 1 снова становится =21. |
- | └─────────────────────────────────────────────────────────┘ | + | В строке 60 использована "Ш", а не "*", чтобы в разные стороны двигались разные фигуры. |
- | Надеюсь, без объяснений понятно, как в 50-й строке делают, | + | |
- | чтобы дойдя до 21 переменная t снова стала =1, а в 70-й строке | + | |
- | k, дойдя до 1 снова становится =21. | + | |
- | В строке 60 использована "Ш", а не "*", чтобы в разные стороны | + | |
- | двигались разные фигуры. | + | |
Переменные x1,y1 и x2,y2 хранят координаты места для стирания. | Переменные x1,y1 и x2,y2 хранят координаты места для стирания. | ||
- | █ Довольно простым заданием будет внести в эту программу | + | <WRAP box> |
- | █ такие изменения, чтобы звездочки двигались не по окружности, | + | Довольно простым заданием будет внести в ту программу такие изменения, чтобы звёздочки двигались не по окружности, а по другой траектории. Для этого нужно изменить координаты положений звёздочки в строках 90–110. Если при этом точек станет больше, то изменится количество пар координат. |
- | █ а по другой траектории. Для этого нужно изменить координаты | + | |
- | █ положений звездочки в строках 90-110. Если при этом | + | |
- | █ точек станет больше, то изменится количество пар координат. | + | |
- | █ Не забудьте внести изменения в строки 20,30,50,70, где это | + | |
- | █ количество учитывается. | + | |
+ | Не забудьте внести изменения в строки 20,30,50,70, где это количество учитывается. | ||
+ | </WRAP> | ||
- | Массивы можно, конечно, использовать не только для координат, | ||
- | но и для хранения любых других данных. Попробуем с помощью | ||
- | массивов составить личный телефонный справочник. В массиве | ||
- | FA$(9) будем держать фамилии 10-ти друзей. В массиве NO(9) | ||
- | будем держать их телефоны. Программа попросит ввести фамилию, | ||
- | разыщет ее в массиве FA$ и по тому же индексу из массива NO | ||
- | возьмет телефонный номер. Вы, конечно же, будете использовать | ||
- | не 10, а нужное вам число друзей и настоящие их фамилии с те- | ||
- | лефонами: | ||
- | ┌───────────────────────────────────────────────────────┐ | ||
- | │ 10 dim fa$(9),no(9) │ | ||
- | │ 20 for k=0 to 9:read fa$(k),no(k):next │ | ||
- | │ 30 input "Введите фамилию";f$ │ | ||
- | │ 40 for k=0 to 9:if f$=fa$(k) then 60 │ | ||
- | │ 50 next:print"Нет в справочнике!":goto 30 │ | ||
- | │ 60 print"Телефон ";no(k):goto 30 │ | ||
- | │ 70 data Петров,29045,Коваль,23433,Павлов,23321 │ | ||
- | │ 80 data Сурков,21412,Моргунов,29981,Мышкин,24337 │ | ||
- | │ 90 data Ауль,22221,Монахов,27725,Робов,21111,Пак,23324│ | ||
- | └───────────────────────────────────────────────────────┘ | ||
- | В 20-й строке заполнили массивы из DATA. Обратите внимание, в | ||
- | DATA фамилии не стоят в кавычках. Это допускается с текстами | ||
- | только в случае, если текст состоит из одного слова без | ||
- | запятых или других знаков. В иных случаях текст в DATA должен | ||
- | заключаться в кавычки. | ||
- | В 40-й строке в цикле просматриваем все фамилии из массива, и | ||
- | если найдем совпадающую с введенной фамилией, то переходим на | ||
- | строку 50, где печатаем телефон из массива no с таким же | ||
- | индексом K, как и найденная фамилия. Если же фамилию в массиве | ||
- | не нашли, то после окончания цикла сработает print из 50-й | ||
- | строки. | ||
- | █ Сделайте программу, которая спрашивает название школьного | + | Массивы можно, конечно, использовать не только для координат, но и для хранения любых других данных. |
- | █ предмета и печатает имя-отчество преподавателя. | + | |
- | Сделаем программу "Электронный продавец", используя массивы. | + | Попробуем с помощью массивов составить личный телефонный справочник. В массиве |
- | Это поможет упростить нахождение цены купленного продукта, | + | FA$(9) будем держать фамилии 10–ти друзей. В массиве NO(9) будем держать их телефоны. Программа попросит ввести фамилию, разыщет её в массиве FA$ и по тому же индексу из массива NO возьмёт телефонный номер. Вы, конечно же, будете использовать не 10, а нужное вам число друзей и настоящие их фамилии с телефонами: |
- | уменьшит объем программы при большем количестве предлагаемых | + | <code> |
- | товаров: | + | 10 dim fa$(9),no(9) |
- | ┌───────────────────────────────────────────────────────┐ | + | 20 for k=0 to 9:read fa$(k),no(k):next |
- | │ 10 color15,1:screen0:keyoff:width80:s=0 │ | + | 30 input "Введите фамилию";f$ |
- | │ 20 read kol:dim towar$(kol),cena(kol) │ | + | 40 for k=0 to 9:if f$=fa$(k) then 60 |
- | │ 30 for k=1 to kol:read towar$(k),cena(k):next │ | + | 50 next:print"Нет в справочнике!":goto 30 |
- | │ 40 '----- прочли данные ------ начинаем цикл ----- │ | + | 60 print"Телефон ";no(k):goto 30 |
- | │ 50 cls:print "М Е Н Ю:" │ | + | 70 data Петров,29045,Коваль,23433,Павлов,23321 |
- | │ 60 for k=1 to kol:locate 0,k+1:print k;towar$(k); │ | + | 80 data Сурков,21412,Моргунов,29981,Мышкин,24337 |
- | │ 70 locate 30,k+1:print cena(k);:next │ | + | 90 data Ауль,22221,Монахов,27725,Робов,21111,Пак,23324 |
- | │ 80 locate30,21:input"Введите выбранный номер";n │ | + | </code> |
- | │ 90 locate30,21:print" "; │ | + | В 20–й строке заполнили массивы из ''DATA''. Обратите внимание, в ''DATA'' фамилии не стоят в кавычках. Это допускается с текстами только в случае, если текст состоит из одного слова без запятых или других знаков. В иных случаях текст в ''DATA'' должен заключаться в кавычки. |
- | │ 100 locate30,21:input"Сколько штук берете";t │ | + | |
- | │ 110 s=s+t*cena(n) │ | + | |
- | │ 120 locate30,21:print" "; │ | + | |
- | │ 130 locate30,21:input"Будем продолжать (да/нет)";yes$ │ | + | |
- | │ 140 if yes$="да" or yes$="ДА" or yes$="Да" then 50 │ | + | |
- | │ 150 print "Общая сумма";s;"руб. Заплатите в кассу!" │ | + | |
- | │ 160 data 5 │ | + | |
- | │ 170 data "журнал <Мурзилка>",40,"аквариум",400 │ | + | |
- | │ 180 data "булочка с изюмом",45,"джинсы",17000 │ | + | |
- | │ 190 data "шоколад <milki way>",250 │ | + | |
- | └───────────────────────────────────────────────────────┘ | + | |
- | В работе программиста с массивами часто необходимо найти | + | В 40–й строке в цикле просматриваем все фамилии из массива, и если найдём совпадающую с введённой фамилией, то переходим на строку 50, где печатаем телефон из массива no с таким же индексом K, как и найденная фамилия. Если же фамилию в массиве не нашли, то после окончания цикла сработает ''print'' из 50–й строки. |
- | максимальный (минимальный) элемент массива, упорядочить | + | |
- | (отсортировать) массив по возрастанию (убыванию), по алфавиту | + | |
- | (для текстового массива). Поучимся это делать: | + | |
- | Найдем максимальный элемент массива. (Заполнить массив из DATA | + | <WRAP box> |
- | или случайными числами я предоставляю самому читателю. Для | + | Сделайте программу, которая спрашивает название школьного предмета и печатает имя–отчество преподавателя. |
- | этого отводятся строки 20-40) | + | </WRAP> |
- | Чтобы найти максимальный элемент, мы заведем переменную MA, | + | |
- | куда вначале поместим 0-й элемент из массива. Просмотим по | + | |
- | очереди все остальные элементы, и если встретится больший MA, | + | |
- | запомним в MA уже его. Таким образом, просмотрев весь массив, | + | |
- | мы будем иметь в MA максимальный элемент: | + | |
- | ┌──────────────────────────────────────────┐ | + | |
- | │ 10 dim a(19) │ | + | |
- | │ . . . │ | + | |
- | │ 50 ma=a(0) │ | + | |
- | │ 60 for k=1 to 19:if a(k)>ma then ma=a(k) │ | + | |
- | │ 70 next:print"Максимум=";ma │ | + | |
- | └──────────────────────────────────────────┘ | + | |
- | Иногда нужно найти не только максимальное число в массиве, но | + | Сделаем программу "Электронный продавец", используя массивы. |
- | и узнать его номер.(Прежде, чем смотреть решение, попытайтесь | + | Это поможет упростить нахождение цены купленного продукта, уменьшит объем программы при большем количестве предлагаемых товаров: |
- | это сделать сами.) | + | <code> |
+ | 10 color15,1:screen0:keyoff:width80:s=0 | ||
+ | 20 read kol:dim towar$(kol),cena(kol) | ||
+ | 30 for k=1 to kol:read towar$(k),cena(k):next | ||
+ | 40 '----- прочли данные ------ начинаем цикл ----- | ||
+ | 50 cls:print "М Е Н Ю:" | ||
+ | 60 for k=1 to kol:locate 0,k+1:print k;towar$(k); | ||
+ | 70 locate 30,k+1:print cena(k);:next | ||
+ | 80 locate30,21:input"Введите выбранный номер";n | ||
+ | 90 locate30,21:print" "; | ||
+ | 100 locate30,21:input"Сколько штук берете";t | ||
+ | 110 s=s+t*cena(n) | ||
+ | 120 locate30,21:print" | ||
+ | 130 locate30,21:input"Будем продолжать (да/нет)";yes$ | ||
+ | 140 if yes$="да" or yes$="ДА" or yes$="Да" then 50 | ||
+ | 150 print "Общая сумма";s;"руб. Заплатите в кассу!" | ||
+ | 160 data 5 | ||
+ | 170 data "журнал <Мурзилка>",40,"аквариум",400 | ||
+ | 180 data "булочка с изюмом",45,"джинсы",17000 | ||
+ | 190 data "шоколад <milki way>",250 | ||
+ | </code> | ||
- | Для этого заведем переменную N, куда вначале занесем номер | + | В работе программиста с массивами часто необходимо найти максимальный (минимальный) элемент массива, упорядочить (отсортировать) массив по возрастанию (убыванию), по алфавиту (для текстового массива). Поучимся это делать: |
- | 0-го элемента, а при обновлении MA будем запоминать новый | + | |
- | номер (k): | + | Найдём максимальный элемент массива. (Заполнить массив из ''DATA'' или случайными числами я предоставляю самому читателю. Для этого отводятся строки 20–40) |
- | ┌──────────────────────────────────────────────┐ | + | |
- | │ 10 dim a(19) │ | + | Чтобы найти максимальный элемент, мы заведём переменную MA, куда вначале поместим 0–й элемент из массива. Просмотрим по очереди все остальные элементы, и если встретится больший MA, запомним в MA уже его. Таким образом, просмотрев весь массив, мы будем иметь в MA максимальный элемент: |
- | │ . . . │ | + | <code> |
- | │ 50 ma=a(0):n=0 │ | + | 10 dim a(19) |
- | │ 60 for k=1 to 19:if a(k)>ma then ma=a(k):n=k │ | + | … |
- | │ 70 next:print"Максимум=";ma;"по номеру";n │ | + | 50 ma=a(0) |
- | └──────────────────────────────────────────────┘ | + | 60 for k=1 to 19:if a(k)>ma then ma=a(k) |
+ | 70 next:print"Максимум=";ma | ||
</code> | </code> | ||
+ | Иногда нужно найти не только максимальное число в массиве, но и узнать его номер.(Прежде, чем смотреть решение, попытайтесь это сделать сами.) | ||
+ | |||
+ | Для этого заведём переменную N, куда вначале занесём номер 0–го элемента, а при обновлении MA будем запоминать новый номер (k): | ||
+ | <code> | ||
+ | 10 dim a(19) | ||
+ | … | ||
+ | 50 ma=a(0):n=0 | ||
+ | 60 for k=1 to 19:if a(k)>ma then ma=a(k):n=k | ||
+ | 70 next:print"Максимум=";ma;"по номеру";n | ||
+ | </code> | ||
====== Ссылки ====== | ====== Ссылки ====== | ||
Строка 1377: | Строка 1014: | ||
- | {{tag>MSX BASIC Book}} | + | {{tag>MSX BASIC}} |