ГА ЗВЕНИГОРОДСКИЙ ПЕРВЫЕ УРОКИ...

143
ГА. ЗВЕНИГОРОДСКИЙ ПЕРВЫЕ УРОКИ ПРОГРАММИРОВАНИЯ

Transcript of ГА ЗВЕНИГОРОДСКИЙ ПЕРВЫЕ УРОКИ...

ГА. ЗВЕНИГОРОДСКИЙ ПЕРВЫЕ УРОКИ ПРОГРАММИРОВАНИЯ

ПРЕДИСЛОВИЕ РЕДАКТОРА До самого последнего времени программирование для электронных

вычислительных машин (ЭВМ) было занятием для взрослых. Это не значит, что о про-граммировании не писали для школьников. Тем не менее и несколько страниц учебника, и пособия для факультативов, и популярные брошюры лишь приоткрывали завесу над этим таинственным делом, а если материал изучался развернуто, то это делалось по-взрослому, решительно выводя читателя за пределы школьной обстановки.

Книга Г. А. Звенигородского в этом смысле обладает рядом особенностей. Во-первых, это первая известная мне книга по программированию, написанная

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

Тем временем было опубликовано постановление о проведении школьной реформы*), в которой среди пяти важнейших направлений повышения качества учебно-воспитательного процесса было названо следующее:

«— вооружать учащихся знаниями и навыками использования современной вычислительной техники, обеспечить широкое применение компьютеров в учебном процессе, создавать для этого специальные школьные и межшкольные кабинеты».

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

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

Когда эта книга уже была подготовлена для сдачи в производство, ее автор, младший научный сотрудник Вычислительного центра Сибирского отделения АН СССР Геннадий Анатольевич Звенигородский, скончался на 33-м году жизни от внезапной тяжелой болезни. Он не дожил нескольких месяцев до завершения возглавляемой им разработки системы Школьница, которая воплощает подход к программированию, описанный в этой книге.

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

ОТ АВТОРА

В основу этой книги положены материалы Заочной школы программирования, публиковавшиеся в журнале «Квант» начиная с № 9 за 1979 год, и учебного пособия «Основные понятия программирования», выпускавшегося Новосибирским университетом для районной школы юных программистов в 1978 и 1979 годах.

Книга адресована прежде всего школьникам пятых-восьмых классов, желающим познакомиться с элементарными основами современного программирования. Она может быть полезна и старшеклассникам, учащимся профессионально-технических училищ и межшкольных учебно-производственных комбинатов и другим категориям читателей. Для таких читателей стиль книги может показаться несколько упрощенным, а темп изложения — чересчур замедленным, за что автор заранее просит у них прощения.

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

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

"Эта книга — не учебник, но она не предназначена и для развлекательного чтения. Возможно, дочитав последнюю главу этой книги, будут разочарованы те школьники, которые хотели бы сразу научиться составлять программы для решения школьных задач по математике и по другим предметам. Для таких читателей нужна другая книга, которая помогала бы им сделать следующий шаг в освоении вычислительной техники. А эта книга предназначена для тех, кто хочет на простых примерах подготовиться к решению настоящих, больших и сложных задач на современных вычислительных машинах. Книга может быть использована и для организации кружковых занятий со школьниками любого возраста. Как показывает опыт Харьковской и Новосибирской Школ юных программистов, материал первых уроков доступен ученикам вторых — третьих классов, занимающихся под руководством преподавателя.

Несколько замечаний для профессиональных программистов и преподавателей программирования. Изложение в этой книге ведется на примере учебного языка Робик — одного из входных языков системы программирования Школьница, разработанной автором в Вычислительном центре Сибирского отделения АН СССР и реализованной под его руководством на персональных ЭВМ Агат, предназначенных для использования в школах и других учебных заведениях.

Реализация системы в короткие сроки осуществлена молодежным коллективом, основу которого составили студенты Новосибирского университета Н. Г. Глаголева, Е. В. Налимов и В. А. Цикоза и школьники П. А. Земцов (9 класс) и Л. Р. Рабинович (7 класс). Все они учились программированию по методике, изложенной в этой книге. А всего по этой методике к началу 1984 года обучалось свыше трех тысяч школьников.

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

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

Чтобы компенсировать некоторую потерю наглядности, связанную с исключением блок-схем, подробно рассматриваются синтаксические диаграммы в качестве средства описания синтаксиса.

Разумеется, на том же материале возможны и другие методические схемы: например, циклы и ветвления могут быть рассмотрены раньше процедур. Г. А. Звенигородский

ВВЕДЕНИЕ

МИР РОБОТОВ И ВЫЧИСЛИТЕЛЬНЫХ МАШИН В середине двадцатого века произошли события, от которых начинается

отсчет эры освоения космоса и мирного использования атомной энергии. 4 октября 1957 года по всем, радиостанциям Советского Союза было передано

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

27 июня 1954 года в городе Обнинске Калужской области начала работать первая в мире атомная электростанция. Все газеты сообщали: энергия атомного ядра впервые обрела мирную профессию, и каждому было ясно, какие перспективы это от-крывает перед человечеством.

А вот о событии, которое произошло 25 декабря 1951 года, известно меньше. Да и сегодня, наверное, только специалисты понимают, как много значил этот день и для космонавтики, и для ядерной физики, и для многих других отраслей. В. этот день в Институте электротехники Академии наук Украинской ССР вступила в строй МЭСМ — первая в СССР электронная вычислительная машина (ЭВМ), разработанная под руководством академика Сергея Алексеевича Лебедева.

Что она умела? Несмотря на скромное название (МЭСМ означает Малая Электронно-Счетная Машина), выглядела она довольно внушительно. Машина занимала площадь 50 м2 (как трехкомнатная квартира), потребляла электроэнергии 25 кВт, а радиоламп в ней было больше шести тысяч — неслыханное по тому времени количество.

И все это огромное сооружение могло выполнять арифметические действия над 5-6-значными числами со скоростью около 50 операций в секунду. Много это или мало?

Попробуй проверить это сам. Отложи ненадолго книгу, возьми карандаш и бумагу, заметь время и попробуй сложить десяток-другой шестизначных чисел. Теперь несложно определить, сколько времени ушло у тебя в среднем на одно сложение. Ско-рее всего, получится от 10 до 30 с. А умножение займет, вероятно, не меньше минуты. Получается, что первая наша машина считала примерно в полторы тысячи раз быстрее, чем человек, вычисляющий вручную.

Вторая советская вычислительная машина — БЭСМ (Быстродействующая Электронно-Счетная Машина), вступившая в строй два года спустя, работала еще в двести раз быстрее. С ее помощью были решены многие задачи, которые еще в соро-ковые годы считались неразрешимыми из-за огромного объема вычислений.

Среди первых советских программистов были: Президент Академии наук СССР, Главный теоретик космонавтики, академик Мстислав Всеволодович Келдыш и один из основателей Сибирского отделения АН СССР, академик Михаил Алексеевич Лаврентьев. И на первых наших ЭВМ рассчитывались , траектории первых спутников и лунников. Можно представить, сколько времени и труда ушло бы на эти расчеты, если бы они выполнялись вручную.

Уильям Шенкс и другие. В 1873 году английский математик Уильям Шенкс завершил титанический труд по вычислению семисот с лишним десятичных цифр числа π. До 1853 года это число было известно с точностью до 208 знака. За двадцать лет paботы Шенкс получил 707 десятичных цифр. Если напечатать их в этой книге, то они займут примерно треть страницы.

По просьбе Шенкса эти цифры были изображены на его надгробии. А впоследствии выяснилось, что только 519 из них были определены правильно. Математик ошибся при вычислении 520-й цифры, и поэтому все последующие тоже

оказались неправильными. Тем не менее, результат Уильяма Шенкса навсегда вошел в историю математики как пример огромной вычислительной работы, как итог величайшего трудолюбия и настойчивости, преданности своему делу, скрупулезной точности расчетов.

В 1981 году девятиклассник из города Арзамаса Сергей Баталов вычислил более 50 тысяч знаков числа π, потратив на это немногим более часа. Никакой сенсации в научном мире этот результат не произвел. Дело в том, что Сергей пользовался для своих расчетов электронной вычислительной машиной БЭСМ-6, выполняющей более миллиона арифметических операций в секунду. Если бы Уильям Шенкс попробовал вручную вычислить π с такой точностью, ему бы понадобилось не меньше двухсот тысяч лет! Понятно, что до появления ЭВМ такая задача была абсолютно неразрешимой. Нетрудно подсчитать, что БЭСМ-6, решая эту задачу, работала в полтора миллиарда раз быстрее, чем один из самых квалифицированных математиков-вычислителей прошлого века.

Уже самые первые вычислительные машины позволили получить две тысячи знаков π. А в 1961 году было вычислено 100000 знаков (за 9 часов работы ЭВМ), так что результат Сергея Баталова был интересен только тем, что эту сложную математи-ческую задачу впервые решил школьник, и притом совершенно самостоятельно (за эту работу Сергей был награжден дипломом первой степени на Всесоюзном конкурсе школьных работ по программированию).

Сегодня уже известно свыше полумиллиона знаков числа π (больше, чем букв в этой книге), и математики знают, что в любой момент можно вычислить новые знаки, если это понадобится.

Итак, вычислительные машины способны очень быстро и точно выполнять арифметические расчеты; самые мощные современные ЭВМ работают еще в сотни раз быстрее, чем БЭСМ-6. Но умение считать, вычислять — отнюдь не единственное и да-же не главное умение современных вычислительных машин. А что же еще они умеют делать? Для ответа на этот вопрос отправимся на небольшую экскурсию туда, где работают эти машины.

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

Но если пересадка должна состояться в Москве, то оформление билетов, вероятнее всего, займет не больше двух-трех минут. Дело в том, что бронированием авиабилетов в Москве занимается автоматизированная система Сирена, основу которой составляет мощная вычислительная машина.

Специальные пункты для связи с этой ЭВМ — так называемые терминалы1) — установлены в большинстве крупных городов нашей страны. На каждом пульте есть печатающее устройство с клавиатурой как у обычной пишущей машинки и экраном, похожим на экран телевизора.

1 Это слово происходит от английского «terminal» — конечный пункт. Терминал называется так потому, что он стоит в конце линии связи.

Несколько слов о терминалах. Вообще-то терминалом называют любое устройство для связи человека с ЭВМ. В шестидесятых годах в качестве терминалов довольно часто использовали электрические пишущие машинки и телеграфные аппараты — телетайпы. В последние годы чаще применяют дисплеи — устройства с телевизионным экраном. Различают графические дисплеи, на экране которых можно нарисовать любой рисунок (рис. 1), и алфавитно-цифровые, которые могут показывать только тексты (рис. 2).

Представь себе, что ты пришел, например, к новосибирскому оператору системы Сирена с намерением приобрести несколько билетов до Харькова (с пересадкой в Москве). Оператор набирает текст запроса, нажимая соответствующие клавиши на терминале, и через одну-две секунды на экране появляется ответ машины. В течение этих секунд вычислительная машина, находящаяся за несколько тысяч километров от Новосибирска, просмотрела расписание, выбрала удобный для тебя рейс, определила, сколько на нем свободных мест, отвела места по твоему запросу и сообщила их номера новосибирскому оператору — словом, проделала всю ту работу, на которую раньше уходило несколько дней.

Если предложенные места тебя устраивают, оператор набирает на пульте подтверждающее сообщение, и далекая ЭВМ запоминает, что места эти забронированы для пассажиров, которые таким-то ; рейсом прилетят из Новосибирска.

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

Первое прерывание Зачем Сирене ЭВМ? Попробуем разобраться, какую работу выполняет в системе Сирена

вычислительная машина и что она должна уметь, чтобы справляться с — этой работой. Первое, машина принимает запросы, поступающие от операторов, и отвечает на

них, то есть ведет диалог с операторами. Умение вести диалог с человеком, а возможно, и со многими людьми одновременно — одно из, важнейших качеств современных вычислительных машин. Для такого диалога предназначены разнообразные терминалы, печатающие устройства и рисующие устройства — графопостроители. На рис. 3, 4 изображены различные печатающие устройства, а на рис. 5 — графопостроитель.

Получив запрос с терминала, вычислительная машина должна подобрать подходящий для пассажира рейс и определить, сколько на нем свободных мест. Для этого ей нужно «помнить» расписание всех самолетов, вылетающих из Москвы, и точный перечень свободных и занятых мест на каждом самолете, по крайней мере, на две недели вперед. Иначе говоря, она должна хранить информацию о расписании и о распределении мест на самолетах.

Умение хранить информацию — второе важнейшее качество вычислительных машин. Каждая ЭВМ имеет одно или несколько, запоминающих устройств (ЗУ), которые часто называют памятью вычислительной машины.

Обычно различают оперативные запоминающие устройства (ОЗУ) и долговременные (ДЗУ). Оперативные устройства — самые быстрые: найти нужную информацию в ОЗУ машина может за миллионную долю секунды. Но в таком ЗУ можно хранить не так уж много сведений, и сохраняются они только во время работы машины: если ЭВМ выключили хотя бы на долю секунды, вся информация в ОЗУ пропадает (стирается).

В ДЗУ можно хранить информацию как угодно долго, поэтому эти устройства и называют долговременными, но зато и искать нужные данные там приходится гораздо дольше, чем в оперативной памяти. В качестве ДЗУ часто используют магнитофоны и запоминающие устройства на магнитных дисках, похожих на грампластинку (рис. 6, 7).

Информация в ОЗУ и ДЗУ не остается неизменной: каждый раз, когда система оформляет очередной авиабилет, какое-то свободное место становится занятым. Бывает и наоборот — когда пассажир сдает билет. Меняются расписания рейсов, выходят на авиалинии новые типы самолетов, и все эти изменения нужно немедленно занести во все таблицы, хранящиеся в памяти ЭВМ. Умение обрабатывать информацию — третье и, пожалуй, самое важное качество современной ЭВМ.

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

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

Мы ничего не сказали об умении вычислять. Дело в том, что системе Сирена почти не приходится производить арифметические действия — разве что подсчитать стоимость детского билета или количество оставшихся свободных мест в самолете. Разумеется, существует немало других систем, в которых машинам приходится решать гораздо более серьезные вычислительные задачи, и там их блестящие арифметические способности могут проявиться в полной мере. Но наш вывод об основных умениях ЭВМ от этого не изменится: ведь числовая информация — это всего лишь один из видов информации, а арифметические операции — один из видов ее обработки. Около 90%. всей информации, обрабатываемой современными ЭВМ, составляет информация нечисловая: тексты, рисунки, графики, разнообразные списки и таблицы, так что на долю арифметических вычислений приходится лишь десятая часть рабочего времени вычислительных машин. Правильнее было бы называть их не вычислительными, а

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

Итак, на вопрос «Что умеет делать вычислительная машина?» мы, в основном, ответили. А теперь продолжим нашу экскурсию

Система Бельчонок ведет поиск. Исследуя состав клеточной мембраны, биохимик обнаружил какой-то белок. Нужно было определить, какой это белок и что о нем уже известно. Для этого его расщепили с помощью специально подобранных химических реактивов — ферментов. Удалось установить, что среди образовавшихся «осколков» есть такая цепочка аминокислот: аланин-валин-аланин (в сокращенных обозначениях AVA). Теперь исследователь должен отойти от лабораторного стола, взять с книжной полки толстые тома каталогов, в которых перечислены структуры всех известных белков, и начать кропотливый поиск: где в этих структурах встречается обнаруженная им цепочка. А белков — сотни, и в каждом — от двух-трех десятков до многих тысяч аминокислот...

Еще несколько лет назад такая проверка отнимала несколько дней, а иногда и недель. Сегодня на нее уходят минуты: биохимик просто подходит к терминалу и набирает свой запрос. И почти сразу же на экране появляется ответ ЭВМ:

ЦЕПОЧКА AVA ВСТРЕЧАЕТСЯ В ТАКИХ БЕЛКАХ: НАЗВАНИЕ БЕЛКА ПОЗИЦИЯ S12 . .-................. ……….. S16 . .- . . ........ . S25 . . .... . .

8 3

512

Это работает система Бельчонок, созданная восьмиклассниками Таней

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

СПРАВКА ФУНКЦИЯ БЕЛКА-ФЕРМЕНТА ВАЛИЛ-ТРНК-СИНТЕТАЗЫ СОСТОИТ В УЗНАВАНИИ СПЕЦИФИЧЕСКОЙ АМИНОКИСЛОТЫ - ВАЛИНА, АКТИВИРОВАНИИ ЕЁ С ПОМОЩЬЮ АТФ И В ПОСЛЕДУЮЩЕМ ПРИСОЕДИНЕНИИ ЭТОЙ АМИНОКИСЛОТЫ К СПЕЦИФИЧЕСКОЙ ТРАНСПОРТНОЙ РНК ВАЛИЛ-ТРНК.

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

И снова — никаких вычислений: вся информация о белках хранилась в ЗУ в виде текстов.

Кстати, раз уж речь, зашла о текстах, заглянем в учреждение, где постоянно имеют дело с текстами — в издательство.

ЭВМ на столе у редактора. Гжатск получил новое название — город Гагарин. А в рязанской областной типографии еще не просохли гранки небольшой книги о родине первого космонавта. Конечно, книгу нужно было переделать, но...легко сказать! Ведь слово «Гжатск» в разных формах и падежах встречалось чуть ли не на каждой стра-нице. И если бы можно было исправлять одно только это слово! Ведь новое название города на одну букву длиннее, значит, увеличится длина всей строки. Скорее всего, одну или несколько букв нужно будет перенести на следующую строку, значит, ее тоже предстоит исправлять, следующую за ней — тоже и так далее. В лучшем случае цепочка исправлений потянется до конца абзаца, в худшем — появится лишняя строка, а тогда нужно будет переделывать и следующую страницу...

Конечно же, при таких переделках неизбежно возникают новые опечатки. А самое обидное, что в одном-двух местах наверняка останется старое название. Понятно, что работникам издательства и типографии пришлось нелегко.

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

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

Архитектор за терминалом. Нелегкая работа у архитектора. Ему приходится одновременно быть и художником, и инженером. Художник мечтает возвести изумительно красивые здания, а инженер должен ответить, можно ли такие здания по-строить. Он должен рассчитать усилия в каждом элементе задуманной художником конструкции, подобрать форму и размеры каждой детали. Его задача — обеспечить прочность, устойчивость и надежность всего сооружения, предусмотреть исполь-зование стандартных деталей всюду, где это возможно. И далеко не всегда воздушные замки, одетые в сборный железобетон, оказываются такими, как хотелось художнику. Можно, конечно, попробовать немножечко изменить проект, поискать такой вариант, который удовлетворил бы и художника, и инженера. Но расчет строительных кон-струкций — дело долгое и кропотливое. Если его повторять много раз, проектирование нового здания может растянуться на десятки лет.

Но вот на помощь архитектору приходит ЭВМ. Чертежную доску заменяет экран графического дисплея. При помощи светового пера — устройства, позволяющего рисовать прямо на экране, можно изобразить любой рисунок, схему или чертеж.

Теперь архитектор-художник может дать волю своей фантазии и нарисовать световым пером такое здание, которое он хотел бы видеть. Этот рисунок воспринимает вычислительная машина. За несколько секунд выполнив инженерный расчет, она изо-бражает на экране свой вариант, соответствующий жестким требованиям строительной механики. Теперь очередь за человеком. Если предложенный машиной вариант его не устраивает, он может предложить какие-то изменения, и машина вновь повторит все расчеты уже для нового варианта. Архитектор может как угодно двигать и поворачивать здание на экране, чтобы проверить, как оно будет выглядеть с разных сторон, с разных расстояний (рис. 8).

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

Примерно так же — в режиме диалога с ЭВМ при помощи графического дисплея и светового пера—работают сегодня авиа- и автоконструкторы, художники-модельеры, радиоинженеры и представители многих других профессий (рис. 9).

Второе прерывание Куда спрятался процессор? Рассказывая о рабочих местах кассиров Аэрофлота и ученых-биохимиков,

авиаконструкторов и архитекторов, мы упоминали только о терминалах, то есть об устройствах для связи с процессором вычислительной машины. А где же находится сам процессор?

Заглянем еще раз в лабораторию биохимика или в рабочий кабинет редактора и присмотримся к их терминалам повнимательнее. Лет 10-15 назад мы, скорее всего, обнаружили бы кабель (линию связи) от терминала к процессору, который наверняка занимал бы целую комнату, может быть, соседнюю, а может быть, расположенную в другом городе (как в системе Сирена).

В течение многих лет, от появления первых ЭВМ до начала семидесятых годов, процессор и запоминающие устройства были самыми большими, сложными и дорогими устройствами в составе вычислительных машин. Поэтому конструкторы и программисты всячески старались увеличить количество терминалов, подключенных к одному или нескольким процессорам, объединенным в вычислительный комплекс. Например, комплекс из трех ЭВМ БЭСМ-6, установленных в Вычислительном центре Сибирского отделения Академии наук СССР (ВЦ СО АН СССР), обслуживает больше

ста терминалов, находящихся не только в самом ВЦ, но и в других институтах Новосибирского Академгородка и даже в других городах.

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

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

Вычислительные машины смогли стать такими миниатюрными, потому что сейчас вместо радиоламп, транзисторов и других деталей традиционных радиосхем используются так называемые большие интегральные схемы (БИС). Одна такая БИС заменяет сотни, а то и тысячи радиоламп, употреблявшихся в первых ЭВМ.

Сравнив рис. 10 и 11, можно получить некоторое представление о том, как изменился внешний облик вычислительных машин всего за двадцать лет. На первом рисунке изображена одна из лучших советских ЭВМ начала пятидесятых годов — Стрела. Работала она со скоростью 2-3 тысячи операций в секунду, а оперативное запоминающее устройство позволяло хранить 2047 чисел или команд. На рисунке показаны шкафы с процессором и ОЗУ этой машины. Видно, что они занимают территорию, ненамного меньшую, чем школьный спортзал.

На втором рисунке показаны интегральные схемы: процессор с быстродействием больше 500 тысяч операций в секунду и запоминающее устройство на 2 тысячи чисел. Площадь каждой такой схемы — около квадратного сантиметра, в спичечном коробке их поместится несколько десятков. Легко видеть, что современные ЭВМ отличаются по размерам от своих предшественниц заметнее, чем муха от слона.

Прочитав эти строки, ты можешь подумать, что большие ЭВМ теперь вообще не нужны. Конечно же, это не так: всегда существуют такие задачи, которые нужно решать на самых быстрых и мощных машинах, таких, как новая советская ЭВМ Эльбрус, выполняющая около 120 миллионов операций в секунду. Эти машины также

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

А теперь, познакомившись с возможностями современных ЭВМ, посмотрим, где еще ты можешь с ними встретиться.

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

Уже появились телефонные аппараты с микропроцессорным управлением. У них есть и оперативная, и. долговременная память. В оперативной хранится тот номер, который мы только что набрали. Если с первого раза дозвониться не удалось (занято), то телефон будет повторять вызов, например, каждые пять минут. А самые нужные номера можно записать в ДЗУ.

Существуют и стиральные машины, в которые нужно только загрузить белье и засыпать порошок — все остальное машина сделает сама: нальет и нагреет, если нужно, воду, замочит белье, выстирает, прополощет, отожмет и сольет воду — оста-нется только вынуть чистое белье. Есть электроплиты, способные выполнить такое, например, задание.

Включить духовку, нагреть ее до 180°С и подать звуковой сигнал, чтобы хозяйка знала, что пирог пора ставить в духовку. Выпекать пирог 20 минут, затем снизить температуру до 100 °С, выдержать пирог еще 10 минут, потом выключить духовку и снова подать звуковой сигнал. Все больше появляется микропроцессорных игрушек: их подключают к обычному телевизору и на экране появляется, например, мишень, на которой можно потренироваться в спортивной стрельбе из светового пистолета, или полоса препятствий, через которые нужно провести автомобиль. Есть и карманные игрушки, для которых телевизор не нужен. Почему бы, например, не поиграть в шахматы или футбол? Впрочем, не только поиграть. Разработано уже немало миниатюрных устройств, которые могут помочь в изучении иностранного языка или в переводе статьи. А для школьников младших классов предназначен карманный тренажер: машина при помощи синтезатора речи произносит слово, а ученик должен набрать его по буквам на клавиатуре. Если он ошибается, машина начинает пищать: «Пробуй снова, пробуй снова, ты не знаешь это слово». Наконец, в известных всем электронных наручных часах и карманных микрокалькуляторах тоже используются микропроцессоры.

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

В отсутствие хозяев домашняя ЭВМ может отвечать на телефонные звонки, поддерживать в квартире заданную температуру, поливать цветы, кормить в определенные часы рыбок в аквариуме. А к приходу хозяев она приготовит или разогреет обед, постирает и выгладит белье.

Через персональную ЭВМ можно получить подборку самых свежих новостей по любой заданной теме, заказать билет на поезд или самолет, просмотреть на экране телевизора текст и рисунки из любой книги, отправить письмо или телеграмму. А для самых маленьких членов семьи машина почитает вслух сказку и покажет заказанный мультфильм. Особенно полезна такая машина школьнику: с ее помощью можно получить любую справку, провести любые эксперименты по физике, химии и другим предметам, проверить свои знания, оформить домашнее задание. А дошкольник может научиться читать и писать с помощью той же машины (уже известны случаи, когда трехлетние дети самостоятельно осваивали грамоту, играя с домашней ЭВМ). Да и играть в шахматы персональная ЭВМ умеет не хуже, чем специализированный шах-матный микропроцессор.

Третье прерывание Что нужно знать и уметь, чтобы работать с ЭВМ? В одном из своих выступлений академик А. П. Ершов ответил на этот вопрос

так: «Программист должен обладать способностью первоклассного математика к абстракции и логическому мышлению, в сочетании с эдисоновским талантом соорудить все, что угодно, из нуля и единицы. Он должен сочетать аккуратность бухгалтера с проницательностью разведчика, фантазию автора детективных романов с трезвой практичностью экономиста. А кроме того, программист должен иметь вкус к коллективной работе, понимать интересы пользователя и многое другое».

Вычислительные машины используются всюду—в заводских цехах и лабораториях ученых, в школьном классе и жилой квартире, на земле, под водой и в космосе (например, на борту нового советского космического корабля «Союз-Т» установлена микро-ЭВМ). Где бы ты ни работал, какую бы профессию ни выбрал, рано или поздно ты встретишься с вычислительной машиной. И тогда очень многое будет зависеть от того, насколько ты готов к такой встрече. По словам А. П. Ершова, человек, не умеющий работать с ЭВМ, может оказаться в положении неграмотного в библиотеке: кругом столько всего интересного — а как прочтешь?

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

Запомни: задание для ЭВМ, написанное на понятном для нее языке, называется программой. Как нетрудно сообразить, человека, составляющего программы, называют

программистом. Первые вычислительные машины понимали только язык цифр. Программы для

них нужно было составлять из отдельных цифровых команд. Например, во многих ЭВМ команда 001 означала сложение, 002— вычитание и так далее. Составление программ из таких команд было очень кропотливым занятием и отнимало много времени, поэтому почти сразу, после появления первых машин программисты начали «учить» их другим языкам, более удобным для людей, чем цифровые команды. Первые такие языки появились в середине пятидесятых годов.

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

программирования. Среди них есть очень мощные и универсальные: ПЛ/1, ал-гол-68, симула-67, ада, смоллток. Существует много специализированных языков, предназна-ченных для решения задач одного какого-нибудь типа (например, для редактирования текстов (снобол) или для анализа музыкальных произведений (МИПЛ)).

«Научить» машину новому языку очень непросто. Для этого нужно написать большую и сложную программу (часто с использованием цифровых команд), которая будет принимать с терминала или с другого устройства текст на языке программиро-вания и переводить его на понятный машине язык команд. Такая программа-переводчик называется транслятором (от английского слова translate — переводить).

Составление транслятора может потребовать нескольких лет работы. Но зато после того, как он будет готов, программисты могут забыть, что машина на самом деле понимает только цифровые команды, и писать все свои программы на удобном для себя языке программирования.

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

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

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

По-разному можно отвечать и на вопрос о вычислительной машине и программе. Точнее всего было бы написать: «Вычислительная машина, работая по программе, составленной программистом, сделала то-то и то-то», но это очень длинно и так обычно не пишут. Если же вычислительная машина управляет роботом, то дело запутывается еще больше: с одинаковым правом можно сказать: «робот принял решение изготовить все детали»... «ЭВМ приняла решение»... или «программа приняла решение»... В этой книге будет употребляться то одно, то другое выражение, смотря по обстановке.

Роботы становятся к станкам. В сборочном цехе автозавода кипела работа.

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

Поднимали, поворачивали и закрепляли ее, конечно же, не человеческие пальцы, а металлические «пальцы» робота. И вообще в этом цехе нет ни одного человека: двери заперты на замок, у всех станков работают роботы.

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

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

«Мозг» каждого робота — это микропроцессор. Языки программирования для них почти не отличаются от обычных, только к привычным для вычислительных

машин действиям (сложить два числа, заменить букву в слове, провести линию на рисунке и так далее) добавляются новые, для каждого робота свои: поднять деталь, установить ее на место, завернуть болт, опуститься под воду в заданной точке и многие другие. Общие правила составления программ для роботов и для обычных ЭВМ одинаковы, так что если ты научишься программировать на ЭВМ, то сможешь управлять и. роботами.

Терминалы в школьном классе. На рис. 12 показана одна из терминальных комнат ВЦ СО АН СССР. Программисты и математики работают здесь над новыми языками и трансляторами, решают на ЭВМ сложнейшие задачи геофизики, биологии, метеорологии, физики океана. А в определенные дни и часы эту комнату заполняют ученики школы юных программистов, работающей при ВЦ СО АН СССР и Новосибирском университете. Школьники, которые изображены на этом снимке, начинали изучать программирование еще во 2-3 классе.

В Вычислительном центре СО АН СССР разработаны учебные языки программирования Робик и Рапира, предназначенные для школьников разного возраста, от второго до десятого класса. Уже написаны трансляторы с этих языков для советской персональной ЭВМ Агат и для некоторых других ЭВМ. Эти трансляторы входят в систему, получившую название Школьница. Кроме Робика и Рапиры, Школь-ница понимает и другие языки программирования, она умеет исполнять музыкальные произведения и рисовать. В состав этой системы входят и десятки программ, предназначенных для применения на уроках по различным школьным предметам, например, модель химической лаборатории, справочник по астрономии, тренажер для обучения умножению в столбик, русско-английский словарь и так далее.

В одной из новосибирских школ оборудован вычислительный кабинет, в котором на каждом столе установлена ЭВМ Агат, оснащенная системой Школьница. Сюда приходят школьники разных классов на уроки по программированию, математи-

ке, физике, химии, биологии и другим предметам. Скоро такие кабинеты появятся во многих школах нашей страны.

Если ты хочешь изучить программирование, а в твоей школе еще нет вычислительного кабинета, тебе могут помочь кружки программирования, работающие сегодня во многих городах. С сентября 1979 года регулярно публикуются материалы для юных программистов в журнале «Квант».

Можно начинать свое знакомство с программированием и с этой книги. А теперь ты должен решить, как читать дальше. Если ты хочешь научиться составлять программы для роботов и

вычислительных машин, освоить важнейшие понятия, законы и приемы про-граммирования, подготовься к серьезной работе. Приготовь тетрадки в клеточку, ручку, карандаш, линейку. Лучше всего завести две тетради: рабочую — для решения задач и конспект, в который нужно выписывать основные правила и определения и

перерисовывать важнейшие диаграммы, отмеченные на полях знаком . Другим

знаком — отмечены новые слова. Их стоит выписать в словарик в конце конспекта. На полях будут встречаться и другие «дорожные» знаки. Вот что они означают:

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

— дополнительный материал. При первом чтении это место можно пропустить.

— «место разворота». Нужно вспомнить какой-то материал из школьной программы или из предыдущих глав этой книги.

А если не смог вспомнить, стоит найти это место и прочитать его заново.

— задача для самостоятельного решения. Постарайся решить ее, прежде чем читать дальше.

— контрольные вопросы и задачи для повторения и закрепления материала.

Звездочкой отмечены задачи, предназначенные только для старшеклассников, а двумя звездочками — задачи повышенной трудности.

Следующие главы разделены на уроки и перемены. За один раз не стоит читать больше одного урока и одной перемены. Обязательно постарайся решить все задачи,

отмеченные знаком , ответить на все контрольные вопросы и решить две-три

задачи на закрепление (со знаком ). Вот первое контрольное задание:

Вспомни и назови важнейшие умения вычислительных машин. Если ты не собираешься заниматься программированием всерьез, но хотел бы

узнать подробнее об устройстве и работе роботов и ЭВМ, об их применении в различных отраслях, можешь бегло просмотреть следующие главы этой книги и сразу перейти к рекомендациям по дальнейшему чтению (с. 193).

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

Теперь представь себе, что ты сидишь за партой в экспериментальном вычислительном кабинете. Правда, машина Агат пока еще выключена — с ней ведь еще нужно научиться работать.

Внимание! Начинается первый урок!

ГЛАВА ПЕРВАЯ ИСПОЛНИТЕЛИ И ПРОГРАММЫ Первый урок Основные законы программирования и правила записи программ Вопросы, утверждения, предписания. Для того чтобы научиться составлять

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

Программы на любых языках программирования состоят из отдельных предложений — точно так же, как привычные для нас тексты, записанные по-русски. Но в таких текстах встречаются предложения различных видов: повествовательные, вопросительные и побудительные, а в большинстве языков программирования все предложения относятся к одному и тому же виду. Почему?

Для ответа на этот вопрос вспомним, как различаются виды предложений в естественных языках.

Вот что об этом сказано в учебнике для четвертого класса: По цели высказывания различаются повествовательные, вопросительные и

побудительные предложения. Предложения, в которых мы сообщаем о чем-либо, называются

повествовательными; предложения, в которых содержится вопрос, — вопроси-тельными; предложения, в которых мы побуждаем кого-либо к действию, приказываем, просим, — побудительными.

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

пользоваться более короткими: утверждение, вопрос и предписание.

Чтобы проще было отличить один вид предложений от другого, запомни такие правила:

Вопрос — это предложение, на которое можно ответить. Предписание — это предложение, которое можно исполнить. Утверждение — это предложение, которое можно проверить (оно может

оказаться истинным или ложным). Применяя эти правила, нужно помнить, что они относятся к буквальному

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

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

Предписание — это такое предложение, к которому можно поставить вопрос: «Как его исполнить?».

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

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

Какой он, этот слонопотам? Неужели очень злой? Идет ли он на свист? И, если идет, то зачем? Любит ли он поросят? И как он их любит?

Хорошо живет на свете Винни-Пух! Позовите, пожалуйста, кота Матроскина к телефону. Кот Матроскин подойти к телефону не может. Он очень занят. Он на печи

лежит. Во что бы то ни стало Мне надо выходить. Нельзя ли у трамвала Вокзай остановить? Это что за остановка — ' Бологое иль Поповка? Первый закон программирования. Если ты любишь читать научно-

фантастическую литературу, то, конечно, помнишь, что роботы и вычислительные машины понимают любое предложение 6 у к в а л ь н о. Переносный смысл и намеки до них совершенно «не доходят». Вероятно, ты без труда сможешь припомнить несколько забавных, а иногда и неприятных ситуаций, возникавших из-за такой «непонятливости». Например, герой одного фантастического рассказа неожиданно выясняет, что роботы в течение трехсот лет знали решение задачи, над которой все эти годы безуспешно ломали головы лучшие ученые Земли. Знали и молчали, потому что их никто не догадался спросить...

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

Программы состоят из предписаний Утверждения и вопросы могут появляться в программах только как

подчиненные предложения в составе сложных предписаний. Например, роботу, ко-торый умеет выполнять арифметические действия и понимает русский язык, можно приказать:

Вычислить, сколько будет дважды два. Результат отпечатать. Но бессмысленно спрашивать у него: Не знаешь ли ты, сколько будет дважды два? или сообщать ему: Я хотел бы узнать, сколько будет дважды два. Он просто не будет знать, что

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

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

Нынешние вычислительные машины и роботы умеют понимать и исполнять только некоторые предписания, записанные по строгим правилам языков

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

Перечень предписаний, которые понимает и умеет исполнять вычислительная машина или робот, называется множеством предписаний (сокращенно — МП).

В описаниях любых роботов и ЭВМ обязательно приводится их МП и

перечисляются правила записи предписаний. В этой книге используются правила учебного языка программирования Робик:

1. Каждое предписание записывается с новой строки. 2. После предписания ставится точка с запятой. 3. Все слова в предписании пишутся прописными (заглавными) буквами. 4. Если предписание не поместилось на одной строке, его можно перенести, но

разрывать слова при этом нельзя и никакие знаки переноса не допускаются. Правило 3 обязательно только для печатных программ; если программа

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

Отметим, что правила расстановки знаков препинания — запятых, тире, двоеточий и так далее — в предписаниях для роботов могут сильно отличаться от правил пунктуации в обычном языке. Поэтому при составлении программ нужно очень внимательно переписывать из МП не только все слова, но и все знаки препинания.

Первая программа. А теперь попробуй выполнить небольшое задание. Нужно составить программу для робота ДЕЖУРИК, который умеет выполнять обязанности дежурного по классу на перемене. Вот его МП:

ЗАКРОЙ ОКНО СОТРИ С ДОСКИ НАМОЧИ ТРЯПКУ ОТКРОЙ ОКНО СЯДЬ НА МЕСТО На перемене ДЕЖУРИК должен проветрить класс и привести в порядок доску.

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

Внимание! Звенит звонок. Робот ждет твоей программы. Попробуй составить программу сам.

Здесь приведены пять программ, составленных юными программистами

новосибирской школы на одном из первых занятий. Пожалуйста, сравни с ними свою программу. Имей в виду, что не все программы правильны! Найди среди них правиль-ные программы (если они есть) и перечисли все ошибки в остальных. «Какие из этих программ робот не поймет? Какие поймет, но не сможет исполнить?

Программа Миши: Открой окно. Намочи тряпку. Сотри с доски. Закрой окно. Сядь на место.

Программа Ани: ЗАКРОЙ ОКНО; СОТРИ С ДОСКИ; НАМОЧИ ТРЯПКУ; ОТКРОЙ ОКНО; СЯДЬ НА МЕСТО; Программа Наташи:

ОТВОРИ ОКНО; НАМОЧИ ТРЯПКУ; ПОДМЕТИ ПОЛ; ВЫТРИ ДОСКУ; ЗАКРОЙ ОКНО; ВЕРНИСЬ НА МЕСТО; Программа Димы: ОТКРОЙ ОКНО; НАМОЧИ ТРЯПКУ; СОТРИ С ДОСКИ; ЗАКРОЙ ОКНО; СЯДЬ НА МЕСТО; Программа Толи: ОТКРОЙ ОКНО; СОТРИ С ДОСКИ; НАМОЧИ ТРЯПКУ; СЯДЬ НА МЕСТО; Решение. Робот не поймет и поэтому не сможет исполнить программы Миши и

Наташи. Миша грубо нарушил правила записи предписаний: разместил в одной строке несколько предписаний (нарушено правило 1), в конце каждого из них вместо точки с запятой поставил точку (правило 2), записал все слова строчными буквами вместо заглавных (правило 3) и, в довершение всего, разорвал слово при переходе на новую строку и поставил знак переноса (правило 4). Словом, в одной крохотной программке он ухитрился нарушить все четыре правила! Если же исправить эти ошибки, получится правильная программа (проверь ЭТО!).

Наташа правил записи не нарушала, но половину предписаний из ее программы ДЕЖУРИК не поймет и исполнить не сможет, потому что этих предписаний нет в его МП! В самом деле, предписание ОТКРОЙ ОКНО есть в МП, поэтому робот его понимает и может исполнить, но предписание ОТВОРИ ОКНО ему неизвестно, и вряд ли ДЕЖУРИК сам догадается, что оно означает. То же самое можно сказать о предписаниях ВЫТРИ ДОСКУ и ВЕРНИСЬ НА МЕСТО. А подметать пол этот робот, по-видимому, вообще не умеет: в его МП нет даже похожего предписания. Похоже, что Наташа писала свою программу «по памяти», совсем не заглядывая в МП. Начинающие юные программисты поступают так довольно часто, но в результате обычно получаются неправильные программы.

А вот Аня поступила наоборот; просто взяла и переписала все предписания из МП, не додумавшись даже расставить их в нужном порядке. Только точки с запятой в конце добавила. Ее программу робот, конечно, поймет, но исполнить все равно не сможет: первое предписание — ЗАКРОЙ ОКНО, но ведь окно с самого начала было закрыто и закрыть его второй раз робот не сможет.

Толину программу ДЕЖУРИК поймет и сможет исполнить до конца, но поведет себя при этом как очень рассеянный дежурный: откроет окно и оставит его открытым, сотрет с доски сухой тряпкой, так что эту программу тоже нельзя назвать правильной. Правильную программу составил Дима: текст каждого предписания в точности соответствует МП, записаны они строго по правилам и расставлены в том порядке, в каком ДЕЖУРИК должен их выполнять.

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

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

Тебя, может быть, удивляет, что мы так много говорим об ошибках вместо того, чтобы заняться правильными программами. Дело в том, что умение быстро найти и исправить ошибки — одно из самых важных для программиста. В программировании,

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

1. Нарушение общих правил записи предписаний (программа Миши). 2. Использование предписаний, которых нет в МП (Наташа). 3. Программу невозможно выполнить, хотя каждое отдельное предписание

записано правильно (Аня). 4. Программу можно исполнить, но она не соответствует заданию (Толя).

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

принято называть синтаксическими. Ошибки третьего и четвертого типов связаны не с синтаксисом, а со смыслом предписаний.

Поиск ошибок в сложной программе больше всего напоминает работу Шерлока Холмса над запутанным делом или охоту на очень хитрого зверя. Программист по крупицам собирает «улики», выдвигает различные версии появления ошибки и орга-низует для их проверки «следственные» эксперименты, он подстраивает ошибкам ловушку за ловушкой, устраивает на них облавы, идет «по следам», выявляет подозрительные предписания и придумывает для них проверки... Впрочем, все это тебе еще предстоит.

Исполнители и второй закон программирования. Составляя и проверяя программы для ДЕЖУРИКа, мы совершенно не интересовались тем, как этот робот выглядит, как он устроен, каким образом стирает с доски или открывает окно. Это может быть, например, симпатичный робот, изображенный на рис. 13.

Впрочем, ДЕЖУРИК вполне может оказаться и тяжеловесным сооружением на многоколесном шасси, напоминающем гибрид Лунохода и подъемного крана (рис. 14). Нам безразлично, как он выглядит, нам нужно знать только, какие предписания он может исполнять. И вообще, при составлении любой программы нам не обязательно знать, что (или кто) будет ее выполнять. Единственное, что нам нужно знать — это множество предписаний, которые понимает и умеет выполнять исполнитель нашей программы.

На следующих уроках мы не будем интересоваться устройством роботов или машин, исполняющих наши программы. Каждый .раз мы будем говорить просто об

исполнителе, для которого известно множество предписаний исполнителя (сокращенно — МПИ).

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

Выполняя предыдущее задание и разбираясь с ошибками юных программистов, ты, наверное, уже понял, что в программе для любого исполнителя можно употреблять те и только те предписания, которые входят в его МПИ. Разумеется, синтаксис всех предписаний в программе должен быть точно таким же, как в МПИ. Нельзя менять ни единой буквы, ни одного знака препинания. И, конечно же, надо соблюдать общие правила записи предписаний. Это правило мы и назовем вторым законом программирования:

В программе для любого исполнителя можно употреблять те и только те предписания, которые записаны в его МПИ, в точности сохраняя их синтаксис и соблюдая общие правила используемого языка программирования. Итак, на первом уроке ты познакомился с основными законами

программирования и с правилами записи программ на языке Робик, узнал, что такое исполнитель и его МПИ, выяснил, какие ошибки встречаются в программах. А сейчас — немного отдохни.

Первая перемена Твое рабочее место В промежутке между уроками познакомимся поближе с твоим рабочим местом

(как ты помнишь, мы договорились, что ты сидишь в вычислительном кабинете). На столе перед тобой вычислительная машина Агат. Рядом с ней обычный цветной телевизор, который может работать как универсальный терминал: на его экран машина может выдавать и текстовые сообщения, и рисунки.

В небольшом корпусе машины, напоминающем по форме переносной магнитофон, размещаются: процессор, оперативное запоминающее устройство, маленький динамик и дисковод для гибких дисков (долговременное запоминающее устройство). К машине постоянно подключены телевизор и клавиатура. Можно присоединить к ней и другую технику, например магнитофон или печатающее устройство. Клавиатура ЭВМ Агат почти такая же, как у пишущих машинок, но кроме букв русского алфавита на ней есть и латинские буквы (рис. 15). Длинная клавиша в нижней части клавиатуры позволяет оставлять промежутки (пробелы) между словами.

Для перехода на новую строчку предназначена клавиша, расположенная справа вверху.

Когда машина выключена, клавиатуру можно надеть, как крышку, на переднюю стенку ее корпуса.

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

Второй урок Диалог с исполнителем ДЕЖУРИК (Лабораторная работа) Первое задание нашей лабораторной работы — набрать на клавиатуре

программу для робота ДЕЖУРИК и проследить за ее исполнением. Вообрази, что робот сидит рядом с тобой за партой. Обстановка в классе примерно такая, какая была описана в задании на с. 39: вся доска исписана, тряпка сухая, вот только окно не закрыто. Перед тобой лежит листок бумаги с Диминой программой. Ты поворачиваешь выключатель. Слышится тихий шелест и пощелкивание — это заработал дисковод. Экран телевизора слегка светлеет и на нем появляются слова:

Пожалуйста, назовите себя! ? Вопросительный знак, изображенный машиной на следующей строке, означает,

что она ждет ответа на свой вопрос. Ты набираешь ответ: Юный программист — и нажимаешь клавишу перевода строки. Ответ машины появляется на экране

мгновенно: Здравствуйте, юный программист! Я система "Школьница" Жду предписаний *

На этот раз машина изобразила на новой строке звездочку. Это означает, что она ждет от тебя предписание и готова его исполнить. Для начала включим нужного исполнителя (не забудь, что все предписания нужно набирать прописными буквами):

ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ ДЕЖУРИК; опять перевод строки и опять на экране появляется ответ машины: Исполнитель ДЕЖУРИК включен! * Со стороны робота слышно легкое гудение: машина его включила. Ну что ж,

начинаем набирать программу: ОТКРОЙ OKKО; Робот не трогается с места, а на экране появляется сообщение системы: Не понимаю! * В чем дело? Ах да, ты ведь набрал ОККО вместо ОКНО. Повторяешь сначала: ОТКРОЙ окно Перевод строки — и... никакой реакции. Впрочем, все правильно: ты не набрал

точку с запятой, и система считает, что предписание еще не закончено. Набери «;» на следующей строке:

Робот поднимается с места, идет к окну и... застывает неподвижно, а на экране появляются слова:

Не могу! Вероятно, ты уже понял, в чем дело. Если не понял, можешь набрать

предписание ПОЯСНИ ОШИБКУ; и ответ машины не заставит себя долго ждать: Окно открыто! * Вот теперь все ясно! Конечно же, Димина программа, правильная в одной

ситуации, не подходит в другой. Нужно было просто вычеркнуть из нее первое предписание. Ну что ж, на ошибках учатся. Продолжим:

СОТРИ С ДОСКИ; Робот подходит к доске, берет тряпку... Стоп! А тряпка-то сухая! Ты набрал не

то предписание! Пока робот водит по доске сухой тряпкой, Попробуем исправить ошибку:

НАМОЧИ ТРЯПКУ; Машина реагирует молниеносно: Не мешай! — и робот продолжает свою бессмысленную работу. Все верно: звездочки на

экране не было и сейчас ее тоже нет. Система не готова принимать новое предписание, пока не исполнено предыдущее. Остановить ее можно только специальным приказом:

СТОП; — робот застыл с тряпкой в руке, а на экране возникает новый текст: Работа программы прервана! Исполнялось предписание СОТРИ С ДОСКИ Теперь звездочка есть, и мы имеем полное право набирать то самое

предписание, с которого и надо было начинать: НАМОЧИ ТРЯПКУ; Робот бежит к умывальнику и вскоре возвращается с мокрой тряпкой в руках.

На экране возникает звездочка. СОТРИ С ДОСКИ; Робот бодро исполняет предписание. Снова звездочка! ЗАКРОЙ ОКНО; * СЯДЬ НА МЕСТО;

На книжной странице текст очередного предписания мы напечатали лод звездочкой. На самом деле он набирается на той же строке. То же можно сказать о вопросительном знаке и других «приглашениях» машины. Поэтому после исполнения программы нижние строки экрана будут выглядеть так:

*СОТРИ С ДОСКИ; * ЗАКРОЙ ОКНО; * СЯДЬ НА МЕСТО; Наберем теперь следующее предписание, последнее: *ВЫКЛЮЧИТЬ ИСПОЛНИТЕЛЯ ДЕЖУРИК; Гудение механизмов робота затихает, и на экране появляется новый текст: Исполнитель ДЕЖУРИК выключен! Множество предписаний системы Школьница. А теперь посмотри на

протокол диалога, оставшийся на экране твоего телевизора и на бумаге печатающего устройства. Вот он:

Пожалуйста, назовите себя! ? Юный программист Здравствуйте, юный программист ! Я система "Школьница" Жду предписаний * ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ ДЕЖУРИК; Исполнитель ДЕЖУРИК включен! *ОТКРОЙ ОККО; Не понимаю! *ОТКРОЙ ОКНО ; Не могу! *ПОЯСНИ ОШИБКУ; Окно открыто! *СОТРИ С ДОСКИ; НАМОЧИ ТРЯПКУ; Не мешай! СТОП; Работа программы прервана! Исполнялось предписание СОТРИ С ДОСКИ *НАМОЧИ ТРЯПКУ; *СОТРИ С ДОСКИ; *ЗАКРОЙ ОКНО; *СЯДЬ НА МЕСТО; *ВЫКЛЮЧИТЬ ИСПОЛНИТЕЛЯ ДЕЖУРИК; Исполнитель ДЕЖУРИК выключен! Некоторые особенности поведения машины во время диалога нуждаются в

пояснениях. Во-первых, мы использовали несколько предписаний, которых не было в МПИ нашего робота. Вот они:

ВКЛЮЧИТЬ, ИСПОЛНИТЕЛЯ ДЕЖУРИК ВЫКЛЮЧИТЬ ИСПОЛНИТЕЛЯ ДЕЖУРИК ПОЯСНИ ОШИБКУ стоп Не нарушен ли здесь второй закон программирования? Оказывается, нет:

перечисленные предписания входят в МП самой системы Школьница и их можно использовать во время работы с любым исполнителем. С другими предписаниями этой системы ты познакомишься позже.

Обрати внимание на форму предписаний. Кроме глаголов повелительного наклонения (СОТРИ, СЯДЬ) в них используются глаголы в неопределенной форме (ВКЛЮЧИТЬ, ВЫКЛЮЧИТЬ) и даже междометия (СТОП). Ты еще встретишься с предписаниями, которые выражены наречиями (ВВЕРХ, ВНИЗ и т. д.) и, даже просто

существительными в именительном падеже (иногда даже сокращенными). Ничего странного в этом нет: такие предписания короче, их легче запоминать и быстрее набирать. А машину грамматическая форма интересует мало: для нее предписание — это предложение, которое есть в МПИ. Впрочем, и в русском языке есть подобные предписания:

На старт! Внимание! Марш! Во время диалога ты уже, вероятно, понял, как реагирует система на различные

ошибки. Синтаксические ошибки вызывают сообщение НЕ ПОНИМАЮ! а смысловые — сообщение НЕ МОГУ! В обоих случаях ты можешь получить более подробное пояснение,

воспользовавшись предписанием ПОЯСНИ ОШИБКУ. Но... не стоит делать это слишком часто — лучше попробовать самому разобраться, в чем состояла ошибка. Кстати, система регистрирует каждое обращение за помощью и сообщает преподавателю о тех ошибках, с которыми ты не смог справиться сам.

Наверное, тебе уже понятен смысл «приглашений к диалогу» — значков, которые появляются на экране в начале очередной строки:

? — означает, что машина задала вопрос и ждет ответа на него. * — машина ждет от тебя предписания Внимание! Набирать предписание можно только после появления на экране звездочки! Предписание СТОП — единственное исключение. Вторая перемена МУРАВЕЙ и МАШИНИСТ Пока машина отдыхает, познакомимся с двумя исполнителями, с которыми тебе

еще не раз предстоит встретиться, в этой книге. Первый из них — МУРАВЕЙ. Он может ползать по клетчатой доске (обычно 10 на 10 клеток) и передвигать по ней кубики с различными надписями или рисунками. За один «ход» МУРАВЕЙ сдвигается на "одну клетку вверх, вниз, вправо или влево (но не по диагонали!). Если он наты-кается на кубик или на несколько кубиков, он будет толкать их перед собой, пока не изменит направление движения или не упрется в край доски. Считается, что края доски ограждены бортиками; попытка толкать кубики дальше вызывает сообщение об ошибке. За движениями исполнителя МУРАВЕЙ можно следить на экране телевизора.

МПИ исполнителя МУРАВЕЙ: ВВЕРХ ВНИЗ ВПРАВО ВЛЕВО

Если кубики на доске были расположены в виде буквы П (рис. 16), то после исполнения программы

ВЛЕВО; ВНИЗ; ВНИЗ; ВВЕРХ; ВВЕРХ; ВПРАВО; она превратится в Н, а МУРАВЕЙ возвратится на прежнее место. Исполнитель МАШИНИСТ управляет небольшим маневровым локомотивом,

который сортирует вагоны и составляет поезда на товарной станции. Форма путей, на которых ему приходится работать, может быть различной. На рис. 17 изображена одна из простейших конфигураций с тремя путями (А, Б, В) и одной стрелкой (1).

В отличие от предыдущего исполнителя, МАШИНИСТ может не только тол-кать, но и тянуть за собой вагоны, зато двигаться он может только в двух направлениях — вперед или назад. Вот его МПИ:

ВПЕРЕД НАЗАД ПЕРЕВЕСТИ СТРЕЛКУ ПРИЦЕПИТЬ ВАГОН ОТЦЕПИТЬ ВАГОН. Выполняя предписание ВПЕРЕД или НАЗАД, МАШИНИСТ будет двигаться до

тех пор, пока не наткнется на тупик, вагон или стрелку, на которой можно выбрать направление движения.

Предписание ПРИЦЕПИТЬ ВАГОН позволяет МАШИНИСТУ прицепить один вагон к своему локомотиву или добавить один вагон к тем, которые уже были к нему прицеплены. Точно так же предписание ОТЦЕПИТЬ ВАГОН позволяет отцепить один, самый дальний от локомотива вагон (впрочем, в тех редких случаях, когда вагоны прицеплены и спереди, и сзади, по этому предписанию будут отцеплены два вагона — по одному с каждой стороны). Прежде чем прицепить вагон, к нему, конечно, нужно подъехать вплотную.

Каждая стрелка перед локомотивом в обычном положении указывает один какой-то путь (на рисунке он отмечен сплошной линией). Чтобы проехать по ней на другой путь, нужно ее перевести. Сразу же после прохода поезда (локомотива) стрелка возвращается в прежнее положение! Двигаясь в обратном направлении, локомотив проходит стрелку не останавливаясь, так как выбирать направление в этом случае, не приходится. Например, чтобы перевести локомотив с пути Б на путь А, нужно вы-полнить три предписания:

ВПЕРЕД; ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД;

Выполнив первое предписание, локомотив остановится на стрелке, которая показывает на путь В (рис. 18, а). После перевода стрелки можно вновь двигаться вперед, на этот раз локомотив остановится, подъехав вплотную к вагонам.

Чтобы лопасть с Б на В, достаточно двух предписаний: ВПЕРЕД; ВПЕРЕД; А для возвращения на путь Б с любого из остальных путей, независимо от

положения стрелки, достаточно одного предписания НАЗАД; Пример программы. Пусть на пути А стоят три вагона: крытый грузовой вагон,

цистерна и платформа (см. рис. 17). Необходимо перевести цистерну на путь В, а платформу (вместе с локомотивом) на путь Б. Это можно сделать, например; так (справа от предписаний указаны номера рисунков, на которых показаны положения локомотива и вагонов после исполнения этих предписаний):

ВПЕРЕД; ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; (рис. 18, б) ПРИЦЕПИТЬ ВАГОН; ПРИЦЕПИТЬ ВАГОН; НАЗАД; (рис. 18, в) ВПЕРЕД; ВПЕРЕД; (рис. 18, г) ОТЦЕПИТЬ ВАГОН; НАЗАД; (рис. 18, д) А теперь попробуй составить несколько программ для исполнителей

МУРАВЕЙ и МАШИНИСТ.

1. МУРАВЕЙ находится на клетке с координатами (3, 2) (рис. 19). На какой

клетке он окажется после исполнения программы ВВЕРХ; ВВЕРХ; ВВЕРХ; ВПРАВО; ВПРАВО; ВНИЗ; ВНИЗ; ВНИЗ; Зарисуй путь исполнителя. Какая буква получилась?

2. Составь программу для перевода исполнителя МУРАВЕЙ с клетки (2, 4) на

клетку (8, 6) (рис. 20) по пути, изображенному сплошной стрелкой. По пути, изображенному штриховой стрелкой. По самому короткому пути.

3. МУРАВЕЙ находится на клетке с координатами (5, 5). Составь такую про-грамму, чтобы его путь был похож на букву П. На букву О. На какую-нибудь другую букву по твоему выбору.

4. На рис. 21 показана часть доски с кубиками и положение исполнителя

МУРАВЕЙ. Зарисуй обстановку на этой части доски после исполнения такой программы.

ВВЕРХ; ВПРАВО; ВПРАВО; ВНИЗ; ВНИЗ; ВЛЕВО; ВЛЕВО;

5. На рис. 22 буквы на кубиках составляют слово КРАБ. Зарисуй положение

кубиков после исполнения программы ВВЕРХ; ВВЕРХ; ВЛЕВО; ВВЕРХ; ВПРАВО; ВПРАВО; ВПРАВО; ВВЕРХ; ВПРАВО; ВНИЗ; Какое слово получилось? 6. В условиях предыдущей задачи получить из слова КРАБ слова: БРА, БРАК,

БАРК (барк - это -тип парусного вооружения на корабле).

7, На пути А стоят: цистерна и крытый вагон (рис. 23). Зарисуй положение

вагонов и локомотива после исполнения такой программы: ВПЕРЕД; ВПЕРЕД; ПРИЦЕПИТЬ ВАГОН; НАЗАД; ВПЕРЕД; ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; ОТЦЕПИТЬ ВАГОН; НАЗАД; ВПЕРЕД; ВПЕРЕД; ПРИЦЕПИТЬ ВАГОН; ВПЕРЕД; ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; ПРИЦЕПИТЬ ВАГОН; НАЗАД; ВПЕРЕД; ВПЕРЕД; ОТЦЕПИТЬ ВАГОН; ОТЦЕПИТЬ ВАГОН; НАЗАД; 8. На пути А стоят: крытый вагон, цистерна и платформа (рис. 17). Перевести

их на путь В, сохранив тот же порядок (рис. 24).

9. .В условиях предыдущей задачи поменять местами вагоны на пути А

(поставить у. тупика платформу, затем цистерну и затем — крытый вагон). Ответы. 1. МУРАВЕЙ окажется на клетке (5, 2). Его путь будет напоминать букву П. 2. Программа «ля пути, показанного сплошной стрелкой. ВВЕРХ; ВВЕРХ; ВВЕРХ; ВПРАВО; ВПРАВО; ВНИЗ;

ВНИЗ; ВПРАВО; ВПРАВО; ВВЕРХ; ВВЕРХ; ВВЕРХ; ВПРАВО; ВПРАВО; ВНИЗ; 3. Для буквы П программа приведена в задаче 1. Впрочем, эту букву можно

было изобразить разными способами, так что твоя программа могла выглядеть и по-другому.

4. Положение на доске показано на рис. 25. 5. Получилось слово РАК. 7. Вагоны на пути А поменяются местами, а локомотив вернется на путь Б. ВПЕРЕД; ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; Локомотив подъехал к вагонам ПРИЦЕПИТЬ ВАГОН; ПРИЦЕПИТЬ ВАГОН; ПРИЦЕПИТЬ ВАГОН; Прицепили все вагоны НАЗАД; ВПЕРЕД; ВПЕРЕД; Весь состав оказался на пути В ОТЦЕПИТЬ ВАГОН; ОТЦЕПИТЬ ВАГОН; ОТЦЕПИТЬ ВАГОН; Вагоны остаются на пути В НАЗАД; Локомотив вернулся на путь Б Пояснения, записанные в этой программе справа от предписаний, называются

комментариями. О них мы поговорим на следующем уроке. 9. Указание. Можно перевести весь состав на путь В (задача 8), а затем

возвращать вагоны на .путь А по одному. Можно и наоборот: по одному перебросить

вагоны на В, а затем вернуть обратно все вместе. Обрати внимание: если с одного пути на другой переводится состав из нескольких сцепленных друг с другом вагонов, то порядок вагонов сохраняется. Если вагоны перебрасывать по одному, порядок меняется на обратный. Это наблюдение тебе пригодится при работе с текстами.

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

Третий урок Как составлять программы (Практическое занятие) План. Попробуем решить такую задачу. Поменять местами три вагона, стоящие

на пути А, если путь В — это маленький тупик, в котором может поместиться не больше одного вагона (рис. 26).

Решать эту задачу можно, конечно, по-разному. Можно, например, рассуждать

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

точно так же, как задача 9 из второй перемены (проверь это!). Но помещается только один вагон, значит, поменять местами сразу три вагона мы не сможем. А вот два вагона, наверное, можно поменять местами и с помощью короткого тупика. Попробуем, например, поменять местами крытый вагон и цистерну (точнее говоря, левый вагон со средним: от замены типа вагонов программа никак не изменится). Не будем пока составлять программу, просто прикинем, можно ли это сделать. Нарисуй начальную обстановку на листе бумаги (если тебе трудно представить себе все передвижения вагонов и локомотива, можно вместо нарисованных вагонов положить, например, резинки и двигать их по рисунку). Подводим локомотив к вагонам, цепляем их все и переводим состав на путь Б. Теперь попробуем «втолкнуть» вагоны в тупик В. Там помещается только крытый вагон. Оставим его там и вернем остальные на путь А. Теперь цистерна стоит на нужном месте: возле тупика. Но рядом с ней должен быть крытый вагон, а стоит платформа. Впрочем, теперь уже видно, как поставить на место и крытый вагон: переводим платформу на путь Б, цепляем к ней крытый вагон и перегоняем получившийся состав обратно на А.

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

Если бы МАШИНИСТ умел исполнять предписание ПОМЕНЯТЬ МЕСТАМИ ВАГОНЫ (с указанием положения вагонов, которые нужно пеpecтавить), то программа для решения нашей задачи могла бы выглядеть так:

ПОМЕНЯТЬ МЕСТАМИ СРЕДНИЙ И ЛЕВЫЙ ВАГОНЫ; ПОМЕНЯТЬ МЕСТАМИ ПРАВЫЙ И СРЕДНИЙ ВАГОНЫ;

ПОМЕНЯТЬ МЕСТАМИ СРЕДНИЙ И ЛЕВЫЙ ВАГОНЫ; Эти три предписания позволяют решить поставленную задачу — поменять

местами все три вагона. Но назвать этот текст программой нельзя: ни одного из предписаний нет в МПИ МАШИНИСТа.

И все-таки эта цепочка предписаний будет для нас очень полезна: ведь это план программы. Любое серьезное и сложное дело — в том числе, конечно, написание программы — нужно начинать с составления плана.

Собственно, программа — это тоже план, только записанный в строгом соответствии со вторым законом программирования и с правилами выбранного языка. Но вообще-то планы обычно предназначаются для людей, а не для ЭВМ, поэтому соблюдать второй закон программирования при их составлении не обязательно. Нужно только, чтобы все предписания были понятными и точными, чтобы в них не было никаких двусмысленностей и чтобы после выполнения любого из них было понятно, какое предписание выполнять следующим.

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

От плана — к программе. Чтобы перейти от плана к программе, нужно вместо каждого пункта плана записать последовательность предписаний, взятых из МПИ нужного исполнителя. Для сложных программ это не всегда удается сделать сразу: часто приходится начинать с замены одного плана другим, более подробным. Например, последовательность предписаний для исполнения первого пункта плана, приведенного выше, может выглядеть так:

Подвести локомотив к вагонам; Прицепить все вагоны; Перевести на путь Б; Оставить левый вагон в тупике; Перевести остальные вагоны на путь А; Оставить там средний вагон; Правый вагон — на путь Б; Прицепить к нему левый вагон; Вернуть оба на путь А; Поставить на место локомотив; Как видишь, это еще не программа, а просто более подробный план. Такие

планы часто называют уточняющими, а план для решения всей задачи — общим. Теперь уже совсем нетрудно превратить уточняющий план в программу:

ВПЕРЕД; Подводим локомотив к вагонам ВПЕРЕД; ПРИЦЕПИТЬ ВАГОН; Цепляем все вагоны ПРИЦЕПИТЬ ВАГОН; ПРИЦЕЛИТЬ ВАГОН; НАЗАД; Перевели на путь Б ВПЕРЕД; Оставляем левый вагон в тупике ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; ОТЦЕПИТЬ ВАГОН; НАЗАД; Переводим остальные вагоны на путь А ВПЕРЕД; ВПЕРЕД; ОТЦЕПИТЬ ВАГОН; Оставляем средний вагон на пути А НАЗАД; Правый вагон — на путь Б ВПЕРЕД;

ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; ПРИЦЕПИТЬ ВАГОН; Цепляем к нему левый вагон НАЗАД; Возвращаем оба вагона на путь А ВПЕРЕД; ВПЕРЕД; ОТЦЕПИТЬ ВАГОН; ОТЦЕПИТЬ ВАГОН; НАЗАД; Ставим локомотив на место Вероятно, теперь тебе будет Нетрудно составить уточняющий план для

следующего пункта общего плана и написать по нему программу. Третий пункт в точности совпадает с первым, поэтому новую программу для него писать незачем — достаточно переписать дословно ту, которая только что была здесь напечатана.

Большая получилась программа. И не исключено, что, решая эту задачу и выписывая бесконечные ВПЕРЕД — НАЗАД, ты не раз подумал: «Неужели программирование — такое нудное занятие? А еще говорили, что машина освобождает нас от однообразного труда!». Что ж, составление, таких программ — дело и впрямь довольно однообразное. Но очень скоро ты познакомишься с предписаниями языка Робик, позволяющими передать машине всю «нудную» часть работы. Ты сможешь добавлять новые предписания к МПИ, «объяснив» системе, что ПРИЦЕПИТЬ 5 ВАГОНОВ - значит повторить 5 раз предписание ПРИЦЕПИТЬ ВАГОН; а ПОМЕНЯТЬ МЕСТАМИ СРЕДНИЙ И ЛЕВЫЙ ВАГОНЫ — значит сделать то-то и то-то. А пока приходится терпеть.

Несколько слов о комментариях. В программах этого урока и в ответах к заданиям предыдущей перемены мы часто использовали комментарии: справа от предписания, после точки с запятой, записывали какой-то текст, поясняющий выполнение программы. Правила записи предписаний это позволяют: с точки зрения системы, предписание заканчивается точкой с запятой, и то, что написано справа от нее, машину не интересует. Удобнее всего использовать в качестве комментариев отдельные Пункты уточняющего плана — тогда программу легче составлять и читать.

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

Хороший комментарий — это мостик между планом и программой, важнейший ориентир в лабиринтах предписаний, похожих друг на друга. При составлении программы он позволяет следить за тем, какой пункт плана превращается сейчас в про-грамму. Без такого ориентира мы рискуем сбиться со счета уже на десятом ВПЕРЕД. Если ты решил изменить план, комментарий позволит сразу найти в программе те участки, которые нужно при этом менять. Наконец, комментарий помогает разобраться в чужой программе (да и. в своей тоже). Поэтому постарайся сразу приучить себя писать программы с подробными и точными комментариями. Помни, что твои программы должны быть понятны не только машинам, но и людям.

Что входит в условие задачи по программирова нию? Приступая к решению любой задачи, нужно сначала прочитать условие и разобраться в том, что дано и что требуется сделать.

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

Прежде всего, конечно, должен быть задан язык программирования, на котором нужно составить программу. В этой книге используется язык Робйк, с общими правилами которого ты уже знаком. Иногда бывает задан не один язык, а набор языков, из которого программист должен выбрать наиболее подходящий. Кроме того, нужно знать МП исполнителя, для которого составляется программа, или нескольких исполнителей.

Но это не все! Решая задачи из этой главы, ты уже обратил внимание, что каждый исполнитель работает в определенной среде. Среда состоит из тех предметов, с которыми исполнитель может что-то делать во время исполнения программы и которые могут как-то повлиять на результат ее исполнения. Для ДЕЖУРИКа средой был класс (точнее говоря, окно, тряпка и доска, остальные предметы в классе и присутствующие там люди этого робота никак не интересовали). Среда для исполнителя МУРАВЕЙ — это клетчатая доска, для МАШИНИСТа — железнодорожные-пути. Если к системе Школьница не подключены никакие исполнители, у нее все равно есть своя среда: экран телевизора, бумага печатающего устройства, лента магнитофона, оперативное запоминающее устройство, клавиатура, гибкий диск.

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

Работая по твоей программе, исполнитель будет как-то менять обстановку: проветривать класс, передвигать кубики на доске, выдавать сообщения на экран, вычерчивать рисунок на бумаге. Обычно цель его работы состоит в том, чтобы получить какую-то конечную обстановку: расставить кубики определенным образом, нарисовать заданный рисунок, выдать на экран результаты расчета и т. д. Конечно, сам исполнитель об этой цели ничего не знает — он просто исполняет программу. А вот программист, который эту программу составляет, обязательно должен знать цель — иначе и программу составлять незачем.

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

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

Итак, условие задачи на составление программы должно включать: 1. Язык программирования, на котором нужно составлять программу, или

список языков, из которых можно выбирать. 2. Список исполнителей и МП каждого из исполнителей. 3. Описание среды для каждого исполнителя. 4. Описание начальной обстановки. 5. Требования к конечной обстановке, то есть цель составления программы. Конечно, не обязательно все» это перечислять в условиях каждой задачи.

Некоторые части условия могут просто подразумеваться, как язык Робик или среда для системы Школьница в этой книге. Но программист всегда должен знать, что подразумевается, а что нужно задавать каждый раз.

Полезные советы (с чего начинать решение задачи и что делать дальше) Как составлять программу? В простейших случаях, когда нужная

последовательность предписаний очевидна сразу, остается только выбрать предписания из МПИ, расположить их в том порядке, в котором они будут исполняться, и набрать на клавиатуре, не нарушая общих правил языка Робик.

Впрочем, как видно из примеров, приведенных на с. 39-40, начинающим программистам это удается далеко не всегда.

А как быть, если нужная цепочка предписаний с первого взгляда не видна? Тогда попытайся составить план из «укрупненных» предписаний, как это только что было сделано в задаче о перестановке вагонов. Для каждого пункта общего плана составляется уточняющий план, затем уточняются все его пункты — и так до тех пор, пока не получится программа, в которой каждое предписание взято из МПИ. Такой прием позволяет разбить большую з а.д.а ч у н а ч а с т и — это особенно важно в крупных программах.

Впрочем, это легко сказать: «Составить план». Ведь сделать это — значит решить задачу больше, чем наполовину! Составление плана — самый трудный, но зато и самый интересный этап решения любой программистской задачи. И здесь невозмож-но привести какой-то универсальный рецепт, который позволил бы тебе без всяких размышлений составлять любые планы. Можно привести только самые общие рекомендации, которые помогут в трудных случаях.

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

Как только получится нужная конечная обстановка — постарайся записать найденный путь решения в виде плана. Теперь нужно составить уточняющий план для каждого пункта и так далее.

Можно порекомендовать и такой прием: попробуй придумать МПИ, в котором нужную программу было бы легко составить. Если это получается — составь программу, используя предписания из такого МПИ. Полученную программу можно считать планом и дальше уточнять его в обычном порядке.

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

Если выяснилось, что план составлен правильно, посмотри, нельзя ли его улучшить. Может быть, есть более простой путь решения, который позволит получить более короткую программу? Лучше уж повозиться лишних 10 минут с планом, чем пы-таться потом переделать программу длиной в несколько страниц. Между прочим, мы этого не сделали, составляя программу перестановки вагонов, — и напрасно! Для этой задачи можно подобрать короткий общий план и получить программу в полтора раза короче! Если ты не заметил этого до сих пор — вернись, пожалуйста, к началу этого урока и попробуй подобрать такой план.

Но вот программа готова. Теперь ее нужно проверить: ты вполне мог где-то ошибиться. Проверить синтаксис программы несложно: достаточно сравнить каждое предписание с МПИ и посмотреть, не нарушены ли где-нибудь правила языка. Смысл проверить сложнее. Один из самых распространенных способов проверки программ и планов — ручная прокрутка: ты вооружаешься карандашом и бумагой, снова рисуешь начальную обстановку и, играя роль исполнителя, выполняешь (на бумаге!) предписание за предписанием. Если получилась заданная конечная обстановка, то программа, скорее всего, правильна. Правда, далеко не все программы можно прокрутить вручную, да и полной гарантии этот метод не дает: ты ведь мог ошибиться дважды — один раз, составляя программу, а второй раз — проверяя ее. Поэтому, если поблизости есть ЭВМ — лучше запустить программу на машине, а она уж сама поможет найти и синтаксические, и смысловые ошибки. Такая проверка называется отладкой программы.

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

получили одинаковые результаты. А машина выдала другой результат. Инженеры долго искали неисправность и не смогли ее найти. Тогда академик С. А. Лебедев, главный конструктор МЭСМ, сам взялся за ручную прокрутку. Проработав всю ночь, он обнаружил, что оба математика ошиблись в одном и том же месте, а машина оказалась права!

И в заключение перечислим еще раз основные этапы составления программы: 1. Изучение условия задачи. 2. Составление общего плана. 3. Проверка (прокрутка) и улучшение общего плана. 4. Составление уточняющих планов для каждого пункта общего. 5. Написание текста программы по каждому уточняющему плану (с

комментариями). 6. Предварительная проверка программы (просмотр и ручная прокрутка). 7. Проверка программы на машине (отладка). Д ом аш н е е з а д а н и е . 1. Убедись, что тебе понятно, в каком смысле здесь употреблены слова: опрос,

утверждение, предписание, исполнитель, МПИ, синтаксис, протокол диалога, план, комментарий, среда для исполнителя, начальная и конечная обстановка в среде, руч-ная прокрутка, отладка.

2. Как формулируются первый и второй законы программирования? 3. Перечисли основные правила записи предписаний в языке Робик. Где

записываются комментарии и зачем они нужны? 4. Какие ты знаешь типы ошибок в программах? 5. Какую клавишу нужно нажимать в конце каждого предписания (после

комментария)? 6. Какие ты знаешь предписания из МП системы Школьница? 7. Какие сообщения системы об ошибках ты знаешь? В каких случаях они

выдаются? 8. Перечисли, что должно входить в условие задачи на составление программы. 9. Перечисли основные этапы составления и проверки программы. 10. Составь программы для исполнителя МУРАВЕЙ: а) переставить кубики так, чтобы получился белый квадрат (рис. 27);

б) переставить кубики так, чтобы из слова АПЕЛЬСИН получилось название

породы собак (перед началом работы МУРАВЕЙ находится под буквой А); в) ** заменить один кубик, чтобы получилась правильная формула кислоты

(рис. 28); г) поменять местами два кубика так, чтобы из слова КАРЕТА получилось

другое осмысленное слово (МУРАВЕЙ находится под буквой К).

11. Локомотив и вагоны расположены так, как показано на рис. 29.

а) собрать все цистерны на пути А, платформы — на пути Б, крытые вагоны —

на пути В; б) собрать все девять вагонов на пути А так, чтобы одинаковые вагоны не

стояли рядом; в) переставить вагоны так, чтобы на каждом пути у тупика стояла цистерна,

затем — платформа, а справа — крытый вагон.

ГЛАВА ВТОРАЯ СИНТАКСИЧЕСКИЕ ДИАГРАММЫ Четвертый урок Гибкие описания МПИ Как описать множество предписаний? Создание нового исполнителя — дело не простое. Инженерам, математикам и

программистам — разработчикам новых роботов и вычислительных машин—приходится решать немало трудных задач. И одна из них состоит в том, чтобы... описать множество предписаний нового исполнителя.

Казалось бы, что здесь сложного? Достаточно перечислить все предписания в инструкции — так, как это было сделано для исполнителей ДЕЖУРИК, МУРАВЕЙ и МАШИНИСТ. Но математикам хорошо известно, что перечисление — далеко не лучший способ описания больших множеств. Как, например, задать перечислением систему предписаний исполнителя ПЛЮСИК, умеющего складывать натуральные числа и печатать результат сложения. Предписания для этого исполнителя имеют вид

СЛОЖИТЬ 12345 С 25131. И ОТПЕЧАТАТЬ РЕЗУЛЬТАТ; СЛОЖИТЬ 1983 С 198319841985 И ОТПЕЧАТАТЬ РЕЗУЛЬТАТ; Перечислить в инструкции все числа? Но их же бесконечно много! Может

быть, написать в МПИ: СЛОЖИТЬ А С В И ОТПЕЧАТАТЬ РЕЗУЛЬТАТ; и пояснить, что вместо А и В можно подставить любые натуральные числа? Но

такое описание понятно человеку, а как растолковать его машине? С ее точки зрения все программы для ПЛЮСИКа должны будут выглядеть

одинаково: СЛОЖИТЬ А С В И ОТПЕЧАТАТЬ РЕЗУЛЬТАТ; СЛОЖИТЬ А С В И ОТПЕЧАТАТЬ РЕЗУЛЬТАТ; и так далее. Никаких изменений в тексте предписания система не допустит:

второй закон программирования неумолим. Чтобы справиться с этим затруднением, нужно подобрать достаточно строгий,

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

Что такое синтаксическая диаграмма? Синтаксическая диаграмма — это рисунок, объясняющий правило построения некоторого множества текстов. Диаграмма показывает, из каких частей складывается текст и в каком порядке эти части можно соединять. Состоит диаграмма из овальных и прямоугольных полей, связанных соеди-нительными линиями. На линиях проставляются стрелки, указывающие направление движения.

Каждое поле содержит часть текста (обычно — одно слово, число или символ), а соединительные линии показывают, в каком порядке эти части могут следовать друг за другом. Например, диаграмм а для МПИ ПЛЮСИКа может выглядеть так:

Треугольники с буквами Н и К обозначают начало и конец диаграммы. Чтобы получить текст по его синтаксической диаграмме, нужно двигаться по

соединительным линиям от начала диаграммы к ее концу строго по направлению стрелок. Встретив по дороге прямоугольник, нужно дословно выписать содержащийся в нем текст на отдельный лист бумаги. Встретив овал, также нужно выписать на бумагу текст, но не тот, который написан внутри овала, а другой! Какой же? На диаграмме 1 овал с надписью НАТУРАЛЬНОЕ ЧИСЛО, очевидно, означает, что на этом месте в тексте может стоять любое натуральное число. Но... это человеку очевидно, а для системы нужна еще одна синтаксическая диаграмма, объясняющая ей, что такое натуральное число. Ее составлением мы займемся позже, а пока запомним, что вместо овала нужно выписать текст, название которого записано в овале. На месте овальных полей могут появляться различные тексты, поэтому такие поля называют гибкими, в отличие от жестких прямоугольных полей, которые всегда заменяются одним и тем же текстом.

Текст, который подставляется вместо гибкого поля, называется значением этого поля (точно так же, как в алгебре значением переменной X называется число, подставляемое в формулу вместо этой буквы).

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

Обычно от начала к концу диаграммы можно пройти разными путями, получая

различные тексты. Таким образом, одна диаграмма позволяет описать синтаксис большого числа текстов, поэтому такие диаграммы удобно использовать для задания сложных МПИ. Но вообще-то их можно применять для описания структуры любых текстов, а не только предписаний. Например, диаграмма 2 описывает синтаксис одного из вариантов простого нераспространенного предложения в русском языке; а мате-матический термин «неравенство» можно пояснить при помощи такой диаграммы:

Ветвления и циклы. Обрати внимание, что на диаграмме 3 от первого гибкого

поля ко второму можно пройти четырьмя разными путями. Каждый путь соответствует одному из знаков >, <, >, <, которые могут стоять в неравенстве между арифме-тическими выражениями. Такая конструкция в диаграммах называется ветвлением.

Диаграммы можно использовать и для описания структуры отдельных слов или просто цепочек символов. Например, по диаграмме 4 получаются «слова» любой дли-ны, составленные из од ной только буквы А: А, ААА, АААААААААА АААААААААА и т. д.

А диаграмма 5 позволяет получать любые цепочки из плюсов и минусов,

разделенных точками. В начале и в конце цепочки обязательно стоит точка! Например, цепочки: -,+ . + . — . + . — . + . + . — . — . — . и . + . — . + . можно получить по диаграмме 5, а цепочки +. —., .+ +. — . + ., .—. — .. + ., . + . —.+—нельзя.

Почему? И как нужно изменить диаграмму 5, чтобы плюсы и минусы могли идти подряд в бом количестве, но между плюсом и минусом обязательно стояла бы точка?

Попробуй ответить на эти вопросы. Р еш е н и е . Решением будет диаграмма 6.

На диаграммах 4 — 6 хорошо видно, как можно получать тексты любой длины.

Для этого достаточно провести соединительную линию назад так, чтобы получился замкнутый путь. Если пройти по такому пути несколько раз, получится текст низ нескольких повторяющихся участков. Замкнутые пути называют также циклами: В диаграммах 5, 6 циклы используются вместе с ветвлением, что позволяет получать более разнообразные тексты.

Уточняющие диаграммы. Попробуем теперь составить обещанную диаграмму

для натурального числа. Запись натурального числа выглядит как последовательность цифр. На языке синтаксических диаграмм это утверждение можно записать так:

Форма этой диаграммы несколько отличается от предшествующих: слева от

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

линии можно передать словами «описывается диаграммой». Тогда весь этот- рисунок можно заменить такой фразой:

Гибкое поле НАТУРАЛЬНОЕ ЧИСЛО описывается диаграммой 8.

Впрочем, эта диаграмма уточняет значение гибкого поля не до конца: в ней

содержится еще одно гибкое поле — ЦИФРА, которое, в свою очередь, нуждается в уточнении. Описать его значение можно, например, так:

В этой диаграмме все поля — жесткие, так что в дальнейших уточнениях она не

нуждается. Как убрать лишний нуль? А теперь вернемся к диаграмме 7. На первый

взгляд кажется, что придраться не к чему: натуральное число — это последовательность цифр, а диаграмма 9 объясняет системе, что вместо гибкого поля ЦИФРА можно подставлять любой из символов 0, 1, ..., 9. Используя одновременно эти диаграммы, можно получать любые натуральные числа, например 121, 120345678909987654321, и т.д. Все правильно?

Но ведь по этим диаграммам можно получить и такие числа: 0005, 07898876, 0000000 и просто 0 (проверь это!). С первыми двумя числами еще можно было бы согласиться, хотя в математике не принято записывать лишние нули перед первой цифрой числа. Но вот нуль явно не подходит: он ведь не является натуральным числом!

Придется переделывать диаграмму 7 — она не совсем точно объясняет, что такое «натуральное число». Чтобы построить правильную диаграмму, - используем искусственный прием: введем новое гибкое поле НЕНУЛЕВАЯ ЦИФРА, которое можно описать так:

Теперь можно несколько по-другому объяснить, что такое ЦИФРА: это либо

НЕНУЛЕВАЯ ЦИФРА, либо нуль:

Диаграмму для натурального "числа можно теперь изобразить так:

Можно обойтись без поля ЦИФРА, но тогда диаграмма станет громоздкой и

прочесть ее будет труднее:

Основные обозначения. И в заключение приведем сводную таблицу

обозначений, применяемых в синтаксических диаграммах.

Третья перемена Вспомним правила и формулы

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

Начиная со следующего абзаца, здесь напечатаны вопросы по различным разделам школьной программы. … Если на какой-то из этих вопросов ты не можешь ответить (потому что еще не изучал этого в школе), загляни на с. 78 — там приведены краткие указания, которых будет вполне достаточно для составления диаграмм. Но если ты проходил соответствующий раздел, не торопись заглядывать в указания. Сначала постарайся ответить на вопрос сам, в крайнем случае открой учебник. После этого загляни в указания и сверь с ними свои ответы. А потом постарайся сам составить синтаксическую диаграмму, описывающую ответ. □ Кстати, обрати внимание, что между знаками О и □ в этом абзаце записан план твоей работы во время этой перемены. Можешь приступить к его исполнению.

Начнем с морфологии русского языка. 1. Из каких частей состоит слово? Какие части слова могут повторяться? Как

записываются сложные слова? А теперь несколько вопросов по синтаксису и пунктуации: 2. Как расставляются знаки препинания при перечислении однородных

предметов без использования союзов? 3. Как выделяется на письме прямая речь в конце предложения? Перейдем к математике. Один математический пример — диаграмму для

натурального числа — мы подробно рассмотрели на предыдущем уроке. 4. Как можно сформулировать правила записи любых целых чисел? 5. Как записываются действительные числа? 6. Что такое числовое выражение? 7. Как выглядит квадратное уравнение? И вообще в математике очень много конструкций, формул, правил, которые

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

Несколько примеров из химии (для старшеклассников): 8. Как выглядят общие формулы для кислот, оснований, солей? 9. Запишите общий вид уравнения реакции нейтрализации. А теперь несколько примеров, не относящихся к школьным предметам. Формы

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

УДОСТОВЕРЕНИЕ УЧАСТНИЦЫ 5 ВСЕСОЮЗНОЙ ЛЕТНЕЙ ШКОЛЫ ЮНЫХ ПРОГРАММИСТОВ ВАНШТЕЙН АННА УЧЕНИЦА 4 КЛАССА ШКОЛЫ № 130

ОРГКОМИТЕТ

Г. НОВОСИБИРСКА

Рисунок 30.

На рис. 30 изображено удостоверение участника Летней школы юных

программистов, отпечатанное вычислительной машиной. На рис. 31 — авиабилет, оформленный системой Сирена. Подумай, как описать их при помощи диаграмм? Как может выглядеть диаграмма для обложки тетради, дневника?

СПРАВКА Ребенок Петров Вадим, возраст 2,5 года, не посещал детский сад № 210 по состоянию здоровья с 10.12.1981 по 15.12.1981. В на- стоящее время здоров и может посещать детское учреждение. Врач:

Рис. 32. Медицинская справка

Для медицинской справки (рис. 32) и справки для покупки авиабилетов (рис.

33)?

СПРАВКА Выдана ____________________ в том, что он__ Действительно учится в ____ классе школы № _____

_________________________ района г. _____________ Дана для предъявления в кассу по продаже авиабилетов. «____» ____________ 198__ г. Директор школы __________________

Рис. 33. Справка для покупки авиабилетов

И, наконец, вернемся к программированию Подумай, какие предписания

должны входить в МПИ таких исполнителей: ПОВАР и ШОФЕР. Как описать их МПИ с помощью синтаксических диаграмм?

У к а з а н и я . 1. Слово состоит из одной или нескольких основ и одного окончания

(окончание может быть пустым). Если основ несколько (сложные слова), то они записываются подряд (как в слове «амперметр») или соединяются буквами «о» или «е». В состав каждой основы может входить одна или несколько приставок (не обязательно), корень (обязательно) и один или несколько суффиксов (не обязательно). Количество приставок, суффиксов и основ в одном слове правилами не ограничивается.

2. Перед перечисляемыми словами ставится двоеточие, между ними — запятые, например:

Предложения можно разделить на три вида: утверждения, вопросы, предписания.

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

4. Целое число — это нуль или последовательность цифр, которая начинается не с нуля. Перед целым числом может стоять + или −.

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

Пр и м е р ы : 546; 129,45; 0,6666; 3,5; 76,0 6. Числовое выражение — это одно или несколько чисел, соединенных

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

Пр и м е р ы :

54,2 (25 + 3) × 231,15:85 80458124

×+

7. Общее квадратное уравнение имеет вид - * ах2 + Ьх + с = 0, где а — действительное число, отличное от нуля, Ь и с - произвольные

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

8. Общая формула кислоты: HmA, где А — произвольный кислотный остаток, т — натуральное число (при т = 1 индекс не пишется).

Пр и м е р ы : HNO3, H2SO4.

Общая формула основания: М (ОН)n, где М — металл либо аммонийная группа NH4. При п = 1 скобки не ставятся и индекс не пишется.

Общая формула соли: Мm(А)n. 9. Формула для реакции нейтрализации: X • М(ОН)n + Y • HmA = Z • Me(A)k + V • Н2О. Попробуй сам составить диаграммы для описания всех текстов и формул,

описанных во время этой перемены. Подумай над МПИ перечисленных на с. 78 исполнителей. Пятый урок Как составлять и читать диаграммы Линейные и ветвящиеся структуры. Проще всего составлять и читать

диаграммы для таких текстов, которые всегда состоят из одних и тех же частей, расположенных в одном и том же порядке. Такие тексты часто встречаются в различных документах. Например, структуру справки, изображенной на рис. 32, можно описать диаграммой 14.

Структуру таких диаграмм называют линейной. В линейных диаграммах от

начала к концу можно пройти только одним путем. Единственное, что может в них меняться — это значения гибких полей.

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

Структуру диаграмм или участков диаграмм, в которых используется

ветвление, называют ветвящейся. Машина ставит оценку. Рассмотрим пример составления диаграммы с

линейными и ветвящимися участками. Сейчас в мире существует большое количество программ для обучения и проверки знаний студентов и школьников. Программа для проверки знаний обычно работает так: на экране терминала появляется вопрос или задача. Учащийся набирает ответ на клавиатуре, машина его проверяет и задает новый вопрос (задачу). В конце работы машина выставляет общую оценку и сообщает ее ученику и преподавателю.

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

Значение гибкого поля ОЦЕНКА можно описать ветвящейся диаграммой:

Если ты используешь диаграммы 16, 17, то сообщения машины могут быть

такими:

РАБОТА ОКОНЧЕНА. ТВОЯ ОЦЕНКА 5. ДО СВИДАНИЯ! РАБОТА ОКОНЧЕНА. ТВОЯ ОЦЕНКА 4. ДО СВИДАНИЯ! и так далее — всего четыре варианта. Но если работать с такой программой

приходится много раз, то однообразные реплики машины в конце концов надоедают и даже начинают раздражать. Программисты давно уже нашли противоядие от этого раз-дражения: предусматривается несколько разных вариантов итогового сообщения, и машина каждый раз выбирает один из них случайным образом. Достаточно предусмотреть четыре-пять вариантов, и диалог с машиной становится гораздо интереснее. Попробуем составить диаграмму для такого «многовариантного» сообщения.

Начинать его можно всегда одними и теми же словами, например РАБОТА ОКОНЧЕНА. Ничего страшного в этом нет. А вот дальше нужно допустить некоторое разнообразие текстов: не только ТВОЯ ОЦЕНКА, но и СЕГОДНЯ ТЫ ПОЛУЧИЛ, СТАВЛЮ ТЕБЕ и просто ОЦЕНКА. Затем, как и в прежнем варианте, может идти оценка. Было бы очень хорошо, если бы машина после оценки добавляла несколько слов — своих для каждого варианта. Например, после пятерки: ОТЛИЧНО!, МОЛО-ДЕЦ!, ПОЗДРАВЛЯЮ!, Я ЗА ТЕБЯ ОЧЕНЬ РАДА!; после четверки: НЕПЛОХО, ХОРОШО, В СЛЕДУЮЩИЙ РАЗ ПОСТАРАЙСЯ ОТВЕТИТЬ НА 5; после тройки: ПОСТАРАЙСЯ БЫТЬ ВНИМАТЕЛЬНЕЕ, СОВЕТУЮ ТЕБЕ ПОВТОРИТЬ ЭТОТ МАТЕРИАЛ; наконец, после двойки: НЕ РАССТРАИВАЙСЯ! ХОРОШЕНЬКО ВСЕ ПОВТОРИ — И В СЛЕДУЮЩИЙ РАЗ ТЫ НАВЕРНЯКА ОТВЕТИШЬ ЛУЧШЕ. «Прощальные слова» в конце сообщения тоже могут звучать по-разному: ДО СВИДАНИЯ!, ДО НОВЫХ ВСТРЕЧ!, Я БУДУ ЖДАТЬ ТВОЕГО ПРИХОДА! и так далее. Вероятно, ты легко сможешь придумать и другие варианты всех этих текстов.

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

Дальше возможны разные варианты, поэтому нужно использовать ветвление:

разделяем соединительную линию на несколько ветвей — по числу вариантов:

Рисуем жесткие поля на каждой ветви:

Теперь нужно предусмотреть поля для оценки и для реплики машины по

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

А сейчас может идти одна из четырех оценок, поэтому нужно снова применить ветвление.

Конечно, путь на этой развилке, в отличие от остальных, машина выберет не случайно, а в зависимости от результатов работы ученика.

Для каждой оценки, кроме двойки, предусмотрены различные варианты реплик, поэтому часть соединительных линий вновь разветвляется (диаграмма 18 г):

Остаются только «прощальные слова». Они опять-таки никак не зависят от

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

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

Телеграмма юного программиста. А теперь попробуй составить диаграмму

для телеграммы, в которой юный программист сообщает родителям о своем возвращении из Летней Школы. Текст выглядит так: ПРИЕДУ тогда-то САМОЛЕТОМ (или: ПОЕЗДОМ, АВТОБУСОМ), РЕЙС № ... (ПОЕЗД №.:., ВАГОН №...). ЮНЫЙ ПРОГРАММИСТ.

Примеры: ПРИЕДУ 12 АВГУСТА В 10-30 САМОЛЕТОМ, РЕЙС № 181. ЮНЫЙ ПРОГРАММИСТ. ПРИЕДУ 14 АВГУСТА В 14-30 ПОЕЗДОМ № 4, ВАГОН № 12. ЮНЫЙ ПРОГРАММИСТ. ПРИЕДУ 13 АВГУСТА В 15-30 АВТОБУСОМ. ЮНЫЙ ПРОГРАММИСТ. Циклические структуры. Синтаксические диаграммы часто приходится

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

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

Как известно, текст на русском языке может состоять из любого количества предложений. Это правило можно описать диаграммой 19, представленной на с. 88.

А первый закон программирования можно записать так:

Если теперь вспомнить правила языка Робик, то эту диаграмму можно сделать

более подробной:

Впоследствии мы еще вернемся к этой диаграмме, а пока отметим только, что

комментарий — это любая последовательность символов:

И еще пример циклической структуры — диаграмма для описания

морфологической структуры слова:

Убедись, что она в точности описывает Правило, приведенное в указаниях к

первому заданию (см. с. 78).■ А теперь просмотри указания к задачам 4 и 5 и попробуй составить по ним

диаграмму для описания действительного числа. О т в е т . Убедись, что по диаграмме 24 получаются числа 123,56; 0,205; —456;

+67,0, но не получаются «числа»: 5,; ,67; 8 — 7; 7,670.

Рекурсивные диаграммы. Попробуем составить диаграмму для описания

числовых выражений, содержащих только четыре знака арифметических операций: +, —, х и :. Казалось бы, ничего необычного в этом задании нет: выражение — это либо отдельное число, либо несколько чисел, связанных знаками операций. Диаграмма, описывающая это правило, выглядит так:

Все правильно? Да, ... если забыть о скобках. Но скобки в выражениях

встречаются довольно часто, поэтому кроме чисел в составе выражения могут встречаться участки, заключенные в скобки:

Гибкое поле, нарисованное между двумя скобками, специально оставлено пустым. Подумай, что должно быть там написано. Что может стоять в скобках? Либо отдельное число, либо несколько чисел, соединенных знаками операций и скобками, то есть... опять-таки числовое выражение!

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

Конечно же, какое-то выражение окажется самым внутренним и скобок в нем

не будет (на диаграмме мы пойдем через гибкое поле ДЕЙСТВИТЕЛЬНОЕ ЧИСЛО). Пожалуйста, не поленись аккуратно проверить, что диаграмма 25в правильно описывает такое, например, выражение:,

519+(21-16 х 5 :(1981 + 365 х (24-28))-5+(2 + 3)). Уточняющие Диаграммы, в которых содержится само уточняемое гибкое поле,

называются рекурсивными, а сам прием — рекурсией. С рекурсией в программировании ты еще не раз встретишься.

Четвертая перемена. Вернемся к нашим диаграммам Если ты еще не составил диаграммы для описания формул, перечисленных во

время предыдущей перемены, попробуй сделать это сейчас, а потом посмотри на приведенные здесь диаграммы 26 - 30 и сравни их со своими.

Шестой урок Элементарные конструкции языка Робик (Практикум по работе с синтаксическими диаграммами) На этом уроке мы познакомимся с некоторыми конструкциями, широко

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

Числа. Начнем с чисел. Во всех языках программирования, в том числе и в Робике, целые числа выглядят так же, как в математических текстах. Для их описания можно использовать диаграмму 28. А вот дробные числа записываются несколько иначе, чем это принято в математике. Вот диаграмма, описывающая гибкое поле ДРОБНОЕ ЧИСЛО:

Сравни этот рисунок с диаграммой 24. Бросается в глаза, что целая часть

отделяется от дробной с помощью точки, а не запятой, как в математических обозначениях. Например, 2.5, а не 2,5, 3.1415, а не 3,1415 и т. д. По словам А. Л. Брудно, автора одного из первых учебников по алголу-60: «Преимущество этого может оценить всякий, кому случалось писать перечень десятичных дробей».

Разберись, пожалуйста, какие из приведенных здесь чисел записаны правильно. Какие из них целые, а какие — дробные: 2, 3.1415, —245, +.0, 2,547, 2/3, —240.0, +0.

Составь диаграмму для описания гибкого поля ЧИСЛО, значением которого может быть любое целое либо дробное число языка Робик.

Ответы: целые числа: 2; —245; +0 дробные числа: 3.1415; —240.0. неправильно записаны: 2,547; 2/3; +.0 Имена. Во всех без исключения языках программирования широко

используются имена. Например, в Робике имена (или названия) есть у исполнителей: ДЕЖУРИК, МУРАВЕЙ, МАШИНИСТ. Для чего еще применяются имена, ты узнаешь на следующем уроке, а пока научись их правильно записывать. Во многих языках гибкое поле ИМЯ описывается диаграммой 33.

Из диаграммы видно, что любое имя может состоять из букв и цифр, причем

первой обязательно должна быть буква. Значением гибкого поля БУКВА может быть любая заглавная буква русского или латинского алфавита. Нарисовать такую диа-грамму несложно, но места она займет довольно много, поэтому здесь мы ее не приводим.

Вот примеры правильных имен: КРОКОДИЛ, ЛУНА2, СКОРОСТЬ, XI, В245ЛНЗ А в каждом из этих имен допущена ошибка. Постарайся найти ее сам: 1. ЛУНОХОД-2 2. СКОРОСТЬ СПУСКА 3. 15А 4. Х(1) 5. α1 Ответы: 1. Знак «-» — это не буква и не цифра. 2. Это два имени, а не одно: пробел — это тоже не буква и не цифра. 3. Имя начинается не с буквы. 4. Скобки — не буквы и не цифры. 5. α — греческая буква, а использовать можно только русские и латинские. Обрати внимание, что имена из двух слов, разделенных пробелом, в Робике

использовать нельзя. А такие имена иногда бывают очень нужны. Например, если при расчете космической траектории нужно хранить в блоках памяти числа, означающие массу Солнца, массу Земли и массу Марса, то эти блоки удобнее всего так и называть: «Масса Солнца» и так далее. Для того чтобы можно было составить имена из нескольких слов, в Робике используется специальный символ — подчеркивание ( __ ). Например МАССА _ СОЛНЦА, УСКОРЕНИЕ _ СВО ВОДНОГО _ ПАДЕНИЯ и т. д. Подчеркивание — это не буква и не цифра, поэтому диаграмма для Имен в Робике несколько отличается от диаграммы 33.

Но и это еще не все. Диаграмма 34 описывает ПРОСТОЕ ИМЯ.

Но, кроме простых, в Робике встречаются составные или, как их еще называют, индивидуальные имена. Чтобы разобраться с этой конструкцией, вернемся к предписанию ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ, которое мы использовали в первой главе.

Честно говоря, использовали мы его не совсем законно: ведь множества предписаний системы Школьница мы не описывали. К сожалению, сделать иначе было невозможно, и ты уже, вероятно, понял, почему. Дело в том, что в предписаниях ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ и ВЫКЛЮЧИТЬ ИСПОЛНИТЕЛЯ употребляется название исполнителя. Названия могут быть разными, поэтому для описания МПИ системы нужно было бы использовать синтаксические диаграммы с гибкими полями. Но ведь тогда ты еще не был знаком ни с гибкими полями, ни с синтаксическими диаграммами вообще! Пришлось пояснить эти предписания на примерах, без строгого описания их синтаксиса. Сейчас можно восполнить этот пробел.

Вот полная синтаксическая диаграмма:

Легко видеть, что те предписания, которыми ты пользовался в первой главе

(ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ ДЕЖУРИК, ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ МАШИНИСТ и т. д.), правильно описываются диаграммой. Но она позволяет нам уз-нать нечто новое об этом предписании. Прежде всего, слово ИСПОЛНИТЕЛЯ писать не обязательно (на диаграмме есть обходной путь). Например, можно писать ВКЛЮЧИТЬ МУРАВЕЙ.

Правда, это предписание не совсем правильно звучит по-русски, казалось бы, нужно писать ВКЛЮЧИТЬ МУРАВЬЯ. Но никакой ошибки здесь нет — предписание записано не на русском языке, а на языке Робик, а в Робике имена не склоняются! Ты уже давно мог заметить, что правила Робика не совпадают с правилами русского языка, хотя и очень на них похожи. Впрочем, если тебе трудно к этому можешь всегда записывать это предписание полностью — тогда никаких трудностей не будет.

Но самое интересное в диаграмме 35 — это два поля в конце, о существовании которых ты и не подозревал. Оказывается, кроме названия у каждого исполнителя может быть еще и собственное имя. Это бывает необходимо в тех случаях, когда в про-грамме используется несколько одинаковых исполнителей. Тогда для каждого из них нужно придумать собственное имя по обычным правилам Робика. Например, если в задаче на перестановку вагонов можно применить два электровоза, то приходится включать двух исполнителей МАШИНИСТ. Имена им можно придумать любые, на твой вкус. Например, ПЕРВЫЙ и ВТОРОЙ или МИША и МАША. Включаются они так:

ВКЛЮЧИТЬ МАШИНИСТ: МИША; ВКЛЮЧИТЬ МАШИНИСТ: МАША; Но недостаточно придумать имена и включить исполнителей — нужно еще

суметь объяснить системе, к какому исполнителю какое предписание относится:

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

Как видно из диаграммы 36, после имени или названия исполнителя ставится

двоеточие, а затем записывается текст предписания. Например, для управления исполнителями МАШИНИСТ: МИША и МАШИНИСТ: МАША можно использовать такие предписания:

МАША:ВПЕРЕД; МИША:ВПЕРЁД; МАША: ОТЦЕПИТЬ ВАГОН; и так далее. Предписание, перед которым указано имя или название исполнителя,

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

каждый из которых имеет свое имя. Например, у исполнителя МУРАВЕЙ в блоках памяти с именами X и Y хранятся координаты исполнителя на доске. Если таких ис-полнителей несколько (например, МУРАВЕЙ: МУРА и МУРАВЕЙ: ШУРА), то и координаты у каждого из них будут, естественно, свои. Чтобы их различить, используют индивидуальные имена: МУРА.Х, МУРА.Y, ШУРА.Х, ШУРА.Y. Такие имена могут встречаться почти всюду, где можно употреблять обычные имена, поэтому гибкое поле ИМЯ в синтаксических диаграммах Робика может с одинаковым успехом обозначать и простое, и индивидуальное имя. Вот теперь, наконец-то, можно нарисовать полные синтаксические диаграммы для гибкого поля ИМЯ в языке Робик.

В тех случаях, когда имя не может быть индивидуальным, в диаграммах

употребляется гибкое поле ПРОСТОЕ ИМЯ. Например, для выключения исполнителя, имеющего собственное имя, незачем указывать название — достаточно указать это имя. Поэтому диаграмма для этого предписания имеет вид:

Понятно, что если собственного имени у исполнителя нет, то ПРОСТОЕ ИМЯ

на диаграмме — это название исполнителя.

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

"ЭТО ТЕКСТ", "РАБОТА ЗАКОНЧЕНА. ВАША ОЦЕНКА — ОТЛИЧНО". К сожалению, слово «текст» используется и в другом смысле, например, «текст

программы», «математический текст», «текст этой книги». Обычно это не вызывает затруднений: всегда можно понять, в каком смысле употреблено это слово. Но первое время будь внимателен.

Диаграмма для описания текста:

Впрочем, эта диаграмма нуждается в одном уточнении: в тексте можно

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

описывающую числовое выражение. В большинстве языков программирования диаграмма для описания синтаксиса выражения оказывается гораздо сложнее, чем диаграмма 25в. А вот в Робике все просто:

Прочитать это можно так: выражение в Робике — это или число, или текст, или

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

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

И в заключение приведем несколько полезных советов по работе с синтаксическими диаграммами.

Составление диаграмм. Составлением диаграмм мы занимались на предыдущем уроке. Здесь попробуем записать нечто вроде общего плана. Итак, чтобы составить синтаксическую диаграмму для описания структуры какого-то текста, необходимо:

— нарисовать треугольник с буквой Н;

— если нужно, нарисовать слева от него уточняемое гибкое поле и соединить его с треугольником двойной линией;

— провести соединительную линию вправо от треугольника и нарисовать на ней стрелку;

— рассмотреть первый элемент описываемого текста (символ, слово, словосочетание):

— если текст всегда начинается с одного и того же элемента — изобразить его в виде жесткого или гибкого поля;

— если какой-то элемент в начале текста может присутствовать, но не является обязательным — использовать обход;

— если есть несколько вариантов начала — использовать ветвление и рассмотреть каждый вариант отдельно по тем же правилам;

— если продолжение текста не зависит от первого элемента, свести все ветви в одну, если зависит — продолжать построение диаграммы для каждой ветви отдельно;

— если первый элемент текста может повторяться несколько раз — использовать цикл;

— зарисовав первый элемент, строим по тем же правилам второй, третий и так далее;

— если для какого-то участка диаграмма не получается сразу — нужно обозначить этот участок гибким полем;

— если построен участок диаграммы, описывающий последний элемент текста — нарисовать треугольник с буквой К и закончить построение диаграммы.

Составленную диаграмму обязательно нужно проверить: Во-первых, не осталось ли неоконченных ветвей (в правильной диаграмме от

любого поля есть путь к концу диаграммы). Во-вторых, нет ли одинаковых участков (если они есть — их имеет смысл

обозначить гибким полем — тогда диаграмма упростится). В-третьих, нет ли других возможностей упростить диаграмму. Желательно сразу сделать «ручную прокрутку»: составить по диаграмме

несколько текстов и посмотреть, получается ли то, что нужно. Затем нужно составить уточняющие диаграммы для всех гибких полей и так далее.

Чтение диаграмм и генерация текстов. Получение какого-либо текста по готовой диаграмме называется генерацией текста. Генерация — задача несложная: нужно просто «двигаться» по соединительным линиям, выбирая путь на каждой развилке случайным образом и выписывая на лист бумаги дословно содержимое всех встретившихся жестких полей. Встретив гибкое поле, нужно найти уточняющую диаграмму и таким же образом «пройтись» по ней от начала до конца. Работая с большими диаграммами, желательно вести по ним кончиком карандаша или указки, чтобы не сбиться.

Несколько более сложная задача — анализ, или чтение, диаграммы. Читая диаграмму, нужно сформулировать для себя то правило построения тестов, которое описано этой диаграммой. Например, если ты ничего не знаешь о морфологии, но имеешь перед глазами диаграмму 23, то ты вполне можешь рассуждать так: «От начала диаграммы соединительная линия ведет к гибкому полю ПРИСТАВКА, значит, слово начинается с приставки. Впрочем, есть обходной путь, значит, приставка не обязательна: слово может начинаться с корня. Кроме того, приставок может быть несколько: есть соединительная линия, образующая цикл. Итак: в начале слова может стоять одна или несколько приставок, затем обязательно идет корень, дальше может появиться один или несколько суффиксов. Вся эта конструкция (приставки — корень — суффиксы) может повторяться несколько раз, причем конструкции эти записываются подряд или разделяются буквами Е или О. В конце слова может стоять окончание».

Заметь, сколько понадобилось слов, чтобы описать не такую уж сложную диаграмму!

При чтении этой книги тебе еще много раз нужно будет разбираться с синтаксическими диаграммами, описывающими МПИ различных исполнителей. Чтобы правильно их понимать, старайся первое время "расшифровывать" диаграммы словами, примерно так, как это только что было сделано. Скоро ты привыкнешь к диаграммам и начнешь понимать их без словесной расшифровки.

Д ом аш н е е з а д а н и е . 1. Какие из перечисленных здесь имен записаны по правилам языка Робик?

Какие из них являются индивидуальными? А5, 6НЗП, К155РУ5, Е2Е4, Е2-Е4, Е2 - Е4, КРОКОДИЛ, ДВА КРОКОДИЛА,

ДВА _ КРОКОДИЛА, 2 _ КРОКОДИЛА, ХВОСТ _ КРОКОДИЛА, КРОКОДИЛ.ХВОСТ, КРОКОДИЛ.ГЛАЗ, КРОКОДИЛ.ЗУБ, КРОКОДИЛ _ ХВОСТ.

2. Какие конструкции, приведенные здесь, можно назвать выражениями языка Робик? Какие из них являются целыми числами, какие — дробными числами, а какие — текстами:

2; 256.0; 314;: 3.1415; 2,5; -512; "КРОКОДИЛ"; КУРИЦА; "ДВА" ПЛЮС"ДВА"; "293.5"; "-.293,5";'

3. Найди среди перечисленных здесь конструкций правильные выражения языка Робик:

ВИННИ _ ПУХ, "ВИННИ-ПУХ", ВИННИ.ПУХ, 1981, "1982", ВИННИ ПУХ, ВИННИ, КОТЕНОК”ГАВ", "КОТЕ НОК ГАВ", "КОТЕНОК ПО ИМЕНИ ГАВ", "2 + 2",2 + 2.

4. На рис. 34 изображена схема железнодорожных путей, на которых работают

два исполнителя типа МАШИНИСТ. В тупике Б может поместиться вагон, но не локомотив. Необходимо собрать все цистерны на пути В, а все платформы — на пути А. Составить программу.

5. Составить синтаксическую диаграмму для описания полного (бесконечного)

текста стихотворения. «У попа была собака» а) с использованием рекурсии; б) с использованием цикла.

6**. Алфавит белибердинского языка состоит из трех символов: ¤. На основе

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

Смысл предложений языка не выяснен. На экспертизу в белибердоведческую

лабораторию поступили две новые надписи (рис. 35).

Предполагается, что одна из них содержит подлинный текст, а другая является

подделкой. Постарайся провести экспертизу и обнаружить подделку, если она есть. Проведи синтаксический разбор подлинного текста и определи, сколько в нем приказов, сколько вопросов и сколько извинений.

Глава третья

РАБОТА С ПАМЯТЬЮ

Седьмой урок Блоки памяти и их имена. Программирование диалога Предписание присваивания. Во время «экскурсии в мир роботов и ЭВМ» мы

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

ОЗУ машины Агат состоит из большого числа блоков, каждый из которых имеет свое имя. Что можно хранить в одном блоке? Во-первых, число (целое или действительное). Во-вторых, текст. В-третьих, рисунок. В-четвертых, программу или часть программы. В-пятых... впрочем, «в пятых» может и подождать. Сначала разберемся с первыми четырьмя.

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

Запомни! Содержимым блока памяти называется хранящаяся в нем информация, то есть число, текст, рисунок" и т. д. Чтобы работать с памятью, нужно, во-первых, уметь размещать информацию в

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

Как же выглядят в языке Робик предписания для размещения информации в памяти, для ее просмотра и обработки? Проще всего ответить на последнюю часть вопроса: н и к а к! В Робике нет никаких специальных предписаний для обработки информации, хранящейся в памяти ЭВМ.

Прочитав эти строки, ты, наверное, подумал: «Вот тебе и раз! Столько говорили об этой обработке, даже называли ее когда-то главным умением ЭВМ, а в Робике ее, оказывается, нет! Или здесь какой-то подвох?»

Подвох, действительно, есть. Предписаний для обработки информации нет в языке Робик, но это не значит, что их нет в системе Школьница! Просто для каждого

вида такой обработки есть свой исполнитель с подходящим МПИ. Например, для работы с числами можно включить исполнителя КАЛЬКУЛЯТОР, умеющего складывать, вычитать, делить и умножать, а можно поработать и с другим исполнителем, под названием МАТЕМАТИК; который немного знает тригонометрию и логарифмы. Есть свои исполнители для обработки текстов и рисунков. С некоторыми из них ты познакомишься на последних уроках в этой книге. А пока посмотрим, как сделать то, что можно сделать в Робике: разместить и просмотреть информацию.

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

Что такое выражение и имя, ты должен помнить (диаграммы 40 и 37).

На диаграмме 42 хорошо видно, что это предписание можно записывать по-

разному: от очень длинного, но зато понятного с первого взгляда варианта: ЗНАЧЕНИЕ ВЫРАЖЕНИЯ "КРОКОДИЛ" ПОМЕСТИТЬ В БЛОК ПАМЯТИ С ИМЕНЕМ ТЕРРАРИУМ _ ДЛЯ _ КРОКОДИЛА; до совсем короткого; 5 ПРИСВОИТЬ А; Первое время, пока ты не привык к этому предписанию, лучше записывать его в

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

Значения имен и выражений. Обрати внимание, что в записи предписания присваивания появилось новое для тебя сочетание слов: значение выражения. До сих пор мы говорили только о значениях гибких полей, так что здесь нужны некоторые пояснения. Как ты помнишь, выражение в Робике — это имя, текст, число или вызов процедуры. Запомни, что если выражение — имя, то значением выражения называется содержимое блока памяти с этим именем. Если же выражение — текст или число, то этот текст или это число и называется значением выражения. О четвертом варианте — вызове процедуры — забудь до девятого урока.

Например, значением выражения "КРОКОДИЛ" будет сам текст "КРОКОДИЛ", значением выражения 5 будет число 5, а вот значением выражения КРОКОДИЛ будет значение имени КРОКОДИЛ, то есть та информация, которая содержится в блоке памяти с именем КРОКОДИЛ.

Итак, в результате исполнения предписания ЗНАЧЕНИЕ ВЫРАЖЕНИЯ 1981 ПОМЕСТИТЬ В БЛОК ПАМЯТИ С ИМЕНЕМ ГОД; имя год получит значение 1981 (то есть в блок памяти с именем ГОД будет

помещено такое число). То же самое предписание можно записать короче:

ЗНАЧЕНИЕ 1981 ПРИСВОИТЬ ИМЕНИ ГОД; В результате присваивания ЗНАЧЕНИЕ "ГОД "ПРИСВОИТЬ ИМЕНИ КАЛЕНДАРЬ; имя КАЛЕНДАРЬ получит значение "ГОД", то есть текст "ГОД" будет помещен

в блок с этим именем. А вот очень похожее присваивание ЗНАЧЕНИЕ ГОД ПРИСВОИТЬ ИМЕНИ КАЛЕНДАРЬ- выполняется совершенно по-другому: в этом случае имени КАЛЕНДАРЬ будет

присвоено значение имени ГОД, то есть то самое число 1981, которое хранится в блоке с именем ГОД.

Стоп! Прежде чем читать дальше, убедись, что тебе понятно, чем отличаются друг от друга эти два предписания и в чем разница между именем ГОД и текстом "ГОД". Читать значение любого имени можно много раз. Но если присвоить этому

имени новое значение, то старое потеряется безвозвратно. Например, после выполнения предписаний:

ЗНАЧЕНИЕ ГОД ПРИСВОИТЬ А; ГОД ПРИСВОИТЬ ИМЕНИ В; ГОД ПРИСВОИТЬ С; имена А, В и С получат одно и то же значение — число 1981 и в блоке памяти с

именем ГОД останется такое же число. Но если набрать на терминале предписание "НОВЫЙ ГОД" ПРИСВОИТЬ ИМЕНИ ГОД; то значением этого имени вместо числа 1981 станет текст "НОВЫЙ ГОД". Определи, какие значения получат имена МУ ШКА, ЛЯГУШКА, УЖ, ЕЖ,

ПЕРВЫЙ _ ТЕРЕМОК, ВТОРОЙ _ ТЕРЕМОК, ТРЕТИЙ __ ТЕРЕМОК после выполнения программы:

ЗНАЧЕНИЕ 1981 ПРИСВОИТЬ ИМЕНИ МУШКА; ЗНАЧЕНИЕ "МУШКА" ПРИСВОИТЬ ИМЕНИ ЛЯГУШКА; ЗНАЧЕНИЕ ЛЯГУШКА ПРИСВОИТЬ ИМЕНИ УЖ; ЗНАЧЕНИЕ УЖ ПРИСВОИТЬ ИМЕНИ ЕЖ; ЗНАЧЕНИЕ ЕЖ ПРИСВОИТЬ ИМЕНИ ПЕРВЫЙ _ ТЕРЕМОК; ЗНАЧЕНИЕ ''ЛЯГУШКА" ПРИСВОИТЬ ИМЕНИ УЖ; ЗНАЧЕНИЕ "УЖ" ПРИСВОИТЬ ИМЕНИ ЕЖ; ЗНАЧЕНИЕ "ЕЖ " ПРИСВОИТЬ ИМЕНИ ВТОРОЙ _ ТЕРЕМОК; ЗНАЧЕНИЕ МУШКА ПРИСВОИТЬ ИМЕНИ ТРЕТИЙ _ ТЕРЕМОК; ЗНАЧЕНИЕ ЛЯГУШКА ПРИСВОИТЬ ИМЕНИ ТРЕТИЙ _ ТЕРЕМОК; ЗНАЧЕНИЕ УЖ ПРИСВОИТЬ ИМЕНИ ТРЕТИЙ _ ТЕРЕМОК;

ЗНАЧЕНИЕ ЕЖ ПРИСВОИТЬ ИМЕНИ ТРЕТИЙ _ ТЕРЕМОК; О т в е т . Приведем таблицу значений имен:

Имя Значение

МУШКА число 1981 ЛЯГУШКА текст "МУШКА" УЖ текст "ЛЯГУШКА" ЕЖ текст "УЖ" ПЕРВЫЙ___ТЕРЕМОК текст "МУШКА" ВТОРОЙ___ТЕРЕМОК текст "ЕЖ" ТРЕТИЙ___ТЕРЕМОК текст "УЖ"

Что чему присваивается? Обрати внимание, что в предписании присваивания

слово «присвоить» означает то же самое, что «поместить в блок памяти». В газетах и журналах это слово очень часто употребляется в совершенно другом смысле (например, «Присвоить Новосибирскому университету имя Ленинского комсомола»). Начинающих программистов это иногда сбивает с толку и они путают, что чему присваивается. Например, предписание

1981 ПРИСВОИТЬ ГОД; иногда ухитряются прочесть так: «Числу 1981 присвоить имя ГОД». Запомни! В программировании значение присваивается имени, а не наоборот. Пока ты привыкнешь к такому употреблению этого слова, старайся не

использовать самой короткой формы предписания присваивания: вместо 1970 ПРИСВОИТЬ ГОД _ РОЖДЕНИЯ пиши ЗНАЧЕНИЕ 1970 ПРИСВОИТЬ ИМЕНИ ГОД _ РОЖДЕНИЯ; — так труднее ошибиться. Откуда берутся имена. Вероятно, ты уже обратил внимание, что одни и те же

имена в наших примерах получали различные значения - от коротких чисел до довольно длинных текстов. Возможно, тебя уже заинтересовал вопрос: не может ли длинный текст «переполнить» блок, в котором раньше хранилось маленькое число или короткий текст. Оказывается, не может! В системе Школьница блоки памяти ведут себя как резиновые, Они могут менять размер и автоматически увеличиваться или уменьшаться в зависимости от того, какое значение в них нужно поместить. Как это сделано — отдельный и очень интересный вопрос, но в этой книге, к сожалению, нам не хватит места, чтобы подробно на него ответить.

А кстати, откуда вообще берутся блоки памяти и их имена? Мы довольно смело использовали в примерах самые разные имена, не интересуясь тем, есть ли в ОЗУ блоки с такими именами. Неужели в запоминающем устройстве заранее предус-мотрены блоки для всех имен, какие только можно придумать? Можешь считать, что так! Во всяком случае, какое бы имя ты не использовал в программе, нужный блок всегда найдется.

Конечно, не нужно думать, что в системе все время существуют блоки с именами «на все случаи жизни». Наоборот, при включении машины почти все блоки вообще не имеют имен, а содержимое у них у все: одинаковое: ПУСТО. Как только в твоей программе встречается новое имя, которому ты присваиваешь какое-то значение, система сама заведет блок с этим именем и разместит в нем нужное значение. Если же ты по ошибке попытаешься прочесть значение имени, которому ничего еще не присваивал, то система и блока заводить не будет, а просто использует пустое значение. Так что ты можешь условно считать, что для любого придуманного и даже еще не придуманного тобой имени в системе заранее заготовлен блок, имеющий перед началом работы программы пустое содержимое (пустой блок, одним словом).

Впрочем, есть и такие блоки, которые действительно всегда существуют в системе. Это, например, блок с именем ПУСТО, который всегда имеет пустое содержимое. Им можно воспользоваться, чтобы уничтожить содержимое любого блока памяти и освободить занимаемое им место. Например, после исполнения предписания

ПУСТО ПРИСВОИТЬ ИМЕНИ ГОД; имя ГОД не будет иметь никакого значения, то есть система просто уберет этот

блок из памяти, а освободившееся место можно будет использовать под другие блоки. Присвоить имени ПУСТО другое значение нельзя: такая попытка сразу вызовет

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

Поговори со мной, система! В первой главе приводились примеры диалога с

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

В начале этой книги уже говорилось о том, что для «разговора» с человеком система должна уметь выдавать сообщения на экран телевизора или на другие устройства и принимать сообщения, поступающие с различных устройств (например, с клавиатуры). Для приема и выдачи сообщений в Робике предусмотрено два предписания: ПРЕДПИСАНИЕ ПРИНЯТЬ и ПРЕДПИСАНИЕ ВЫДАТЬ. Синтаксис последнего описан диаграммой 43.

На первый взгляд, диаграмма выглядит страшновато, особенно, если учесть, что

здесь она приведена не полностью! Ее изучение могло бы стать неплохим упражнением к пятому уроку — в ней использованы чуть ли не все описанные там конструкции: линейные, ветвящиеся, циклические структуры, обходы, гибкие поля — нет только ре-курсии.

Впрочем, присмотревшись повнимательнее, можно понять, что ничего страшного в диаграмме нет. Займемся для начала тем вариантом этого предписания,

которое получится, если мы пройдем от Н к К по прямой, никуда не сворачивая. Подставляя разные значения гибкого поля ВЫРАЖЕНИЕ, мы можем получить по этой диаграмме такие, например, предписания:

ВЫДАТЬ НА ЭКРАН СООБЩЕНИЕ: "ЗДРАВСТВУЙТЕ!"; ВЫДАТЬ НА ЭКРАН СООБЩЕНИЕ: 1982; ВЫДАТЬ НА ЭКРАН СООБЩЕНИЕ: ГОД _ РОЖДЕНИЯ; Скорее всего ты уже понял, как они будут выполнены: на экране телевизора

появится сообщение, то есть текст или число. Легко сообразить, что на экран попадает значение указанного в предписании выражения. Например, если имя ГОД _ РОЖДЕНИЯ по-прежнему имеет значение 1970 (с. 110), то после выполнения трех этих предписаний изображение на экране будет выглядеть так:

ЗДРАВСТВУЙТЕ! 1982 1970 Обрати внимание, что кавычки не выводятся на экран! Это сделано для того, чтобы текст на экране легче было читать. Кстати, предписание ВЫДАТЬ можно использовать для того, чтобы

просмотреть на экране значение какого-то имени. Например, если тебя интересует значение имени ПЕРВЫЙ _ ТЕРЕМОК, ты можешь набрать такое предписание:

ВЫДАТЬ НА ЭКРАН СООБЩЕНИЕ: ПЕРВЫЙ _ ТЕРЕМОК; Для полей НА ЭКРАН и СООБЩЕНИЕ предусмотрены обходные пути, так что

эти слова в предписании можно не указывать: ВЫДАТЬ: ПЕРВЫЙ _ТЕРЕМОК; Сообщение может быть и более сложным: на диаграмме предусмотрен цикл,

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

ВЫДАТЬ: 1981, ГОД _ РОЖДЕНИЯ, 1983; ВЫДАТЬ: "ТЕРЕМОК", УЖ, ЕЖ, МУШКА; на экране появятся две строки: 1981 1970 1983 ТЕРЕМОКЛЯГУШКАУЖ 1981 Заметь, что перед каждым числом машина вставляет один пробел, а вот тексты

никак не разделяются на экране. Конечно, разбираться в таком месиве очень неудобно, поэтому программисты обычно используют такой прием: перед каждым именем, значение которого нужно напечатать, они вставляют в сообщение какой-нибудь текст, чаще всего — несколько пробелов и то самое имя, значение которого должно быть выдано на экран. Например:

ВЫДАТЬ: 1981, "ГОД _ РОЖДЕНИЯ =", ГОД РОЖДЕНИЯ, " ", 1983; ВЫДАТЬ: "ТЕРЕМОК: ", УЖ, " ", ЕЖ, " ", МУШКА; Теперь сообщение на экране будет выглядеть так: 1981 ГОД _ РОЖДЕНИЯ = 1970 1983

ТЕРЕМОК: ЛЯГУШКА УЖ 1981 Пожалуйста, просмотри еще раз приведенные примеры. Убедись, что тебе

понятно, для чего использованы тексты "ГОД__РОЖДЕНИЯ =" и "ТЕРЕМОК". Вспомни, в чем разница между именем УЖ и текстом "УЖ".

Если попытаться выдать значение имени, которому еще ничего не присвоено, то на экране появится слово

"ПУСТО" Заметь, что это слово выдается в кавычках, в отличие от текста!

А теперь потренируйся сам: попробуй выписать на отдельном листе бумаги сообщения, которые будут появляться на экране терминала во время выполнения такой программы:

ЗНАЧЕНИЕ "СИНИЦА" ПРИСВОИТЬ ИМЕНИ ЖУРАВЛЬ; ЗНАЧЕНИЕ 25 ПРИСВОИТЬ ИМЕНИ ЧИСЛО _ ПТИЦ; ЗНАЧЕНИЕ ЖУРАВЛЬ ПРИСВОИТЬ В _ НЕБЕ; ВЫДАТЬ: "ЧИСЛО ПТИЦ:", ЧИСЛО _ ПТИЦ, ", А В НЕБЕ_", ЖУРАВЛЬ; "КУРИЦА" ПРИСВОИТЬ КУРЯТНИК; "ГУСЬ" ПРИСВОИТЬ КУРЯТНИК; "ИНДЮК" ПРИСВОИТЬ КУРЯТНИК; "ЛИСА" ПРИСВОИТЬ КУРЯТНИК; ВЫДАТЬ СООБЩЕНИЕ: "СЕЙЧАС В КУРЯТНИКЕ — ", КУРЯТНИК; КУРИЦА ПРИСВОИТЬ КУРЯТНИК; ГУСЬ ПРИСВОИТЬ КУРЯТНИК; ВЫДАТЬ: "А СЕЙЧАС В КУРЯТНИКЕ-", КУРЯТНИК; Ответ. ЧИСЛО ПТИЦ: 25, А В НЕБЕ – СИНИЦА СЕЙЧАС В КУРЯТНИКЕ – ЛИСА А СЕЙЧАС В КУРЯТНИКЕ - "ПУСТО" Сообщение можно выдать не только на экран, но и на бумагу. Как это сделать,

видно из диаграммы! Например, если набрать предписание ВЫДАТЬ НА БУМАГУ СООБЩЕНИЕ: "МОЙ ГОД РОЖДЕНИЯ -", ГОД___РОЖДЕНИЯ: то на бумажной ленте печатающего устройства появится сообщение МОЙ ГОД РОЖДЕНИЯ – 1970 Система принимает сообщение. Ты, конечно, помнишь, что во время диалога

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

Для приема сообщений существует ПРЕДПИСАНИЕ ПРИНЯТЬ:

Например: ПРИНЯТЬ С КЛАВИАТУРЫ СООБЩЕНИЕ И ПРИСВОИТЬ ИМЕНИ: ОТВЕТ; или просто ПРИНЯТЬ: ОТВЕТ; ПРИНЯТЬ: ГОД—РОЖДЕНИЯ; и так далее. Встретив в программе предписание ПРИНЯТЬ С КЛАВИАТУРЫ, система

выдает на экран вопросительный, знак и ждет, пока человек, работающий за пультом, наберет свое сообщение. Весь набранный текст — от начала строки до нажатия на

клавишу — записывается в блок памяти с указанным именем. Например, если предписание выглядело так:

ПРИНЯТЬ: ГОД___РОЖДЕНИЯ; а ты набрал такое сообщение:

МОЙ ГОД РОЖДЕНИЯ – 1972

то значением имени ГОД _РОЖДЕНИЯ станет текст "МОЙ ГОД РОЖДЕНИЯ _ 1972"

Заметь, что сам символ в сообщение не входит, зато кавычки вокруг текста система подставляет сама.

Если нужно присвоить имени числовое, а не текстовое значение, применяется другая форма этого предписания:

ПРИНЯТЬ ЧИСЛО

Сравни два примера:

ПРЕДПИСАНИЕ: ПРИНЯТЬ: ОЦЕНКА; ПРИНЯТЬ ЧИСЛО:ОЦЕНКА;

Система запрашивает: Человек набирает: Имя ОЦЕНКА получает значение:

? 5

"5"

? 5

5 Если нужно принять несколько чисел, расположенных на одной строке,

необходимо использовать вариант ПРИНЯТЬ ЧИСЛА Например: ПРИНЯТЬ ЧИСЛА:

ХИМИЯ, ФИЗИКА, ИСТОРИЯ, ЯЗЫК; Если теперь ты наберешь в строчку 2, 3, 5, 5 то имя ХИМИЯ получит значение 2, имя ФИЗИКА — значение 3, а остальные

два имени — значение 5. На этом уроке мы словно забыли, что кроме имен блоков памяти есть еще

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

Таким образом, в блоках памяти, кроме чисел, текстов и рисунков могут храниться еще и описания исполнителей — это и есть обещанное «в-пятых». Если исполнитель включен, то его имя, конечно, является защищенным: ему нельзя присвоить никакое другое значение. Если название или собственное имя исполнителя попадается в предписании ВЫДАТЬ, то выдается текст

"ИСПОЛНИТЕЛЬ" Пятая перемена Ручная прокрутка В первой главе уже упоминалось о ручной прокрутке: чтобы проверить

правильность плана или программы, нужно нарисовать на листе бумаги начальную обстановку, а затем «исполнять» предписания по одному, отмечая все изменения, происходящие при этом в среде. Важнейшая составная часть среды в любой программе — запоминающее устройство. Поэтому для ручной прокрутки нужно уметь изображать на бумаге начальную обстановку в ОЗУ и происходящие в нем изменения. Разумеется, нас интересуют не все блоки памяти, а только те из них, которые используются в про-грамме.

Удобнее всего рисовать блоки и их значения мелом на школьной доске: ведь для того, чтобы поместить в блок новое содержимое, нужно уничтожить (стереть) старое — на доске это сделать очень просто. Каждый блок можно рисовать в виде домика, на крыше которого записано имя блока, а внутри размещается содержимое. Например, на рис. 36 изображен блок с именем ГОД и содержимым 1981. Защищенные имена на таком рисунке нужно как-то выделить (например, обвести их кружком или отметить цветными мелками).

Телевизор, магнитофон, дисковод и Рис. 36 другие устройства, входящие в

состав системы, тоже составляют часть среды. Их тоже нужно как-то изобразить на доске. Например, для прокрутки программы, напечатанной на с. 109, можно заготовить такую картинку (рис. 37, а).

Теперь можно «исполнять» программу. Чтобы присвоить значение любому

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

Проследим, например, за прокруткой программы со с. 114. Перед началом

работы нарисуем таблицу (рис. 38, а). После исполнения первых четырех предписаний таблица будет выглядеть так (рис. 38,б):

Следующие четыре предписания работают с одним и тем же именем

КУРЯТНИК, причем каждое новое значение стирает предыдущее. Поэтому после выполнения второго предписания ВЫДАТЬ вид таблицы изменится (рис. 38, в).

Теперь хорошо видно, что имена КУРИЦА и ГУСЬ никаких значений не имеют

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

А теперь попробуй сделать такую же прокрутку для программы со с. 109 и

убедись, что таблица действительно получается такой, как показано на рис. 37, б.

Восьмой урок Процедуры Храните программы в ОЗУ! Мы уже много раз упоминали о программах,

хранящихся в памяти ЭВМ. Такие программы называются процедурами. Имя блока памяти, в котором хранится программа, называется именем процедуры. Обычно стараются выбирать такие имена, чтобы по ним можно было понять, для чего процедура предназначена.

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

На диаграмме видно, что процедуру можно вызвать двумя способами: написать

перед именем процедуры слово ВЫЗВАТЬ или поставить после имени процедуры круглые скобки, в которых могут быть указаны значения параметров (что это такое, ты узнаешь на следующем уроке). Например, если программа для робота ДЕЖУРИК, описанного в первой главе, хранится в блоке с именем ДЕЖУРСТВО, то вызвать ее можно такими способами:

ВЫЗВАТЬ ПРОЦЕДУРУ ДЕЖУРСТВО; ВЫЗВАТЬ ДЕЖУРСТВО; ДЕЖУРСТВО ( );

А можно и так: ВЫЗВАТЬ ДЕЖУРСТВО (); Как запоминаются процедуры? Посмотрим теперь, что нужно сделать, чтобы

система запомнила процедуру. Проследим за работой юной программистки Оли, набирающей на клавиатуре процедуру ДЕЖУРСТВО.

Девочка только что включила машину. Система Школьница уже поздоровалась с ней и выдала на экран звездочку — приглашение к диалогу (если ты забыл, как происходит диалог с системой, вернись на с. 46). Сейчас Оля набирает новое для тебя предписание языка Робик:

ЗАПОМНИТЬ ПРОЦЕДУРУ ДЕЖУРСТВО; Нажата клавиша перевода строки и с машиной начинают происходить странные

вещи. Сначала на несколько секунд включается дисковод. Затем изображение на экране телевизора мгновенно гаснет, раздается звуковой сигнал, на верхней строке появляется надпись РЕДАКТОР, а на следующей строке вместо привычной звездочки цифра 1.

Что же произошло? Это включился РЕДАКТОР — один из исполнителей, входящих в состав системы Школьница. РЕДАКТОР предназначен для запоминания, просмотра и исправления различных текстов, в том числе текстов процедур. Этот исполнитель имеет два режима работы: режим запоминания и режим исправления. Если включить этот исполнитель с помощью предписания ЗАПОМНИТЬ ПРОЦЕДУРУ, как это сделала Оля, то он начинает работать в режиме запоминания и каждое следующее предписание будет записывать в запоминающее устройство вместо

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

После того как Оля наберет первые три предписания, текст на экране телевизора будет выглядеть так:

РЕДАКТОР 1 ОТКРОЙ ОКНО; 2 СОТРИ С ДОСКИ; 3 ЗАКРОЙ ОКНО; 4 Ты уже, наверное, понял, что заголовок и номера строк в этом тексте выдала

система Школьница (точнее говоря, исполнитель РЕДАКТОР, входящий в состав этой системы), а все предписания набирала Оля. Еще раз обрати внимание на то, что машина сейчас не исполняет и даже не проверяет эти предписания, а только запоминает их.

Кстати, а для чего нужны номера строк? Сейчас увидим. Вероятно, ты заметил, что Оля допустила ошибку. Если не заметил, вернись и попробуй ее |найти. Нашел? Конечно же, она пропустила предписание НАМОЧИ ТРЯПКУ. Чтобы вставить его на место, придется перейти в другой режим — режим исправления. Для этого достаточно в ответ на очередное приглашение (в нашем примере — в ответ на номер 4) нажать на клавишу перевода строки, не набирая никакого предписания. При этом на экране появится другое приглашение — двоеточие. Это значит, что РЕДАКТОР перешел в режим исправления и готов принять и исполнить любое предписание из своего МПИ. Оля набирает нужное предписание:

ВСТАВИТЬ 2; Это значит, что перед второй строкой нужно вставить одно или несколько

предписаний. Теперь РЕДАКТОР автоматически возвращается в режим запоминания и выдает на экран номер нужной строки:

2 Оля набирает НАМОЧИ ТРЯПКУ; и переводит строку. На экране появляется цифра 3, исполнитель ждет

продолжения, но программистка сразу переводит строку, тем самым переключая РЕ-ДАКТОР в режим исправления. На экране вновь появляется двоеточие. Теперь можно дописать последнее предписание процедуры. Для этого Оля переводит РЕДАКТОР в режим запоминания:

ДОПИСАТЬ; На экране появляется цифра 5, Оля набирает предписание СЯДЬ НА МЕСТО; Появляется цифра 6, но Оля опять меняет режим, нажав клавишу перевода

строки. Для контроля она решила просмотреть полный текст процедуры и для этого набирает новое предписание:

ВЫДАТЬ; На экране появляется полный текст процедуры: 0 ПРОЦЕДУРА ДЕЖУРСТВО; 1 ОТКРОЙ ОКНО; 2 НАМОЧИ ТРЯПКУ; 3 СОТРИ С ДОСКИ; 4 3АКРОЙОКНО; 5 СЯДЬ НА МЕСТО; Обрати внимание, что номера предписаний СОТРИ С ДОСКИ и ЗАКРОЙ

ОКНО автоматически увеличились на единицу, когда Оля вставила перед ними новое предписание. А строчку с нулевым номером РЕДАКТОР добавил сам.

Убедившись, что все правильно, Оля набирает еще одно, последнее предписание из МПИ РЕДАКТОРа:

ЗАКОНЧИТЬ;

Какую-то долю секунды ничего не происходит: система просматривает текст процедуры в поисках ошибок. Не обнаружив ошибок, она запрашивает:

Записывать на диск? Оля отвечает: ДА Вновь на секунду включается дисковод: теперь текст процедуры хранится на

магнитном диске и не потеряется при случайном выключении машины. Затем раздается звуковой сигнал, гаснет надпись РЕДАКТОР, экран очищается и на нем появляется звездочка. Система выключила РЕДАКТОР и вернулась в обычный режим диалога.

* * *

Предписания, входящие в состав процедур, называют операторами, а обычные

предписания, которые исполняются сразу, называют директивами. Почти все предписания из МПИ различных исполнителей могут быть и

операторами, и директивами. Такие предписания называют универсальными. Если ты набираешь универсальное предписание в обычном режиме, когда система выдает на экран звездочку, получится директива, которую система тут же исполнит (если, конечно, ты набрал ее без ошибок). А если такое же предписание набрать в режиме запоминания процедуры, когда система выдает номер строки, получится оператор.

Некоторые предписания могут быть только директивами, то есть их нельзя использовать в составе процедур. К ним относятся известные тебе предписания из МПИ РЕДАКТОРа, предписание ЗАПОМНИТЬ ПРОЦЕДУРУ и некоторые другие.

Полная синтаксическая диаграмма для процедуры приведена на с. 124 (диаграмма 46).

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

Во-первых, заметим, что запоминание процедуры в каком-то смысле напоминает присваивание: некоторому имени (имени процедуры) присваивается новое значение — текст этой процедуры. Если такое же значение нужно присвоить другому имени, можно использовать обычное присваивание. Например, предписание

ЗНАЧЕНИЕ ДЕЖУРСТВО ПРИСВОИТЬ ИМЕНИ УБОРКА; позволит записать в блок с именем УБОРКА точно такое же описание

процедуры. Теперь ты можешь с одинаковым успехом писать ВЫЗВАТЬ ПРОЦЕДУРУ ДЕЖУРСТВО; ИЛИ ВЫЗВАТЬ ПРОЦЕДУРУ УБОРКА; в обоих случаях робот ДЕЖУРИК начнет исполнять одни и те же предписания. И все-таки имя процедуры — не совсем обычное имя! Это станет заметным,

если ты попробуешь присвоить ему другое значение, например: ЗНАЧЕНИЕ 5 ПРИСВОИТЬ ИМЕНИ УБОРКА; Система исполнит такое предписание не сразу! Сперва она переспросит: Процедура УБОРКА: Стирать? Если на этот вопрос ответить ДА, то машина исполнит предписание, если

ответить НЕТ или набрать любой другой ответ, предписание останется неисполненным. Такой контроль предусмотрен для того, чтобы избежать случайных ошибок: ведь описание большой процедуры занимает много времени и было бы обидно из-за минутной забывчивости или описки уничтожить результат своего или, тем более, чужого труда. Таким образом, имена процедур частично защищенные: им можно присваивать другие значения, но только после некоторых «переговоров» с системой. Впрочем, во время исполнения процедуры ее имя будет уже не частично, а полностью защищенным и его значение вообще нельзя будет изменить!

Остановиться, оглянуться... А теперь стоп! Процедуры — это важнейшая конструкция современных языков программирования. Ты обязательно должен хорошо разобраться с тем, как их запоминать и как вызывать. Убедись, пожалуйста, что тебе понятно: — что такое процедура (приведем полное определение):

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

понимают разницы между запоминанием и вызовом процедуры);

Помни, что все операторы в процедуре будут исполняться только тогда, когда процедуру вызывают, а не тогда, когда ее запоминают. — что такое операторы и чем они отличаются от директив; —для чего нужны номера строк в процедуре; — в каких случаях система выдает на экран звездочку *, в каких — двоеточие

(:), а в каких — номер строки; — что такое частично-защищенные и полностью защищенные имена. Если хотя бы один из этих вопросов тебе не совсем понятен, вернись,

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

важнее, чем в программах, состоящих из директив. Комментарии обязательно нужно набирать вместе с операторами — тогда они будут храниться в ЗУ и их можно будет просмотреть вместе с текстом процедуры.

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

ЗАПОМНИТЬ ПРОЦЕДУРУ НОВОЕ___ДЕЖУРСТВО; ; Эта процедура предназначена ; для управления исполнителем ;ДЕЖУРИК, убирающим класс ;на перемене ДЕЖУРИК проветривает ; класс и готовит доску к новому ;уроку. Начальная ситуация ;окно закрыто, доска грязная, тряпка сухая. ОТКРЫТЬ ОКНО; ТОМ__СОЙЕР красит забор. Если с процедурами тебе все понятно (или, по

крайней мере, кажется, что понятно), попробуем провести небольшую практическую работу. Для этого нам понадобятся два исполнителя: наш старый знакомый МАШИНИСТ и новичок - робот-маляр по имени ТОМ__СОЙЕР. В одной руке у него кисть, а в другой — ведро с краской. Конечно, настоящие роботы-маляры пользуются гораздо более современным оборудованием, но для тренировки нам подойдет и такой робот (рис. 39).

ТОМ__СОЙЕР красит заборы, сделанные из досок разной ширины и различным

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

Необходимо покрасить забор, изображенный на рис. 40. Ширина большой

доски 40 см, маленькой — 20 см, ширина промежутка между досками 10 см. Забор нужно покрасить в три слоя, причем сделать это «в три прохода»: сначала покрасить весь забор один раз слева направо, потом еще два раза в том же направлении. Перед началом работы ТОМ __ СОЙЕР стоит в 20 см от левого края забора.

Можно, конечно, решить эту задачу без всяких процедур. Но тогда получится

ужасно длинная программа. Чтобы покрасить одну только большую доску в три слоя, нужно в общей сложности 24 взмаха кисти и столько же перемещений робота, а на каждый взмах приходится три предписания! Значит, на каждую большую доску нужно 24 × 4 = 96 предписаний, на маленькую 48, а всего в программе будет (с учетом интервалов между досками) 96 × 5 + 48 × 20 + 25 × 3 = 1515 предписаний! Честное слово, проще самому покрасить забор в десять слоев, чем писать такую программу! И самое обидное, что программа-то сплошь состоит из совершенно одинаковых кусочков; ОБМАКНУТЬ — СТРЯХНУТЬ — ПРОВЕСТИ, ОБМАКНУТЬ — СТРЯХНУТЬ — ПРОВЕСТИ... Раз такие участки в программе повторяются в точности, значит, имеет смысл их запомнить и назвать каким-то одним общим именем. Одним словом, нужно описать процедуру. Так и запишем:

ЗАПОМНИТЬ ПРОЦЕДУРУ ОДИН___ВЗМАХ; ОБМАКНУТЬ КИСТЬ; СТРЯХНУТЬ ЛИШНЮЮ КРАСКУ; ПРОВЕСТИ ПО ДОСКЕ; ЗАКОНЧИТЬ;

Уже проще. Теперь, чтобы покрасить маленькую доску в один слой, достаточно вызвать эту процедуру 4 раза, каждый раз сдвигая робота на 5 см вправо. А таких досок двадцать. Внимание! Опять повторяющийся участок, только «более крупный». Что ж, опишем еще одну процедуру:

ЗАПОМНИТЬ МАЛЕНЬКАЯ_ДОСКА; ВЫЗВАТЬ ОДИН _ ВЗМАХ; ВПРАВО НА 5 СМ; ВЫЗВАТЬ ОДИН _ ВЗМАХ; ВПРАВО НА 5 СМ; ВЫЗВАТЬ ОДИН _ ВЗМАХ; ВПРАВО НА 5 СМ; ВЫЗВАТЬ ОДИН _ ВЗМАХ;

Процедура окраски маленькой доски (ширина 20 см) в один слой. В начале работы ТОМ__СОЙЕР стоит у левого края доски. В конце-у правого.

ЗАКОНЧИТЬ; Обрати внимание на комментарий: сведения обо всей процедуре расписаны по

разным строчкам — так поступают довольно часто. Теперь займемся большой доской. Можно было бы описать для нее такую же

процедуру, только вдвое длиннее. Но зачем же повторяться — достаточно два раза вызвать уже готовую процедуру МАЛЕНЬКАЯ _ДОСКА:

ЗАПОМНИТЬ БОЛЬШАЯ___ДОСКА; МАЛЕНЬКАЯ _ ДОСКА ( ); ВПРАВО НА 5 СМ; МАЛЕНЬКАЯ _ ДОСКА ( ); ЗАКОНЧИТЬ; Итак, можно сформулировать для себя правило: если есть повторяющиеся

участки, объединяй их в процедуру. Но ведь у нас есть еще один повторяющийся участок: «блок» из одной большой и четырех маленьких досок. Вывод ясен:

ЗАПОМНИТЬ БЛОК; БОЛЬШАЯ _ ДОСКА ( ); ВПРАВО НА 15 СМ; МАЛЕНЬКАЯ _ ДОСКА ( ); ВПРАВО НА 15. СМ; МАЛЕНЬКАЯ _ ДОСКА (); ВПРАВО НА 15 СМ; МАЛЕНЬКАЯ _ ДОСКА ( ); ВПРАВО НА 15 СМ; МАЛЕНЬКАЯ _ ДОСКА ( ); ВПРАВО НА 15 СМ;

ЗАКОНЧИТЬ; Предписание ВПРАВО НА 15 СМ повторяется после каждой процедуры. А

нельзя ли его «спрятать» внутрь процедур? Например, добавить это предписание в конец процедуры МАЛЕНЬКАЯ _ ДОСКА? Осторожно! Ведь тогда процедура БОЛЬШАЯ _ ДОСКА сработает неправильно! Впрочем, не так уж сложно описать новую процедуру МАЛЕНЬКАЯ__ДОСКА ___ И___СДВИГ. Попробуй сделать это сам и заодно посмотри; как исправить процедуру БЛОК. Получилось?

Итак, окраска всего забора в один слой: ЗАПОМНИТЬ ОДИН _ ПРОХОД;

БЛОК ( ); БЛОК ( ); БЛОК ( ); БЛОК ( ); БЛОК ( );

ЗАКОНЧИТЬ;

Все хорошо? Не совсем: после каждого прохода роботу нужно возвращаться назад, так что это предписание имеет смысл поставить в конец процедуры ОДИН _ ПРОХОД:

ДОПИСАТЬ; ВЛЕВО НА 845 СМ; ЗАКОНЧИТЬ; Теперь нам, пожалуй, описывать процедуру не понадобится. Оставшаяся часть

программы состоит только из директив: ВКЛЮЧИТЬ ТОМ _ СОЙЕР; ВПРАВО НА 20 СМ; Заняли исходное положение ОДИН__ПРОХОД ( ); ОДИН___ ПРОХОД (); ОДИН___ПРОХОД (.); Остановились у левой доски ВЫКЛЮЧИТЬ ТОМ___СОЙЕР; Вместо, полутора тысяч предписаний не больше пятидесяти. И, самое главное,

почти нет однообразных повторений (как избавиться от этого «почти» ты узнаешь на одном из следующих уроков).

Новая встреча с рекурсией. Попробуем решить новую задачу. Забор состоит из очень большого количества досок шириной 20 см; Сколько их — точно неизвестно, но, во всяком случае, не меньше тысячи. В остальном сохраняются условия предыдущей задачи. Нужно составить программу для покраски такого забора в один слой.

С первого взгляда вообще непонятно, как подступиться к такой задаче. Больше тысячи досок, да еще и неизвестно, сколько именно! Попробуем в лоб. Посмотрим, как будет выглядеть программа для покраски нескольких первых досок. Процедура МАЛЕНЬКАЯ _ ДОСКА уже описана, так что можно написать (но набирать пока не стоит) такие предписания:

ВКЛЮЧИТЬ ТОМ _ СОЙЕР; ВПРАВО НА 20 СМ; МАЛЕНЬКАЯ _ ДОСКА ( ); ВПРАВО НА 15 СМ; МАЛЕНЬКАЯ _ ДОСКА ( ); ВПРАВО НА 15 СМ; . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Каждый раз после вызова процедуры МАЛЕНЬКАЯ __ ДОСКА повторяется

одна и та же директива: ВПРАВО НА 15 СМ: Значит, имеет смысл превратить ее в оператор и добавить к описанию процедуры:

ДОПИСАТЬ; ВПРАВО НА 15 СМ;

ЗАКОНЧИТЬ; Вот и готово еще одно правило «для себя»: если после вызова процедуры или

перед ним всегда используются одни и те же предписания, то их, вероятно, стоит добавить к описанию процедуры... После вызова исправленной процедуры МАЛЕНЬКАЯ _ ДОСКА у нас опять-таки всегда стоит одно и то же предписание — вызов этой же процедуры! А нельзя ли и этот вызов добавить к описанию процедуры?

ДОПИСАТЬ;

ВЫЗВАТЬ МАЛЕНЬКАЯ _ ДОСКА; ЗАКОНЧИТЬ;

Теперь эта процедура имеет вид ПРОЦЕДУРА МАЛЕНЬКАЯ _ ДОСКА;

ВЫЗВАТЬ ОДИН _ ВЗМАХ; ВПРАВО НА 5 СМ; ВЫЗВАТЬ ОДИН _ ВЗМАХ; ВПРАВО НА 5 СМ; ВЫЗВАТЬ ОДИН _ ВЗМАХ; ВПРАВО НА 5 СМ; ВЫЗВАТЬ ОДИН _ ВЗМАХ; ВПРАВО НА 15 СМ;

Процедура окраски маленькой доски (ширина 20 см) в один слой. В начале работы ТОМ__СОЙЕР стоит у левого края доски. В конце-у правого.

ВЫЗВАТЬ МАЛЕНЬКАЯ _ ДОСКА; ЗАКОНЧИТЬ; Кстати, комментарий тоже нужно исправить, но с этим ты вполне можешь

справиться сам. Обрати внимание, что эта процедура вызывает сама себя! С такой ситуацией ты уже встречался во второй главе, помнишь? Такую конструкцию мы называли рекурсией, так что тебя не должно удивлять, что

Процедуры, которые вызывают сами себя, называются рекурсивными. А теперь посмотрим, как будет выполняться такая процедура. Представь себе,

что исполнитель уже включен и ты набираешь на клавиатуре терминала предписание ВЫЗВАТЬ МАЛЕНЬКАЯ __ ДОСКА. ТОМ__СОЙЕР начинает работу. Он исполняет процедуру в порядке номеров: взмах — сдвиг, взмах — сдвиг и т. д. Вот он дошел до конца доски... сдвинулся на 15 сантиметров... вновь вызвал ту же самую процедуру и начал исполнять те же самые предписания: взмах — сдвиг, взмах — сдвиг... снова дошел до конца доски и все повторяется сначала. Похоже, что по такой программе робот действительно выкрасит все доски, сколько бы их ни было, а потом... а что потом? До каких пор будет работать ТОМ __СОЙЕР? Если судить по программе, то он зациклится, то есть будет работать до бесконечности.

На самом деле, конечно, забор когда-нибудь да кончится, и робот не сможет выполнить очередное предписание (не будет доски, по которой можно было бы ПРОВЕСТИ КИСТЬЮ). Тогда робот остановится, и система выдаст сообщение об ошибке, а потом будет ждать следующего твоего предписания.

Рекурсивные процедуры можно использовать в тех случаях, когда одни и те же предписания можно повторять много раз подряд. Но делать это надо очень осторожно, чтобы программа не зациклилась. Если робот работает медленно и программист легко может за ним уследить, опасность не так уж велика. И все-таки для робота-водолаза, который должен снять с подводной части корабля двенадцать неисправных заклепок, рекурсивную программу писать не стоит. Такой робот может зациклиться и начать разбирать весь корабль, а программист заметит это, только оказавшись в воде.

Можно, однако, добиться, чтобы рекурсивная процедура сама следила за своей работой, чтобы не зациклиться. Об этом мы узнаем в следующей главе. Там же будут описаны более удобные, чем рекурсия, средства для программирования повто-ряющихся действий. Тогда мы сможем подробнее обсудить и достоинства, и недостатки рекурсии.

Процедуры и планы. А теперь вернемся к программе для МАШИНИСТа, которую мы составляли на третьем уроке (с. 61). Программа получилась довольно длинной, и мы обещали научить тебя, как сделать ее покороче. С первого взгляда видно; что в программе встречается много повторяющихся участков. А раз есть повторения, стоит посмотреть, не пригодятся ли нам процедуры.

Можно попробовать применить тот же прием, что для исполнителя ТОМ _ СОЙЕР: посмотреть, какие группы предписаний в программе повторяются в точности, и превратить эти группы в процедуры. Для нашей программы это сделать несложно: она ведь уже написана и можно посмотреть, какие именно предписания повторяются.

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

Для исполнителя ТОМ __СОЙЕР мы сразу обнаружили такие действия, которые наверняка будут много раз повторяться в программе: один взмах кисти, покраска одной доски и т. д. Может быть, и здесь можно так же? К сожалению, нет. Для МАШИНИСТа можно придумать чересчур много процедур и трудно предсказать, какие из них пригодятся. Может быть описать процедуру для перевода одного вагона в тупик? Или для перевода всего состава на путь Б? Или что-нибудь еще? Можно, ко-нечно, сочинить процедуры на все случаи жизни, а потом посмотреть, какие из них и в самом деле понадобились. Но нетрудно сообразить, что это не самый лучший способ: уж больно много бесполезных процедур можно придумать. А нельзя ли догадаться заранее, какие процедуры нам будут нужны, а потом описывать только их? Можно! Для этого достаточно составить общий план, а затем описать процедуру для каждого его пункта.

Посмотри на общий план, приведенный на с. 60. Если следовать ему, то для нужной нам перестановки вагонов необходимо выполнить три предписания. В МПИ МАШИНИСТа ни одного из них нет, поэтому на третьем уроке мы начали уточнять этот план и только на последнем этапе уточнения составили по нему программу. А сейчас попробуем взглянуть на него несколько по-новому.

Если бы у нас были описаны разные процедуры для перестановок вагонов, то пригодились бы из них только три — те, которые выполняли бы Пункты этого алгоритма. Точнее говоря, даже две — первое и третье предписания одинаковы. Значит, не нужно описывать много процедур, достаточно описать эти две! Названия для них уже есть — это сами пункты общего плана (хотя можно их сделать чуть покороче). Порядок, в котором их нужно вызывать, известен.

Мы знаем названия процедур и порядок, в котором их надо вызывать. А нужно ли что-нибудь еще, чтобы превратить общий план в программу? В общем-то ничего! Нужно, конечно, запомнить эти процедуры, но это можно сделать и чуть позже. Правда, сейчас мы не сможем их вызвать, поэтому составлять такую программу из директив пока нельзя — система все время будет отвечать НЕ ПОНИМАЮ. А вот запомнить все это в виде процедуры можно уже сейчас, но вызовем мы эту процедуру только тогда, когда все будет описано:

ЗАПОМНИТЬ ПРОЦЕДУРУ ПЕРЕСТАНОВКА___ ВАГОНОВ; ПОМЕНЯТЬ _ СРЕДНИЙ _ И _ ЛЕВЫЙ ( ); ПОМЕНЯТЬ _ ПРАВЫЙ _ И _ СРЕДНИЙ ( ); ПОМЕНЯТЬ _ СРЕДНИЙ _ И _ ЛЕВЫЙ ( ); ЗАКОНЧИТЬ; Этот текст уже можно набирать на терминале. А теперь опишем все

вызываемые здесь процедуры. Начнем с процедуры ПОМЕНЯТЬ _: СРЕДНИИ __И _ ЛЕВЫЙ. Уточненный

план для нее уже написан (с. 60). Можно применить тот же прием : сразу описываем эту процедуру, заменяя все предписания, которых нет в МПИ, вызовами новых процедур. Нужно только следить, чтобы одинаковые предписания получали одинаковые имена:

ЗАПОМНИТЬ ПРОЦЕДУРУ ПОМЕНЯТЬ___СРЕДНИЙ___.И___ЛЕВЫЙ; ПОДВЕСТИ___НА___А ( ); Подводим локомотив ПРИЦЕПИТЬ___ТРИ___ВАГОНА ( ); к вагонам НАЗАД; ' Переводим на путь Б НА___ПУТЬ___В ( ); . Оставляем левый вагон ОТЦЕПИТЬ ВАГОН; в тупике

НАЗАД ПОДВЕСТИ___НА___ А ( ); Переводим остальные на А ОТЦЕПИТЬ ВАГОН; Оставляем НАЗАД; там средний вагон НА___ПУТЬ___В ( ); Правый вагон - на Б ПРИЦЕПИТЬ ВАГОН; Цепляем к нему , НАЗАД; левый вагон ПОДВЕСТИ___НА___А ( ); Возвращаем оба вагона ЛОКОМОТИВ___НА___МЕСТО (); на путь А ЗАКОНЧИТЬ; Осталось составить только несколько простых процедур. Приведем для

примера текст одной из них (с остальными ты без труда справишься сам): ЗАПОМНИТЬ ПРОЦЕДУРУ НА _ ПУТЬ _ В; ВПЕРЕД; ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; ЗАКОНЧИТЬ; Теперь осталось только описать уточняющие планы для остальных двух

предписаний, превратить их в процедуры и описать все встретившиеся при этом новые процедуры (если такие будут). Сделай это, пожалуйста, сам.

Вот и все, программа готова. Чтобы ее исполнить, достаточно набрать одну-единственную директиву:

ВЫЗВАТЬ ПЕРЕСТАНОВКА _ ВАГОНОВ; или ПЕРЕСТАНОВКА _ ВАГОНОВ ( ); Сверху вниз и снизу вверх. Ты уже заметил, конечно, что процедуры для

робота-маляра и для МАШИНИСТа мы описывали по-разному. Для маляра мы начинали с процедур нижнего уровня, то есть с таких, которые содержат только предписания из МПИ, без вызовов других процедур. От нижнего уровня мы перешли к процедурам для описания более сложных действий (покраска маленькой доски, один проход и т. д.), а в самом конце составили главную процедуру (процедуру верхнего уровня). Главн ая процедура соответствует общему плану решения задачи.

Такой способ программирования называют программированием снизу вверх: от нижнего уровня — к верхнему, от простых предписаний — к более сложным, от уточненного плана — к общему. Программа для МАШИНИСТа составлялась в обрат-ном порядке — сверху вниз: мы начали с общего плана, сразу написали для него программу (главную процедуру), а затем, стали описывать те процедуры, вызов которых был предусмотрен в главной.

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

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

сверху вниз еще до того, как будут составлены процедуры нижнего уровня, но для маленьких программ эти приемы неудобны.

Метод «снизу вверх», хотя и требует большого труда, бывает очень полезен на первых порах. Пусть даже половину составленных тобой процедур придется потом выбросить, но зато ты хорошо почувствуешь, какие процедуры для этого исполнителя можно составить. Да и отлаживать каждую написанную процедуру можно сразу: ведь все, что «под ней», уже описано (а обычно — и отлажено). Словом, любишь кататься сверху вниз — люби и саночки возить (в обратном направлении).

Опытные программисты иногда применяют метод «снизу вверх» для того, чтобы заранее заготовить для каждого нового исполнителя набор процедур, которые могут понадобиться в различных задачах. Например, если предстоит много работы с исполнителем вроде ЧЕРТЕЖНИКа, который умеет только проводить прямые линии, то наверняка стоит заготовить процедуры для изображения прямоугольников, окружностей и других геометрических фигур — по своему усмотрению. Таким спо-собом программист как бы расширяет МПИ, добавляя недостающие, по его мнению, предписания, приспосабливая исполнителя к определенной группе задач и к себе. К себе? Конечно: ведь он выбирает такие процедуры и такие названия для них, с ко-торыми именно ему будет удобнее, привычнее, приятнее работать. Так что возить саночки приходится не только новичкам!

Хорошо подобранный набор процедур нижнего уровня позволяет вообще забыть об МПИ: мы словно обучаем для себя нового, более умелого исполнителя, который может выполнять более сложные действия. Например, научили исполнителя ТОМ____СОЙЕР выполнять предписание ОДИН___ВЗМАХ ( ) — и можно забыть про ведро с краской. Так что процедуры, помимо всего прочего, можно считать средством обучения исполнителей!

Самое интересное, что мы сами учимся примерно так же! Когда в первом классе ты учился писать буквы, то, наверняка, хорошо помнил, в каком порядке нужно выписывать, например, букву А: сначала ставим ручку сюда... рисуем завитушку, те-перь наверх, теперь палочку, теперь перекладину. Но прошло совсем немного времени — и тебе уже не нужно было вспоминать про все эти палочки и перекладины. Ты освоил новое предписание (написать букву А), и его составные части спрятались куда-то в запоминающее устройство. Похоже на запоминание процедуры, правда?

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

Итак, зачем нужны процедуры? О т в е т . Использование процедур позволяет: 1. Запомнить программу (часть программы)и вызывать ее всякий раз, когда она

понадобится. 2. Обучать исполнителя новым предписаниям, то есть расширять МПИ,

приспосабливая его к набору задач и к себе. 3. Писать, проверять и отлаживать большую программу по частям. 4. Составлять программу сверху вниз, одновременно с планом и в точном

соответствии с ним. 5. Избежать повторения одинаковых участков в программах: такие участки

можно один раз описать в виде процедуры, а затем каждый раз вызывать ее в нужном месте.

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

На следующем уроке ты познакомишься с параметрами и внутренними именами процедур, и этот список можно будет дополнить. А пока — очередная перемена!

Шестая перемена МАЛЫШ и ЧЕРТЕЖНИК Составим несколько программ для двух простых исполнителей, с которыми нам

предстоит работать на следующем уроке. Один из них называется МАЛЫШ, а другой — ЧЕРТЕЖНИК. МАЛЫШ умеет считать — примерно на уровне середины первого класса. Его МПИ можно описать диаграммой 48.

Как и полагается первокласснику, этот исполнитель может работать только с

целыми неотрицательными числами. Попробуем составить для него простенькую программу. Пусть нам нужно вычислить, чему будет равно 531—250 + 48. Программа может выглядеть так:

ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ МАЛЫШ; ВЫЧЕСТЬ 250 ИЗ 531 И ПРИСВОИТЬ ИМЕНИ А; 531-250-> А; СЛОЖИТЬ АС 48 И ПРИСВОИТЬ А; А + 48 - > А; ВЫДАТЬ: "РЕЗУЛЬТАТ РАВЕН", А; Проведи прокрутку этой программы и убедись, что она выдаст на экран именно

то, что нужно. Обрати внимание на комментарий справа. Такую запись часто используют, чтобы легче было .следить за составлением программы. Стрелка — >, составленная из минуса и знака >, заменяет выражения «присвоить имени» или «поместить в блок памяти с именем».

Еще одна задача. МАЛЫШ должен подсчитать, сколько лет исполнится сидящему за пультом школьнику в любом заданном году. Будем считать, что исполнитель уже включен, и попробуем запомнить и вызвать процедуру, которая запросит у школьника год рождения и год, для которого нужно найти возраст, а затем отпечатает ответ:

ЗАПОМНИТЬ ПРОЦЕДУРУ ОПРЕДЕЛИТЬ _ ВОЗРАСТ; ВЫДАТЬ: "В КАКОМ ГОДУ ТЫ РОДИЛСЯ?"; ПРИНЯТЬ ЧИСЛО: ГОД _ РОЖДЕНИЯ; ВЫДАТЬ: "КАКОЙ ГОД ТЕБЯ ИНТЕРЕСУЕТ?"; ПРИНЯТЬ ЧИСЛО: ЗАДАННЫЙ___ГОД; ВЫЧЕСТЬ ГОД___РОЖДЕНИЯ ИЗ ЗАДАННЫЙ___ГОД И ПРИСВОИТЬ ИМЕНИ ВОЗРАСТ; ВЫДАТЬ: "В", ЗАДАННЫЙ___ГОД, "ГОДУ ТЕБЕ ИСПОЛНИТСЯ"; ВОЗРАСТ, " ЛЕТ"; ЗАКОНЧИТЬ; Обрати внимание, что имена всех блоков памяти выбраны так, что можно

обойтись без комментариев: и так все понятно.

Следующая задача. Нужно принять число, умножить его на 32 и отпечатать результат умножения. Может показаться, что решить такую задачу МАЛЫШ не сможет: он ведь не умеет умножать. Но такой вывод был бы слишком поспешным.

Попробуй составить программу для решения этой задачи. Постарайся использовать не больше восьми-девяти предписаний.

Р еш е н и е . Если не стараться составить короткую программу, то решить задачу несложно; умножить число на 32 — значит, по определению, «взять его слагаемым» 32 раза. Для этого подойдет такая программа:

ПРИНЯТЬ ЧИСЛО: X; ЗНАЧЕНИЕ О ПРИСВОИТЬ ИМЕНИ СУММА; СЛОЖИТЬ X С СУММА

И ПРИСВОИТЬ ИМЕНИ СУММА; СЛОЖИТЬ X С СУММА И ПРИСВОИТЬ ИМЕНИ СУММА; . . . . . . . . . . . . и так далее 32 раза, а в конце программы написать предписания: ЗНАЧЕНИЕ СУММА ПРИСВОИТЬ ИМЕНИ РЕЗУЛЬТАТ; ВЫДАТЬ НА БУМАГУ: РЕЗУЛЬТАТ; Но можно сделать программу немного короче, если заметить, что сложить

число само с собой — значит, умножить его на два. Получается, что умножать на два МАЛЫШ умеет!

ПРИНЯТЬ ЧИСЛО; X; ЗНАЧЕНИЕ X ПРИСВОИТЬ ИМЕНИ ПРОИЗВЕДЕНИЕ; СЛОЖИТЬ ПРОИЗВЕДЕНИЕ С ПРОИЗВЕДЕНИЕ

И ПРИСВОИТЬ ИМЕНИ ПРОИЗВЕДЕНИЕ; СЛОЖИТЬ ПРОИЗВЕДЕНИЕ С ПРОИЗВЕДЕНИЕ

И ПРИСВОИТЬ ИМЕНИ ПРОИЗВЕДЕНИЕ; СЛОЖИТЬ ПРОИЗВЕДЕНИЕ С ПРОИЗВЕДЕНИЕ

И ПРИСВОИТЬ ИМЕНИ ПРОИЗВЕДЕНИЕ; СЛОЖИТЬ ПРОИЗВЕДЕНИЕ С ПРОИЗВЕДЕНИЕ

И ПРИСВОИТЬ ИМЕНИ ПРОИЗВЕДЕНИЕ; СЛОЖИТЬ ПРОИЗВЕДЕНИЕ С ПРОИЗВЕДЕНИЕ

И ПРИСВОИТЬ ИМЕНИ ПРОИЗВЕДЕНИЕ; ЗНАЧЕНИЕ ПРОИЗВЕДЕНИЕ ПРИСВОИТЬ

ИМЕНИ РЕЗУЛЬТАТ; ВЫДАТЬ НА БУМАГУ: РЕЗУЛЬТАТ; Можно, конечно, еще немного сократить эту программу. Например, с точки

зрения системы совершенно необязательно использовать в ней три блока памяти (с именами X, ПРОИЗВЕДЕНИЕ И РЕЗУЛЬТАТ). Вполне хватило бы и одного блока (например, с именем X). Тогда можно было бы выбросить из программы еще два предписания — второе и предпоследнее.

Итак, еще два предписания и два блока памяти можно сэкономить, но... это тот случай, когда экономия может обойтись слишком дорого! Машине все равно, какие имена ты используешь в программе. Но человеку, которому придется читать про-грамму и разбираться в ней, это далеко не все равно! На примере процедуры ОПРЕДЕЛИТЬ _ ВОЗРАСТ ты только что мог убедиться, как легко читать программу с

хорошо подобранными именами. А ведь и там можно было обойтись двумя именами вместо трех (проверь это!). Но тогда понимать программу было бы труднее. Поэтому всегда старайся выбирать имена блоков памяти так, чтобы по ним можно было понять, что хранится в этих блоках.

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

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

З а д а ч а . Составь программу для умножения числа, запрошенного с терминала,

на 67.

* * *

Исполнитель ЧЕРТЕЖНИК имеет МПИ: ЧЕРТЕЖНИК умеет проводить отрезки прямых линий между заданными

точками на экране телевизора или на бумаге. Например, по программе ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ ЧЕРТЕЖНИК; ПОДВЕСТИ ИНСТРУМЕНТ В ТОЧКУ (40, 40); точка А НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (40, 10); отрезок АВ НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (10, 10); отрезок ВС НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (10, 40); отрезок СD НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (25, 50); отрезок DЕ НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (40, 40); снова в А (ЕА) НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (10, 40); отрезок АD

ВЫКЛЮЧИТЬ ЧЕРТЕЖНИК; будет нарисован домик, показанный на рис. 41.

Стандартная единица масштаба на экране и на бумаге 1 мм, стандартный

размер экрана (листа бумаги) 255 × 255 мм. Однако на экране масштаб, можно немного менять, используя ручки настройки телевизора.

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

Вероятно, ты уже понял, как выполняются предписания из МПИ ЧЕРТЕЖНИКа. На всякий случай приведем краткие пояснения.

ПОДВЕСТИ ИНСТРУМЕНТ. По этому предписанию инструмент переводится в заданную точку, при этом никакого следа на бумаге (экране) не остается (ручка поднята над бумагой, луч погашен).

НАЧЕРТИТЬ ЛУЧ. Исполняя предписание, ЧЕРТЕЖНИК проводит луч (точнее, отрезок прямой линии) от точки, в которой перед этим находился инструмент, до заданной точки.

З а д а ч и . 1. Составить программу для изображения ракеты, показанной на рис. 42. 2. Составить программу для вычерчивания по одной букве слова КВАНТ. Девятый урок Процедуры с параметрами Параметры. Составляя программы для ЧЕРТЕЖНИКа, ты уже, вероятно,

заметил, что они получаются громоздкими: во-первых, каждое его предписание само по себе довольно длинное, во-вторых, у ЧЕРТЕЖНИКа нет предписаний для рисования фигур, вычерчивания букв и т. д. Например, чтобы написать текст КВАНТ, тебе при-шлось составлять каждую букву из отрезков и определять координаты всех нужных точек.

Понятно, что буквы, треугольники, прямоугольники, окружности, дуги и другие геометрические фигуры и линии могут встречаться едва ли не в каждом рисунке, то есть все эти конструкции часто повторяются в различных программах. Ты уже знаешь, что повторяющиеся конструкции имеет смысл превращать в процедуры, чтобы не описывать их каждый раз заново. Но обычные процедуры, которыми мы занимались на предыдущем уроке, здесь не помогут. Для того чтобы их вызвать, мы указывали только их имена, без всяких вспомогательных гибких полей. А в процедурах для ЧЕРТЕЖНИКа без таких полей не обойтись.

Например, не так уж трудно составить программу для рисования прямоугольника высотой 20 и длиной 25 сантиметров, расположенного посередине экрана (координаты нижнего левого угла — (3, 28)). Очень легко превратить эту программу в процедуру, которую можно назвать ПРЯМ__1:

ЗАПОМНИТЬ ПРОЦЕДУРУ ПРЯМ _ 1;

ПОДВЕСТИ ИНСТРУМЕНТ В ТОЧКУ (3, 28); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (253, 28); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (253, 228); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (3, 228); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (3, 28);

ЗАКОНЧИТЬ; Все хорошо, но... вряд ли во многих программах будут встречаться именно

такие прямоугольники. А вот другие прямоугольники, с разными размерами и координатами, могут встречаться очень часто. На рис. 43 изображен робот, сплошь составленный из них.

Для того чтобы наша процедура стала по-настоящему полезной, требуется

определить ее так, чтобы она годилась для любых координат и размеров. Для этого нужно, прежде всего, заменить в тексте процедуры все конкретные числа именами блоков памяти и организовать вычисление всех координат с использованием предпи-саний МАЛЫШа. Тогда для изображения конкретного прямоугольника будет достаточно разместить в этих блоках его размеры и координаты, а затем вызвать процедуру. Текст новой процедуры ПРЯМ__2 будет выглядеть так:

ЗАПОМНИТЬ ПРЯМ _ 2; СЛОЖИТЬ ДЛИНА С X И ПРИСВОИТЬ ИМЕНИ XI; СЛОЖИТЬ ВЫСОТА СУ И ПРИСВОИТЬ ИМЕНИ У1; ;Вычислили координаты всех крайних точек ПОДВЕСТИ ИНСТРУМЕНТ В ТОЧКУ (X, V), НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (X, VI); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (XI, V));

НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (XI, V); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (X, V); ЗАКОНЧИТЬ; Чтобы теперь нарисовать прямоугольник высотой 10 и длиной 15 сантиметров,

начиная с точки (5,5), нужно выполнить такую программу: ЗНАЧЕНИЕ 5 ПРИСВОИТЬ ИМЕНИ X; ЗНАЧЕНИЕ 5 ПРИСВОИТЬ ИМЕНИ V; ЗНАЧЕНИЕ 100 ПРИСВОИТЬ ИМЕНИ ВЫСОТА; ЗНАЧЕНИЕ 150 ПРИСВОИТЬ ИМЕНИ ДЛИНА; ВЫЗВАТЬ ПРЯМ _ 2; Вызов процедуры получился довольно. неуклюжим, а ведь в других процедурах

для ЧЕРТЕЖНИКа может встретиться гораздо больше чисел, текстов или имен, от значений которых зависит форма, размер или цвет рисунка. Было бы куда удобнее, если бы мы могли при запоминании процедуры предусмотреть для них гибкие поля — такие же, как в предписаниях ЧЕРТЕЖНИКа ПОДВЕСТИ ИНСТРУМЕНТ и НАЧЕРТИТЬ ЛУЧ.

Правила языка Робик позволяют предусмотреть во время запоминания процедуры одно или несколько имен, значения которых будут указаны во время ее вызова. Такие имена называются параметрами процедуры.

Посмотри еще раз на синтаксические диаграммы для текста и вызова процедуры (диаграммы 45, 46). Упомянутые там гибкие поля ПАРАМЕТРЫ и ЗНАЧЕНИЯ ПАРАМЕТРОВ описываются так:

Например, текст процедуры с параметрами для рисования прямоугольника

может выглядеть так: ЗАПОМНИТЬ ПРЯМ (X, У, ДЛИНА, ВЫСОТА); СЛОЖИТЬ ДЛИНА С X; И ПРИСВОИТЬ ИМЕНИ X1; СЛОЖИТЬ ВЫСОТА СУ; И ПРИСВОИТЬ ИМЕНИ V1; ПОДВЕСТИ ИНСТРУМЕНТ В ТОЧКУ (X, У); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (X, У1); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (X1, У1); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (X1, У); НАЧЕРТИТЬ ЛУЧ ДО ТОЧКИ (X, V); ЗАКОНЧИТЬ; а ее вызов так: ПРЯМ (5,5,150,100);

Заметь, что длинная цепочка присваиваний перед вызовом процедуры стала теперь ненужной: она «спрятана» в самом предписании вызова.

А сейчас сформулируем правила работы с параметрами, которыми мы воспользовались в этом примере и будем пользоваться в дальнейшем:

1. При запоминании процедуры после ее имени могут быть указаны параметры. 2. Параметры записываются в круглых скобках, через запятую. 3. При вызове такой процедуры после ее имени обязательно должны быть

перечислены выражения (см. с. 99), значения которых будут присвоены параметрам процедуры.

4. Выражения перечисляются в круглых скобках, через запятую (так же, как параметры при описании процедуры).

5. Исполнение такой процедуры начинается с того, что значения всех выражений, указанных в скобках после имени процедуры, вычисляются и при-сваиваются параметрам в том порядке, в каком они

ВЫЗВАТЬ ПРОЦЕДУРУ ПРЯМ(5,5,150,100); ЗАПОМНИТЬ ПРОЦЕДУРУ ПРЯМ(X, У, ДЛИНА,ВЫСОТА) указаны в описании процедуры, слева направо (рис. 44).

6. Все параметры являются внутренними именами процедуры (что это такое, ты

сейчас узнаешь). З а д а ч и . 1. Описать процедуру ЛИНИЯ (X1, Y1, Х2, Y2) для изображения отрезка

прямой линии, соединяющего точки (X1, Y1) и (Х2, Y2). Используя эту процедуру, составить программу для вычерчивания рис. 45.

2. Составить программу для вычерчивания робота, изображенного на рис. 43,

используя описанную выше процедуру ПРЯМ. Стандартные процедуры. Система Шпага. В системе Школьница, как и во

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

Кроме системных, в Школьнице предусмотрены групповые и личные библиотеки процедур. В групповые библиотеки включаются те процедуры, которыми пользуются группы программистов, например, все ученики одного класса. Личную библиотеку каждый программист создает для себя.

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

Системой Шпага можно пользоваться не только на Робике, но и на Рапире и других языках. В ее разработке активно участвовали новосибирские школьники Ася Салихова (6 кл.), Наташа Соколова (7 кл.), Виталий Цикоза (8 кл.), Павел Земцов (6 кл.). Аня Филатова (8 кл.) и другие (возраст школьников указан на момент окончания их работы над системой).

Каждая процедура Шпаги имеет два названия: полное и сокращенное. Полное используется для того, чтобы быстрее понять и запомнить смысл процедуры, а сокращенное — сделать программы не такими громоздкими. Начинающим программи-стам можно посоветовать при составлении первых графических программ пользоваться полными названиями всех процедур, а потом постепенно переходить на сокращенные названия.

Перечислим важнейшие процедуры системы Шпага. ПОДВОД (Х,Y) или П (Х,Y). Процедура подводит рисующий инструмент в

точку с координатами (X, Y), то есть действует так же, как предписание ПОДВЕСТИ ИНСТРУМЕНТ исполнителя ЧЕРТЕЖНИК.

ЛУЧ (X, Y) или Л (X, Y). Проводит отрезок прямой линии от точки, в которой находился рисующий инструмент, до точки (X, Y).

ТОЧКА (X, Y) или Т (X, Y). Изображается точка, с координатами (X, Y). ОКРУЖНОСТЬ (X, Y, R.) или ОКР (X, Y, R). Изображает окружность радиуса

R. с центром в точке (Х, Y). После завершения рисунка инструмент остается в центре окружности.

НАДПИСЬ (ТЕКСТ, Х, Y) или НП (ТЕКСТ, X, Y). Вычерчивает на рисунке надпись, заданную значением имени ТЕКСТ. Параметры X и Y обозначают координаты левого нижнего угла надписи. После вычерчивания надписи инструмент переводится в точку с координатами (X + Д, Y), то есть в правый нижний угол надписи.

ДУГА (X1, Y1, Х2, Y2, ХЗ, YЗ) или Д (X1, Y1, Х2, Y2, ХЗ, YЗ). Процедура изображает дугу окружности, соединяющую точки (X1, Y1) и (ХЗ, YЗ) и проходящую через точку (Х2,Y2).

ЦВЕТ (НАЗВАНИЕ _ ЦВЕТА). Эта процедура не имеет сокращенного названия. Она позволяет установить цвет, которым будут вычерчиваться все линии и символы, заданные последующими вызовами процедур Шпаги. Если в программе не было ни одного обращения к этой процедуре, то линии рисунка будут иметь стандартный цвет: черный — для рисования на бумаге и белый — для экрана. Если нужно рисовать другим цветом, достаточно обратиться к этой процедуре, указав в качестве значения параметра название нужного цвета, то есть один из следующих текстов: "БЕЛЫЙ", "КРАСНЫЙ", "ОРАНЖЕВЫЙ", "ЖЕЛТЫЙ", "ЗЕЛЕНЫЙ", "ГОЛУБОЙ", "СИНИЙ", "ФИОЛЕТОВЫЙ"; "ЧЕРНЫЙ". Можно указывать и сокращенные названия, состоящие из одной буквы: "Б", "К", "О", "Ж", "3", "Г", "С", "Ф", "Ч". Заданный цвет будет сохраняться до следующего обращения к этой процедуре или до конца программы.

Кроме перечисленных процедур в системе есть средства для изменения системы координат (перенос начала, поворот, изменение масштаба, переход от декартовых координат к полярным и обратно) и некоторые другие специальные процедуры. Подробнее о системе можно прочитать в статье А. Салиховой и Н. Соколовой «Графическая система Шпага», опубликованной в журнале «Квант», № 1, 1980 г. Нужно иметь в виду, что в статье описан ранний вариант системы, поэтому названия некоторых процедур и состав их параметров могут отличаться от приведенных в этой книге.

С использованием процедур системы Шпага было написано много графических программ. Пример картинки, нарисованной с помощью одной из них, показан на рис. 46.

На рис. 47-54 показаны примеры других изображений, полученных на ЭВМ.

Авторы всех соответствующих графических программ — учащиеся школ Новоси-бирска в возрасте от 8 до 17 лет.

Линейная и точечная графика. Процедуры, перечисленные в предыдущем

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

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

Рисунки, состоящие из отдельных линий, удобнее формировать линейным способом. Но зато точечный способ хорошо подходит для построения рисунков, составленных из цветных геометрических фигур.

В системе Шпага предусмотрены процедуры для построения цветных точечных изображений. Вот некоторые из таких процедур.

ПРЯМОУГОЛЬНИК (X, Y, Д, В) (сокращенно ПР). ТРЕУГОЛЬНИК (Х1, Y1, Х2 Y2, ХЗ, YЗ) (сокращенно ТР). Параметрами процедуры — являются координаты вершин треугольника. КРУГ (X, Y, R) (сокращенно K). Параметры такие же, как у процедуры ОКР, но

процедура КРУГ рисует цветной кружок целиком, тогда как процедура ОКРУЖНОСТЬ позволяет изобразить только его границу.

СЕГМЕНТ (Х1, Y1, Х2, Y2, ХЗ, YЗ) (сокращенно СГ). Параметры имеют такой же смысл, как у процедуры ДУГА. Изображается окрашенный круговой сегмент, границами которого служат дуга, проведенная из точки (X1, Y1) в точку (ХЗ, YЗ) через (Х2, Y2), и отрезок прямой, соединяющий концы этой дуги (хорда).

СЕКТОР (Х1, Y1, Х2, Y2, ХЗ, YЗ) (сокращенно СК). Смысл параметров здесь несколько иной: X1 и Y1 — это координаты центра круга, из которого вырезается сектор, а Х2, Y2 и ХЗ, YЗ — координаты концов стягивающей его дуги. Сектор закрашивается от точки (Х2, Y2) к точке (ХЗ, YЗ) против часовой стрелки.

МНОГОУГОЛЬНИК (X, Y, R, N) (сокращенно МНГ). Изображает правильный многоугольник с горизонтальным основанием. X, Y, R — параметры описанной окружности, N — число сторон.

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

Например, вызов процедуры ПР (0,0,255,255); позволяет изобразить черный прямоугольник, заслоняющий все остальные

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

З а д а н и я . 1. Придумай несколько линейных и точечных рисунков и составь программы для их построения с использованием процедур системы Шпага.

2; С помощью процедур системы Шпага попробуй написать программу, которая будет рисовать кота Леопольда.

Внутренние имена. В этой книге уже несколько раз упоминалось, что многие

исполнители имеют свои собственные запоминающие устройства со своими блоками памяти. Эти блоки называют внутренними, а блоки памяти из общего ЗУ системы Школьница — общими. Точно так же различают внутренние имена (имена внутренних блоков памяти) и общие имена (имена общих блоков). Исполнители хранят во внутренних блоках памяти ту информацию, которая нужна им во время работы, так что содержимое этих блоков может оказаться самым различным.

Некоторые из внутренних имен могут случайно совпадать с общими именами, которые ты используешь в своей программе. Но ничего страшного при этом не произойдет: ты даже не заметишь, что произошло такое совпадение. Как бы ни менялось во время работы программы содержимое блоков памяти в собственном ОЗУ

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

Таким образом, внутренние имена, с которыми работает исполнитель, не связаны с общими именами из основной программы — они, как говорят программисты, локализованы внутри исполнителя.

Параметры процедуры обладают тем же свойством: они локализованы внутри процедуры! Поэтому параметры также называют внутренними именами.

Удобно представить себе это так, как будто каждая процедура имеет свое небольшое ОЗУ, в котором размещено несколько блоков памяти для ее внутренних имен. Если в операторе процедуры встретилось какое-то имя, то она сначала попытает-ся найти его значение в своем ОЗУ, и только потом обратится к общему запоминающему устройству. Это значит, что если какие-то общие имена в твоей программе случайно совпадут с параметрами процедуры, то значения этих имен не будут изменяться во время исполнения процедуры. Например, после выполнения программы

ЗНАЧЕНИЕ 100 ПРИСВОИТЬ ИМЕНИ X; ПРЯМ (10, 10, 20, 20); Описание на с. 147. значением общего имени X останется число 100, хотя в тексте этой процедуры

был использован параметр X, который при вызове получил значение 10. Вероятно, ты понял, почему параметры процедуры обладают таким свойством.

Если бы это было не так, то пользоваться процедурами было бы очень неудобно: нужно было бы знать, какие параметры используются в каждой процедуре и перед каждым вызовом проверять, не могут ли при выполнении процедуры измениться значения каких-нибудь общих имен. А если программа большая и имен в ней много, то проверить это не так-то просто! Если бы в примере, приведенном на предыдущей странице, значение имени X изменилось, это стало бы весьма неприятным сюрпризом для программиста, вызвавшего процедуру ПРЯМ, — ведь из текста программы никак не следует, что это значение может меняться!

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

Разумеется, внутренняя память процедуры — это не какое-то отдельное устройство, а часть общего ЗУ, которую система Школьница отвела для работы процедуры. Но сути дела это не меняет: блоки памяти в этой части ОЗУ никак не свя-заны с другими блоками, даже если их имена совпадают.

При описании процедур, кроме параметров, часто приходится использовать различные вспомогательные имена (например, для хранения промежуточных результатов вычислений). Такие имена тоже должны быть локализованы в процедуре по тем же причинам, что и параметры: чтобы случайно не испортить значения совпавших с ними имен из основной программы. Чтобы завести блоки памяти для таких имен, применяется конструкция ВНУТРЕННИЕ ИМЕНА (диаграмма 46). Например, текст процедуры СЛОЖИТЬ для исполнителя МАЛЫШ, которая вычисляет и выводит на экран сумму значений своих параметров, может выглядеть так:

ЗАПОМНИТЬ ПРОЦЕДУРУ СЛОЖИТЬ (А, В); ВНУТРЕННИЕ ИМЕНА: СУММА; СЛОЖИТЬ А С В И ПРИСВОИТЬ ИМЕНИ СУММА; ВЫДАТЬ "А = ", А, "В = ", В, "СУММА = ", СУММА; ЗАКОНЧИТЬ;

Одно из неписаных правил, принятых среди профессиональных программистов, гласит: «Все имена в процедурах должны быть внутренними». Это значит, что в операторах процедур нужно стараться употреблять только параметры и те вспомо-гательные имена, которые объявлены внутренними в этой процедуре.

Если это правило нарушено, процедура начинает вести себя как старуха Шапокляк, исподтишка подстраивая в разных местах программы мелкие гадости. Рассмотрим небольшой пример. Юному программисту по имени Миша предложили две задачи.

З а д а ч и . 1. Точки с координатами (5,10), (25,50) и (150,200) отметить «птичками»

шириной 10 мм и высотой 5 мм (рис. 55).

Как и положено юному программисту, Миша сразу заметил, что «птичку»

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

координаты отмечаемой точки. Миша назвал свою процедуру ПТИЧКА, но мы приведем ее под другим названием:

ЗАПОМНИТЬ ГЛУПАЯ _ ПТИЧКА (X, Y); СЛОЖИТЬ 5 С X И ПРИСВОИТЬ ИМЕНИ X1; ВЫЧЕСТЬ 5 ИЗ X И ПРИСВОИТЬ ИМЕНИ Х2; СЛОЖИТЬ 5 С Y И ПРИСВОИТЬ ИМЕНИ Y1; ПОДВОД (X1, Y1); ЛУЧ (Х,Y); ЛУЧ (Х2, Y1);

ЗАКОНЧИТЬ; Теперь Мише было уже нетрудно составить основную программу: ГЛУПАЯ _ ПТИЧКА (5,10); ГЛУПАЯ _ ПТИЧКА (25,50); ГЛУПАЯ _ ПТИЧКА (150,200); Работая по этой программе, система изобразила совершенно правильную

картинку (сделай прокрутку и убедись в этом!). Но тут Мише предложили следующую задачу.

2. Составить программу, которая запросит с клавиатуры шесть чисел: Х,Y, Х1,Y1,Х2,Y2 и нарисует «птички» в точках (X, Y), (X1,Y1) и (Х2,Y2).

Разумеется, Миша решил воспользоваться готовой процедурой ГЛУПАЯ _ ПТИЧКА:

ПРИНЯТЬ ЧИСЛА: Х,Y,Х1,Y1,Х2,Y2; ГЛУПАЯ__ПТИЧКА (X, Y); ГЛУПАЯ __ ПТИЧКА (X1, Y1); ГЛУПАЯ__ПТИЧКА (Х2, Y2). Придраться не к чему: программа совершенно правильная. Но на всякий случай

Миша решил ее проверить. Он вызвал программу и набрал на клавиатуре числа 10, 5, 10, 15, 25, 15, уверенный в том, что на экране появятся три «птички», расположенные «уголком» (рис. 56, а).

Наверное, он очень удивился, увидев совершенно другую картину (рис. 56, б).

Внимательно просмотрев свою программу и не обнаружив в ней никаких ошибок, он, скорее всего, решил, что испортилась машина. А ты уже понял, в чем дело? Если еще нет — проведи ручную прокрутку Мишиной программы, положив перед собой текст процедуры ГЛУПАЯ _ ПТИЧКА. Все ясно? Эта «глупая птичка» спутала Мише все карты, незаметно подменив значения имен X1, Y1 и Х2. Правильное значение осталось только у имени Y2, но это уже ничего не дало.

А сейчас попробуй описать процедуру УМНАЯ__ПТИЧКА (X, Y), которая будет рисовать то же самое, но без изменения общих имен.

О т в е т : ЗАПОМНИТЬ УМНАЯ___ПТИЧКА (X, Y); ИМЕНА: Х1,Y1,Х2; СЛОЖИТЬ 5 С X И ПРИСВОИТЬ X1; ВЫЧЕСТЬ 5 ИЗ X И ПРИСВОИТЬ Х2; СЛОЖИТЬ 5 С Y И ПРИСВОИТЬ Y1; ПОДВОД (X1, Y1); левое крыло ЛУЧ (X, Y); ЛУЧ (Х2, Y1); правое крыло ЗАКОНЧИТЬ; Глобальные имена и побочные эффекты. Если в процедуре все-таки

использовано имя, которое не является параметром и не объявлено внутренним именем, то его называют глобальным именем. Обычно глобальное имя — это имя блока памяти из общей части. ОЗУ. Однако, если одна процедура вызывает другую, то внутреннее имя из вызывающей процедуры может оказаться глобальным для вызываемой.

Внимательно ознакомься с приведенным здесь участком программы. Определи, какие из имен, используемых в процедуре ТРУБА, внутренние, а какие — глобальные. Выполни ручную прокрутку этой программы и определи, что будет выдано на экран в результате ее работы.

ЗАПОМНИТЬ ТРУБА (А); ВНУТРЕННИЕ ИМЕНА: Б; ВЫДАТЬ "А ", А, ", Б", Б, ", И", И; "УПАЛО" ПРИСВОИТЬ ИМЕНИ А, "ПРОПАЛО" ПРИСВОИТЬ ИМЕНИ Б; "ОСТАЛОСЬ НА ТРУБЕ" ПРИСВОИТЬ ИМЕНИ И; ВЫДАТЬ: "А", А, ", Б", Б, ", И", И;

ЗАКОНЧИТЬ;

"НА ТРУБЕ" ПРИСВОИТЬ ИМЕНИ А; "НА МЕСТЕ" ПРИСВОИТЬ ИМЕНИ Б, "ВСЕ ВМЕСТЕ" ПРИСВОИТЬ ИМЕНИ И; ВЫДАТЬ: "А ", А, ", Б", Б, '.', И", И; ТРУБА (Б); ВЫДАТЬ: "А", А, ", Б", Б, ", И", И,

О т в е т . В процедуре ТРУБА: имя А — локальное (параметр), имя Б — локальное (объявлено внутренним), имя И — глобальное. Вот что будет выдано на экран:. А НА ТРУБЕ, Б НА МЕСТЕ, И ВСЕ ВМЕСТЕ А НА МЕСТЕ, Б "ПУСТО", И ВСЕ ВМЕСТЕ А УПАЛО, Б ПРОПАЛО, И ОСТАЛОСЬ НА ТРУБЕ А НА ТРУБЕ, Б НА МЕСТЕ, И ОСТАЛОСЬ НА ТРУБЕ Обрати внимание на вторую и четвертую строки! При вызове процедуры

внутреннему имени А (параметру) присвоено значение глобального имени Б (то есть текст "НА МЕСТЕ"), а внутреннее (вспомогательное) имя Б имеет в это время пустое значение. После завершения процедуры значения общих имен А и Б остались без изменений, а значение имени И изменилось!

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

Запомни: если в процедуре используются глобальные имена — это рискованно! Если процедура присваивает глобальному имени новое значение — это очень рискованно! Изменение значения глобального имени в результате работы процедуры

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

звучит, например, «эффект глупой птички». Но мы все-таки будем использовать общепринятое название. Иногда применение таких эффектов позволяет получить инте-ресные результаты и обойти некоторые ограничения, принятые в языке Робик. Но гораздо чаще оно приводит к неприятным и трудно обнаруживаемым ошибкам в программах. Поэтому повторим еще раз: постарайся обойтись в своих программах без побочных эффектов. Впрочем, из этого правила есть одно исключение: при использовании вложенных вызовов процедур (то есть в тех случаях, когда одна процедура вызывает другую) иногда нельзя обойтись без использования в вызываемой процедуре имен из процедуры вызывающей. Многочисленные примеры таких процедур будут приведены в следующей главе. Разумеется, в этом случае в вызываемых процедурах появляются глобальные имена и правило, о котором говорилось выше, несколько усложняется. При использовании вложенных процедур рекомендуется:

1. В вызывающих процедурах «верхнего уровня» использовать только внутренние имена. 2. В вызываемых процедурах использовать в качестве глобальных только внутренние имена из вызывающей процедуры. 3. Ни в коем случае не использовать вызываемую процедуру отдельно от вызывающей.

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

рассчитывает получить определенный результат. Таким результатом может быть изменение обстановки в среде (с. 63). Например, на экран выдается какой-то текст,

вагоны на путях меняются местами или появляется новая линия на рисунке. Но довольно часто результат работы процедуры — это число или текст, которые должны использоваться в основной программе. Например, для исполнителя МАЛЫШ пришлась бы очень кстати процедура УМНОЖИТЬ, которая перемножала бы значения своих параметров. Понятно, что в результате работы должно быть получено число: произведение значений параметров. Это число нужно выдать в основную программу, то есть присвоить какому-то имени из общей части ОЗУ, чтобы продолжать с ним работу. Но... как это можно сделать? Ведь все имена, используемые в процедуре, должны быть внутренними, и их значения никак не могут попасть в общую часть ОЗУ. Может быть, использовать глобальное имя? Но ты ведь знаешь, что этого делать не стоит. Так как же быть?

Для того чтобы процедура могла передать результат в общую часть ОЗУ, в языке Робик предусмотрена специальная разновидность предписания ВЫДАТЬ. На диаграмме 46 видно, что оно обязательно должно быть последним в описании процедуры.

В языке Робик процедура, в которой используется предписание ВЫДАТЬ РЕЗУЛЬТАТ, называется функцией.

Вызов функции может быть использован в качестве выражения (например, в предписании ПРИСВОИТЬ или в вызове другой процедуры). Значением такого выражения будет результат функции, то есть значение выражения, указанного в предписании ВЫДАТЬ РЕЗУЛЬТАТ.

Рассмотрим небольшой пример. Описание функции СУММА для исполнителя МАЛЫШ может выглядеть так:

ЗАПОМНИТЬ СУММА (А,В); ИМЕНА: РЕЗ; СЛОЖИТЬ А С В И ПРИСВОИТЬ ИМЕНИ РЕЗ; ВЫДАТЬ РЕЗУЛЬТАТ: РЕЗ; ЗАКОНЧИТЬ; Теперь при выполнении предписания СУММА (5,10) ПРИСВОИТЬ ИМЕНИ X; имя X получит значение 15. Сделай прокрутку и проверь, что это будет именно

так! Используя эту процедуру мы можем сложить четыре числа одним

предписанием: СУММА (СУММА (20.40), СУММА (50.60)) ПРИСВОИТЬ ИМЕНИ Y; С функциями и другими разновидностями процедур ты еще встретишься в

последней главе. А пока постарайся выполнить небольшое контрольно-тренировочное задание.

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

2. Перечисли основные правила работы с параметрами процедур. 3. Опиши процедуру ЗВЕЗДОЧКА (X, Y), которая нарисует в заданной точке

звездочку шириной 10 мм (рис. 57).

4. Опиши процедуру ГРУЗОВИК (X, Y), которая нарисует в заданном месте

экрана грузовик, изображенный на рис. 58. X и Y — это координаты верхней левой точки кабины, все размеры указаны на чертеже. 5. Опиши функцию ЧЕТЫРЕЖДЫ (X), результатом которой будет значение

имени X, умноженное на 4. Так, при исполнении директивы. ВЫДАТЬ ЧЕТЫРЕЖДЫ (ЧЕТЫРЕЖДЫ (8)); на экран должно быть выдано число 128.

ГЛАВА ЧЕТВЕРТАЯ ВЕТВЛЕНИЯ И ЦИКЛЫ В ПРОГРАММАХ Десятый урок Тринадцать задач, девять планов и три предписания. Задачи. Внимательно прочитай условия приведенных здесь задач, но не

торопись их решать! З а д а ч а 1. Составить программу для перевода исполнителя МУРАВЕЙ с

клетки (1,1) на клетку (10,10) вдоль края доски. Кубиков на доске нет и исполнитель может двигаться по ней свободно.

З а д а ч а 2. На пути А (рис. 17) стоит пассажирский cостав из 16 вагонов. Необходимо его развернуть, то есть переставить вагоны так, чтобы первый вагон оказался на месте последнего, второй — на месте предпоследнего и т. д. Составить программу для исполнителя МАШИНИСТ, считая, что на каждом из путей А, Б и В можно разместить все 16 вагонов и локомотив.

3 а д а ч а 3. Исполнитель ТОМ __СОЙЕР должен покрасить в один слой забор, состоящий из 1984 досок шириной 15 сантиметров каждая. Ширина промежутка между досками 10 сантиметров. Перед началом работы ТОМ _ СОЙЕР стоит у правого края забора. Составить программу.

З а д а ч а 4. Составить программу для вычерчивания домика, показанного на рис. 59. Можно использовать все стандартные процедуры системы Шпага. Размеры указаны на рисунке.

З а д а ч а 5. Несколько досок забора, описанного в задаче 3, заменили новыми некрашеными. ТОМ __ СОЙЕР должен их покрасить, не трогая остальных досок. Перед началом работы он стоит у левого края забора. Составить программу.

З а д а ч а 6. Описать для исполнителя МАЛЫШ функцию ПРОИЗВЕДЕНИЕ (А, В), результатом которой будет произведение значений ее параметров. Например, после выполнения директивы

ПРОИЗВЕДЕНИЕ (5, 25) ПРИСВОИТЬ ИМЕНИ РЕЗУЛЬТАТ; имя РЕЗУЛЬТАТ должно получить значение 125. З а д а ч а 7. Описать функцию ОСТАТОК (А, В), результатом которой будет

остаток от деления А на В. З а д а ч а 8. Описать функцию ЧАСТНОЕ (А, В), вычисляющую частное от

деления А на В. З а д а ч а 9. Описать процедуру ПЕРЕВОД (X, Y), которая переведет

исполнителя МУРАВЕЙ с любой клетки доски на клетку (X, Y) при условии, что на доске нет кубиков, которые могли бы помешать движению исполнителя.

З а д а ч а 10. Описать для исполнителя МАЛЫШ функцию ФАКТОРИАЛ (N), результатом которой будет N!, то есть произведение всех натуральных чисел от 1 до N. Например, значение вызова ФАКТОРИАЛ (7) должно быть равно 5040 =1 × 2 × З × 4 × 5 × 6 × 7. По определению, значение ФАКТОРИАЛ (0) равно 1.

З а д а ч а 11. Описать процедуру ОБМЕН (X 1, Х2) для исполнителя МУРАВЕЙ, позволяющую поменять местами два кубика на пятой горизонтали. Координаты клеток, на которых стоят эти кубики (X1, 5) и (Х2, 5), причем выполняются неравенства 1 < X1 < Х2 < 10. Перед началом работы этой процедуры МУРАВЕЙ СТОИТ на клетке (1,5), после окончания работы он должен возвратиться на ту же клетку.

Например, если из кубиков составлено слово БРАК, то превратить его в слово КРАБ можно одной директивой:.

ОБМЕН (2,5); или ОБМЕН (5,2);

З а д а ч а 12*. Описать функцию ФИБО (N) для получения числа Фибоначчи с

номером N (fN). По определению, f1 = f2 = 1, а при N > 2 справедливо fN fN-1 + fN-2 равенство: Например:f3 = 2; f4 = 3; f5 = 5; f6 = 8; f7 = 13... З а д а ч а 13*. Описать процедуру для построения графика функции Y = X2/128. Если использовать только те конструкции Робика, о которых уже

рассказывалось в этой книге, то программы для решения этих задач либо вообще нельзя будет составлять, либо они получатся очень громоздкими. Как, например, объяснить исполнителю ТОМ__СОЙЕР, что он должен красить только те доски, которые еще не покрашены? Об этом мы еще не рассказывали, поэтому программу для решения задачи 5 ты сейчас составить не сможешь. А вот план для решения этой задачи составить можно и сейчас: понятно, что робот должен двигаться вдоль забора и проверять, окрашена ли каждая доска, и красить ее, если она окажется неокрашенной. Попробуй составить сейчас общие планы для решения нескольких первых задач. Если какой-то план не получится, посмотри на следующих страницах решение (или указания), а потом вернись к задачам и обязательно постарайся самостоятельно составить следующий план.

Решение начинается с плана. К з а д а ч е 1. Для того чтобы с левой нижней клетки (1,1) попасть на правую

верхнюю (10,10), нужно сделать 9 ходов вверх и 9 ходов вправо (или наоборот — сначала 9 ходов вправо, а потом 9 ходов вверх). Все остальные возможные маршруты (например: 4 хода вверх, 5 ходов вправо, 5 ходов вверх, 4 хода вправо) не соответствуют условию задачи, так как не проходят вдоль края доски.

Общий план для одного из двух возможных путей можно записать так: . ПОВТОРИТЬ 9 РАЗ: ВВЕРХ;

ПОВТОРИТЬ 9 РАЗ: ВПРАВО; К з а д а ч е 2. Похожие задачи, хотя и для меньшего количества вагонов,

встречались в первой главе, поэтому план подобрать нетрудно: нужно по одному перегнать все вагоны на путь В, а потом объединить их в один состав и перевести его обратно на А (или наоборот: перевести все вагоны с А на В и вернуть их обратно по одному):

ПОВТОРИТЬ 16 РАЗ: ПЕРЕВОД ОДНОГО ВАГОНА С А НА В; ПРИЦЕПИТЬ 16 ВАГОНОВ К ЛОКОМОТИВУ; ПЕРЕВЕСТИ СОСТАВ С В НА А; ОТЦЕПИТЬ 16 ВАГОНОВ; ВЕРНУТЬ ЛОКОМОТИВ НА МЕСТО; Если ты не смог сразу составить этот план, попробуй сейчас записать план для

разворота состава вторым способом (с А на В весь состав, а обратно по одному вагону). К з а д а ч е 3. ПОВТОРИТЬ 1984 РАЗА: ПОКРАСИТЬ ОДНУ ДОСКУ; ВЛЕВО НА 15 СМ; ПЕРЕХОД К СЛЕДУЮЩЕЙ ДОСКЕ;

Рамкой обведены пункты, которые нужно повторять. К з а д а ч е 4. Рисунок состоит из нескольких линий, изображающих контуры

стен и крыши (высота крыши 20), и из пяти «этажей» по шесть окон в каждом. План можно записать так:

НАРИСОВАТЬ КОНТУР ДОМИКА; ПОВТОРИТЬ 5 РАЗ: ПОДВЕСТИ ИНСТРУМЕНТ К НАЧАЛУ ЭТАЖА; НАРИСОВАТЬ ЭТАЖ;

А НАРИСОВАТЬ ЭТАЖ — это, значит, нарисовать шесть окон. Перед

изображением каждого окна нужно подвести к нему инструмент. Тогда уточняющий план для предписания НАРИСОВАТЬ ЭТАЖ будет выглядеть так:

ПОВТОРИТЬ 6 РАЗ: ПОДВЕСТИ ИНСТРУМЕНТ К НАЧАЛУ ОКНА; НАРИСОВАТЬ ОКНО;

Можно и объединить эти два плана: НАРИСОВАТЬ КОНТУР ДОМИКА; ПОВТОРИТЬ 5 РАЗ: ПОДВЕСТИ ИНСТРУМЕНТ К НАЧАЛУ ЭТАЖА; ПОВТОРИТЬ 6 РАЗ: ПОДВЕСТИ ИНСТРУМЕНТ К НАЧАЛУ ОКНА; НАРИСОВАТЬ ОКНО;

Обрати внимание, что два пункта должны быть исполнены тридцать раз! К з а д а ч е 5. Чтобы выполнить такое задание, ТОМ__СОЙЕР должен отличать

окрашенную доску от неокрашенной. План может выглядеть, например, так:

ПОВТОРИТЬ 1984 РАЗА: ЕСЛИ ДОСКА НЕ ОКРАШЕНА, ТО ПОКРАСИТЬ ДОСКУ; ВПРАВО НА 15 СМ А ЕСЛИ ДОСКА ОКРАШЕНА, ТО ВПРАВО НА 25 СМ;

; Несколько слов о делении на нуль и о других особых случаях. Продолжим

составление планов. На очереди несколько задач на составление процедур (точнее функций) для исполнителя МАЛЫШ.

К з а д а ч е 6. Вспомним, что во время последней перемены мы уже сталкивались с необходимостью заменить умножение сложением. Проделаем это снова, используя сокращенные обозначения:

ПРОЦЕДУРА ПРОИЗВЕДЕНИЕ (А, В);

0 -> Р;

ПОВТОРИТЬ А РАЗ: Р + В-> Р; ВЫДАТЬ РЕЗУЛЬТАТ: Р;

В большой рамке - пункты плана, которые должны превратиться в текст

процедуры; маленькая рамка показывает повторяемое предписание. Еще раз напоминаем, что это не программа, а только план, поэтому мы можем

использовать любые понятные обозначения. К з а д а ч е 7. Деление натуральных чисел «с остатком» легко можно заменить

вычитанием, точно так же, как умножение мы заменили сложением. Чтобы разделить А на В, нужно вычитать В из А до тех пор, пока оставшееся число не станет меньше, чем В — это и будет остаток, который нам нужно найти,. Для решения этой задачи, как и для всех предыдущих, нужно несколько раз повторить какие-то действия. Разница только в том, что мы не знаем заранее, сколько раз нужно эти действия повторять. Вычитание нужно продолжать до тех пор, пока выполняется условие А ≥ В. Запишем это в виде плана:

ПРОЦЕДУРА ОСТАТОК (А,B);

ДО ТЕХ ПОР ПОКА А ≥ В ПОВТОРЯТЬ:

А — В —>А; ВЫДАТЬ РЕЗУЛЬТАТ: А ;

Проверим этот план. Для этого прокрутим его вручную. Попробуем, например, разделить

ОСТАТОК (16,3) ПРИСВОИТЬ ИМЕНИ ОСТ;' При вызове процедуры ее параметры имеют такие значения: А = 16, В = 3.

Начинаем повторять вычитания. После первого повторения А = 13, В = 3, после второго — А = 10, В = 3, наконец, после пятого вычитания получим: А = 1, В = 3 и значение А станет меньше значения В, условие перестанет выполняться, повторения закончатся и процедура выдаст в качестве результата число 1 —а это как

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

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

Получается, что план правильный? Не торопись! Для любых положительных чисел он подходит, отрицательных чисел в программе для исполнителя МАЛЫШ быть не может, но нули там вполне могут встретиться.

Посмотрим, что сделает процедура, написанная в соответствии с нашим планом, если вызвать ОСТАТОК (5,0).

Если следовать нашему плану, то МАЛЫШ должен вычитать нуль из пяти до тех пор, пока результат не станет меньше нуля. Долго же ему придется работать! Ведь от вычитания нуля число, естественно, никак не изменяется, и значит, никогда не ста-нет отрицательным, даже если бы МАЛЫШ и умел работать с отрицательными числами. Очевидно, что случай деления на нуль нужно предусмотреть отдельно.

Можно договориться, например, что в этом случае результатом функции будет нуль, и одновременно на экран должно быть выдано сообщение: ВНИМАНИЕ! В ФУНКЦИИ «ОСТАТОК» — ПОПЫТКА ДЕЛЕНИЯ НА НУЛЬ.

Новый план будет выглядеть так:

ПРОЦЕДУРА ОСТАТОК (А, В);

ЕСЛИ В = 0, ТО

О—>А; ВЫДАТЬ: АВАРИЙНОЕ _ СООБЩЕНИЕ;

ИНАЧЕ

ПОКА А ≥ В ПОВТОРЯТЬ:

А — В —>А;

ВЫДАТЬ РЕЗУЛЬТАТ: А;

К з а д а ч е 8. Вычисление частного отличается от определения остатка только

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

План: ПРОЦЕДУРА ЧАСТНОЕ (А, В); О -> СЧЕТЧИК; ЕСЛИ В = 0, ТО ВЫДАТЬ: АВАРИЙНОЕ СООБЩЕНИЕ; ИНАЧЕ ПОКА А > В ПОВТОРЯТЬ: А-В-> А; СЧЕТЧИК +1-> СЧЕТЧИК; ВЫДАТЬ РЕЗУЛЬТАТ: СЧЕТЧИК; Сравни этот план с предыдущим и разберись во всех отличиях. К з а д а ч е 9. Чтобы перевести исполнителя МУРАВЕЙ на заданную клетку,

нужно сначала определить, на какой клетке он находится. Потом необходимо выяснить, в какую сторону он должен двигаться, и подсчитать количество ходов, которые нужно сделать в каждом направлении.

План:

ПРОЦЕДУРА ПЕРЕВОД (X, Y);

ОПРЕДЕЛИТЬ КООРДИНАТЫ КЛЕТКИ,

НА КОТОРОЙ НАХОДИТСЯ МУРАВЕЙ:

ХТи YТ;

ЕСЛИ Х >ХТ, ТО

ПОВТОРИТЬ (Х - ХТ) РАЗ: ВПРАВО;

ИНАЧЕ

ПОВТОРИТЬ (ХТ - Х) РАЗ: ВЛЕВО

ЕСЛИ Y > YТ, ТО

ПОВТОРИТЬ (Y - YТ) РАЗ: ВВЕРХ;

ИНАЧЕ

ПОВТОРИТЬ (YТ - Y) РАЗ; ВНИЗ;

: Остальными задачами мы займемся на следующем уроке. А сейчас

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

Циклические предписания и предписания ветвления. Конечно, ты уже заметил, что в девяти составленных нами планах все время встречались три конструкции:

ПОВТОРИТЬ столько-то РАЗ такое-то действие ПОКА выполняется такое-то условие ПОВТОРЯТЬ то-то и то-то ЕСЛИ выполняется условие ТО сделать это ИНАЧЕ сделать то Первые две конструкции использовались для того, чтобы повторить один или

несколько пунктов плана столько раз, сколько нужно. Третья конструкция применялась там, где нужно было выбрать один из двух возможных вариантов (например, в задаче 9 нужно было выбрать направление движения: вверх или вниз, вправо или влево).

Ты должен помнить, что на синтаксических диаграммах для многократного повторения одного и того же участка применялся цикл, а для выбора одного варианта из нескольких возможных — ветвление.

Такие же названия используются для перечисленных конструкций в планах. Те пункты планов, В которых используются конструкции ПОВТОРИТЬ столько-то РАЗ или ПОКА - ПОВТОРЯТЬ, называют циклическими, а те, в которых используется ЕСЛИ — ТО — ИНАЧЕ и другие похожие конструкции, называют ветвящимися.

Для того чтобы можно было составить программы по ветвящимся и циклическим пунктам планов, в Робике предусмотрены три предписания: ПОВТОРИТЬ, ПОКА и ЕСЛИ. Их синтаксис описывается диаграммой 51.

Заметим, что предписание ЕСЛИ существует в двух вариантах — полном и

сокращенном. В сокращенном варианте опускается ключевое слово ИНАЧЕ и следующее за ним предписание.

Уточняющая диаграмма для гибкого поля УСЛОВИЕ, встречающегося в предписаниях ЕСЛИ и ПОКА:

Вот несколько примеров условий: А>В ТЕКСТ = "КРОКОДИЛ" Х/ = 25 РАССТОЯНИЕ > =3.1415 Другие условия ты без труда сможешь составить сам. Только не забывай, что

записываются они не по правилам русского языка, а по правилам Робика, а в этом языке ни имена, ни тексты, ни другие слова не изменяются. А теперь посмотри еще раз на диаграммы 51 и 52. Обрати внимание, что во всех трех предписаниях нет ни одного знака препинания! Начинающих программистов обычно так и тянет поставить запятые перед ключевыми словами ТО и ИНАЧЕ и двоеточие после ПОВТОРЯТЬ. Это приводит к синтаксическим ошибкам, которые система сразу обнаруживает. И еще одна очень важная особенность этих диаграмм: после слов ТО, ИНАЧЕ, ПОВТОРЯТЬ и РАЗ можно записывать только по одному предписанию. В планах к задачам 1-9 мы часто записывали после этих слов по нескольку предписаний, обводя их рамочками, чтобы не ошибиться. Но ведь в программе-то рамочку не нарисуешь! А что же делать, если по смыслу задачи нужно, например, повторять не одно, а несколько предписаний? Нужно объединить их в процедуру и вместо нескольких предписаний

записать вызов объединяющей их процедуры. Запомни это правило — оно пригодится нам еще не раз.

А теперь разберемся с тем, как выполняются циклические и ветвящиеся предписания Робика.

Предписание ПОВТОРИТЬ. Сначала система определяет значение выражения, записанного между словами ПОВТОРИТЬ и РАЗ. Если это значение — натуральное число, то предписание, указанное после слова РАЗ, будет выполнено соответствующее число раз. Например, если значением имени А будет число 8, то в результате исполнения директивы

ПОВТОРИТЬ А РАЗ ВВЕРХ; исполнитель МУРАВЕЙ сдвинется на 8 клеток вверх, а если набрать директиву ПОВТОРИТЬ 5 РАЗ ВПРАВО; то он сдвинется на 5 клеток вправо. Если значением выражения будет нуль, то предписание, разумеется, не

выполнится ни разу. И еще одно свойство предписания ПОВТОРИТЬ: если значение указанного в

нем выражения меняется при выполнении предписания, то это уже не влияет на число повторений.

З а п о м н и : значение выражения, указанного после слова ПОВТОРИТЬ, вычисляется машиной один раз и больше не проверяется! Например, после выполнения предписаний

ЗНАЧЕНИЕ 5 ПРИСВОИТЬ ИМЕНИ А; ПОВТОРИТЬ А РАЗ СЛОЖИТЬ А С 1 И ПРИСВОИТЬ ИМЕНИ А; имя А получит значение 10, потому что предписание СЛОЖИТЬ будет

исполнено 5 раз. Если бы система каждый раз проверяла значение имени А, эта программа зациклилась бы, потому что при каждом повторении значение А увеличивается на 1.

Предписание ПОКА. Сначала система вычисляет значения обоих выражений, входящих в условие, и проверяет условие. Если оно ложно (то есть не выполнено), то предписание, записанное после слова ПОВТОРЯТЬ, вообще не будет исполняться. Ес-ли условие истинно, то система исполняет это предписание и вновь проверяет условие. Дальше все проверяется в том же порядке: исполняем предписание — проверяем условие — исполняем — проверяем — и т. д., пока условие не станет ложным. После этого выполнение цикла прекращается и начинают исполняться следующие за ним предписания программы.

Обрати внимание, что в цикле ПОКА, в отличие от цикла ПОВТОРИТЬ, условие проверяется каждый раз после очередного повторения. При этом предписание, повторяемое в цикле, обязательно должно как-то менять значение одного из выраже-ний, входящих в условие (или обоих сразу). Если это будет не так, программа зациклится! Зацикливание программы по этой причине — одна из самых распространенных ошибок у начинающих программистов.

Предписание ЕСЛИ. Исполнение начинается с проверки условия. Если оно истинно, будет выполнено предписание, стоящее после слова ТО. Если же условие ложно, будет выполнено предписание, записанное после слова ИНАЧЕ. Например, после выполнения предписания-

ЕСЛИ А БОЛЬШЕ В ТО А ПРИСВОИТЬ ИМЕНИ БОЛЬШЕЕ _ ЧИСЛО ИНАЧЕ В ПРИСВОИТЬ ИМЕНИ БОЛЬШЕЕ _ ЧИСЛО; значением имени БОЛЬШЕЕ _ ЧИСЛО станет большее из значений имен А и В

(проверь это на нескольких конкретных примерах).

Таким образом, предписание ЕСЛИ позволяет выбрать один вариант из двух возможных, то есть Осуществить в программах то самое ветвление, с которым мы много раз встречались на синтаксических диаграммах. Впрочем, ветвление может быть и более сложным. Например, довольно часто нужно выбрать один вариант из трех-четырех возможных, а не из двух. Это можно сделать с помощью нескольких предписаний ЕСЛИ, связанных в такую цепочку:

ЕСЛИ-ТО- ИНАЧЕ ЕСЛИ-ТО- ИНАЧЕ ЕСЛИ-ТО- . . . . . . . . . . . . ИНАЧЕ Например, описание функции НАЗВАНИЕ — ОЦЕНКИ, которая по числовому

обозначению школьной оценки выдает ее официальное название, может выглядеть так: ЗАПОМНИТЬ НАЗВАНИЕ___ОЦЕНКИ (ЧИСЛО); ИМЕНА: СЛОВО;

ЕСЛИ ЧИСЛО = 1 ТО '"ПЛОХО" ПРИСВОИТЬ ИМЕНИ СЛОВО ИНАЧЕ ЕСЛИ ЧИСЛО = 2 ТО "НЕУДОВЛЕТВОРИТЕЛЬНО" ПРИСВОИТЬ ИМЕНИ СЛОВО ИНАЧЕ ЕСЛИ ЧИСЛО = 3 ТО "УДОВЛЕТВОРИТЕЛЬНО" ПРИСВОИТЬ ИМЕНИ СЛОВО ИНАЧЕ ЕСЛИ ЧИСЛО = 4 ТО "ХОРОШО" ПРИСВОИТЬ ИМЕНИ СЛОВО ИНАЧЕ ЕСЛИ ЧИСЛО = 5 ТО "ОТЛИЧНО" ПРИСВОИТЬ ИМЕНИ СЛОВО ИНАЧЕ "НЕПРАВИЛЬНОЕ ОБОЗНАЧЕНИЕ" ПРИСВОИТЬ ИМЕНИ СЛОВО;

ВЫДАТЬ РЕЗУЛЬТАТ: СЛОВО; ЗАКОНЧИТЬ; Простейший вариант ветвления — обход, встречающийся на синтаксических

диаграммах, тоже можно выполнить с помощью предписания ЕСЛИ. Как видно из диаграммы 51, слово ИНАЧЕ и стоящее после него предписание можно не указывать. В этом случае предписание ЕСЛИ выполняется так: если условие истинно — исполняется предписание, стоящее после ТО, а если условие ложно, то это предписание не исполняется (как будто мы прошли по обходному пути на диаграмме).

Например, если в какой-нибудь медицинской программе нужно проверить значение имени ТЕМПЕРАТУРА и выдать сообщение, если она повышена, то для этой цели можно использовать такое предписание:

ЕСЛИ ТЕМПЕР АТУ РА > 37 ТО ВЫДАТЬ: "ТЕМПЕРАТУРА ПОВЫШЕННАЯ"; Если температура будет нормальной, то на экране не появится никакого

сообщения. Обрати внимание, что при записи условных и циклических предписаний мы

разбивали их на несколько строчек, так, чтобы слова ПОКА, ЕСЛИ, ИНАЧЕ, ПОВТОРЯТЬ были хорошо заметны. Использование такой записи входит в число непи-саных правил, принятых среди опытных программистов.

И еще одно такое правило. Не рекомендуется записывать сразу после слова ТО предписание ЕСЛИ. Правила языка это разрешают, но такая конструкция может привести к трудностям при чтении программы. Например, если ключевые слова расста-влены так:

ЕСЛИ-ТО ЕСЛИ-ТО-ИНАЧЕ-

то с первого взгляда трудно сообразить, к какому ЕСЛИ относится ИНАЧЕ — к первому или ко второму. По правилам Робика, каждое следующее ИНАЧЕ относится к ближайшему из стоявших перед ним ЕСЛИ, для которого еще не было использовано слово ИНАЧЕ.

Несмотря на короткую формулировку, пользоваться этим правилом довольно трудно, особенно в сложных конструкциях с большим числом ИНАЧЕ, ЕСЛИ и ТО. Поэтому старайся не писать подряд слова ТО и ЕСЛИ!

Седьмая перемена Новое о знакомых исполнителях Для решения большинства задач, формулировки которых были приведены в

начале этой главы, нам понадобятся внутренние имена исполнителей МУРАВЕЙ, МАШИНИСТ, ТОМ _ СОЙЕР и ШПАГА. Об этих именах мы уже неоднократно упоминали, а сейчас приведем полный перечень таких имен.

Исполнитель МУРАВЕЙ. Внутренние имена X и Y. Значения этих имен - координаты той клетки доски, на которой находится МУРАВЕЙ. Имена защищенные: новые значения им может присвоить только сам исполнитель во время движения по до-ске. В общих программах можно только читать значения этих имен, чтобы узнать, на какой клетке доски находится МУРАВЕЙ.

Исполнитель МАШИНИСТ. Внутренние имена: ЧИСЛО _ ВАГОНОВ _ СПЕРЕДИ, ЧИСЛО _ ВАГОНОВ _ СЗАДИ, ТИП __ НОВОГО _ ВАГОНА и ПРИЧИНА__ОСТАНОВКИ. Значения первых двух имен — числа, показывающие, сколько вагонов прицеплено к локомотиву спереди и сзади. Значение имени ТИП__НОВОГО __ВАГОНА — текст, соответствующий типу того вагона, который был прицеплен к локомотиву во время исполнения последнего предписания ПРИЦЕПИТЬ ВАГОН. Обрати внимание, что предписание ОТЦЕПИТЬ ВАГОН не влияет на значение этого имени. Возможные варианты значений: "КРЫТЫЙ", "ЦИСТЕРНА", "ПЛАТФОРМА", "ПАССАЖИРСКИЙ", "НЕИЗВЕСТНЫЙ", ПУСТО. Вариант ПУСТО возможен только в том случае, если после включения исполнителя МАШИНИСТ еще ни разу не исполнялось предписание ПРИЦЕПИТЬ ВАГОН.

Значение имени ПРИЧИНА _ ОСТАНОВКИ — один из следующих текстов: "СТРЕЛКА", "ВАГОНЫ", "ТУПИК".Значение может измениться только при выполнении одного из предписаний ВПЕРЕД или НАЗАД.

Исполнитель ТОМ _ СОЙЕР. Внутренние имена: СОСТОЯНИЕ _ ДОСКИ, КОЛИЧЕСТВО _ КРАСКИ. Имя СОСТОЯНИЕ__ДОСКИ может иметь одно из трех значений: "ОКРАШЕНА", "НЕ ОКРАШЕНА", ПУСТО. Пустое значение может быть в том случае, если перед роботом нет доски, то есть он находится напротив промежутка между досками или вообще в стороне от забора. Значение имени КОЛИЧЕСТВО__КРАСКИ — это вещественное число, соответствующее количеству оставшейся в ведерке краски (в литрах).

В системе ШПАГА предусмотрено много внутренних имен, но мы назовем сейчас только два из них: X и Y, их значения — дробные числа, определяющие текущие координаты рисующего инструмента.

Все внутренние имена перечисленных исполнителей защищенные. Напоминаем, что в общих программах использовать внутренние имена исполнителей можно только в виде индивидуальных имен, например: МУРАВЕЙ.Х, ШПАГА.Х или МАШИНИСТ. ПРИЧИНА__ОСТАНОВКИ!

Одиннадцатый урок Составление программ с ветвящейся и циклической структурой Обходчик отправляется в путь. Составим несколько программ для

исполнителя ОБХОДЧИК, который предназначен для проверки качества стыков между рельсами на железнодорожных линиях. Его МПИ очень напоминает множество предписаний исполнителя МАШИНИСТ.

МП исполнителя ОБХОДЧИК: ВПЕРЕД НАЗАД ПЕРЕВЕСТИ СТРЕЛКУ ПОКРАСИТЬ СТЫК Последнее предписание предназначено для того, чтобы ОБХОДЧИК мог

отметить специальной краской неисправные стыки — по этим меткам их легко сможет найти ремонтная бригада.

Останавливается ОБХОДЧИК в тех же случаях, что и МАШИНИСТ, и, кроме того, на каждом стыке. Внутренние имена: ПРИЧИНА _ ОСТАНОВКИ (возможные значения: "СТРЕЛКА", "ВАГОНЫ", "ТУПИК", "СТЫК"), СОСТОЯНИЕ _ СТЫКА ("ИСПРАВЕН" или "НЕИСПРАВЕН").

Все задачи, приведенные на этом уроке, относятся к одной и той же среде для работы ОБХОДЧИКА: нужно проверить все стыки на длинной ветке, которая заканчивается тупиком. Ни стрелок, ни вагонов на ветке нет. Связь с ОБХОДЧИКОМ поддерживается по радио. Перед началом работы ОБХОДЧИК остановился у первого стыка новой ветки. Значение имени ПРИЧИНА _ ОСТАНОВКИ равно "СТЫК".

З а д а ч а 1. ОБХОДЧИК должен проверить все стыки на ветке и отметить краской неисправные стыки. Добравшись до конца ветки, он должен послать на терминал сообщение "ЛИНИЯ ПРОВЕРЕНА ПОЛНОСТЬЮ". Описать процедуру ПРОВЕРКА__СТЫКОВ для решения этой задачи.

Р еш е н и е . Общий план очевиден: нужно повторять предписание ВПЕРЕД до тех пор, пока значение имени ПРИЧИНА _ ОСТАНОВКИ не окажется равным тексту "ТУПИК". Каждый раз нужно проверять состояние стыка, перед которым остановился ОБХОДЧИК. Если стык оказался неисправным, его нужно отметить краской. Перед на-чалом работы исполнитель уже остановился перед стыком, поэтому нужно сначала проверить этот стык, а затем уже двигаться дальше.

П л а н :

ПРОЦЕДУРА ПРОВЕРКА _ СТЫКОВ;

ПОКА НЕ ВСТРЕТИЛИ ТУПИК ПОВТОРЯТЬ

ЕСЛИ СТЫК НЕИСПРАВЕН ТО

ПОКРАСИТЬ СТЫК

ВПЕРЕД

ВЫДАТЬ СООБЩЕНИЕ

Рамочки, использованные при записи алгоритма, позволяют сразу заметить, что

в цикле ПОКА нужно повторять два предписания (ЕСЛИ и ВПЕРЕД). Следовательно, их нужно объединить в процедуру, которую можно назвать ПРОВЕРКА _ ОДНОГО _ СТЫКА.

Составлять программу будем, как мы уже привыкли, сверху вниз: ЗАПОМНИТЬ ПРОВЕРКА ____СТЫКОВ; ПОКА ОБХОДЧИК ПРИЧИНА _ ОСТАНОВКИ / = "ТУПИК" ПОВТОРЯТЬ ПРОВЕРКА ОДНОГО _ СТЫКА (); ВЫДАТЬ: "ЛИНИЯ ПРОВЕРЕНА ПОЛНОСТЬЮ"; ЗАКОНЧИТЬ; ЗАПОМНИТЬ ПРОВЕРКА___ОДНОГО___СТЫКА; ЕСЛИ ОБХОДЧИК СОСТОЯНИЕ - СТЫКА = "НЕИСПРАВЕН" ТО ПОКРАСИТЬ СТЫК; ВПЕРЕД; ЗАКОНЧИТЬ; Прокрутку этой программы сделай, пожалуйста, сам. З а д а ч а 2. ОБХОДЧИК должен сообщить, обнаружены ли на линии

неисправные стыки, В остальном условия те же, что в задаче 1. Р еш е н и е . Посмотрим, как изменится план. Очевидно, что при обнаружении

первого же неисправного стыка нам нужно будет записать в какой-то блок памяти (назовем его РЕЗУЛЬТАТ) информацию об этом стыке. Можно, например, записать туда текст "ОБНАРУЖЕН НЕИСПРАВНЫЙ СТЫК". Если такое присваивание не будет выполнено ни разу за все время работы ОБХОДЧИКа, значит, неисправных стыков на линии нет. В этом случае в блоке с именем РЕЗУЛЬТАТ останется старое содержимое. Какое? Если этот блок еще не использовался в программе, то значение ПУСТО. Значит, в конце работы процедуры мы легко сможем проверить, попадались ли ОБХОДЧИКу неисправные стыки: если они были, то в блоке памяти с именем РЕЗУЛЬТАТ будет храниться текст "ОБНАРУЖЕН НЕИСПРАВНЫЙ СТЫК", а если их не было — там ничего не будет... Нехорошо! Пусть в этом случае там будет текст "НЕИСПРАВНЫХ СТЫКОВ НЕ ОБНАРУЖЕНО".

Попробуй сам довести до конца решение этой задачи.

О т в е т . ЗАПОМНИТЬ НОВАЯ___ПРОВЕРКА; ИМЕНА: РЕЗУЛЬТАТ; "НЕИСПРАВНЫХ СТЫКОВ НЕ ОБНАРУЖЕНО" ПРИСВОИТЬ ИМЕНИ РЕЗУЛЬТАТ; ПОКА ОБХОДЧИК. ПРИЧИНА___ОСТАНОВКИ/= "ТУПИК" ПОВТОРЯТЬ ПРОВЕРКА___ОДНОГО___СТЫКА (); ВЫДАТЬ: "ЛИНИЯ ПРОВЕРЕНА ПОЛНОСТЬЮ"; ВЫДАТЬ: РЕЗУЛЬТАТ; ЗАКОНЧИТЬ; ЗАПОМНИТЬ ПРОВЕРКА___ОДНОГО___СТЫКА; ЕСЛИ ОБХОДЧИК. СОСТОЯНИЕ___СТЫКА ="НЕИСПРАВЕН" ТО НЕИСПРАВНЫЙ___СТЫК ( ); ВПЕРЕД; ЗАКОНЧИТЬ ЗАПОМНИТЬ НЕИСПРАВНЫЙ___СТЫК; ПОКРАСИТЬ СТЫК; ЗНАЧЕНИЕ "ОБНАРУЖЕН НЕИСПРАВНЫЙ СТЫК" ПРИСВОИТЬ ИМЕНИ РЕЗУЛЬТАТ, ЗАКОНЧИТЬ; Обрати внимание, что в процедуре НЕИСПРАВНЫЙ___СТЫК использовано

имя РЕЗУЛЬТАТ. Это как раз тот случай, когда побочный эффект полезен и обойтись без него трудно (убедись в этом!). Если процедура НЕИСПРАВНЫЙ _ СТЫК используется только внутри процедуры НОВАЯ___ПРОВЕРКА, то ее побочный эффект не опасен, потому что имя РЕ ЗУЛЬТАТ в этой процедуре объявлено внутренним. И все-таки будь осторожен с этой процедурой!

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

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

Ответы и указания к первым девяти задачам десятого урока. К з а д а ч е 1. ВКЛЮЧИТЬ ИСПОЛНИТЕЛЯ МУРАВЕЙ; ПОВТОРИТЬ 9 РАЗ

ВВЕРХ; ПОВТОРИТЬ 9 РАЗ

ВПРАВО; ВЫКЛЮЧИТЬ ИСПОЛНИТЕЛЯ МУРАВЕЙ; Во всех последующих программах мы не будем приводить предписания для

включения и выключения исполнителей. Будем считать, что все нужные исполнители включены.

К з а д а ч е 2. ЗАПОМНИТЬ РАЗВОРОТ _ СОСТАВА; ПОВТОРИТЬ 16 РАЗ ПЕРЕВОД _ ОДНОГО _ ВАГОНА ( ); ВПЕРЕД;

ВПЕРЕД; ПОВТОРИТЬ 16 РАЗ ПРИЦЕПИТЬ ВАГОН; НАЗАД; Переводим состав с В на А ВПЕРЕД; ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; ПОВТОРИТЬ 16 РАЗ ОТЦЕПИТЬ ВАГОН; НАЗАД; Возвращаем локомотив на место

ЗАКОНЧИТЬ; ЗАПОМНИТЬ ПЕРЕВОД —ОДНОГО _ВАГОНА;

ВПЕРЕД; ПЕРЕВЕСТИ СТРЕЛКУ; ВПЕРЕД; ПРИЦЕПИТЬ ВАГОН; НАЗАД; ВПЕРЕД; ВПЕРЕД; ОТЦЕПИТЬ ВАГОН; НАЗАД;

ЗАКОНЧИТЬ; ВЫЗВАТЬ РАЗВОРОТ___СОСТАВА; К з а д а ч е 4. При решении этой задачи самое трудное — организовать переход

от одного окна к другому — и от одного этажа к другому. Сделать это можно разными способами. Например, можно использовать глобальные имена X и Y и после каждого нарисованного окна увеличивать значение X, а после каждого нарисованного этажа - значение Y. Приведем другую программу, в которой использованы внутренние имена системы Шпага: X и Y.

ЗАПОМНИТЬ ДОМИК;

ПОДВОД (140,90); Рисуем контур домика ЛУЧ.(140,10); ЛУЧ'(10,10); ЛУЧ (10,90); ЛУЧ (140,90); ЛУЧ (90,120); ЛУЧ (60,120); ЛУЧ (10,90); ПОДВОД (20,15); ПОВТОРИТЬ 5 РАЗ ЭТАЖ ( );

ЗАКОНЧИТЬ; ЗАПОМНИТЬ ЭТАЖ; ИМЕНА: НАЧАЛЬНАЯ___ВЫСОТА; КОНЕЧНАЯ___ ВЫСОТА;

СЛОЖИТЬ ШПАГА.Y С 5 И ПРИСВОИТЬ ИМЕНИ НАЧАЛЬНАЯ _ ВЫСОТА; ПОДВОД (20, НАЧАЛЬНАЯ _ ВЫСОТА), ;Подводим к началу этажа ПОВТОРИТЬ 6 РАЗ ОКНО ( ); СЛОЖИТЬ НАЧАЛЬНАЯ _ ВЫСОТА С 10 И ПРИСВОИТЬ ИМЕНИ КОНЕЧНАЯ _ ВЫСОТА; ПОДВОД (20, КОНЕЧНАЯ _ ВЫСОТА);

ЗАКОНЧИТЬ;

ЗАПОМНИТЬ ОКНО; ИМЕНА: X1, Y1, Х2, Y2, ХЗ;

ШПАГА. X ПРИСВОИТЬ X1; Определяем текущие ШПАГА.Y ПРИСВОИТЬ Y1; координаты СЛОЖИТЬ X1 С 10 И ПРИСВОИТЬ Х2; СЛОЖИТЬ Y1 С 10 И ПРИСВОИТЬ Y2; ЛУЧ (X1, Y2); Рисуем ЛУЧ (Х2, Y2); контур ЛУЧ (Х2, Y1); окна ЛУЧ (X1, Y1); СЛОЖИТЬ Х2 С 10 И ПРИСВОИТЬ ХЗ; ПОДВОД (ХЗ, Y1); Подвод в начальную точку ;следующего окна

ЗАКОНЧИТЬ; ВЫЗВАТЬ ДОМИК; Проведи полную ручную прокрутку этой программы. Посмотри, нельзя ли улучшить процедуру ЭТАЖ. Постарайся обойтись одним

сложением и одним подводом вместо двух. Напиши программу для решения этой задачи без использования внутренних имен системы Шпага.

К з а д а ч е 5. Приведем только основную процедуру: ЗАПОМНИТЬ ОКРАСКА _ ОТДЕЛЬНЫХ _ ДОСОК;

ПОВТОРИТЬ 1984 РАЗ ЕСЛИ ТОМ___СОЙЕР. СОСТОЯНИЕ___ДОСКИ = "НЕ ОКРАШЕНА" ТО ОКРАСКА___ОДНОЙ___ДОСКИ ( ) ИНАЧЕ ВПРАВО НА 25 СМ;

ЗАКОНЧИТЬ; Как видишь, в этой процедуре всего один оператор. К з а д а ч е 6. ЗАПОМНИТЬ ПРОИЗВЕДЕНИЕ (А,В); ИМЕНА: РЕЗУЛЬТАТ;

ЗНАЧЕНИЕ 0 ПРИСВОИТЬ ИМЕНИ РЕЗУЛЬТАТ; ПОВТОРИТЬ А РАЗ СЛОЖИТЬ РЕЗУЛЬТАТ С В И ПРИСВОИТЬ РЕЗУЛЬТАТ;

ВЫДАТЬ РЕЗУЛЬТАТ: РЕЗУЛЬТАТ; ЗАКОНЧИТЬ; Сравни эту процедуру с алгоритмом, приведенным на с. 169. К з а д а ч е 7. ЗАПОМНИТЬ ОСТАТОК (А.В),

ЕСЛИ В = О ТО ДЕЛЕНИЕ___НА___НУЛЬ ( ) ИНАЧЕ ПОКА А > =В ПОВТОРЯТЬ ВЫЧЕСТЬ В ИЗ А И ПРИСВОИТЬ ИМЕНИ А,

ВЫДАТЬ РЕЗУЛЬТАТ: А; ЗАКОНЧИТЬ; ЗАПОМНИТЬ ДЕЛЕНИЕ___НА___НУЛЬ;

ЗНАЧЕНИЕ О ПРИСВОИТЬ ИМЕНИ А;

ВЫДАТЬ: "ОШИБКА! ДЕЛЕНИЕ НА НУЛЬ";

ЗАКОНЧИТЬ; К з а д а ч е 8. ЗАПОМНИТЬ ЧАСТНОЕ (А,В); ИМЕНА: СЧЕТЧИК;

ЗНАЧЕНИЕ О ПРИСВОИТЬ ИМЕНИ СЧЕТЧИК; ЕСЛИ В = О ТО ДЕЛЕНИЕ.__НА___НУЛЬ ( ) ИНАЧЕ ПОКА А > = В ПОВТОРЯТЬ ОДНО___ВЫЧИТАНИЕ ( );

ВЫДАТЬ РЕЗУЛЬТАТ: СЧЕТЧИК; ЗАКОНЧИТЬ;

ЗАПОМНИТЬ ОДНО___ВЫЧИТАНИЕ; ВЫЧЕСТЬ В ИЗ А И ПРИСВОИТЬ ИМЕНИ А; СЛОЖИТЬ СЧЕТЧИК С 1 И ПРИСВОИТЬ ИМЕНИ СЧЕТЧИК;

ЗАКОНЧИТЬ; К з а д а ч е 9. ЗАПОМНИТЬ ПЕРЕВОД (Х,Y);

ЕСЛИ Х> МУРАВЕЙ. X ТО ДВИЖЕНИЕ___ВПРАВО (Х,МУРАВЕЙ.Х) ИНАЧЕ ДВИЖЕНИЕ___ВЛЕВО (Х,МУРАВЕЙ.Х); ЕСЛИ Y > МУРАВЕЙ. Y ТО ДВИЖЕНИЕ___ВВЕРХ (Y,МУРАВЕЙ.Y) ИНАЧЕ ДВИЖЕНИЕ___ВНИЗ (Y, МУРАВЕЙ.Y);

ЗАКОНЧИТЬ; ЗАПОМНИТЬ ДВИЖЕНИЕ _ ВПРАВО (Х,ХТ);

ИМЕНА: РАЗНОСТЬ; ВЫЧЕСТЬ ХТ ИЗ X И ПРИСВОИТЬ ИМЕНИ РАЗНОСТЬ; ПОВТОРИТЬ РАЗНОСТЬ РАЗ ВПРАВО;

ЗАКОНЧИТЬ; ЗАПОМНИТЬ ДВИЖЕНИЕ___ВЛЕВО (Х,ХТ),

ИМЕНА: РАЗНОСТЬ; ВЫЧЕСТЬ X ИЗ ХТ И ПРИСВОИТЬ ИМЕНИ РАЗНОСТЬ; ПОВТОРИТЬ РАЗНОСТЬ РАЗ ВЛЕВО;

ЗАКОНЧИТЬ; ЗАПОМНИТЬ ДВИЖЕНИЕ___ВВЕРХ (Y,YТ), ИМЕНА: РАЗНОСТЬ;

ВЫЧЕСТЬ YТ ИЗ Y И ПРИСВОИТЬ ИМЕНИ РАЗНОСТЬ; ПОВТОРИТЬ РАЗНОСТЬ РАЗ ВВЕРХ;

ЗАКОНЧИТЬ; ЗАПОМНИТЬ ДВИЖЕНИЕ___ВНИЗ (Y,YТ); ИМЕНА: РАЗНОСТЬ;

ВЫЧЕСТЬ Y ИЗ YТ И ПРИСВОИТЬ ИМЕНИ РАЗНОСТЬ; ПОВТОРИТЬ РАЗНОСТЬ РАЗ ВНИЗ;

ЗАКОНЧИТЬ; Последние четыре процедуры похожи как близнецы. Нельзя ли объединить их в

одну? Проявим чуть-чуть изобретательности:

ЗАПОМНИТЬ ДВИЖЕНИЕ (БОЛЬШАЯ _ КООРДИНАТА, МЕНЬШАЯ _ КООРДИНАТА, НАПРАВЛЕНИЕ), ИМЕНА: РАЗНОСТЬ; ВЫЧЕСТЬ МЕНЬШАЯ _ КООРДИНАТА ИЗ БОЛЬШАЯ _ КООРДИНАТА И ПРИСВОИТЬ ИМЕНИ РАЗНОСТЬ; ПОВТОРИТЬ РАЗНОСТЬ РАЗ ЕСЛИ НАПРАВЛЕНИЕ = "ВВЕРХ" ТО ВВЕРХ ИНАЧЕ ЕСЛИ НАПРАВЛЕНИЕ= ВНИЗ" ТО ВНИЗ ИНАЧЕ ЕСЛИ НАПРАВЛЕНИЕ = "ВПРАВО" ТО ВПРАВО ИНАЧЕ ЕСЛИ НАПРАВЛЕНИЕ = "ВЛЕВО" ТО ВЛЕВО ИНАЧЕ ВЫДАТЬ: "ОШИБОЧНОЕ НАПРАВЛЕНИЕ"; ЗАКОНЧИТЬ; Теперь запишем новый вариант основной процедуры : ЗАПОМНИТЬ ПЕРЕВОД (Х,Y);

ЕСЛИ X > МУРАВЕЙ X ТО ДВИЖЕНИЕ (X, МУРАВЕЙ.Х, "ВПРАВО") ИНАЧЕ ДВИЖЕНИЕ (МУРАВЕЙ.Х,Х, "ВЛЕВО"); ЕСЛИ Y > МУРАВЕЙ. Y ТО ДВИЖЕНИЕ (Y, МУРАВЕЙ.Y, "ВВЕРХ") ИНАЧЕ ДВИЖЕНИЕ (МУРАВЕЙ.Y,Y, "ВНИЗ");

ЗАКОНЧИТЬ; Рекурсия и цикл. Займемся задачей 10. В определении функции ФАКТОРИАЛ

нет ничего необычного и общий план составить несложно: нужно присвоить какому-то имени значение 1, а затем N раз умножить его на последовательно возрастающие натуральные числа. Для того чтобы эти числа получить, нужно присвоить другому имени значение 0 и каждый раз прибавлять к нему по единице.

Итак:

ПРОЦЕДУРА ФАКТОРИАЛ (N);

ИМЕНА: Р, СЧЕТЧИК;

1 -> Р;

0 -> СЧЕТЧИК;

ПОВТОРИТЬ N РАЗ

СЧЕТЧИК + 1 -> СЧЕТЧИК;

Р* СЧЕТЧИК - > Р;

ВЫДАТЬ РЕЗУЛЬТАТ: Р;

Программу по этому плану составить нетрудно:

ЗАПОМНИТЬ ФАКТОРИАЛ (N); ИМЕНА: Р, СЧЕТЧИК; ЗНАЧЕНИЕ 1 ПРИСВОИТЬ ИМЕНИ Р; ЗНАЧЕНИЕ 0 ПРИСВОИТЬ ИМЕНИ СЧЕТЧИК, ПОВТОРЯТЬ N РАЗ ОДИН___ШАГ ();

ВЫДАТЬ РЕЗУЛЬТАТ: Р; ЗАКОНЧИТЬ; ЗАПОМНИТЬ ОДИН _ ШАГ;

СЛОЖИТЬ СЧЕТЧИК С 1 И ПРИСВОИТЬ ИМЕНИ СЧЕТЧИК; ПРОИЗВЕДЕНИЕ (Р, СЧЕТЧИК) ПРИСВОИТЬ ИМЕНИ Р;

ЗАКОНЧИТЬ; А теперь обрати внимание, что при N > 1 ФАКТОРИАЛ (N).= N × ФАКТОРИАЛ (N-1) Если учесть, что ФАКТОРИАЛ (0)= 1, то это свойство вполне можно принять

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

ЗАПОМНИТЬ ФАКТОРИАЛ (N); ИМЕНА: Р;

ЕСЛИ N > 0 ТО ПРОИЗВЕДЕНИЕ (N, ФАКТОРИАЛ (РАЗНОСТЬ (N,1))) ПРИСВОИТЬ ИМЕНИ Р ИНАЧЕ 1 ПРИСВОИТЬ ИМЕНИ Р;

ВЫДАТЬ РЕЗУЛЬТАТ: Р; ЗАКОНЧИТЬ;

ЗАПОМНИТЬ РАЗНОСТЬ (Х,Y); ИМЕНА: Р; ВЫЧЕСТЬ Y ИЗ X И ПРИСВОИТЬ ИМЕНИ Р,

ВЫДАТЬ РЕЗУЛЬТАТ: Р; ЗАКОНЧИТЬ; Обязательно проведи прокрутку этой интереснейшей программы! К з а д а ч е 13. ЗАПОМНИТЬ ГРАФИК; ИМЕНА: X;

ЗНАЧЕНИЕ 0 ПРИСВОИТЬ ИМЕНИ X; ПОДВОД (X, ФОРМУЛА (X)); ПОВТОРИТЬ 255 РАЗ ОДИН _ УЧАСТОК _ ГРАФИКА ( );

ЗАКОНЧИТЬ; ЗАПОМНИТЬ ОДИН___УЧАСТОК___ГРАФИКА,

СЛОЖИТЬ X С 1 И ПРИСВОИТЬ ИМЕНИ X; ЛУЧ (X, ФОРМУЛА (X));

ЗАКОНЧИТЬ; ЗАПОМНИТЬ ФОРМУЛА (X); ИМЕНА: Р;

ЧАСТНОЕ (ПРОИЗВЕДЕНИЕ (Х,Х).128) ПРИСВОИТЬ ИМЕНИ Р;

ВЫДАТЬ РЕЗУЛЬТАТ: Р; ЗАКОНЧИТЬ; Подумай, нельзя ли переделать процедуру ГРАФИК так, чтобы с ее помощью

можно было построить график любой функции, способ вычисления которой задан отдельной процедурой ФУНКЦИЯ (X).

Восьмая и последняя перемена Еще два исполнителя Приведем краткие сведения о двух исполнителях, предусмотренных в системе

Школьница. Исполнитель МАТЕМАТИК позволяет выполнять арифметические операции с целыми и дробными числами, работать с логарифмами и тригономе-трическими функциями. МАТЕМАТИК во многом напоминает систему Шпага: для этого исполнителя предусмотрен комплект стандартных процедур (точнее, функций), многие из которых имеют по два названия — полное и сокращенное. Значениями пара-метров всех функций могут быть только числа, попытка использовать другие значения вызываетсообщение об ошибке. Перечислим важнейшие функции.

СУММА (Х,Y (сокращенно СМ). РАЗНОСТЬ (Х,Y (сокращенно РЗ). ПРОИЗВЕДЕНИЕ (Х,Y (сокращенно ПРВ). ЧАСТНОЕ (Х,Y (сокращенно ЧС). Вычисляет ХY. Если Y = 0, система выдаст

сообщение об ошибке и прекратит работу. СТЕПЕНЬ (Х,Y) (сокращенно СТ). Вычисляет ХY. Например, значение

выражения СТ (5,2) равно 25, а значение СТ (4,0.5) равно 2. МОДУЛЬ (X) (сокращенно МД). Вычисляет модуль (абсолютную величину)

числа. Например: МД(25) = 25;

МД(0) = 0; МД (-25) = 25; ЦЕЛАЯ _ ЧАСТЬ (X) (сокращенно ЦЧ). Результат этой функции — наибольшее

целое N. удовлетворяющее неравенству N < = X. Например: ЦЧ (5) = 5; ЦЧ (5.2) = 5; .ЦЧ (5.9) = 5; ЦЧ (-5.2) = -6; Тригонометрические и обратные тригонометрические функции: SIN (X), COS (X), ТG (X), ARCSIN (X), ARC COS (X), ARCTG (X), ARCCTG

(X). Логарифмы: LG (X) — десятичный логарифм, LN (X) — натуральный логарифм

(по основанию е = 2.71828...). Параметры всех тригонометрических функций должны быть выражены в радианах (1 радиан ≈ 57.256 градусов).

Исполнитель КОРРЕКТОР предназначен для работы с текстами. Для него описаны три стандартные функции:

ДЛИНА (ТЕКСТ). Эта функция позволяет определить число символов в произвольном тексте. Например, значение выражения ДЛИНА ("КРОКОДИЛ") равно 8.

СЦЕПКА (ТЕКСТ _ 1, ТЕКСТ _ 2). Результат этой функции — текст, получающийся при сцеплении значений параметров (то есть в том случае, если значения параметров записать подряд и считать одним текстом). Например:

СЦЕПКА ("КРОКО", "ДИЛ") = "КРОКОДИЛ" СЦЕПКА ("РАДИО", "МОНТЕР") = "РАДИОМОНТЕР" Эту операцию над текстами иногда называют приписыванием или

конкатенацией. ФРАГМЕНТ (ТЕКСТ, НОМЕР _ 1, НО МЕР__2). Результат этой функции —

текст, который получается, если из значения первого параметра «вырезать» заданный фрагмент. Параметр НОМЕР__1 обозначает номер символа, с которого начинается вырезаемый фрагмент, а НОМЕР__2 — номер символа, которым он заканчивается. Например:

ФРАГМЕНТ ("КРОКОДИЛ", 2,4) = "РОК"; ФРАГМЕНТ ("КРОКОДИЛ", 4,6) = "КОД"; ФРАГМЕНТ ("КРОКОДИЛ", 3,3) = "О"; Двенадцатый урок. Продолжение следует Подведем итоги. Вот и заканчивается эта небольшая книга. На ее страницах ты

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

Конечно, язык Робик, который использовался здесь, — это язык учебный. Его легко понять и освоить, но большие и сложные задачи решать с его помощью трудно, а то и вовсе невозможно. Для решения таких задач тебе нужно будет освоить какой-либо другой язык, например Рапиру или паскаль. Если ты внимательно прочитал эту книгу и выполнил несколько тренировочных заданий, то тебе будет совсем нетрудно изучить

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

Разобравшись со всем этим, ты уже будешь знать структуру языка и сможешь составлять на нем программы для решения большинства задач — при этом приемы составления и проверки планов и программ останутся такими же, как в этой книге.

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

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

Желаем тебе удачи! Что читать дальше? Если ты хочешь научиться составлять программы на

различных языках программирования, советуем тебе прочитать материалы Заочной школы программирования, которые опубликованы в журнале «Квант» с № 9 за 1979 г. На уроках Заочной школы ты сможешь познакомиться с языками Рапира (№№ 1-3, 1980 г.) и паскаль (№№ 10-12, 1981 г.; 1-4, 1982 г.), с одной из версий системы Шпага (№ 1, 1980 г.) и с различными приемами решения задач на ЭВМ. В журнале № 9 за 1980 г. рассказывается о применении циклического оператора, в номере 11 за тот же год обсуждаются задачи, связанные с обработкой текстов на ЭВМ. В других номерах журнала ты прочтешь о решении геометрических задач на ЭВМ с применением полярной системы координат (№ 10, 1980 г.), об ассоциативном поиске (№1, 1981 г.), решении уравнений (№ 2, 1981 г.), работе е графами (№ 3, 1981 г.) и о других задачах.

Обзор языков программирования опубликован в № 9 за 1981 год. Свойства различных конструкций, используемых в языках программирования,

обсуждаются в книге Д. Баррона «Введение в языки программирования» (М.: Мир, 1980). О разных структурах блоков памяти можно прочитать в книге П. Холла «Вычис-лительные структуры. Введение в нечисленное программирование» (М;: Мир, 1978). Интересные примеры рекурсии приводятся в книге Д. Баррона «Рекурсивные методы в программировании» (М.: Мир, 1974). О языке паскаль можно прочитать, помимо «Кванта», в книге Н. Вирта «Систематическое программирование. Введение» (М.: Мир, 1977) или в. книге П. Грогоно «Программирование на языке паскаль» (М.: Мир, 1982).

Общие методы и приемы программирования, способы составления алгоритмов и программ описываются в следующих книгах:

1. Нивергельт Ю., Фаррар Дж., Рейнголд Э. Машинный подход ,к решению математических задач.—М.: Мир, 1977;

2. Гудман С, Хидетниеми С. Введение в разработку и анализ алгоритмов.—М.: Мир, 1981;

3. Кнут Д. Искусство программирования для ЭВМ.— М.: Мир, 1976, т. 1; 1977, т. 2; 1978, т. 3;

4. Ершов А. П. Введение в теоретическое программирование. Беседы о методе.—М.: Наука, 1977.

Если тебя заинтересовала история появления вычислительной техники, почитай книгу Р. С. Гутера и Ю. Л. Полунова «От абака до компьютера» (М.: Знание, 1981). Более подробные сведения можно найти в книге И. А. Апокина и Л. Е. Майстрова «Развитие вычислительных машин» (М.: Наука, 1974).

Об устройстве вычислительных машин и принципах их работы можно прочитать в статьях Ю. Первина и А. Салтовского «Память ЭВМ» (Квант, 1980, № 4) и «Как работает процессор» (Квант, 1980, № 3); А. Салтовского «Организация ввода,и вывода в ЭВМ» (Квант, 1980, № 6); Ю. Первина «Трехадресные, одноадресные и... безадресные машины» (Квант, 1981, № 4) и в других материалах раздела «Искусство программирования» в журнале «Квант». Можно порекомендовать и книгу Л. Н. Королева «Структуры ЭВМ.и их математическое обеспечение» (М.: Наука, 1978). О применениях ЭВМ рассказывается в книгах А. Н. Тихонова и Д. П. Костомарова «Рассказы о прикладной математике» (М.: Наука, 1984); Н. Н. Моисеева «Математика ставит эксперимент» (М.: Наука, 1979); В. М. Глушкова и В. Я. Валаха «Что такое ОГАС» (М.: Наука, 1981.—Библиотечка «Квант», вып. 10); в статье А. П. Ершова «Программирование — вторая грамотность» (Квант, 1982, № 2). Созданию и применению микропроцессоров посвящена статья «Пришла пора оставить счеты» (Наука и жизнь, 1981, № 3,4).

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

Задачи для самостоятельного решения. З а д а ч и д л я и с п о л н и т е л я МАШИНИСТ. Конфигурация путей

соответствует рис. 29. Длина всех путей считается неограниченной: 1. На путях А, Б и В стоит по одному вагону. Нужно определить тип каждого

вагона и выдать соответствующее сообщение, например: НА ПУТИ А СТОИТ КРЫТЫЙ ВАГОН НА ПУТИ Б СТОИТ ЦИСТЕРНА

и так далее.. 2. На путях А, Б и В стоит по 10 вагонов. Необходимо определить их типы и

отпечатать на бумаге полный список вагонов, стоящих на каждом пути, с указанием типов.

3. В той же начальной обстановке нужно подсчитать количество вагонов каждого типа, используя предписания исполнителя МАЛЫШ, и отпечатать результат на бумаге.

4**. В условиях задачи 2 необходимо переставить вагоны так, чтобы на каждом пути стояли вагоны одного какого-нибудь типа.

З а д а ч и д л я и с п о л н и т е л е й КОРРЕКТОР и МАТЕМАТИК. 5. Описать функцию ПОДСЧЕТ _ БУКВ, (ТЕКСТ, БУКВА), которая

подсчитывает, сколько раз встречается определенная буква в тексте. Например, значение выражения ПОДСЧЕТ__БУКВ

("КУКАРЕКУ", "К") должно быть равно 3. 6. Описать функцию ЗАМЕНА _ БУКВЫ (ТЕКСТ, НОМЕР, БУКВА),

заменяющую заданную букву в тексте. Например, вызов ЗАМЕНА _ БУКВЫ ("КРОКОДИЛ", 3, "Я") имеет значение "КРЯКОДИЛ". 7. Описать функцию ПОДСЧЕТ _ ФРАГМЕНТОВ (ТЕКСТ, ФРАГМЕНТ),

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

ПОДСЧЕТ __ ФРАГМЕНТОВ ("КУКАРЕКУ", "КУ") = 2 8. Описать функцию РАЗВОРОТ (ТЕКСТ), которая переставляет все буквы

заданного текста в обратном порядке. Например, РАЗВОРОТ ("КРОКОДИЛ") = "ЛИДОКОРК" 9. Описать функцию ЗАМЕНА _ ФРАГМЕНТА (ТЕКСТ, СТАРЫЙ __

ФРАГМЕНТ, НОВЫЙ __ ФРАГМЕНТ), которая всюду в заданном тексте заменит одно сочетание символов на другое. Например,

ЗАМЕНА _ ФРАГМЕНТА ("КУКАРЕКУ", "КУ", "МЯУ") = МЯУКАРЕМЯУ;

10 *. Используя функцию, составленную в задаче 9, исправить ошибку в математическом тексте

tg (x) = cos (x)/sin (x), который является значением имени ФОРМУЛА. 11*. Решить ту же задачу для текста tg (x) = sin (x)/cos (s), который является значением имени ФОРМУЛА __ 2. 12**. Описать функцию ЧИСЛО (ТЕКСТ), которая преобразует заданный текст

в число. Например, значение выражения ЧИСЛО ("245") должно быть равно числу 245. 13**. Описать функцию ТЕКСТ для преобразования числа в текст. 14**. Значением имени КНИГА является полный текст некоторой книги.

Необходимо отпечатать его на бумаге, разделив на строки (по 50 букв в строке) и на страницы (по 40 строк на странице). Между двумя страницами нужно пропускать по 6 строк. На переносы не обращать внимания.

15**. В условиях задачи 14 предусмотреть нумерацию страниц. 16**. В условиях предыдущей задачи обеспечить такое расположение текста,

чтобы конец каждой строки совпадал с концом слова при сохранении длины строки (50 символов). Если это требование не соблюдается, нужно произвести выключку, то есть увеличить расстояние (количество пробелов) между словами в строке.

17*. Составить программу, проверяющую правильность расстановки скобок в математической формуле (См. «Квант», 1980, № 11).

З а д а ч и д л я и с п о л н и т е л я МАТЕМАТИК и с и с т е м ы Шпага. 18*. Составить программу для построения графиков тригонометрических

функций. 19. Описать функцию ЧЕТ (X), которая будет проверять, делится ли заданное

число на 2. Результатом должен быть текст "ДА", если значение имени X — четное, и "НЕТ" — если оно нечетное.

20. Описать функцию ДЕЛИМОСТЬ (X, Y), проверяющую, делится ли X на Y без остатка.

21. Описать процедуру ДЕЛИТЕЛИ (X), которая выдаст на терминал список всех делителей числа X, включая единицу и само число.

22**. Составить программу, печатающую на бумаге список всех простых чисел, не превосходящих 1000000.

23*. Закрасить на терминале красным цветом геометрическое место точек, удовлетворяющих формуле

[х/8] + |y/8] = 2k, где [ ] обозначает целую часть числа, а k — произвольное целое число. 24. Найти все натуральные числа X, не превосходящие 1000 000, которые

удовлетворяют уравнению Х4-115Х3 + 62000Х2 − 66 500Х +330 000 =0; 25*. Вычислить с точностью до 0.01 все корни уравнения х2-25sin2х + 12 = 0, лежащие на отрезке [-100,100]. 26. Описать процедуру для изображения почтового индекса (форма цифр

должна соответствовать стандарту, указанному на конверте). 27**. Составить программу для проверки теоремы Ферма на некотором

конечном числовом множестве. 28**. Описать функцию для вычисления площади под графиком любой

заданной непрерывной функции на отрезке [-1,+ 1]. 29**. Изобразить траекторию движения в земной атмосфере камня, брошенного

под углом к горизонту. 30**. Изобразить траекторию движения в атмосфере самолета (с учетом

подъемной силы и аэродинамического сопротивления).

ДОПОЛНЕНИЕ ЕСЛИ ТЫ ХОЧЕШЬ ДАЛЬШЕ ИЗУЧАТЬ ПРОГРАММИРОВАНИЕ (Краткое описание языка Рапира) Приведем краткое (и не строгое) описание Рапиры. Общие правила записи программ. Программа состоит из предписаний (и

описаний процедур и функций), разделяемых точкой с запятой. На одной строке может располагаться несколько предписаний; одно

предписание может занимать несколько строк (сравни с Робиком!). Комментарии можно ставить в любом месте — только не внутри слова. Они

записываются в особых скобках: (* Это комментарий *) Объекты и операции над ними. Имена. Вы р а ж е н и я . Объекты: целые числа, дробные (вещественные) числа,

тексты, кортежи, множества, записи, процедуры, функции, файлы, ПУСТО. Далее в примерах нам понадобится предписание вывода. Его простейшая

форма— «?»: ? 525 ; (* В Робике: ВЫДАТЬ: 525;*) 525 Любой объект можно присвоить имени: 999.9-> СТРАННОЕ_ИМЯ; (* 999.9 ПРИСВОИТЬ СТРАННОЕ _ ИМЯ; *) ? СТРАННОЕ _ ИМЯ; 999.9 Если имя используется в программе впервые, то оно имеет значение ПУСТО: ? НОВОЕ_ИМЯ; .ПУСТО. Посмотреть список всех имен можно при помощи предписания КАТАЛОГ ИМЕН; Над числами определены операции +, —, * (умножение), / (деление), **

(возведение в степень). ? 4 + 3*8-2/2 + (-5)**2; 52 Разрешена запись вещественных чисел в экспоненциальной форме:. 1Е20,

5.8Е-6. В Рапире выражением называется последовательность чисел, текстов и имен с

правильно расставленными знаками операций и скобками. Над текстами орределены такие операции: № (мощность, или длина), +

(конкатенация, или сцепка), [ ] (выборка) и [:] (вырезка). ? № "КРОКОДИЛ"; 8 ? "КРОК" + "ОДИЛ"; КРОКОДИЛ ? "КРОКОДИЛ" [4]; К ? "КРОКОДИЛ" [2:4];

РОК. Составные объекты строятся с помощью операций формирования. Их

элементами могут быть любые (в том числе и составные) объекты. Кортеж — упорядоченная совокупность элементов: ? <5, "ТЕКСТ", 8+8>; <5, "ТЕКСТ", 16> Множество — неупорядоченная совокупность попарно различных элементов: <*1,5,1,2*>—>А; ?А; *2,1,5»> («Внимание!») Запись — совокупность именованных полей: ?<§ФАМИЛИЯ: "ПЕТРОВ", ВОЗРАСТ: 1985-1973 §>; <§ФАМИЛИЯ: "ПЕТРОВ", ВОЗРАСТ: 12 §> Операции над кортежами: № (мощность), + (конкатенация), [ ] (выборка), [:]

(вырезка) ?№<1<2>,»КРОК»>; 3 ?<1,2> + <3>; <1,2,З> ?<4,5,6>[2]; 5 ?<4,5,6>[2:3]; <5,6> ?<4,5,6>[2:2]; <5> («Внимание!*) Операции над множествами: № (мощность), + (объединение), * (пересечение),

— (разность). ?№<*3><4>,<*5,6*>,1*>; 4 ?<*3,1*> + <*4,1,5*> <3,5,1,4*> ?<*3,1*>*<*4,1,5*>; <*1*> ?<*3,1*>-<*4,1,5*>; <*3*> Над записью определена только операция доступа к полю: <§ЧИСЛО: 1, МЕСЯЦ: "СЕНТЯБРЬ"§>—>ДАТА; ?ДАТА.МЕСЯЦ; СЕНТЯБРЬ О с н о в н ы е п р е д п и с а н и я : присваивание, цикл, ветвление, вывод, ввод,

вызов процедуры, включить и выключить, каталог, контроль, предписания файловой системы, предписания СТОП, ПУСК, ШАГ, ВЫХОД.

Простейший вариант присваивания уже был показан выше. Кроме того, можно

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

"КРОКОНИЛ'- <К;

"Д"—>К[6]; («Только один символ!*) ? К; КРОКОДИЛ <§ НАЗВАНИЕ: "А", КООРДИНАТЫ: <5,10>§> - > ТОЧКА; 5—>ТОЧКА.КООРДИНАТЫ [2]; ?ТОЧКА; <§НАЗВАНИЕ: "А",КООРДИНАТЫ:<5,5>§> <1,5,8,4>—> А; <"Б", "В">— >А [2:3]; (*Длина кортежа в левой части присваивания*) (*равна длине вырезки в правой части*) ?А; <1, "Б", "В", 4> Предписания ветвления — это предписания ЕСЛИ, ВЫБОР, ВЫБОР-ИЗ. Простое условие — это два выражения, соединенные знаком сравнения ( = ,/=,>,

<, >=, <=, ВИДА, ИЗ): <§А:5§>/=<§Б:5§> <1,2,3>/ = <2,3,1> <*1,2,3*> = <*3,2,1)1,1*> "ВАГОН" [4:5] = "СЛОН" [3:4] 5 ИЗ <3,5> («Элемент из кортежа, *) <2> ИЗ <*<2>,<3>*> («множества, *) "Я" ИЗ «КРЯКВА» («символ из текста *) <1> ВИДА <"Т","Т"> (*Оба объекта - кортежи *) (Все приведенные условия истинны.) Сложное условие строится из простых с помощью операций И, ИЛИ, НЕ и

круглых скобок: 2*2 = 4И 48.5 / = 56 НЕ (1 ИЗ <*4,5*>) (1 < 3 И 3 < = 5) ИЛИ (8 = 8) (Эти условия тоже истинны.) Предписания ветвления: ЕСЛИ А>В (*В Робике после слов *) ТОА->С; («ТО и ИНАЧЕ может») ?"ПЕРВОЕ" («стоять лишь по од-*) ИНАЧЕ В->С; («ному предписанию*) ?"ВТОРОЕ" ВСЕ; ВЫБОР ИЗ ВЕТЕР <3; ?»СЛАБО"; 0- >А! ВЕТЕР<7: ?"УМЕРЕННО";1—>А! ВЕТЕР < 70: ?"ТРЕВОГА!";10— >А " ИНАЧЕ ?"СКОРОСТЬ ВЕТРА ЗАДАНА НЕПРАВИЛЬНО!" ВСЕ; (* Выполняется только одна ветвь, где условие истинно *) ВЫБОР ОЦЕНКА ИЗ 5: ?"ОТЛИЧНО"! 4: "ХОРОШО"! 3: "УДОВЛЕТВОРИТЕЛЬНО"! 2,1: ?"ПЛОХО"

ИНАЧЕ ?"НЕПОНЯТНО" ВСЕ; (*Это - другая запись для частного*) («случая ВЫБОРа - ИЗ. Сравни!*) Предписаний цикла в Рапире несколько: ПОВТОР 30 РАЗ:: (*30 раз напеча-*) ?"Я НА СОЛНЫШКЕ ЛЕЖУ" (*тать эту фразу*) ВСЕ; 1—>Х; ПОКА Х**2 < 1000:: («Печать всех целых*) ?Х**2; («чисел, меньших 1000*) Х + 1—>Х; (*и являющихся квадра-*) ВСЕ; , (*тами натуральных.*) ДЛЯ X ОТ 1 ДО 100 ШАГ 2:: ?"Х = ", X, "Х**2 = ", Х**2 ВСЕ; (*Печать квадратов всех нечетных чисел*) (*от 1 до 100 *) (*Обрати внимание на разницу в задачах! *) Цикл ДЛЯ —ИЗ предназначен для поэлементной обработки текстов, кортежей

и множеств: 0—>СЧ; ДЛЯ БУКВА ИЗ КНИГА:: (*Подсчет количества*) ЕСЛИ БУКВА = "А" (*букв А в тексте*) ТО СЧ + 1—>СЧ (*с именем КНИГА*) ВСЕ ВСЕ; ?"В ТЕКСТЕ ""КНИГА""", СЧ, " БУКВ ""А"""; Предписание вывода (его частные случаи). Вывод на экран: ВЫВОД: 1, 2, "И ЭТОТ ТЕКСТ"; 1 2 И ЭТОТ ТЕКСТ Это эквивалентно той форме, которой мы пользовались до сих пор: ?1, 2, " И ЭТОТ ТЕКСТ"; Выводить можно не только на экран, например: ВЫВОД НА БУМАГУ: "ВАЖНОЕ СООБЩЕНИЕ"; Числа и тексты можно выводить по формату: ? 5:3, " ", 1/3 :5:2; 5 0.333 Предписание ввода. Самая простая форма: ВВОД: НОВЫЙ_ТЕКСТ; («Принять новый ТЕКСТ;*) Можно вводить числа, кортежи и множества: ВВОД ДАННЫХ: («Сравни с*) ЧИСЛО, КОРТЕЖ; («"ПРИНЯТЬ ЧИСЛА"*) Процедуры и функции. Пример процедуры: ПРОЦ ШИВОРОТ_НАВЫВОРОТ; («Печать текста наоборот*) ИМЕНА: ТЕКСТ, И; («Описание локальных имен*) ?"ВВЕДИТЕ ТЕКСТ"; ВВОД:ТЕКСТ;

ДЛЯ И ОТ №-ТЕКСТ ДО 1 ШАГ- 1:: ВЫВОД БПС («Без перевода строки*): ТЕКСТ [И] ВСЕ; ?; («Перевод строки*) КНЦ; Пример функции (аналог функции в Робике — процедура с результатом): ФУНК ФАКТ (N); (*Вычисляет факториал числа N*) ИМЕНА:Ф; ЕСЛИ N = 0 то 1—>4 ИНАЧЕ ФАКТ (N-1)*N—>Ф ВСЕ; РЕЗ:Ф; («Результат») КНЦ; Вызов процедуры — это предписание, а вызов функции — выражение (в этом

случае вызов считается операцией над функцией и ее параметрами). Примеры вызовов: ШИВОРОТ _ НАВЫВОРОТ (); ВВЕДИТЕ ТЕКСТ ?НОС (*Этот "?" выдает ЭВМ!*) СОН ?ФАКТ(1+5)-ФАКТ(5); 600 У процедур допустимы входные, выходные и возвратные параметры; у функций

— только входные. Указание способа передачи: ПРОЦ ПРИМЕР (ВХОДНОЙ _1, => ВХОДНОЙ _ 2, ВЫХОДНОЙ=>, < =

>ВОЗВРАТНЫЙ); ... КНЦ; Предусмотрены стандартные процедуры и функции: элементарные

математические, для работы с текстами, для работы с внешними устройствами, графические и другие.

Р е д а к т о р . (Экранный, основан на использовании функциональных клавиш;

в режиме меню — работа с файловой системой.) После слов "ПРОЦ ИМЯ _ ПРОЦ ...;" ЭВМ переходит в режим редактирования

процедуры. Если процедура с таким именем уже была в ОЗУ или ДЗУ, то ее текст появится на экране. (То есть конструкция "ПРОЦ ..." выполняет то, для чего в Робике использовалось два предписания: "ЗАПОМНИТЬ ПРОЦЕДУРУ ..." и "ИСПРАВИТЬ ПРОЦЕДУРУ ...".)

Теперь можно набирать текст процедуры и редактировать его. Для того чтобы изменить часть текста, достаточно подвести курсор к тому месту на экране, где расположен этот текст, и внести исправления. (Можно вставлять символы, убирать, заменять их, вставлять и убирать строки, управлять курсором.)

Точно так же редактируются функции. Чтобы посмотреть каталог всех процедур и функций, хранящихся на диске

(точнее, всех файлов на диске), надо набрать предписание

КАТАЛОГ; или КАТАЛОГ НА БУМАГУ; Фа й л ы . Существуют текстовые файлы прямого доступа. Вывод (ввод) можно

настроить на файл: везде, где в примерах стоит "НА БУМАГУ", может стоять "В ФАЙЛ ИМЯ _ ФАЙЛА"; после слова "ВВОД" может быть указано "ИЗ ФАЙЛА ИМЯ _ ФАЙЛА"

С р е д с т в а о т л а д к и . Автоматическая прокрутка имен: ВКЛ ПРОКРУТКУ ИМЕН: А, В; ВЫКЛ ПРОКРУТКУ; След вызовов процедур (функций): ВКЛ СЛЕД; След строк процедур (функций): ВКЛ СЛЕД СТРОК; Вывод протокола работы на внешнее устройство: ВКЛ ПРОТОКОЛ НА БУМАГУ; Изменение направления всего вывода (ввода) ВКЛ ВЫВОД НА БУМАГУ; ВКЛ ВВОД ИЗ ФАЙЛА ИМЯ _ФАЙЛА; Полная или частичная защита имен по записи: ВКЛ ЗАЩИТУ: А, В; ВКЛ ЧАСТ ЗАЩИТУ: С, Д, Е; ВЫКЛ ЗАЩИТУ: В, Е; Контрольная точка: КОНТРОЛЬ: А = В; Приостанов выполнения процедуры: СТОП; В режиме приостанова можно посмотреть и изменить значение любого имени

(изменить — если имя не защищено), продолжить выполнение процедуры (ПУСК;), прекратить выполнение процедуры и выйти из режима приостанова (ВЫХОД;), продолжить выполнение процедуры по одной строке (ШАГ;).

ОГЛАВЛЕНИЕ

Предисловие редактора

От автора

Введение. МИР РОБОТОВ И ВЫЧИСЛИТЕЛЬНЫХ МАШИН

Первое прерывание. Зачем Сирене ЭВМ?

Второе прерывание. Куда спрятался процессор?

Третье прерывание. Что нужно знать и уметь, чтобы работать с ЭВМ?

Глава первая. ИСПОЛНИТЕЛИ И ПРОГРАММЫ

Первый урок.

Основные законы программирования и правила записи программ

Первая перемена. Твое рабочее место

Второй урок.

Диалог с исполнителем ДЕЖУРИК (лабораторная работа)

Вторая перемена. МУРАВЕЙ и МАШИНИСТ

Третий урок.

Как составлять программы (практическое занятие)

Глава вторая. СИНТАКСИЧЕСКИЕ ДИАГРАММЫ

Четвертый урок.

Гибкие описания МПИ

Третья перемена. Вспомним правила и формулы

Пятый урок.

Как составлять и читать диаграммы

Четвертая перемена. Вернемся к нашим диаграммам

Шестой урок.

Элементарные конструкции языка Робик

(практикум по работе с синтаксическими диаграммами)

Глава третья. РАБОТА С ПАМЯТЬЮ

Седьмой урок.

3

5

7

11

22

27

35

35

44

46

51

58

70

70

77

81

91

92

105

Блоки памяти и их имена. Программирование диалога

Пятая перемена. Ручная прокрутка

Восьмой урок.

Процедуры

Шестая перемена. МАЛЫШ и ЧЕРТЕЖНИК

Девятый урок.

Процедуры с параметрами

Глава четвертая. ВЕТВЛЕНИЯ И ЦИКЛЫ В ПРОГРАММАХ

Десятый урок.

Тринадцать задач, девять алгоритмов и три предписания

Седьмая перемена. Новое о знакомых исполнителях

Одиннадцатый урок.

Составление программ с ветвящейся и циклической структурой

Восьмая и последняя перемена. Еще два исполнителя

Двенадцатый урок.

Продолжение следует

Дополнение. ЕСЛИ ТЫ ХОЧЕШЬ ДАЛЬШЕ ИЗУЧАТЬ

ПРОГРАММИРОВАНИЕ Краткое описание языка Рапира)

105

117

120

139

144

164

164

178

180

190

192

199

Геннадий Анатольевич Звенигородский ПЕРВЫЕ УРОКИ ПРОГРАММИРОВАНИЯ Серия «Библиотечка «Квант»» Редактор Л. Г. Силкова Художественный редактор Т. Н. Кольченко Технический редактор Е. В. Морозова Корректоры Л. И. Назарова, И. Я. Кришталь ИБ № 12271 Сдано в набор 16.01.85. Подписано к печати 22.07.85. Т-16626. Формат 84 ×

1081/32. Бумага тип. № 3. Гарнитура таймс. Печать высокая. Усл. печ. л. 10,92. Усл. кр.-отт. 11,34. Уч.-изд. л. 10,67. Тираж 150000 экз. Заказ № 1786. Цена 30 коп.

Ордена Трудового Красного Знамени издательство «Наука Главная редакция физико-математической литературы 117071 Москва В-71, Ленинский проспект, 15

Ордена Октябрьской Революции, ордена Трудового Красного Знамени Ленин-градское производственно-техническое объединение «Печатный Двор» имени А. М. Горького Союзполиграфпрома при Государственном комитете СССР по делам издательств, полиграфии и книжной торговли. 197136 Ленинград П-136, Чкаловский пр., 15