Текст
                    * о ►
С.А.АБРАМОВ
ЭЛЕМЕНТЫ
ПРОГРАММИРОВАНИЯ
i

НИКИТИНА
ПОПУЛЯРНЫЕ ЛЕКЦИИ ПО МАТЕМАТИКЕ ВЫПУСК 56 С. А. АБРАМОВ ЭЛЕМЕНТЫ ПРОГРАММИРОВАНИЯ МОСКВА «НАУКА» ГЛАВНАЯ РЕДАКЦИЯ ФИЗИКО-МАТЕМАТИЧЕСКОЙ ЛИТЕРАТУРЫ 1983
22.18 A 16 УДК 519.6 Абрамов С. А. А16 Элементы программирования. — М.: Наука, 1982. — 96 с.—(Популярные лекции по мате- матике). —15 к. Книга посвящена популярному изложению начальных све- дений о программировании и программном обеспечении. Рас- сматриваются такие основные понятия, как алгоритм, алгорит- мический язык, вычислительная машина, трансляция и опера- ционная система. Для чтения книги достаточно знаний в объеме программы средней школы. 1500000000—028 „ А 053(02)-82 74 2 ББК 22.18 519.6 1500000000—028 А 053(02)-82 74'82 © Издательство «Наука», Главная редакция физнко-математическоД литературы, 1982
ОГЛАВЛЕНИЕ Предисловие ,...............................................4 Введение....................................................5 Глава I. Об алгоритмах решения задач......................8 § 1. Экономия операций..................................8 § 2. Обозначения........................................Ю § 3. Повторения........................................13 § 4. Условия...........................................17 Глава II. Пример алгоритмического языка......................20 § 1. О записи программ. Выражения......................20 § 2. Операторы ввода, вывода и присваивания. Программа 23 § 3. Условный и составной операторы....................27 § 4. Оператор перехода, пустой оператор . ............30 § 5. Целый тип.........................................33 § 6. Массивы чисел.....................................36 § 7. Оператор цикла................................... 39 Глава III. Вычислительная машина и ее входной язык ... 43 § 1. Память машины. Машинные слова.....................43 § 2. Арифметические операции. Команды перехода .... 46 § 3. Выполнение программы..............................49 § 4. Регистры. Обработка массивов .....................52 § 5. Операции над словами произвольного вида...........56 Глава IV. Трансляция..................................... 61 § 1. Преобразование последовательностей символов ... 61 § 2. Вычисление значения выражения.....................63 § 3. Трансляция выражений..............................68 § 4. Трансляция операторов и программы.................71 Глава V. Диалоговые программы. Операционная система . . 75 § 1. Диалоговые программы..............................75 § 2. Обмен сообщениями в диалоге.......................77 § 3. Многопрограммный режим работы машины..............79 Д о п о л п е н н е. О доказательстве свойств программ . . 85 Литература для дальнейшего чтения..........................95 1*
ПРЕДИСЛОВИЕ Знакомство с кругом вопросов, затронутых в предла- гаемой книжке, необходимо для того, чтобы составить представление о программировании. Первые три главы посвящены основным понятиям программирования — понятиям алгоритма, программы, алгоритмического языка, входного языка вычислитель- ной машины. В гл. IV рассматриваются методы пере- вода с алгоритмического языка на входной язык вычис- лительной машины. Эта глава труднее других, -и при первом чтении можно ограничиться ее просмотром. В гл. V речь идет о диалоговых программах (игровых программах, программах продажи авиационных билетов и т. д.) и о многопрограммном режиме работы вычисли- тельной машины (строении операционной системы). В Дополнении рассказывается о том, каким образом могут доказываться различные свойства программ. Сжатость изложения позволит читателям сберечь время, но потребует взамен некоторого напряжения внимания. Книжка рассчитана на читателей, интересующихся началами программирования. Кроме представления о системе счисления по целому основанию q 2 (о таких системах в серии «Популярные лекции по математике» имеется книга С. В. Фомина «Системы счисления». — М.: Наука, 1974), от читателей не требуется никаких зна- ний, выходящих за пределы школьного курса матема- тики.
ВВЕДЕНИЕ Прежде чем подойти к рассматриваемым в програм- мировании задачам, вспомним некоторые задачи из школьной математики. В геометрических задачах на по- строение требуется предложить такой способ построения определенных фигур, который основывается исключи- тельно на оговоренных заранее операциях — как пра- вило, на тех операциях, которые можно выполнить с помощью циркуля и линейки. Способ построения должен охватывать возможные случаи взаимного расположения фигур, образующих исходные данные. Такие задачи из- вестны и в алгебре — например, получение корней квад- ратного уравнения, заданного своими коэффициентами, при помощи операций сложения, вычитания, умножения, деления и извлечения квадратного корня. Вывод соот- ветствующих формул дает решение задачи в общем виде. В алгебре обычно не пользуются термином «построе- ние», а говорят о вычислении, но тем не менее между подобными геометрическими и алгебраическими зада- чами есть существенное сходство: в тех и других рас- сматривается некоторое множество — геометрических фигур или чисел — и оговариваются' операции, с по- мощью которых можно из имеющихся элементов полу- чать новые; требуется указать способ построения удов- летворяющего некоторому условию элемента множества (или группы элементов). Задачи на построение можно рассматривать применительно к самым разным множе- ствам с наборами операций. Четко описанный способ построения (в частности, вычисления) называется алгоритмом, этот термин полу- чил широкое распространение в последние десятилетия. Поиски алгоритмов решения различных задач увле- кали математиков во все времена. Уже в древности были открыты способы построения середины отрезка и 5
биссектрисы угла с помощью циркуля и линейки, полу- чены формулы площадей и объемов геометрических фи- гур и тел, правила выполнения арифметических дей- ствий над числами в десятичной системе. Решения мно- гих подобных задач имеют большое практическое зна- чение. В настоящее время интерес к алгоритмам особенно велик из-за возможности использования в научных ис- следованиях, технике, экономике и т. д. вычислительных машин — специальных автоматов, выполняющих по- строение некоторых величин в точном соответствии с указанным алгоритмом. Эта возможность привлека- тельна по той причине, что явления и процессы, кото- рые изучаются в рамках упомянутых исследований, часто удается описать с помощью понятий математики — множеств, функций, систем уравнений, неравенств и т. д. — и для получения конкретных сведений об изу- чаемых явлениях и процессах надо произвести некото- рые действия над математическими объектами. Чело- веку достаточно описать алгоритм необходимых преоб- разований, вычислений и т. д., а сами эти действия (как правило, настолько обширные и громоздкие, что их не- возможно выполнить вручную) выполнит машина. Построения с помощью циркуля и линейки давно перестали представлять практический интерес, и, конеч- но для их выполнения вычислительные машины не нуж- ны. Но аналогия процесса составления алгоритма с ре- шением геометрической задачи на построение полезна для уяснения как характера этого процесса, так и самого понятия алгоритма. Не следует думать, что вычислительные машины вы- полняют только численные алгоритмы: эти машины мо- гут преобразовывать и получать последовательности символов — например, алгебраические формулы, тексты и т. д. (числа, заданные наборами цифр, — частный слу- чай последовательностей символов). Правила записи алгоритма для выполнения его вы- числительной машиной оказываются очень жесткими—• автомат не может ничего додумывать за человека. Со- вокупность средств и правил записи алгоритмов назы- вается алгоритмическим языком. Алгоритм, записанный на понятном вычислительной машине алгоритмическом языке, называется програм- мой. 6
Соответственно говорят о программировании, заклю- чающемся в создании и исследовании программ для вычислительных машин. Для удобства программирова- ния предлагаются новые алгоритмические языки; это ста- вит задачу разработки алгоритмов перевода программ на этих языках в такие программы, которые понятны вычислительной машине в силу ее конструкции. Алго- ритм перевода записывается в виде программы, после чего перевод может выполнить сама вычислительная машина. Имеется много программ, которые, подобно этим программам-переводчикам, предоставляют различ- ные удобства программистам, расширяют возможности вычислительной машины. Такие программы образуют программное обеспечение вычислительной машины. Благодаря соответствующему программному обеспе- чению становится возможным составление программ, управляющих диалогом между человеком и вычисли- тельной машиной. Сюда относятся различные игровые программы, программы, автоматизирующие справочные службы (машина дает ответ на вопрос человека) и про- дажу авиационных и железнодорожных билетов.
ГЛАВА I ОБ АЛГОРИТМАХ РЕШЕНИЯ ЗАДАЧ В настоящей главе рассматривается важнейшее по- нятие программирования — алгоритм, т. е. способ по- строения одних величин, исходя из других, с помощью данных операций. При решении задач всегда имеется в виду, что практический интерес представляют эконом- ные алгоритмы. § 1. Экономия операций Если предстоит выполнить работу, сводящуюся к по- следовательности некоторых знакомых операций, и если мы хотим сделать все необходимое с меньшей затратой сил и времени, то надо продумать такой порядок выпол- нения работы, который позволит обойтись возможно меньшим количеством операций. Разберем математиче- ский пример. Пусть дано некоторое число а и натуральное число п. Способ вычисления а'1, основанный на формуле ап — а • а • ... - а п ’ годится в любом случае, но слишком разорителен. На- пример, а4 экономнее вычислять как (а2)2. Как для дан- ного п решить задачу, выполнив наименьшее число ум- ножений? Если накоплен некоторый запас значений степеней величины а, например ат', а"2, ...,атр, т°, выполнив одно умножение, можно пополнить его любым из значе- ний ami+mi, 1 де i <0 j <0 р. Первоначально запас со- стоит только из а1, и он пополняется одним умножением до а1, а2. Это изобразим графически с помощью рис. 1. От а1, а2 одним умножением можно перейти либо к а1, а2, а3, либо к а1, а2, а4; графическое изображение 8
см. на рис. 2, каждый путь от вершины 1 к вершине т задает способ вычисления ат. Так можно наращивать это «дерево» и дальше: если i'i, is, ik — путь от вершины 6 = 1 к концевой вер- шине ik, то от вершины 1ь отводим отрезки к новым вер- шинам 6 +is, причем берем только не равные между Рис. 1. собой значения, большие ik- «Дерево», изображенное на рис. 2, без труда превращается в «дерево» на рис. 3. Итак, двумя умножениями могут быть вычислены а3, а4, тремя умножениями — а4, а5, а6, а8 (а5 и а6 — двумя способами). Чтобы найти способ скорейшего вычисле- ния а'1, надо наращивать «дерево» ярус за ярусом до появления вершины п. Наращивая «дерево», изображен- ное на рис. 3, еще на ярус, получаем, например, число п — 10 (рис. 4). Получается, что а19 невозможно вы- числить тремя умножениями, но четырех умножений до- статочно. Для этого существуют четыре способа: а1, а2, а3, а5, а10; а1, а2, а4, а5, а10; а1, а2, а4, а6, а10; а1, а2, а4, а8, а10. 9
Нам удалось перебрать все способы экономного вы- числения, которое можно успешно использовать в вы- числительной практике. Здесь и далее мы разделяем разработку способа вычислений, с одной стороны, и фактическое выполнение вычислений, с другой. Пред- метом наших занятий будет исключительно разработка способов вычислений — достижения современной тех- ники позволяют переложить выполнение самих вычис- лений на специальные вычислительные машины. Послед- нее не снижает важности усилий человека по экономии операций. Как бы быстро ни работала вычислительная машина, время ее работы в некоторых случаях все-таки может оказаться слишком большим, чтобы считать его прие'млемым: это могут быть месяцы или годы. Опасность больших затрат времени возникает при решении сложных задач, но экономное решение элемен- тарной задачи тоже может сыграть существенную роль, если она многократно повторяется при решении слож- ной задачи. Задачи. 1. Показать, что при неограниченном наращивании «дерева» любое число п появляется лишь конечное число раз. 2. Сколько существует способов вычисления а5 (пу- тей от 1 к 5)? 3. Каково наименьшее число умножений, необходи- - мых для'вычисления а15? I 4. Пусть п = 2т. Каково наименьшее чис- / ло умножений, необходимое для вычисле- \ / ния а"? нашив. 5. Из ящика, в котором лежат 5 белых п • 3 черных шара, один за другим извлекаются Рис. 5. 6 шаров. Построить «дерево» возможных из- влечений. Начинается построение с «дере- ва», соответствующего извлечению первого шара (рис. 5). § 2. Обозначения Рассмотрим следующий порядок вычисления а10: а1, а2, а3, а®, а10. Хотелось бы описать его точнее, пока- зывая, из каких сомножителей получается каждая ве- личина. Обычный прием для этого — введение буквен- ных обозначений всех промежуточных величин и опи- 10
сание вычисления очередной величины с помощью уже введенных обозначений. Чтобы ввести обозначение, например и, для значения выражения v-w, будем писать и : = V • w. Последнюю запись следует понимать как инструк- цию (приказ) следующего содержания: вычислить зна- чение v-w и обозначить его и. Вычисление а!0 описывается четырьмя инструкциями: b:=a-a; c:=b-a; d:—b-c, e:=d-d. Ясно, что b — а2, с = a3, d = а5, е — а13. После вычис- ления d, т. е. а5, величины b = а2 и с = а3, сыграв свою роль, становятся ненужными. Поэтому все вычисление можно описать, например, так: b : = а-а; с: = Ь-а; с := Ь-с\ с := с-с. Выполнение третьей инструкции ведет: 1) к вычислению b-с (т. е. а5); 2) к забвению прежнего значения с (т. е. а3); 3) к обозначению через с вновь вычисленного значе- ния. Аналогично, выполнение последней инструкции при- водит к тому, что а10 обозначается через с. Мы получаем возможность экономить обозначения. Порядок вычисления a1, a2, a4, a5, ai0 предпочтительнее, чем а1, а2, а3, а5, а10, — он описывается с единственным дополнительным обозначением: b:=a-a-, b:=b-b', b:=b-a; b:=b-b. Кроме а, на каждом этапе вычислений надо помнить только одно число, обозначенное через Ь. Хотя память (специальное электронное устройство) современных вычислительных машин способна вместить большое число величин, решение сложных задач часто упирается именно в нехватку памяти. Поэтому эконо- мия памяти в практическом отношении не менее важна, чем экономия операций. Дальше будут разбираться задачи, подобные задаче вычисления а10, в следующем смысле: в рассматривае- мом множестве можно выполнять над элементами неко- торые операции; требуется описать способ построения оговоренного условием задачи элемента. Именно, в за- даче вычисления а10 рассматривалось множество чисел с операцией умножения. Требовалось описать способ вы- 11
числения десятой степени данного элемента рассматри- ваемого множества, т, е. составить алгоритм. Задачи на построение хорошо известны из геомет- рии. Там рассматривается множество элементарных гео- метрических объектов на плоскости (точек, прямых, ок- ружностей), в котором, по предположению, можно вы- полнять известные операции: выделение общих точек, проведение прямой через две точки, проведение окруж- ности с центром в выделенной точке радиусом, равным расстоянию между двумя выделенными точками, и т. д. Пример задачи вычисления ап показывает, что геомет- рия—не единственная область математики, способная предлагать задачи на построение. Программирование как раз и занимается задачами на построение *). Решить задачу по программированию — это значит составить алгоритм. Думая о возможности практического применения ал- горитма, программист старается сделать алгоритм более экономным и по трудоемкости (числу операций), и по расходу памяти. Если алгоритм будет выполняться вы- числительной машиной, то он должен быть записан так, чтобы машина была в состоянии, прежде всего, его про- честь и понять. Позднее о вычислительных машинах и о средствах записи алгоритмов будет рассказано достаточно под- робно. Пока же надо выяснить, на какого рода инструк- ции распадается алгоритм. То, что инструкций вида где — знак некоторой операции, недоста- точно, будет ясно уже из следующего параграфа. Задачи. I. Показать, что для описания последовательного вычисления а\ а2, а3, а5, а10 недостаточно одного допол- нительного обозначения. 2. Указать на «дереве», изображенном на рис. 4, путь, соответствующий следующему алгоритму вычис- ления а10: b:=a-cr, с-.= Ь-Ь\ с\—с-с\ с-.— с-Ь. 3. Описать алгоритм экономного вычисления а15. 4. Рассмотрим множество целых чисел с операциями сложения и умножения. Пользуясь инструкциями вида ti:=ViW, где «— это знак сложения + или знак ум- *) Множество вместе с фиксированным набором операций в программировании принято сейчас называть типом. 12
ножения • , записать алгоритм вычисления значения у по формуле ах3 + Ьх2 -ф сх -ф d так, чтобы не потребо- валось более шести операций и более одного дополни- тельного обозначения. 5. Рассмотрим множество Т всех подмножеств неко- торого множества Q вместе с известными операциями объединения, пересечения и разности. Пусть даны А, В, С <=Т. Описать алгоритм построения D е Т, содержа- щего те элементы Q, каждый из которых принадлежит ровно одному из А, В, С. То же самое — ровно двум. § 3. Повторения Предложенные алгоритмы вычисления а10 универ- сальны в том смысле, что а можно придавать разные значения. Предварительное тщательное изучение соот- ветствующего «дерева» окупается тем, что получен эко- номный алгоритм, который можно многократно исполь- зовать для разных а. Что представляет собой алгоритм вычисления ап с произвольным натуральным показате- лем п? Если пойти прежним путем минимизации умножений, то алгоритм должен включить в себя описание процесса наращивания «дерева», это обещает много хлопот (а если считать, что все построения ведутся только в множестве целых чисел, то надо еще придумать, как записывать «дерево» в виде набора чисел). «Дерево» быстро разрастается, и при выполнении такого алго- ритма на манипуляции с «деревом» будет потрачено больше времени и памяти, чем при простейшем вычис- лении а • а > ... • а. п Займемся пока описанием простейшего алгоритма; остроумный алгоритм, который требует существенно меньше п—1 умножений и не предполагает никаких действий с «деревом», рассмотрим в следующем параг- рафе. В математике алгоритмы, подобные алгоритму вы- числения ап, записываются с помощью многоточия или каких-либо слов вроде «и так далее», потому что число операций, которые надо выполнять, существенно зави- сит от данных задачи, в нашем случае от п. Чтобы описание алгоритмов было более точным, мы воспользуемся циклическими инструкциями. Так, для 13
того чтобы заставить некоторую инструкцию Р выпол- няться п раз подряд, будем писать п раз повторять Р и эту запись назовем циклической инструкцией. С при- влечением такой инструкции алгоритм вычисления изо- бражается так: b : = 1; п раз повторять b : = Ь-а При выполнении выписанного алгоритма с обозначе- нием b будут последовательно связываться значения 1, а, а2, ап. Если нужно, чтобы п раз повторилось вы- полнение последовательности инструкций Pi; P2;...;Pm, мы будем писать п раз повторять (Pi; Р2; ...; Рт) Например, алгоритм вычисления п\ можно изобразить так: р 1; i := 0; п раз повторять {i'.— i-V 1; p: — p-i) При выполнении последней циклической инструкции i будем поочередно обозначать 1, 2, п, а р — пооче- редно обозначать 1, 1-2, .... 1-2- ... -п. Без инструк- ций р := 1; Z: = 0, предшествующих в алгоритме цикли- ческой инструкции, обойтись нельзя: если р и I ничего не обозначают, то невозможно выполнить инструкции i: — i + 1; Р : = Р • i • Пусть разрешается пользоваться операциями умно- жения, деления и сложения. Алгоритм вычисления сум- мы 7] + ~2Г + • • • + ~ > на первый взгляд, должен предписывать поочередное получение слагаемых возве- дением х в соответствующую степень, вычислением фак- ториала и делением одного значения на другое. Но же- лание составлять по возможности экономные алгоритмы обязывает нас быть менее расточительными. Надо ста- раться так применять циклическую инструкцию, чтобы каждый следующий шаг максимально использовал сде- ланное на предыдущих шагах. Если уже получено , то для вычисления -у- достаточно домножить V */• ” предыдущий результат на — . 14
Естественным будет следующее решение: i:=l, у := х; s:=x; п—I раз повторять (z := i + 1; у := у • у ; з := s + у} . Решая задачу, программист в большинстве случаев не стремится полностью минимизировать число опера- ций и обозначений, а просто не позволяет себе заведо- мых излишеств. Анализ, подобный проведенному нами для задачи вычисления а1'0, в более сложных случаях может оказаться невозможным. Кроме того, хитроумная экономия операций часто требует дополнительного рас- хода памяти. Приходится иметь дело и с алгоритмами, при описа- нии которых тоже надо бы употребить циклическую ин- струкцию, но число шагов в ней определяется непосред- ственным рассмотрением исходных данных. Алгоритм Евклида нахождения наибольшего общего делителя натуральных чисел а и b (а>Ь) НОД (а, Й) основывается на соотношении НОД(а, й) == НОД (й, г(а, й)), где г(а, й)— остаток от деления а на Ь, и на очевидном равенстве НОД (а, 0)= а. Например, НОД (25, 15) = НОД (15, 10) = НОД(Ю,5) = = НОД(5, 0) = 5 Для описания подобных алгоритмов нужен другой вид циклической инструкции: пока В повторять Р где В — некоторое условие (равенство или неравенство), а Р — это или инструкция, или взятая в скобки последо- вательность инструкций; как только окажется, что В неверно, выполнение циклической инструкции прекра- тится. Вот полное описание алгоритма Евклида: пока b #= 0 повторять (с: — г (а, й); а Ь; Ь;—с) В результате выполнения этой инструкции значения а и b будут изменены. Значение b станет равным нулю, значение же а станет равным наибольшему общему де- лителю первоначальных значений а и Ь. Если, например, 15
было а — 25, b — 15, то при выполнении выписанной циклической инструкции с обозначением с последова- тельно связываются значения 10, 5, 0, с обозначением а — значения 15, 10, 5, с обозначением b — значения 10, 5, 0. Описывая алгоритм Евклида, мы предполагали, что можно пользоваться операциями нахождения остат- ка и сравнения данного числа с нулем. Задачи. Считается, что можно пользоваться следующими опе- рациями над числами: сложение, вычитание, умножение, деление, нахождение остатка и частного от деления с остатком, сравнение. 1. Описать алгоритм вычисления суммы х х2 . х3 хп Ti ~ 21 ‘ 31 ~ ‘ ± п1. знак последнего слагаемого определяется четностью п. 2. Описать алгоритм вычисления суммы Указание. Значение х‘ получается из х ‘ до- множением на х2'-1. Значение х2;-1 получается из x2(<-i)-i домножением на х2. 3. Описать алгоритм вычисления первого элемента последовательности 1, 1 + V ’ 1 “Ь ~2~ + Т ’ ' • • ’ большего данного числа а. 4. Описать алгоритм вычисления суммы цифр дан- ного натурального числа п в системе счисления с осно- ванием р. 5. Рассмотрим множество S всех конечных множеств натуральных чисел. Рассмотрим операцию, применение которой к 4 eS дает множество, состоящее из одного- единственного элемента, равного наибольшему элементу множества А (обозначение: $(А)). Кроме того, допу- стимы операции разности множеств и операция сравне- ния множества с пустым (А = 0, Д=И=0). Описать алгоритм, применимый к любому непустому 4eS, вы- полнение которого дает множество, состоящее из одного- единственного элемента, равного наименьшему эле- менту Д. 16
§ 4. Условия В этом параграфе при составлении алгоритмов при- нимается без оговорок, что допустимы арифметические операции сложения, вычитания, умножения, деления, на- хождения частного и остатка (для целых неотрицатель- ных операндов) п операции сравнения чисел между собой. Идея одного достаточно экономного алгоритма вы- числения ап, не требующего рассмотрения «дерева», за- ключена в следующем: если п = 2k, то ara = (a2)4; если же п — 2k + 1, то ап = (а2)й-а. Степень с показателем k вычисляется с учетом этих же соображений. Итак, надо разделить п на 2 с остатком п = 2k + I (0 сС I 1), по- том это же проделать с k и т. д. Эти действия приво- дят, как известно, к построению двоичной записи п. Так вот, предлагается следующий алгоритм вычис- ления ап. Если ... оиао — двоичная запись п, то последовательно вычисляются значения аа°, аа‘<1°, ... ..., aTnam-i “i“o. Для ЭТОГо вычисляется цифра за циф- рой двоичная запись п и, параллельно, значение за зна- '2') (20 (22) чением а- , а , а , ... — каждое следующее значение получается возведением в квадрат предыдущего. Под- считывается произведение тех значений, для которых со- ответствующая цифра двоичного представления равна 1. Пример. Запись числа 9 в двоичной системе: 1001 (9 = 1'8 ф- 0-4 + 0-2 1); для вычисления а9 до- статочно найти a2, а4, аа (3 умножения), а затем опре- делить a1-a8 (1 умножение). Преимущество этого алгоритма в сравнении с про- стейшим: простейший алгоритм требует числа умноже- ний, растущего как линейная функция от п, а здесь число умножений, грубо говоря, пропорционально коли- честву цифр числа п или двоичному логарифму п. Словесное описание алгоритма содержит многоточия, которые мы исключаем, вставляя в алгоритм определен- ную в предыдущем параграфе циклическую инструкцию (q(x,y) и г(х, у) будут обозначать частное и остаток от деления х на у): с;=1; Ъ-.— СГ, пока п > 0 повторять (I := г (п, 2); п := q (п, 2); если I — 1, то с:— с • b', b\ — b-b) 2 С. А. Абрамов 17
Здесь пришлось воспользоваться новым видом инструк- ции: если .то ... Благодаря этому домножение с на b происходит, только когда остаток от деления га на 2 получается равным I. Инструкция такого вида называется условной, в об- щем случае она выглядит так: если В, то Р или если В, то Р иначе Q где В — некоторое условие, а Р и Q — либо инструкции, либо взятые в скобки последовательности инструкций. Например, алгоритм вычисления наименьшего из х, у записывается одной инструкцией: если х <Zy, то zi= х иначе z: = у т Когда к словам то или иначе относится несколько инструкций, эти инструкции должны заключаться в скобки. Напишем алгоритм подсчета количества отрицатель- ных элементов в наборе чисел а\, ..., ап, тле a, = sinZ (считаем, что синус — допустимая операция). Искомая величина обозначается через пг. /:= 1; т:=0; п раз повторить {если sin I < 0, то ш := m + 1; i := i + 1) Еще пример: алгоритм распознавания, является ли данное натуральное число удвоенным нечетным; k полу- чает значение 1, если ответ положительный, и 0 — в про- тивном случае: если г (п, 2) #= 0, то k := 0 иначе если г (п, 4) = 0, то k:=Q иначе k: = 1 Задачи. 1. Показать, что предложенный в этом параграфе алгоритм вычисления ап для некоторых п требует числа умножений, превышающего минимальное. Указание. Рассмотреть п = 15. 2. Описать алгоритм вычисления количества единиц в записи данного натурального п в р-ичной системе. 18
3. Описать алгоритм вычисления суммы положитель- ных и числа отрицательных элементов среди чисел sin i, i — 1, 2, ..., п. 4. . Описать алгоритм распознавания, верно ли, что a sC 6 с {а, b и с — данные числа). 5. Вновь рассмотрим множество Т всех подмножеств некоторого множества Q. Допустимы операции разности двух элементов Т и сравнения элемента Т с пустым мно- жеством. Описать алгоритм, применимый к любым А, В<=Т, в результате выполнения которого выясняется, верно ли, что А с В. * * * Читатель видел примеры задач по программирова- нию, он получил представление и о средствах, кото- рыми располагает программист, решая задачу (описывая алгоритм). Однако полученные представления прибли- зительны. Рассмотренные виды инструкций не обра- зуют небходимого для работы минимума (хотя и могли бы составить его ядро). Как, например, описать алго- ритм получения по данному п всех значений г!, i = 1, 2, ..., п? Кроме того, предложенные виды инструкций нуждаются в уточнении. Например, к чему приводит вы- полнение инструкций у 3; если х^О, то если то у:=2 иначе у: = 1 Пусть х =—1, будет ли у равен 1 или 3? Все зави- сит от того, как понимать вторую инструкцию; к какому из двух «если» относится единственное «иначе»? Если алгоритм предназначается для машины, то та- кие двусмысленности совершенно недопустимы. Необхо- димы достаточно богатые и однозначно понимаемые средства представления алгоритмов. Такие средства на- зывают теперь алгоритмическими языками. Один из та- ких языков будет разобран в следующей главе.
ГЛАВА II ПРИМЕР АЛГОРИТМИЧЕСКОГО ЯЗЫКА Будет рассмотрен, с существенными сокращениями, язык алгол 60. Это международный алгоритмический язык, разработанный группой американских и евро- пейских ученых в 1960 г. Многие современные вычисли- тельные машины способны выполнять алгоритмы, запи- санные на этом языке. Рассматриваемый сокращенный вариант языка алгол 60 в тексте будет именоваться алголом. Всюду в этой главе слово «программа» означает про- грамму на алголе. § I. О записи программ. Выражения Программа записывается в виде последовательности специальных символов. К их числу относятся буквы, цифры, знаки препинания, знаки операций и некоторые слова в английском написании (последние рассматри- ваются как самостоятельные неделимые символы). Под- строчные индексы, всякого рода надстрочные показа- тели не допускаются, никаких специальных знаков пе- реноса не существует. В качестве букв используются буквы латинского ал- фавита, в качестве цифр — арабские цифры. Буквенному математическому обозначению в алголе соответствует идентификатор — любая конечная после- довательность букв и цифр, обязательно начинающаяся с буквы. Примеры идентификаторов: A, b, xl, х2, pi, ala2. Идентификатор, являющийся обозначением числа, называется переменной, а число, им обозначенное,— значением переменной. Числа записываются в десятич- 20
ной системе, вместо запятой пишется точка. Примеры: О, 260, 3.1415, +0.567, —0.18 Переменные и числа — простейшие частные случаи выражения. Более сложные выражения строятся из чи- сел и переменных с помощью знаков операций сложе- ния, вычитания, умножения, деления и возведения в сте- пень. Эти знаки суть +, —, X, /, f. Кроме того, в вы- ражении могут быть использованы круглые скобки и некоторые функции. Указанные знаки операций деления и возведения в степень /, f позволяют записывать в одну строчку вы- ражения, которые традиционно записываются с выходом из строки: у3 и-у записываются как у f 3, а/b. Знак опе- рации умножения в алголе нельзя опускать или изобра- жать точкой. Допустимая для математического текста запись 0,5 (х—1)(х— 2) (х— 3) в алголе должна вы- глядеть так: 0.5 X (х — 1) X (х — 2) X (х — 3). Значение выражения может быть вычислено, исходя из значений входящих в него переменных. При вычис- лении действуют обычные правила старшинства опера- ций: самая старшая — возведение в степень, следующие по старшинству — умножение и деление, затем — сложе- ние и вычитание. Из двух операций одинакового стар- шинства первой выполняется та, знак которой в выра- жении встречается раньше. Круглые скобки служат, как обычно, для изменения естественного порядка выполне- ния операций: % 2 следует записать в виде (х — у)/2, а не х — у/2. Квадратные, фигурные скобки для регулирования по- рядка операций применять нельзя. В выражениях могут встретиться функции sin, cos, arctan, In, exp, abs, entier, sqrt. Вслед за обозначением функции в круглых скобках указывается аргумент: sin(E) — синус Е(Е радиан), cos (Е) — косинус Е (Е радиан), arctan(E)— главное значение арктангенса Е, In (Е) — натуральный логарифм Е, ехр(Е) — показательная функция Е, abs (Е) — абсолютная величина Е (модуль Е), 21
entier (E) —целая часть E, т. e. наибольшее целое, не превосходящее Е, sqrt (Е) — квадратный корень из Е. Традиционная математическая запись этих функций: sin Е, cos Е, arctgE, In Е, еЕ, | Е |, [Е], х/Е. Перепишем по правилам алгола выражение получим 0,3 X ((( sin (х) f 2 — cos (х) f 2)/sin ((х + р)/2) — exp (abs (cos (x) + sin (x)))) X In (x) — sqrt (2 X x — г/)). Записывая выражение, нельзя размещать рядом два знака арифметических операций; записи of—2, ЗХ—2, xl/ — х2 не являются выражениями, выражениями бу- дут a f (- 2), 3 X (- 2), xl (- х2). Задачи. 1. Какие из следующих записей являются идентифи- каторами? х3 4, хЗ, х • 3, х3, 100t, tlOO, max 2. Записать по правилам алгола выражение 1,7 • [(sin2 2х + cos2 Зх) • (|aj — a32 [ + a2a) — 3a] xat a2 3. Записать выражение по традиционным правилам! 2.1 Xabs(xl2 + 3 f х f 2) X (3.27- (sin (x+^)f3 + a3s(p)f 3))/(mX«)X^t2Xxf (2Xx). - + 1,2. 4. Вычислить значение выражения (sin(x f 2 - 1) f 2) + cos(x f 3 - 1) f 3 f abs(x - 2))/y f 3 X (3 f 2 f 2 + a&s(z/) f 3) при следующих значениях переменных: х = 1, у = —2. 22
5. В выражении a/b X c/d Xe/fXh расставить скобки так, чтобы выражению со скобками соответствовало а § 2. Операторы ввода, вывода и присваивания. Программа Запись алгоритма подразделяется на отдельные ин- струкции, которые в алголе принято называть операто- рами. Для ввода данных и вывода результатов используют- ся операторы ввода и вывода. Вот как, например, они могут выглядеть: input (х) input (xl, х2, е) output (х) output (х, у, z, р, q, г) Оператор ввода состоит из идентификатора input (input по-английски означает ввод) и следующего за ним в круглых скобках списка переменных. Число пере- менных в списке не ограничено; если их больше одной, то они разделяются запятыми. Оператор вывода состоит из идентификатора output (output означает вывод) и следующего за ним в круглых скобках списка пере- менных. При выполнении оператора ввода переменным при- сваиваются значения исходных данных. Программу, содержащую такие операторы, необходимо снабдить приложением — конечной последовательностью чисел, ко- торую удобно рассматривать как очередь чисел (пер- вый элемент — первый в очереди, второй элемент'—вто- рой в очереди и т. д.). Когда выполняется оператор ввода, переменным присваиваются очередные значения. Пусть приложение (очередь чисел) выглядит так: 3, 8.2, — 1, 0.5, 23
тогда после выполнения оператора input(a) перемен- ной а будет присвоено значение 3. Если же через неко- торое время будут выполнены операторы input (Ь, с); input(t), то b получит значение 8.2, с — значение —1, t — значение 0.5. С помощью оператора вывода осуществляется вывод значений переменных. Выведенная последовательность чисел является результатом выполнения программы. В результате выполнения оператора присваивания переменной присваивается значение некоторого выраже- ния. Примеры операторов присваивания: xl :=(—& + sqrt(Ь]2-4ХаХ с))/(2 Xа) х2 ~(-b- sqrt (Ь f2-4ХаХ с))/(2 Xа) XI— х +1 Последний оператор предписывает увеличение х на еди- ницу. Если до выполнения оператора х:=«+/ пере- менная х имела значение 1, то после выполнения этого оператора значение х станет равным 2. Кроме операторов программа содержит описания. Описание может выглядеть, например, так*): real xl или real у, z, t В описании сообщается о том, какие переменные исполь- зуются в программе. Программа схематически может быть изображена следующим образом: begin A; Pt; Р2; ..Pk end**) Здесь А—описание, a Pi, Рг, .... Р/г — операторы. Пока оператор — это или оператор ввода, или опе- ратор вывода, или оператор присваивания, а описа- *) Специальные символы-слова в печатном тексте набираются жирным шрифтом, а в рукописном тексте подчеркиваются. Слово real означает по-английски действительный; далее переводы слов будут даваться в подстрочных примечаниях без указания на то, что слова английские. ♦*) begin — начало, end — конец. . 24
ния — это символ real, за которым через запятую пере- числены переменные; позднее понятия оператора и опи- сания будут расширены. Далее без специальных огово- рок считается, что при расширении понятий оператора и описания автоматически расширяются все те понятия, которые определялись раньше с помощью понятий опе- ратора и описания. Пример. Программа вычисления корней квадрат- ного уравнения ах2 + Ьх + с = 0, заданного коэффи- циентами а, b и с (предполагается, что а ф 0 и что корни действительные): begin real a, b, с, xl, х2; input (а, Ь, с); х! ;=(—& + sqrt (Ь12 ~4ХаХ с))/{2 X а); х2 ;=(-b — sqrt (b] 2 — 4ХаХ с))/{2 X а)’, output (х/, х2) end При выполнении этой программы придется дважды вычислить значение sqrt(b f 2 — 4 X а X с) и дважды — значение 2Ха- Поэтому более разумным вариантом будет begin real a, b, с, xl, х2, d, е; input (а, Ь, с\, d := sqrt (b f 2 — 4XaXc); e:=2 Ха; xl := (— b + d)/e; x2 (—b — d)/e; output {xl, x2) end Если это почему-либо удобно, можно одно длинное описание заменить совокупностью более коротких. Во всех случаях описания располагаются в начале про- граммы и отделяются друг от друга точкой с запятой. Итак, возможен следующий вид программы: begin Л1; А2; Рр, Р2; ...;Pk end где Ль Л2, ..., Ап — описания, а Р\, Р2, .... Р* —опе- раторы. 25
Второй вариант рассмотренной программы может быть переписан следующим образом: begin real a, b, с; real xl, х2\ real d, с, input (a); input (b, с); d := sqrt (b f 2 — 4 \ a'X c); e\=2')^a\ xl := (— b + d)/e-, x2 :=(— b — d)/e; output (x/); output (x2) end Пример. Программа вычисления площади тре- угольника ио трем сторонам: begin real a, b, с, р, S; input (а, Ь, с); р :== (а + b + с)/2; S := sqrt (р X (р — а) X (р — &) X (Р — с))’> output (S) end Видно, что площадь вычисляется по формуле Герона. При выполнении программы вычисления могут про- водиться приближенно: числа в алголе имеют конечное число знаков после десятичной точки, и округления не- избежно возникают, например, при вычислении значе- ний sqrt (2), sin(l) и т. д. Задачи. 1. Написать программу вычисления значения квад- ратного трехчлена ах2 + Ьх + с. 2. Написать программу нахождения среднего ариф- метического и среднего геометрического двух чисел. 3. Написать программу нахождения гипотенузы и площади прямоугольного треугольника по двум данным катетам. 4. Смешано щ литров воды температуры t\ с лит- рами воды температуры t2. Написать программу вычис- ления объема и температуры образовавшейся смеси. 5. Показать, что выполнение программы begin real а, b, с, х; input {а, Ь, с); с sqrt (b \ 2 — 4'Х.а'>(су, а := 2 X а; х :== (— b + с)/а; Ъ := (— b — с)/а; output (х, Ь) end 26
приведет к тем же результатам, что и выполнение про- грамм для решения уравнения ах2- + Ьх Ц- с = 0, разо- бранных в тексте параграфа. В новой программе вво- дится лишь одна дополнительная переменная, и при выполнении этой программы не повторяются уже проде- ланные вычисления. § 3. Условный и составной операторы Если хотим присвоить переменной max наибольшее из значений переменных xl и х2, мы должны сравнить зна- чения xl и х2 и в зависимости от результата сравнения выполнить либо оператор тах:=х1, либо тах-.= х2. Действия такого рода задаются условным оператором^ if В then Pi else Р2*) где В — условие, Pi и Р2— операторы. Если условие удовлетворяется, то выполняется Pi, иначе выпол- няется Р2. В качестве условий используются отношения. Отно- шения представляют собой записи равенств и нера- венств. Примеры отношений: а — b, d=/=0, b\2 — 4\аХс>0 В общем случае отношение — это два выражения, разделенных одним из знаков =, =#, >, <, Для решения задачи о присваивании переменной max наибольшего из значений xl и х2 достаточно выполнить условный оператор if xl > х2 then max:=xl else тах:—х2 Оператор, расположенный после else, может быть лю- бым оператором; оператор, расположенный между then и else, не может быть условным. Рассмотрим примеры программ, включающих в себя условные операторы. Пусть задана функция ( 0, если х 'С 0; У —у 2 п (, х , если х > 0. *) if — если, then — то, else — иначе. 27
Требуется написать программу вычисления значения у по значению х. Программа может выглядеть так: begin real х, у; input (х); if х^О then у.= 0 else у:—х\2', output (у) end Значение у зависит от значения х, и график зависи- мости приведен на рис. 6. Программа вычисления зна- чения у по значению х: begin real х, у; input (х); if х < 2 then у. — х else if х < 3 then y:=2 else y:=x — 1; output (y) end Если удовлетворено условие x <Z 2, то у получит значе- ние, равное значению х, и это значение затем будет вы- ведено. Если условие х < 2 не удовлетворяется, то значение у будет определено выполнением условного оператора if х <3 then у := 2 else у.— х — 1 Допускается сокращенная форма условного оператора: if В then Р где В — условие, Р— оператор, не являющийся условным. В слу- чае, если В удовлетворено, должен быть выполнен опе- ратор Р; если же В не удовлетворено, его выполнять не нужно. Пример. Пусть даны два числа. Если первое боль- ше второго по абсолютной величине, то необходимо уменьшить первое в пять раз. Иначе оставить числа без изменения. Программа: begin real х, у; input (х, у)', if abs (х) > abs (у) then х:=х/5; output (х, у) end 28
В условном операторе после then и else можно по- мещать по одному оператору. Однако часто необходимо в зависимости от результата проверки выполнить ту или иную группу операторов. Алгол предоставляет возмож- ность сделать из группы операторов один составной one* ратор. Структура составного оператора: begin Ру, Р2‘, >..',Pk end или begin Р end где Р, Р\, Р2, Ph — любые операторы. Существенно, что оператор begin Р end при любом операторе Р не является условным и может быть разме- щен после then. Пусть квадратное уравнение ах2 3 + Ьх + с = 0 задано коэффициентами а, b и с (а =/= 0). Ниже следует программа, при выполнении которой исследуется дискриминант уравнения, выводится число О, если дискриминант отрицателен, и выводится пара корней, если дискриминант неотрицателен. begin real a, b, с, xl, х2, cP, input (а, Ь, с); d-.= b^2-4Xa%c-, if d <0 then begin d :—(), output (d) end else begin d:=sqrt(d); a:—2Xct', X1 d)/a; x2’.= (-b- d)(2; output {xl, x2) end end В этой программе в условном операторе после then и else размещены составные операторы. Задачи. 1. Написать программу вычисления значения функ- ции . z ( х2, если — 2 гф х sC 2; У—\ X (4 в остальных случаях. 2. Написать программу выбора наибольшего из трех чисел. 3. Показать, что если периодическая функция f(x) с периодом t задана на отрезке [0, t\, то для любого х 29
значение выражения х— entier(x/i)')^t принадлежит от- резку [О, /] и значение функции для этого значения ар- гумента равно значению /(х). Пользуясь этим, написать программу вычисления значения f(х), период которой равен 4,5, а часть графика изображена на рис. 7. 4. Условный оператор if х | 2 > 2 then begin if x > 2 then у := x f 3 eise у :== 8 end else у :=8 ~X.x f 2 устанавливает зависимость значения у от значения .г. Построить график этой зависимости. 5. Написать программу полного исследования сово- купности корней биквадратного уравнения ах4 ф- Ьх2 + + с = 0. Должен быть выведен О, если действительных корней нет, и два или четыре корня в прочих случаях. § 4. Оператор перехода, пустой оператор Рис- '• Каждый оператор может быть помечен меткой (идентификато- ром). Метка располагается перед оператором и отде- ляется от него двоеточием. Оператор output (х), помечен- ный меткой finish, запишется так: finish-, output (х) Метка не влияет на выполнение оператора. В рассмотренных программах операторы выполня- лись в том порядке, в каком были написаны. Изменить этот порядок можно с помощью оператора перехода. Оператор перехода состоит из символа goto*), за кото- рым следует метка. Примеры: go to finish go to M Оператор перехода прерывает естественную последо- вательность выполнения операторов: следом за ним вы- полняется оператор, помеченный указанной меткой. *) go to — перейти к. $0
Пусть программа содержит последовательность опе- раторов: х:=2; А:=В; goto Т; Л1:Л:=0; х:=В; Т:у :=х; х : = О В этом случае сначала выполняются операторы х:=2 и А : = В. Затем следует переход к оператору, помечен- ному меткой Т; у := х. После оператора у:=х будет выполнен оператор х := 0. Напишем программу нахождения среди чисел 0.3, О'.З X 1.3, 0,3 х 1.3 X 2.3, ... первого, большего данного числа а: begin real а, Ь, с input (а); Ь:= — 0.7; с:—1; repeat: b := b + 1; с:=сХ&; if а 7^ с then go to repeat; output (c) end При выполнении этой программы переменная с по- следовательно принимает значения 0.3, 0.3 X 1-3, 0.3 X X 1-3 X 2.3, ... ; переменная Ь в свою очередь прини- мает значения 0.3, 1.3, 2.3, ... Изменение этих значений происходит до тех пор, пока значение с не станет больше значения а. Перед оператором ' repeat: b : = b + 1 переменные b и с получают некоторые начальные зна- чения, которые подобраны так, чтобы после первого вы- полнения операторов repeat: Ь : — Ь + Г, с: — с\Ь переменные b и с приобрели значения, равные 0,3. О пустом операторе. Пустой оператор ие предписы- вает никаких действий. По определению он представ- ляет собой пустую совокупность символов. Как и все операторы, пустой оператор может быть помечен мет- кой. В участке программы 7 k: — 0; ;пг: = 1 31 .
между двумя операторами присваивания находится пу« стой оператор. Рассмотрим конец некоторой программы или состав- ного оператора ... М: end Здесь перед символом end расположен помеченный мет- кой М пустой оператор. Основное назначение пустого оператора — дать возможность выхода из середины про- граммы или составного оператора. Последнюю программу из предыдущего параграфа можно переписать так: begin real a, b, с, xl, х2, d; input (а, b, с); d~b\ 2-4\аХс; if d < 0 then begin d := O’, output (d); go to finish end; d := sqrt (d); a:=2X xl :=(-b-r d)/a-, x2 := (— b — dj/a; output (xl, x2); finish: end Задачи. 1. Выяснить, какие значения будут выведены в ре- зультате выполнения программы begin real х, у; L: х :=0: у :—х + Г, М: х:=х-Ру; у: — х-{-у; go to Д; N: х := abs (х — 2)\ go to Д; P: у :=x; go to Ip, K: x :—x f 2: go to N; F: go to P; R: у := abs (x — y); S: output (x, y) end 32
2. Написать программу нахождения среди чисел 1> 1 + у> 1 + у + у. ••• первого, большего данного числа а. 3. Дано положительное число е. Последователь- ность а\, а2, а3, ... образована по следующему закону: Найти первый член ап последовательности, для которого выполнено условие |ая —«я-1| <е. Написать программу выполнения этого задания. 4. Может ли конец выполнимой программы иметь вид: а) ; go to К end б) go to К end в) go to Л'; /<: end г) go to K; L: end 5. Воспользуясь приемом, продемонстрированным в последней программе этого параграфа, написать про- грамму решения следующей задачи. Даны два числа; вывести первое число, если оно больше второго, и оба числа, если это не так. § 5. Целый тип В § 2 было приведено схематическое изображение программы. Тогда нам было известно всего лишь три вида операторов. В дальнейшем понятие оператора су- щественно расширилось, теперь же у нас появится но- вый вид описания, в котором вместо real пишется integer *), например: integer i, j В данном случае мы имеем дело с описанием пере- менных целого типа (или переменных типа integer). Применявшиеся ранее описания были описаниями пе- ременных действительного типа, или переменных типа real. *) integer — целый. 3 С. А. Абрамов 33
Переменные типа integer могут принимать лишь це- лые значения, а переменные типа real — как целые, так и нецелые. Числа в алголе тоже разделяются на целые, или имеющие тип integer, и действительные, или имею- щие тип real: если в записи числа использована точка, то оно действительное, в противном случае — целое. Примеры целых чисел: О, —3, 17, +0.193, —1000000, 5 Примеры действительных чисел: 3.14, —0.0001, 0.6, +17.0, — 19.19191919, 5.0 Объясним причину, по которой выделяются вели- чины типа integer. Уже говорилось, что значения ариф- метических выражений, в которые входят переменные и числа типа real и некоторые функции, могут вычислять- ся выполняющим программу приближенно, т. е. с не- большой погрешностью. Так, 0.1ХЮ может вычисляться как 0.999999999999, или 1.000000000001, или как что-нибудь в этом роде. По- этому не имеет смысла проверять выполнение равенства между двумя действительными числами. Арифметические операции сложения, вычитания, ум- ножения и возведения в целую неотрицательную степень над целыми числами производятся абсолютно точно, и результатами этих операций снова являются целые чис- ла. Значение функции entier всегда целое. Целочислен- ное значение выражения может быть сохранено в точ- ном виде для дальнейших вычислений присваиванием этого значения переменной типа integer. Программа вычисления п\\ begin integer п, I, р\ input (п); р:=Г, i:=0; L: i:=i + 1; p-.— pXi', if i <п then go to Z,; output (p) end Здесь вычисление проводится за п шагов. Перемен- ная принимает последовательно значения 1, 1X2, IX Х2ХЗ, ..., 1Х2ХЗХ ••• Хп. Условный оператор обеспечивает контроль за тем, чтобы в произведение вошло ровно п сомножителей. 34
Если бы единственным описанием программы было real п, I, р, то, после того как в произведение вошло п сомножителей, переменная i могла бы иметь значение, чуть меньшее п, и в итоге имели бы приближенное зна- чение (п + 1)!. Кроме названных ранее арифметических операций в алголе есть еще деление нацело. Для натуральных а и b это частное от деления а на b с остатком. В общем случае целых a, b, b =/= 0, определение операции таково: [аТ а „ -г- , если -г>0; b J ’ ь ’ U а |1 а л -г , если -г < 0. b J ь Эта операция одного старшинства с умножением и делением, что важно иметь в виду при вычислении зна- чений выражений. Операцию деления нацело можно использовать, что- бы узнать, кратно ли целое р целому q. А именно, р кратно q тогда и только тогда, когда р-? qXq — р. Если р и q — натуральные, то остатком от деления р на q будет p — p~qXq. Пример. Алгоритм Евклида нахождения НОД (а, Ь) для натуральных а и Ь. begin integer а, b, с; input (а, Ь)', L: с:—а — а-^-ЬХЬ', а:=Ь; Ь:=с; it b^O then go to Ц output (а) end Рассмотрим примеры программ, в которых встре- тятся величины разных типов. Программа вычисления суммы 1 + у + • • • + —. begin integer i, п; real s; input (n); s := 0; I := 0; L: i:=i + l; s:=s+l/i; if i < n then go to £; output (s) end Программа, в результате выполнения которой вы- ясняется, имеются или не имеются среди чисел 3* 35
cos (z3) sin (10000 + -jQ^QQ-), J = 0, 1,2, .... zz, меньшие •уо^оо"- Если имеются, то выводится 1, если нет — 0. begin integer i, п; input (ri); i:= — Г, L'. z: = z’ -J- /; if cos (i f <?) X sin (10000 + z710000) < 0.0001 then begin i go to finish end; if i < n then go to L; i:=0; finish’, output (i) end „ 1 Если оказывается, что некоторый член меньше '10000 » то следующие члены уже не рассматриваются. Задачи. 1. Верно ли, что b X а -4- b = а тогда и только тогда, когда а кратно б? 2. Дано натуральное п. Написать программу вычис- ления суммы всех чисел вида г3 — 3zn2-|-/i (z = 1,2, .., ... /г), которые являются удвоенными нечетными чис- лами. 3. Последовательность uq, u\, U2, ... определяется правилами Но==О, г/1 = 1, Ui+2 — U(+i + и{ (i = 0, 1,2,3,...). Написать программу вычисления ип. 4. Написать программу, в результате выполнения ко- торой выясняется, есть ли среди чисел i3—17z/z2 + п3 (z= 1,2, п) хотя бы одно число, которое кратно а и не кратно Ь. 5. Доказать, что любую целочисленную (в рублях) денежную сумму больше 7 руб. можно выплатить без сдачи трешками и пятерками. Написать программу вы- работки по данному целому числу п > 7 пары целых не- отрицательных чисел а и b таких, что п = За + 5Ь. § 6. Массивы чисел Переменные, снабженные индексом, широко исполь- зуются в математике — например, координаты точки в пространстве часто обозначаются Xi, хг, Хз- Алгол также предоставляет удобную возможность использования та- 36
ких переменных. Выражения х[1], х[2], .... х[п], где вместо х может стоять любой идентификатор, а вместо п — любое целое положительное число, называются пе- ременными с индексом. ’ Выписанные переменные с индексом образуют мас- сив х, идентификатор х называется идентификатором массива. В операторе присваивания слева от знака : = может быть и переменная с индексом: 5 [7] := 55; b [2] ;= 125. Массивы можно вводить и выводить целиком с по- мощью операторов ввода и вывода: в соответствующем операторе указывается идентификатор массива. Пусть а — простая переменная, Ъ обозначает массив из 20 чисел, с — массив из двух чисел; тогда в резуль- тате выполнения операторов input(a,b) и output(a, с) будет введено одно число для переменной а, 20 чисел — для массива b и будет выведено значение переменной а и два числа — элементы массива с. Описания массивов располагаются среди других опи- саний и содержат в себе сведения о том, сколько эле- ментов в массиве и какого типа эти элементы. Примеры: integer array b [/ : 10] real array c [/ : 2], p[l5] integer array t, x, y[l'.2O]*) После real array или integer array пишется иден- тификатор массива, за которым в квадратных скобках указывается количество элементов в виде двух чисел, разделенных двоеточием, первое число — номер первого элемента, второе число — номер последнего; дальше че- рез запятую пишутся другие идентификаторы массивов и указываются соответствующие количества элементов, если имеются еще массивы того же типа. Из приведен- ных выше примеров видно, что если несколько массивов одного типа имеют одно и то же количество элементов, то это количество можно указать один раз. Так, мас- сивы t, х, у имеют по 20 элементов. Описания integer array a, b]l:2], с[1:5], р, t[l : 10] real array х, у[1 '• 20], I [7 : 7], h, g[l : 7S] *) array — массив. 37
дают следующие сведения. Целочисленные массивы а и b содержат по два элемента, с — пять элементов, р и t — по 10 элементов; действительные массивы х и у со- держат по 20 элементов, I — один элемент /[1], h и g — по 18 элементов. Переменная с индексом должна иметь индекс, величина которого не превышает номера послед- него элемента массива, заданного в описании массива. Индексом может быть не только целое число, но и произвольное выражение с целым значением. Например, переменные с индексами &[j], b[2Xi], b[2\i— /] удобно использовать для поочередного рассмотрения всех элементов массива, элементов, стоящих на четных и нечетных местах. Здесь проявляется преимущество обозначений 6[/], Ь[2], ... перед обозначениями bl, Ь2, ... Программа нахождения наибольшего значения из Й2, , «90 • begin integer i; real max', real array a[l : 90]; input (a); i := 1; max := a [/]; L : i: = i + 1; if a [i] > max then max := a [i]; if i < 90 then go to L; output (max) end Значение наибольшего элемента определяется за 90 шагов. После выполнения г-го шага значение max равно наибольшему из а\, az, ..., а/. Программа построения целочисленного массива aj, az, ..., «2оо, элементы которого соответственно равны значениям b\, ct, b2, с2, ..., Ьюо, Сюо, где bt, bz, ..., &юо и Ci, Cz, ..., сюо — данные целочисленные массивы: begin integer i, т; integer array c, b[l, 100], a [/ : 200]; input (b, c); m := 0; i := 0; L: /:=/+?; m := m + 1; a [i] := b [m]; i := i + 1; a [i] := c \tn]; if i < 200 then go to L; output (a) end Построение массива осуществляется за 200 шагов. На i-м шаге присваивается необходимое значение пере- 38
менной a[i]. Это присваивание производится по-раз- ному в зависимости от четности i: если i = 2т, то а,- = с™; если i = 2т — 1, то а, = Ьт. Программа вычисления ац&юоо + Заг&эээ 4~, • • • + 4- 999<7999&2 + 1 OOOcziooo^i - begin integer i; reals; real a, b[l'. 1000]-, inout (a, b); i := O', s :== O', L -Л : — i + Г, s: — s + i\a [i]X& [1001 — i]; if i < 1000 then go to L', output (s) end Задачи. 1. Написать программу вычисления суммы элемен- тов данного массива а\, аг, ..., а2$. 2. Написать программу вычисления количества тех элементов целочисленного массива П\, пг, ..., «юо, ко- торые являются удвоенными нечетными числами. 3. Дан массив а\, аг, .йгоо- Написать программу построения массивов Ь\, Ь2, .. ., Ьюо и сь с2, ..., Cioo, элементы которых равны соответственно значениям О1, а3, ..., aigg и а2, aiy ..., а200. 4. Написать программу определения количества эле- ментов в данном массиве ai, а2, ..., а?оо, удовлетворяю- щих условию 0 < ai I. 5. Написать программу, после выполнения которой становится известным, имеются ли в целочисленном Массиве Ci, ..., Сюоо два подряд идущих нулевых эле- мента. § 7. Оператор цикла Для многократного повторения каких-либо действий часто используют оператор цикла for р:=А step В until С do 8*) Буквой р обозначена некоторая переменная (без ин- декса), она называется параметром цикла, буквами А, В и С — выражения, буквой 8— оператор. Предпола- гается, что Л, В и С не зависят от р и что выполнение оператора 8 не приводит к изменению значений пара- метра цикла и выражений А, В, С. *) for —для, step — шаг, until — до, do — выполнять. 39
Оператор цикла заставляет выполняться оператор S многократно. Сначала он выполняется для р = А, за- тем для р = А + В, затем для р = А + 2В и т. д. для всех значений р вида А + тВ,‘принадлежащих отрезку [Л, В] или [В, Л] в зависимости от того, А В или В < Л. Рассмотрим, например, оператор цикла for i := 1 step 1 until 99 do s := s + i f 2 Если перед его выполнением переменная s имела зна- чение 0, то после выполнения переменная s примет зна- чение I2 + 22+ ... 4-992. Программа вычисления п\: begin integer i, п, р; input (и); Р := /; for г:=2 step 1 until п do р:=рХ^ output (р) end Программу можно написать и так: begin integer i, п, р\ input (п); р:=1; for i := п step — 1 until 2 do p‘.= p X G output (p) end При составлении программы вычисления суммы 1! 4-2! + ... 4~°! естественно воспользоваться соотно- шением г! — i(i— 1)!, О! = 1: begin integer п, i, a, s; input (п); s:=0; а:=1; for i := 1 step 1 until n do begtna:=aX4 s:=« + a end; output (s) end Оператор S, выполняемый многократно, может со- держать в себе оператор перехода. В этом случае вы- полнение оператора цикла может кончиться раньше, чем будет перебрана вся серия значений параметра цикла. Во всех случаях по окончании выполнения оператора 40
цикла значение параметра цикла считается неопреде- ленным. Программа нахождения индекса первого четного эле- мента среди элементов с нечетными индексами массива а\, а2, .... «юоо. Если поиск окажется безуспешным, то надо вывести —1. begin integer k, i; integer array a[l: 1000]; k:= — 1; for i := 1 step 2 until 999 do if a [i] 4- 2 X2 = a [i] then begin ki; go to L end; L: output (k) end Програма останется правильной, если .. .until 999... заменить на ... until 1000... Интересна конструкция, когда оператор в цикле сам является оператором цикла. Таких вложений операто- ров цикла может быть несколько. Рассмотрим следую- щий оператор: for k 1 step 1 intil 20 do for p: = 1 step 1 until a do output (k, p) Для каждого значения параметра k параметр р будет пробегать все значения от 1 до а. Для каждого значе- ния р и соответствующего значения k будет выполнен оператор вывода значений k и р. Будут выв-едены числа: 1,1, 1,2, ..., 1,а, 2,1, 2,2, ..., 2, а, 20,1, 20,2. 20, а. Пр имечание. Оператор цикла, как и условный оператор, нельзя помещать непосредственно после then. Задачи. 1. Написать программу вычисления величин «1&1 + «2^2 + • • • + Язо&ЗО и «1&80 + ^2&79 + . . . + flgo&l. 2. Написать программу вычисления суммы !-д + |г----+Ь 3. Даны массивы а\, Яг, ..., Язоо, &2, &is2. Написать программу построения массива cj, с2, ..., ciS2, элементы которого соответственно равны Ci,a2, ..., «зоо, &1, &2, • • • > Ь182. 41
4. Написать программу выполнения следующего за- дания: выяснить, является ли данный массив ai, аг, .. . ..., «55о упорядоченным по убыванию. 5. На плоскости даны 700 точек, эти точки попарно соединены отрезками. Написать программу вычисления длины наибольшего из отрезков. Считать, что коорди- наты i-й точки суть (х;, у>) и массивы %i, ..., х7Оо; У\, • • •, г/7оо заданы. Полезно прорешать еще раз все задачи предыдущего параграфа, пользуясь операторами цикла. * * Алгол 60 не единственный алгоритмический язык, которым пользуются программисты. Этот язык хорош прежде всего, для решения вычислительных задач, т. е. для работы с данными числового типа (real и integer). Хотя числами и можно представлять весьма сложные структуры, для удобства программирования созданы и применяются языки, позволяющие работать с данными специальных типов (формулами, текстами и т. д.). Одна и та же вычислительная машина может понимать не- сколько языков: первоначально она владеет одним (входным) языком, но ее снабжают программами-пере- водчиками, которые будут переводить на этот язык про- граммы с других языков. Об этом пойдет разговор в следующих главах.
ГЛАВА III ВЫЧИСЛИТЕЛЬНАЯ МАШИНА И ЕЕ ВХОДНОЙ ЯЗЫК Разные марки вычислительных машин имеют разные входные языки, из тех и других трудно выбрать наибо- лее типичные. Мы рассмотрим упрощенную модель вы- числительной машины. Хотя и эта модель, и ее входной язык являются вымышленными, они довольно точно от- ражают то, чем на самом деле располагают програм- мисты. § 1. Память машины. Машинные слова В памяти машины хранится программа и все рас- сматриваемые в ходе вычислений величины. Память со- стоит из отдельных ячеек, в ячейке может храниться любая последовательность из 24 двоичных цифр — ну- лей и единиц. Каждую такую последовательность будем называть машинным словом (иногда — просто словом). Примеры машинных слов: 111111111111111111111111 010110110000011000000111 Если в ячейке хранится слово ocioca • • • «24, то цифра a, (l^i^24) называется содержимым i-ro разряда ячейки. Память нашей модели машины будет содержать 2,s ячеек, пронумерованных числами от 0 до 215— 1. Номер ячейки называется ее адресом. В арифметических задачах исходными данными слу- жат числа. Число для машины — это слово специального вида. Если бы нужны были только целые числа, то можно было бы первый разряд ячейки использовать для записи знака числа (0 — это плюс, 1—это минус), а в 43
остальных 23 разрядах записывать абсолютную вели- чину числа в двоичной системе. Так удалось бы записы- вать в ячейке любое целое число с абсолютной величи- ной гС223. Но приходится работать и с нецелыми чис- лами, поэтому выбран универсальный способ записи, основанный на представлении числа а =/= 0 в двоичной нормализованной форме 2°-т, где v— целое число и 1 /2 | т | < 1. Число v называется двоичным порядком числа а, число т — двоичной мантиссой этого числа. Со- ответствующее машинное слово устроено так: первый разряд — это знак числа, второй — знак порядка, сле- дующие 7 разрядов — целое число, равное абсолютной величине порядка, последние 15 разрядов — цифры, стоя- щие после запятой в абсолютной величине мантиссы. Число 1 запишется в виде слова 000000001100000000000000, число —2 в виде 100000010100000000000000. Запишем число —1/3. Это число изображается бес- конечной двоичной дробью —0,01010101 ..., учитывают- ся первые цифры: . 11000000110101010101010101. Число 0 записывается словом 000000000000000000000000. Числа — не единственный встречающийся вид дан- ных. При обработке текстов каждой литере (букве, циф- ре, знаку операции, знаку препинания и т, д.) присваи- вается номер (числовой код) — целое неотрицательное число, меньшее 256, и каждая ячейка хранит три ли- теры. Номер каждой литеры, записанный в двоичной системе, занимает 8 последовательных разрядов (если запись номера литеры в двоичной системе содержит ме- нее 8 цифр, то старшие цифры объявляются нулями, например, 1 заменяется на 00000001). Машинное слово может быть и командой, т. е. эле- ментарной инструкцией машине. Машина может выпол- нять над словами некоторые операции, за каждой такой операцией закреплен код — целое число. Первые 9 раз- рядов команды заняты кодом операции, а последние 15 —адресом ячейки, в которой может, например, хра- ниться слово, над которым выполняется операция. Если 44
код некоторой операции 1010, а адрес ячейки, который по смыслу надо указать в команде,— 10, то команда запишется так: 000001010 000000000000010, код адрес операции ячейки Соглашение: 24-разрядные двоичные машинные слр. ва слишком длинны. При записи машинного слова йа бумаге его разбивают на грани по 3 цифры, рассматри» вают каждую грань как запись некоторого числа й двоичной системе и записывают это число одной из цифр. 0, 1, 2, 7. Получается 8-разрядное восьмеричное ело* во. Приведенные в качестве примера В начале параграфа двоичные слова запишем так; 77777777, 26603007. Числа 1, —2, —1/3, 0 представляются словами 00140000, 40240000, 60152525, 00000000, Последний пример команды перепишем так: 012 00002 код адрес операции ячейки Задачи. 1. Рассмотреть 24 буквы названия настоящей книги, Получить машинное слово, заменяя каждую букву, изо* бражающую гласный звук, единицей, и каждую букву, изображающую согласный звук, нулем. Записать эта двоичное слово в виде восьмеричного. 2. Записать в виде машинных слов числа 3,14; 100; — 1,1; 8/17. Какие числа записаны машинными словами 123456701, 400400400, 4444444? 3. Показать,- что если двоичное слово является записью ненулевого числа, то его десятая цифра — еди* вица. 4. Пусть буквы русского алфавита АБВГДЕЁЖЗИЙ КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ пронумерованы числами от 11 до 43. Некоторое слово русского языка записано в виде двух машинных слов 03410023,03001401 так, как предлагалось в тексте параграфа: в каждое слово входит 3 номера литер-букв. Прочитать слово. 43
5. Доказать, что для перевода целого числа из двоич- ной системы в восьмеричную достаточно разбить после- довательность двоичных цифр числа (начиная с млад- шей цифры) на грани по 3 цифры и каждую грань пе- ревести в число от 0 до 7. Например, для перевода чис- ла сто, записанного в двоичной системе как 1100100, в восьмеричную систему можно поступить так: разбиваем его запись на грани 1 ] 100| 100 и получаем 144. Об- ратно, для перевода из восьмеричной системы в двоич- ную достаточно заменить, каждую восьмеричную цифру тремя двоичными. Сформулировать подобные правила для записей це- лых чисел в системах с основаниями q и qk. § 2. Арифметические операции. Команды перехода Машина может выполнять ряд арифметических опе- раций над числами. Типичные арифметические операции имеют два операнда. При выполнении операций используется специальная ячейка — так называемый сумматор. Эта ячейка не вхо- дит в число занумерованных ячеек, о которых шла речь выше. Сумматор не упоминается в командах явно. Его роль станет ясной после рассмотрения примеров. Операция сложения имеет код 001*). Выполнение команды 00101173 приведет к сложению числа из сум- матора с числом из ячейки 01173; результат будет по- мещен опять в сумматор (прежнее содержимое сумма- тора пропадет). Аналогично выполняются операции вы- читания с кодом 002, умножения с кодом 003, деления с кодом 004, возведения в степень с кодом 005: первый операнд берется из сумматора, второй — из ячейки, ад- рес которой указан в команде. Результат остается в сум- маторе. Имеются две операции считывания слов (в част- ности, чисел): 011 — считывание слова из сумматора в ячейку, адрес которой указан в команде; 012 — считы- вание слова из ячейки в сумматор. Считывание значе- ния из ячейки или сумматора не приводит к изменению содержимого этой ячейки или сумматора. *) В конце этой главы приведен список кодов всех операций рассматриваемой модели вычислительной машины; разбирая приме- ры и решая задачи, можно заглядывать в этот список. 46
Соглашение о ячейке 00000: в этой ячейке всегда хранится слово 00000000, ее содержимое ничем нельзя изменить. Команды выполняются специальным устройством машины — процессором. Выполнив находящуюся в не- которой ячейке команду, процессор, как правило, пере- ходит к выполнению команды из следующей ячейки. Этот порядок нарушается только специальными коман- дами перехода и остановки, о них будет рассказано позже. Напишем последовательность команд, выполнение которой приведет к вычислению значения у—ах2-\- + Ьх с и помещению его в ячейку 40000, коль скоро значения а, Ь, с, х размещены в ячейках 40001, 40002, 40003, 40004. Слева от команды указываем номер ячейки, в кото- рой будет находиться эта команда. Справа будем давать пояснения, сумматор в них будет обозначаться <т. И ле- вая, и правая части в память машины не попадают. 00001 00002 00003 00004 00005 00006 01240001 00340004 00140002 00340004 00140003 01140000 сг := а <т:=<тХ^(— ах) сг := ц Ь (= ах 4- Ь) сг := а X х (— ах2 4- Ьх) <т := <т 4- с (= ах2 + Ьх 4- с) у.= о Если заставить процессор приступить к выполнению команды из ячейки 00001, то будет выполнена вся вы- писанная последовательность. Приведенная последовательность команд, в прин- ципе, могла бы быть размещена в любых идущих под- ряд ячейках, лишь бы она не попадала в «числовые» ячейки 40000, 40001, .... 40004. Во входном языке машины отсутствуют аналоги ал- гольных условных операторов и операторов цикла. Здесь все строится на командах перехода. Рассмотрим две из них. Первая — команда безусловного перехода; после кода операции 021 указывается адрес команды, к вы- полнению которой надо перейти. Вторая (команда ус- ловного перехода) имеет код операции 022. По этой команде процессором исследуется содержимое сумма- тора, которое для применения этой команды обязано быть числом. Если это число 0, то происходит переход к команде с адресом, указанным в команде 47
перехода. Если число < 0, то выполняется следующая команда. Рассмотрим последовательность команд вычисления у = | х |. Пусть х расположен в ячейке 01000, а у должен оказаться в ячейке 01001: 00010 00011 00012 00013 00014 01201000 02200014 01200000 00201000 01101001 а := х если а^0, то на 00014 о := 0 (у := о — х (— — х) У :=ог Эта последовательность команд, в отличие от преды- дущей, не допускает перемещения в памяти из-за команды условного перехода, которая отсылает к ячейке с явно выписанным адресом 00014. Задачи. 1. Написать последовательность команд вычисления ( ах + b \п , , у = > где а, о, с, а, х, п — числа, располо- женные, начиная с ячейки 50000. Значение у должно за- нять место прежнего значения х. 2. Написать последовательность команд обмена зна- чениями между ячейками 10000 и 10001. 3. Написать последовательность команд вычисления среднего арифметического и среднего геометрического положительных чисел а и Ь, значения которых находят- ся в ячейках 74375 и 74376. Считать, что в ячейке 74377 находится значение 1/2. Результаты вычисления должны быть помещены в ячейки 74400 и 74401. 4. Написать последовательность функции signx: signx — 0, - 1, 1, если если если команд вычисления х > 0, х = 0, х < 0. Считать, что значение х находится в ячейке 10000, а зна- чение sign х должно быть в сумматоре. 5. Написать последовательность команд вычисления суммы х + х2 + х4 4- х8 + ..., учитывая только слагае- мые, большие положительного числа а. Данные числа а и х (|х| < 1) расположены в ячейках 70001 и 70002. Ре- зультат получить в ячейке 70000. 48
§ 3. Выполнение программы Чтобы попасть в память машины, программа должна пройти через устройство ввода, а для этого надо ее сначала перенести с листа бумаги, на котором она запи- сана, на перфокарты. Перфокарта — это особого фор’ мата листок тонкого картона. В определенных местах перфокарты могут быть пробиты отверстия. Отверстие рассматривается как представление цифры 1, а отсут-' ствие отверстия — цифры 0, это позволяет комбина- циями отверстий записывать двоичные слова. Перфо- карта может вместить несколько таких слов. Группа всех слов, которые должны быть в конечном счете введены в память, разбиваются на порции. Каж- дая порция вводится в один прием и размещается в по- следовательных ячейках памяти. Сейчас будет сказано об управлении этим вводом. Каждая порция двоичных слов начинается с заго- ловка. Заголовок сам является словом; в дальнейшем считаем, что он всегда занимает отдельную перфокарту. Структура заголовка ОООо^агазо^ав, где — запись в восьмеричной системе числа машинных слов в порции. Если в порции 19 слов, то ее заголовком будет 00000023. Заголовок сам не попадет в память, при каж- дом обращении к устройству ввода он считывается в сумматор и исследуется процессором. После запуска машины процессор первым делом включает устройство ввода. Прочитав заголовок самой первой порции, процессор вводит столько слов, сколько указано в заголовке (т. е. всю первую порцию слов). Эти слова размещаются в памяти, начиная с ячейки 00001. После этого устройство ввода выключается, про- цессор считывает слово из ячейки 00001 и, рассматри- вая его как первую команду, приступает к выполнению программы. Все остальные порции вводятся по команде ввода: код операции 031, за ним указывается адрес ячейки, начиная с которой надо ввести очередную порцию слов. Для составления простейших программ необходимы еще две команды — вывода результатов и остановки. По команде с кодом операции 032 устройство вывода печатает на бумаге содержимое нескольких последова- тельных ячеек. В адресной части этой команды поме- щается адрес первой из ячеек; в сумматоре должно 49
находиться слово, имеющее вид заголовка и указывающее количество ячеек. Если в сумматоре находится слово 00000001, то выполнение команды 03201000 приведет к выводу слова из ячейки 01000. По команде с кодом one’ рации 041 и произвольным адресом выполнение про’ граммы заканчивается. Вернемся к задаче вычисления значения у = ах2 +' -\-bx-\-c. Эта программа будет размещена, начиная с ячейки 00001, а для величин у, а, Ь, с, х будут отведены, как и прежде, ячейки с 40000 по 40004. Используем имеющуюся заготовку. о 00000013 заголовок 00001 03140001 ввод (а, Ь, с, х) 00002 01240001 00003 00340004 00004 00140002 00005 00340004 как прежде 00006 00140003 00007 01140000 00010 01100013 подготовка заголовка 00011 03240000 вывод (у) 00012 04100000 конец 00013 00000001 слово, используемое командой 00010 о 00000004 заголовок 40001 а 40002 b 40003 с 40004 . . . . X Во второй порции помещаются записи значений а, Ь, с, х. Эта порция не входит в программу. Программа может быть выполнена для любых значений величин а, Ь, с, х; в этом ее универсальность. Слово в ячейке 00013 — не команда, а константа, не- обходимая для команды вывода, но оно включается в программу. Команда остановки препятствует интерпре- тации этого слова как команды^' Вторая из рассмотренных в предыдущем параграфе последовательностей команд при превращении в закон- ченную программу доставляет больше хлопот: если все сделать, как при вычислении значения трехчлена, то по- 50
следовательность команд введется, начиная с ячейки 00001, а это не годится, так как последовательность не- перемещаема в памяти и непременно должна распола- гаться, начиная с ячейки 00010. На первый взгляд, эту ситуацию можно не рассмат- ривать: всегда программу можно писать в предположе- нии, что она будет располагаться, начиная с ячейки 00001. Но программы иногда составляют из отдельных частей уже имеющихся программ. В нашем случае можно поступить так: а 00000002 заголовок 00001 03100007 ввод команд, начиная с ячейки 00007 00002 02100007 переход на 00007 а 00000012 заголовок 00007 03101000 ввод (х) 00010 01201000 X 00011 02200014 00012 01200000 как прежде 00013 00201000 00014 01101001 X 00015 01100020 подготовка заголовка 00016 03201001 вывод (х) 00017 04100000 конец 00020 00000001 слово, используемое командой 00015 о 00000001 01000 • • • • X Первоначально будет выполнена часть программы, обеспечивающая пуск; ее задача — заставить процессор ввести основную часть программы и перейти к ее вы- полнению. Пусковая часть содержит две команды, они будут введены по общему правилу в ячейки 00001 и 00002. Примечание. Числовые исходные данные и ре- зультаты имеют вид машинных слов. Обычно входной язык машины содержит команды, позволяющие вводить десятичные числа и переводить их в двоичную нор- мализованную форму, и команды вывода результа- та в десятичном виде. Десятичная запись числа 51
рассматривается как текст и может быть представлена, например, способом, показанным в § 1. Мы здесь этими вопросами заниматься не будем. Задачи. 1. Написать программу вычисления signx (см. за' дачу 4 предыдущего параграфа). 2. Даны два числа а, Ь. Написать программу, в ре- зультате выполнения которой эти числа выводятся в об' ратном порядке: Ь, а. 3. Переделать программу вычисления квадратного трехчлена, включив в пусковую часть программы коман- ду ввода значений а, Ь, с, х. 4. Скомпоновать из имеющихся последовательностей команд вычисления |х| и ах2 + Ьх-]-с программу вы- числения Указание. Последовательность команд вычис' ления |х| дополнить командой безусловного пере- хода. 5. Написать программу вычисления среднего ариф' метического и среднего геометрического двух данных положительных чисел а и Ь. Машинное слово, изобра’ жающее необходимое для вычислений число 1/2, по- местить вместе с командами программы (команды пере- хода и остановки должны предотвратить истолкование процессором этого слова как команды). § 4. Регистры. Обработка массивов Рассмотрим задачу вычисления суммы п чисел Ci, а2, ап, расположенных в последовательных ячей- ках памяти. Для прибавления к накопленной в сумма- торе сумме первых i — 1 слагаемых очередного слагае- мого ai достаточно выполнить команду 001 (аг), где (а;)—адрес ячейки, хранящей at. Если п известно уже при составлении программы, то можно выписать явно все необходимые команды. Если же п будет опреде- ляться только при выполнении программы, то это не- возможно. В таких случаях обращается к регистрам. Ре- гистры— это специальные ячейки; их в машине 7, и они пронумерованы числами 1, 2, 3, 4, 5, 6, 7. Каждый ре- гистр способен вместить произвольное 15-разрядное двоичное слово, которое можно записывать как 5-раз- 52
рядное восьмеричное. Назначение регистров — измене- ние адресной части команд. Предложенные в предыду- щих параграфах операции имели трехзначные восьме- ричные коды, но первой из трех всегда была цифра 0. Вместо первого нуля можно указать номер регистра. Например, можно использовать команду 20150000: к со- держимому сумматора будет прибавлено число из ячей- ки с адресом, равным сумме 50000 и содержимого второго регистра. Пусть во втором регистре находится слово 00003, тогда к содержимому сумматора будет при- бавлено содержимое ячейки 50003. Итак, адресная часть команды изменяется на величину содержимого, указан- ного в первом восьмеричном разряде кода операции регистра. При сложении адресной части команды с со- держимым регистра может получиться 16-значное двоич- ное число. В таком случае старшая единица отбрасы- вается. В программу вычисления «1-р ... + ап вместо команд 001(щ), i — 1, 2, ..., п, достаточно вставить цикл с командой 201 (aj). Содержимое второго регистра должно при выполнении этого цикла принимать значе- ния 00000, 00001, 00002, ... (п значений). Чтобы составлять такие программы, нужны опера- ции, позволяющие изменять и исследовать содержимое регистров. Операция с кодом 013: 15 последних двоичных раз- рядов содержимого сумматора помещаются в регистр, номер которого указан в адресной части команды. Если в сумматоре содержится слово 67125530, то в резуль- тате выполнения команды 01300001 в первый регистр попадет слово 25530. Операция с кодом 014: содержимое регистра с ука- занным в адресной части команды номером заносится в последние разряды сумматора, первые разряды сумма- тора заполнятся нулями. Слова произвольного вида могут изменяться, в част- ности, с помощью операции с кодом 051: содержимое сумматора и ячейки, указанной в адресной части команды, складываются как 24-разрядные двоичные числа. Если в результате сложения возникает 25-ризряд- ное число, то самая старшая единица пропадает. Пусть в ячейке 10005 хранится слово 111011101100001011010000, 5?
или, в восьмеричном виде, 73541320; пусть содержимое сумматора представляет собой 011011011100001010010001, или, в восьмеричном виде, 33341221. Поскольку , 111011101100001011010000 + 011011011100001010010001 1010111001000010101100001 то в результате восполнения команды 05110005 содер- жимым сумматора станет слово 010111001000010101100001, или, в восьмеричном виде, 27102541. Для сравнения двух слов будет использоваться one' рация поразрядного сравнения, ее код 052. Слово, хра- нящееся в ячейке, которая указана в адресной части команды, сравнивается поразрядно с содержимым сум- матора. Если содержимое разрядов совпало, то в этом же разряде слова-результата помещается 0, иначе 1. Пусть содержимое ячейки 10005 и сумматора такие же, как в предыдущем примере; тогда в результате вы- полнения команды 053100005 в сумматоре появится слово 100000110000000001000001, или, в восьмеричном виде, 40600101. Учесть результат сравнения двух слов можно с по- мощью операции условного перехода с кодом 023: переход к команде с адресом, записанным после кода 023, если содержимым сумматора является ненулевое слово. Теперь у нас есть все необходимое, чтобы составить- программу вычисления s — ад -Ь ... 4- ап. Числа ait ... ..., ап будут расположены, н^йиная с ячейки 10000, число п — в ячейке 50000, для s отводится ячейка 50001. В комментариях к этой и следующим программам со- держимое регистров будет обозначаться, соответственно, Р1, .... Р7- 54
Программа: ст 00000022 00001 03110000 00002 01150000 00003 01210000 00004 01150001 00005 01200022 00006 01300002 00007 01250001 00010 20110000 00011 01150001 00012 01400002 00013 05100021 00014 01300002 00015 05250000 00016 02300007 00017 01100022 00020 03250000 00021 04100000 00022 00000001 заголовок ввод (аь .... а„) пст j s :=а{ } Р2 := 1 а :=s(=ai+ ... +az_j) <т := о + аг (= ai + ••• +«/) s := ст Р2 :== Р2 + 1 | если п =£ ст, то на 00007 подготовка заголовка вывод (s) конец слово, используемое командами 00005, 00017 заголовок и числа аь ..., ап Циклически выполняются команды 00007—00016, команда 00010 использует второй регистр. При составле- нии этой программы учтено, что заголовок порции при вводе в машину попадает в сумматор (команда 00002). Задачи. 1. Написать программу вычисления суммы положи- тельных и числа отрицательных элементов массива at, ..., ап. 2. Написать программу, при выполнении которой вы- ясняется, является ли данный массив «1, .... ап неубы- вающим, т. е. верно ли, что од «2 ««. Отве- том должно быть число 1 или 0. 3. Написать программу вычисления суммы а.\ — —2а2 + За3— ... ±пап, где знак перед последним сла- гаемым определяется четностью п. 4. Как уменьшить содержимое некоторого регистра на 1? 55
5. Используя решение задачи 4, написать программу вычисления величины a\bn + aibn-\+ ••• + <2^1 для данных массивов «1, ап и bi, ..., bn. § 5. Операции над словами произвольного вида В предыдущих параграфах мы занимались главным образом арифметическими задачами, хотя не менее важны и интересны задачи обработки нечисловых дан- пых, например упоминавшиеся задачи обработки тек- стов. Возможны и программы, предназначенные для по- строения или анализа других программ. Рассмотрим следующий простой пример. Даны два массива машин- ных слов. Каждое слово является командой. Требуется ввести массивы в память машины, начиная с указанных ячеек, и заставить машину выполнить программы одну за другой. Предположим, что программы и ячейки, ис- пользуемые в них, не налагаются друг на друга. Тогда для решения задачи достаточно заменить в первой про- грамме все команды остановки на команды безуслов- ного перехода к началу второй программы. Кроме описанных операций двоичного сложения и сравнения слов, мы будем использовать операции сдвига слова на несколько двоичных разрядов влево и вправо. Сдвиг влево: код операции 053, после кода указы- вается число, на которое надо сдвинуть влево содержи- мое сумматора (существенный момент: после кода опе- рации стоит не адрес, а само число). Пусть, например, сумматор содержит слово 011011011100001010010001, или, в восьмеричной записи, 33341221. Выполнение команды 05300023 приведет к появлению в сумматоре слова 100010000000000000000000 5 последних Цифр прежнего слова или, в восьмеричной записи, 42000000 (так как 23 — это запись в восьмеричной системе числа 19). Операция с кодом 054 — сдвиг вправо. Выполнение команды 05400023 привело бы к появлению в сумматоре 56
слова 000000000000000000001101 5 первых цифр прежнего слова или, в восьмеричной записи, 00000013. Теперь вернемся г примеру этого параграфа и напи- шем требуемую программу. Пусть заданные массивы программы надо ввести в память, начиная с ячеек 30000 и 40000. Число слов в первом массиве в комментариях обозначим через п. а 00000025 заголовок 00001 03130000 ввод 1-го массива 00002 01100100 по 00003 03140000 ввод 2-го массива 00004 00005 01200000 01300001 | Pi :== 0 00006 01400001 00007 05100023 Pi := Pi + 1 00010 01300001 00011 11227777 о := слово из 1-го массива 00012 05400020 L совпадает ли код операции с 041? 00013 05200024 00014 02300017 если не совпадает, то на 00017 00015 01200025 00016 11127777 | замена команды остановки 00017 01400001 o’ :=Р1 00020 05200100 сравнение с п 00021 02300006 если не совпало, то на 00006 00022 02103000 переход к выполнению 1-й про* граммы 00023 00000001 слово, используемое командой 00007 00024 00000041 слово, используемое командой 00013 00025 02104000 слово, используемое командой 00015 заголовок и 1-й массив слов 1 заголовок и 2-й массив слов J 57
Операции над словами произвольного вида важны для реализации на машине целочисленной арифме- тики. Выполняя арифметические операции над числами в нормализованной форме, машина не разбирает, це- лые ли попались операнды, и, возможно, будет вы- числять результат приближенно. С последним об- стоятельством, как известно, не всегда можно прими- риться. Задачи. 1. Написать программу, после выполнения которой выясняется, совпадают ли двоичные порядки двух дан- ных чисел. Ответом должно быть число 1 или 0. 2. Дан массив машинных слов, изображающий неко- торый текст: каждое слово содержит код трех литер. Пусть двоичный код буквы А есть 0001011. Написать программу проверки, входит ли в данный текст буква А. Ответом должно быть число 1 или 0. 3. Обратным кодом двоичного слова называется сло- во, получающееся из исходного заменой 1 на 0 и 0 на 1. Пусть слова а и b рассматриваются как целые числа <224. Пусть в этом смысле а Ь. Доказать, что для построения слова а—b достаточно применить опера- цию сложения. 051 к словам а и обратному коду слова b — 1 (сравните с задачей 4 § 4). 4. Написать программу преобразования неотрица- тельного целого числа <224 из нормализованной формы в слово, являющееся записью данного числа в двоич- ной системе. Старшие незанятые разряды, как обычно, заполняются нулями. Указание. Показать, что если р — двоичный по- рядок данного числа, то для решения исходной задачи достаточно сдвинуть число на 9 разрядов’ влево, а ре- зультат этого сдвига —на 24 — р разрядов вправо; 24 — р = 25 — р— 1 =25 — (р + 1) (далее см. предыду- щую задачу). Значение 24 — р заносится в какой-нибудь регистр, а в команде сдвига вправо используется номер этого регистра. 5. Написать программу вычисления ап (п—целое не- отрицательное, а — любое число) двоичным алгоритмом (см. гл. I, § 4). Указание. Деления на 2 с остатком не пона- добятся, так как число п записано в двоичной системе и можно читать его цифры по очереди. 58
Разобранные в этой главе примеры показывают, что составление программ решения даже несложных задач на входном языке вычислительной машины — дело тру- доемкое и малоприятное. Это и явилось стимулом к со- зданию богатых языков программирования вроде ал- гола 60 и к разработке методов перевода (трансляции) программ на этих языках в программы на входном языке. Вопросы, связанные с трансляцией, обсуждаются в следующей главе. В заключение приведем список операций рассмот- ренной модели вычислительной машины. Этот список может пригодиться для справок. В скобках указаны страницы книги, на которых операции разъясняются подробно. Арифметические 001 — сложение (46), 002 — вычитание (46), 003 — умножение (46), 004 — деление (46), 005 — возведение в степень (46). Считывания 011 — из сумматора в ячейку (46), 012 — из ячейки в сумматор (46), 013 — содержимого 15 младших разрядов сумматора в регистр (53), 014 —из регистра в младшие разряды сумматора, старшие 9 разрядов заполняются нулями (53). Перехода 021—безусловный (47), 022 — при неотрицательном содержимом сумма- тора (47), 023 —при наличии ненулевого слова в сумма- торе (54). Ввода и вывода 031 — ввод порции слов (49), 032 — вывод порции слов (49). 59
Остановки 041 (50). Над словами произвольного вида 051 — двоичное сложение; если возникает 25-значное число, то самая старшая единица пропа- дает (53), 052 — поразрядное сравнение (54), Q53—сдвиг вправо (56), 054 — сдвиг влево (56),
ГЛАВА IV ТРАНСЛЯЦИЯ В этой главе в самых общих чертах излагается один из методов трансляции (перевода) алгольных программ на язык машины. Изложение носит общий характер, в разбираемых же иллюстративных примерах под языком машины подра- зумевается язык модели машины, обсуждавшейся в пре- дыдущей главе. § 1. Преобразование последовательностей символов Рассмотрим пока некоторые простые преобразова- ния последовательностей символов, они не решают за- дачи трансляции, но оказываются нужными при ее решении. Поэлементное преобразование последовательности символов состоит в замене по определенному правилу каждого символа. Это правило иногда задается табли- цей. Простейший способ кодирования текста — замена каждой буквы табличным кодом. Все переменные в про- грамме могут при трансляции заменяться по таблице адресами ячеек, хранящих их значения, — такая таб- лица создается при анализе описаний программы. Второе преобразование, рассматриваемое здесь,—* перестановка элементов. Перестановки при трансляции получаются главным образом с помощью магазина. Ма- газин задается упорядоченный совокупностью элемен- тов, которые в наших рассмотрениях будут машинными словами или порциями машинных слов. Принцип устрой- ства магазина — «последним вошел — первым вышел», в названии подразумевается сходство с магазином огне- стрельного оружия. Часто при объяснении принципа пе- рестановки элементов с помощью магазина прибегают 61
к аналогии не с оружием, а с железнодорожным тупи- ком (рис. 8). Предполагаются две операции: занесение очередного символа исходной последовательности в магазин (обо- значим эту операцию В) и вывод из магазина послед- него из попавших туда символов, про который говорят, что он находится на верхушке магазина (эту операцию обо- значим ИЗ). Выведенный сим- вол присоединяется в конец по- следовательности - результата. Последовательность а\, а% с помощью операций В, В, ИЗ, ИЗ преобразуется в йг, ai. Не любую перестановку элемен- тов последовательности мож- но получить с помощью опе- раций В и ИЗ. Например, из ai, а2, Оз никак не получить Рис. 8. Оз, 01, о2: когда аз выходит из магазина, Oi и о2 нахо- дятся там, но «1 попал в магазин раньше, чем аг, и обя- зан выйти позже. Обсудим вкратце представление таблиц и магазина в памяти машины. Таблица замены одного машинного слова другим может иметь вид двух массивов: преобра- зуемое слово разыскивается среди слов первого массива, из второго массива берется слово, имеющее тот же по- рядковый номер, что и найденное в первом массиве. По- рядок слов в первом массиве выбирают таким, чтобы поиск был возможно более быстрым; чаще всего этот порядок аналогичен словарному. Магазин занимает несколько последовательных ячеек, в которые попадают переставляемые элементы; еще одна ячейка (или регистр) хранит адрес верхушки ма- газина, эта ячейка, или регистр, называется указателем верхушки. Если упомянутые последовательные ячейки имеют адреса т, m-f-1, m-(-2, ... и в некоторый мо- мент магазин содержит k слов, то эти слова находятся в ячейках с адресами т, m + 1, ..., т-\- k — 1 и в ука- зателе верхушки находится адрес т + k — 1. Если надо поместить в магазин еще один элемент, то он должен попасть в ячейку с адресом т + k, соответственно дол- жен увеличиться адрес, хранящийся в указателе вер- хушки. Извлечение элемента из магазина приводит к 62
извлечению элемента из ячейки, адрес которой хранится в указателе верхушки; содержимое указателя верхушки уменьшается после этого на 1. Если магазин должен оперировать с элементами, представляющими собой порции слов, то в начало каж- дой порции добавляется слово-заголовок, указывающее количество слов в элементе. Содержимое указателя вер- хушки изменяется при операциях занесения и вывода элемента уже не на единицу: если в заголовке указано число I, то содержимое указателя верхушки должно быть изменено на / + 1 — слагаемое 1 добавлено по- тому, что заголовок тоже занимает ячейку. Задачи. 1. Последовательность букв названия этой книги за- менить последовательностью чисел. Число, сопоставляе- мое букве, определяется как количество различных букв, предшествующих первому вхождению рассматриваемой буквы в название. 2. Последовательность чисел 1, 2, 3, 4 преобразуется операциями В, В, В, ИЗ, ИЗ, В, ИЗ, ИЗ. Выписать по- лучающуюся перестановку. 3. Выписать перестановки элементов ал, а%, а3, кото- рые могут быть получены с помощью операций В и ИЗ. 4. Пусть таблица имеет вид двух массивов из п эле- ментов и элементами первого массива являются числа, упорядоченные по возрастанию. Продумать метод поис- ка номера данного числа в первом массиве, основанный на делении массива на две части: сравнением с элемен- том с номером [п/2] выясняется, в какой половине мас- сива надо продолжить поиск. Показать, что число необ- ходимых сравнений не превзойдет [log’s п] + 1. 5. Пусть указателем верхушки магазина служит ре- гистр 5. Написать команды вывода элемента в сумматор и занесения из сумматора в магазин. Для вспомога- тельных целей можно использовать ячейку 70000. Какие машинные слова необходимо запасти для преобразова- ния указателя верхушки? Считать, что они запасены в последовательных ячейках, начиная с ячейки 70001. § 2. Вычисление значения выражения Вычисление значения выражения требует соблюде- ния старшинства операций. Например, применение из- вестного из школьного курса математики алгоритма к 63
выражению b\2— 4ХаХс включает предварительное установление порядка выполнения операций 14 2 3 b * 2 — 4ХаХ<!> для этого выражение просматривается несколько раз. Выполнение каждой операции дает некоторое число — его приходится записывать отдельно от выражения, за- поминая тот фрагмент выражения, для которого число является значением. Соответственно до выполнения опе- рации должно быть установлено, к значениям каких фрагментов исходного выражения она должна приме- няться. Так, перед выполнением операции вычитания, помеченной цифрой 4, устанавливается, что применяется к значениям выражений, Ь\2 и 4ХаХ^. Ясно, что полное описание этого алгоритма было бы очень сложным, выполнение же такого алгоритма на машине потребовало бы и больших затрат времени (ко- торое будет уходить главным образом не на выполнение операций, а на просмотры выражения, поиски нужных промежуточных результатов и т. д.), и большого числа ячеек памяти (например, потребуется много ячеек па- мяти для сопоставления промежуточным результатам фрагментов исходного выражения). Сейчас будет предложен экономный алгоритм вычис- ления значения выражения, использующий 2 магазина для перестановки элементов выражения с учетом стар- шинства операций и для хранения промежуточных ре- зультатов. Магазины обозначим Mi и Мг; в Mi будут попадать знаки операций, в М2 — числа, участвующие в записи выражения, значения переменных и все промежуточные числовые значения. Ограничимся выражениями, состоящими только из чисел и переменных без индекса, связанных знаками операций f, X, /, +, —• Знак минус всегда будет зна- ком двухместной операции вычитания, выражения вроде —а + 1 исключаются из рассмотрения. От этих ограничений можно было бы и отказаться, но это удли- нило бы изложение. Пока предположим также, что в выражении нет скобок. Опишем алгоритм вычисления. Исходное выражение читается слева направо; если прочитано число, то оно заносится в Мг, если переменная — в М2 заносится ее 64
ей значение; если же прочитан знак операции, то необхо- димо различать несколько случаев. 1) Mi пуст; прочитанный знак помещается на вер- хушку iVIi. 2) То же самое, если прочитанный знак обозначает операцию, которая старше и поэтому должна выпол- няться до операции, знак которой расположен на вер- хушке Мь 3) Если операции равноправны или если та, знак которой только что прочитан в выражении, должна вы- полняться позднее, необходимо применить операцию, знак которой расположен на верхушке Мь к двум верх- ним числам из М2 (число на верхушке — второй опе- ранд, число под ним — первый); знак операции на вер- хушке Mi удаляется из Mi, вместо двух верхние чисел из М2 помещается результат выполненной над ними операции. В некоторый момент в исходном выражении не остается символов. Если пуст и Мь то вычисление окон- чено, результат находится в М2; иначе знаки операции извлекаются по очереди из Mi и соответствующие опе- рации применяются к числам из М2. Рассмотрим вычисление выражения b f 2— 4ХаХс1 значения переменных а, Ь, с обозначим А, В, С. м2 в М! t 2 - 4 X а X м2 Mi -4\aXc 2 t В м2 Ml ~4Ха\с В\2 м2 м. ХаХс 4 — В\2 м2 м. Хс А X 4 — В\2 65
м2 4Х.А В\2 М, Хс М2 С 4ХА В] 2 X М2 4ХАХС В\2 М, м2 в]2-4ХАХС Mj Про знак операции говорят, что он имеет более вы- сокий приоритет в сравнении с другим знаком, если обозначаемая им операция старше. В соответствующих случаях говорят о равных приоритетах и более низком приоритете. Рассмотренные знаки операций распадают» ся на группы равных по приоритету: t X, / +» — Группы упорядочены по убыванию приоритета. Полное доказательство, что предложенный алгоритм действительно приводит к вычислению значения выра- жения, основывается на возможности представления ис- ходного выражения Е в виде Ei0iE202 Qk-iEk, где 0i,02, 0*-i — знаки операций одинакового приори- тета, а Е],Е2, Ek — выражения, в которые не вхо- дят знаки операций с приоритетами, более высокими или равными приоритету знаков 0ь 02, ..., Исполь- зуя это, можно провести индукцию по числу групп рав- ных по приоритету знаков операций — для каждого Ei, i=l,2, ..., k, это число по крайней мере на 1 меньше, чем для Е. Теперь дадим правило работы со скобками. Левая скобка заносится в М] сразу после прочтения. Прочте- ние правой скобки влечет выполнение всех операций, 66
знаки которых находятся в Mi выше левой скобки; после выполнения этих операций обе скобки уничто- жаются. Вот что будет происходить при вычислении ,(а + Ь)Хс: м2 А М, ( + b) М2 М, )Xc В + А ( М2 Ml ) Xc А + В ( М2 Mt Xc А + В М2 Ml С X А + В М2 Ml (4 + В) ХС Задачи. 1. С помощью предложенного алгоритма вычислить значение 4 X 3/2 — (2 + 2Х(3 + 4 + 5)). 2. В некоторый момент вычисления значения выра- жения находящийся на верхушке Mi знак не совпадает со вторым (т. е. следующим за ним в магазине) знаком, но совпадает с третьим знаком. Какие возможности су- ществуют для верхних трех знаков из Mi? 3. Среди выражений аХ^Хс, аХ(ЬХс), (аХЬ)Х X с найти такие, при вычислении значений которых с помощью предложенного алгоритма порядок выполне- ния операций будет одинаковым. 4. В выражении а^хХу -f- &X*Xz+ сХуХ? расставить скобки так, чтобы они однозначно опреде- ляли тот порядок выполнения операций, который возни- кает при вычислении исходного выражения по предло- женному алгоритму. 5. Напомним, что отношение в алголе — два выраже- ния, соединенных одним из знаков отношения =, =И=, £>, <, Значением отношения будем считать 1, 67
если оно выполнено, и 0 — в противном случае. Вставить в приведенный в конце параграфа список групп знаков операций группу знаков отношений так, чтобы описан- ный метод вычисления значений стал пригодным для вычисления значений отношений. § 3. Трансляция выражений Предложенный в § 2 алгоритм позволял неслож- ными действиями с двумя магазинами получать значе- ние выражения — число. Алгоритм можно преобразо- вать так, чтобы получалось не само число, а последо- вательность машинных команд вычисления этого числа. В магазин М2 теперь будут заноситься не числа, а порции из нескольких машинных слов, содержащие команды вычисления некоторого числа с помещением его в сумматор. В моменты, когда прежний алгоритм предписывал произвести операцию над двумя верхними элементами М2, мы будем соединять две верхние порции команд в одну — выполнение получившихся команд должно привести к появлению в сумматоре соответ- ствующего числа. Оговоримся, что соединение нескольких порций команд в одну понимается не как простое приписыва- ние порций друг к другу (такую операцию мы будем называть склеиванием), между исходными порциями команд вставляются некоторые связующие команды. И при соединении, и при склеивании заголовки исход- ных порций убираются, а в начало порции-результата помещается новый заголовок. • Иногда заносимая в М2 порция будет содержать лишь одно слово: пусть в рассматриваемом выражении очередным элементом является переменная — прежний алгоритм предписывал занести в М2 значение этой пе- ременной, теперь же в М2 пойдет слово, в младших раз- рядах которого записан адрес ячейки, хранящей значе- ние переменной, а в старших разрядах — нули. Такое слово-заготовка легко превращается и в команду пере- несения значения в сумматор, и в любую команду вы- полнения действия над содержимым сумматора и со- держимым ячейки. При вычислении значения выражения возникают не- которые промежуточные значения. Для них должны быть зарезервированы ячейки. Адреса этих ячеек будут участвовать в командах, возникающих в М2.
Стандартный прием соединения двух порций из М2 в одну при выходе из Mi знака операции будет состоять в следующем. Обе порции выводятся из магазина, затем исследуется вторая порция, которая должна определять первый операнд. Если она состоит более чем из одного слова и, следовательно, является последовательностью команд получения первого операнда в сумматоре, то к ней добавляется команда считывания значения сумма- тора в одну из зарезервированных ячеек. Если вторая порция — из одного слова, которое, следовательно, яв- ляется заготовкой команды, то последовательность команд получения первого операнда в некоторой ячейке нам не нужна. Таким образом, описанный первый этап даст последовательность команд, которая может ока- заться пустой. Второй этап заключается в построении последовательности команд получения в некоторой ячей- ке второго операнда — если первая порция состоит из слова-заготовки, то эта последовательность оказывается пустой. Третий этап заключается в построении двух команд — считывания первого операнда в сумматор и выполнения нужной операции над содержимым сумма- тора и содержимым ячейки, выделенной для второго операнда. Три последовательности команд, получив- шиеся на трех этапах, склеиваются в одну и помещают- ся на верхушку М2. Посмотрим теперь, как возникают с помощью этого варианта алгоритма команды вычисления (а-|-&)Хс. Предполагается, что значения а, Ь, с хранятся в ячейках 01001, 01002, 01003. Каждая порция слов в М2 предва- ряется заголовком, указывающим число слов в порции. м2 Mt 00000001 ( 00001001 м2 Mt )Хс 00000001 + 00001002 00000001 00001001 м2 Ml )Хс 00000002 ( 01201001 00101002 69
м2 00000002 01201001 00101002 М, Хе м2 00000001 00001003 00000002 01201001 00101002 М, X м2 00000005 01201001 00101002 01177777 01277777 00301003 Ml В заключение несколько замечаний. Числа, встречающиеся в рассматриваемом выраже- нии, как и переменные, должны заменяться словами-за- готовками, содержащими адреса ячеек, хранящих эти числа. В магазин Mi попадают знаки арифметических опе- раций, представленные некоторыми машинными сло- вами. Естественно брать слова, в старших разрядах которых помещен код соответствующей операции. При этом станет удобным изготовление команд из слов-за- готовок. Продумывая последний алгоритм, мы игнорировали принятое в алголе разделение переменных и чисел по типам. Задачи. 1. Сколько получится команд в результате трансля- ции выражения а % b X сХ d? 2. Оттранслировать выражение а + b X с. 3. Программа, полученная в конце параграфа, после трансляции выражения (п + Ь)Хс обладает очевидным дефектом — третью и четвертую команды можно уда- лить. Внести поправку в приведенную рекомендацию по соединению двух порций из М2 в одну при выходе из Mi знака операции. 70
4. Трансляция выражения (a -J-&)Xc может дать последовательность команд, не включающих адреса за- резервированных ячеек, — надо воспользоваться реше- нием задачи 3. Показать, что это не будет иметь места при трансляции выражения + 1+ g X h X i. 5. Сколько адресов ячеек для запоминания промежу- точных значений будет использовано в командах, воз- никающих при трансляции выражения а X b X с + dX XeXf + gX/iXi? Продумать способ экономии ячеек Для запоминания промежуточных значений; эта эконо- мия должна привести к тому, что для данного выраже- ния потребуется только одна ячейка. § 4. Трансляция операторов и программы Предложенный в § 2 алгоритм вычисления значения выражения удалось в § 3 превратить в алгоритм получе- ния машинных команд вычисления этого значения. В на- стоящем параграфе область определения последнего ал- горитма будет расширена: станет возможным примене- ние алгоритма не только к выражению, но и к опера- тору, и к программе в целом. Как и полагается при трансляции, результатом применения алгоритма будет по-прежнему последовательность машинных команд, эк- вивалентная заданной алгольной конструкции*). Оператор присваивания не доставляет трудностей. Присваивание переменной значения выражения выпол- няется после вычисления этого значения, и знаку : — дается более низкий, в сравнении со знаками арифмети- ческих операций, приоритет. При выходе из Mi знака '= из М2 извлекаются две очередные порции. Если Первая порция состоит из одного слова и, значит, бу- дет лишь заготовкой команды, то ее надо превратить в настоящую команду — записать в старшие разряды код операции считывания в сумматор. Вторая порция *) Правомерна следующая точка зрения. Выполнение предло- женного в § 3 алгоритма можно толковать в определенном смысле как вычисление значения выражения: значением выражения счита- ется последовательность эквивалентных ему команд. Операторы ал- гольной программы в этом смысле тоже можно считать выражения- ми —им тоже соответствуют последовательности команд Таким об- разом, задача трансляции может рассматриваться как задача вычис- ления значения. Естественно пытаться вычислять это значение — Последовательность команд — действиями с магазинами Mi и Мг. 71
заведомо должна быть заготовкой, так как в левой части оператора присваивания всегда располагается пе- ременная; в старшие разряды этой заготовки записы- вается код операции считывания с сумматора. Две пор- ции после указанной доработки склеиваются. В предположении, что для х отведена ячейка 01000, а для а, Ь, с — ячейки 01001, 01002 и 01003, оператор присваивания х:=(я-)-Ь)Хс будет транслироваться в следующем порядке. В Mi попадает заготовка 00001000, в М2 — знак : = , они остаются в магазинах до оконча- ния трансляции выражения (я-|-&)Хс, которая идет так, как говорилось в предыдущем параграфе. Затем за- готовка 00001000 превращается в 01101000 и помещает- ся вслед за последовательностью команд вычисления значения выражения. На верхушке Mi появится порция 00000100 01201001 00101002 00301003 01101000 Как обычно, первое слово порции — это заголовок; предполагается, что при трансляции выражения (а + &)Х с использовано решение задачи 3 предыдущего параграфа. Трансляция составного оператора тоже очень проста: begin и end ведут себя как левая и правая скобки. Символ ; можно рассматривать как знак операции про- стого склеивания последовательностей команд, такая операция должна иметь приоритет более низкий, чем другие операции. Рассмотрим теперь условный оператор, ограничась конструкцией if В then С else D Эту конструкцию надо рассматривать уже как трех- местную операцию получения группы команд (до сих пор все операции были двухместными). Первая цель — разработка правил получения в Mi групп команд, соот- ветствующих В (см. задачу 5 § 2), С и D; знаком опе- рации соединения этих групп будет else (if и then должны уничтожиться). Вот эти правила: символ if, попадая в ЛК, ведет себя как левая скобка — ничего не выталкивает, then выталкивает все, вплоть до if. 72
Потом if уничтожается, a then попадает на верхушку. Символ else точно так же заменяет then. Попав в Мь else получает приоритет более высокий, чем ; , и более низкий, чем := . Все получающие приоритет знаки располагаются еле’ дующим образом по его убыванию: t X, / <> >, =, else (внутри каждой группы приоритеты одинаковы). При соединении последовательностей команд для В, С и D (это соединение происходит при выходе символа else из Mi) нужна команда перехода, а в такой команде должен указываться адрес команды, к которой нужно перейти. Но этот адрес остается неизвестным, пока не оттранслирована вся программа. Указанная проблема возникает и при трансляции операторов перехода. Обычный путь решения этой проблемы — помещение вместо команд перехода и тех команд, к которым надо переходить, некоторых заготовок. После получения с помощью магазинов Mi и Мо всей последовательности машинных слов, содержащей среди команд некоторое количество заготовок, эта последовательность про- сматривается и заготовки заменяются настоящими командами. При построении заготовок и замене их командами составляются и используются некоторые таблицы. Трансляция описания сводится к резервированию ячеек памяти. Каждому встреченному в программе чис- лу тоже ставится в соответствие ячейка, в которую сразу же заносится изображающее это число машин- ное слово. Соответствие между переменными, числами и ячейками описывается таблицей. Задачи. 1. Наряду с операторами алгола рассмотрим опе- ратор обмена значениями между переменными, изо- бражаемый х *-> у, где х и у — переменные. Задать 73
приоритет знака в сравнении со знаками алгола и объяснить, как бы можно было транслировать оператор обмена значениями. 2. Разработать правила трансляции оператора цикла. 3. Кроме рассмотренной в тексте этого параграфа формы условного оператора, в алголе, как известно, допустима форма if В then С. Разработать общие пра- вила трансляции условного оператора (then должен по- лучить некоторый приоритет среди > других знаков). 4. Почему после then правилами алгола запрещается помещать условный оператор и оператор цикла? (Ка- кого рода неоднозначности могли бы возникнуть, если бы не было этого запрещения?) 5. Разработать намеченную в конце параграфа тех- нику работы с заготовками команд перехода и тех команд, к которым надо переходить. * * * После трансляции написанной на некотором алгорит- мическом языке программы машина приступает к вы- полнению программы-результата. В следующей главе мы вернемся к понятию выполнения программы: это по- нятие будет расширено — станет возможным временное прерывание выполнения.
ГЛАВА V ДИАЛОГОВЫЕ ПРОГРАММЫ. ОПЕРАЦИОННАЯ СИСТЕМА Рассматриваются программы, с помощью которых человек может вести диалог с вычислительной машиной. Обсуждаются возможности использования машины во время ожидания реплик человека. § 1. Диалоговые программы При выполнении программ возможен диалог (обмен сообщениями) человека с машиной. К диалоговым отно- сятся, например, игровые программы, программы со- вместного решения задачи человеком и машиной и т. д. После вывода сообщения об очередном ходе или о ре- зультате этапа вычислений такие программы ждут от человека сообщения об ответном ходе или указаний от- носительно дальнейших действий. Программа ждет — значит, ее выполнение приостанавливается до получения сообщения человека. Для написания диалоговых программ созданы спе- циальные языки, предоставляющие много удобств, на- пример обмен текстовыми сообщениями. Эти языки здесь рассматриваться не будут, так как речь пойдет только о принципе организации диалога человека и машины. Рассмотренный язык алгол становится пригодным для написания диалоговых программ, коль скоро принято следующее толкование оператора ввода. Если числа еще не подготовлены к моменту, когда надо выполнять этот оператор, то выполнение программы прерывается и продолжается только после появления нужных чисел. В следующих параграфах будет рассказано о выполне- нии таких программ машиной. Разберем пример игровой программы. Игра в 100 спи- чек: из кучки, первоначально содержащей 100 спичек, та
двое играющих поочередно берут от 1 до 10 спичек. Проигрывает взявший последнюю спичку. Для делаю- щего ход невыгодными (т. е. проигрышными при безуко- ризненной игре противника) являются положения, когда в кучке содержится 11m 4-1 спичек (т = 0, I, 2, ...). Это легко доказывается индукцией по т. При т = 0 утверждение очевидно; если же т > 0 и если взято t спичек (IsC^sClO), то противник может взять 11 — t спичек: 1 11 — t 10, и после этого приходится де- лать ход в положении, когда в кучке содержится 11 (т — 1)4- 1 спичек. Во всех других положениях делающий ход может легко выиграть — надо привести число спичек в кучке к виду 11 т + 1. Напишем реализующую эту стратегию программу. Человек и машина будут обмениваться числами, озна- чающими число остающихся в кучке спичек. Первый ход будет за человеком. Машина всегда выигрывает, так как 100 = 11-9+ 1. begin integer п, t, s; JOO; repeat; input (/); if i = 0 then go to finish; s;— 11 — (n — /); n;—t — s; output (n); go to repeat; finish; end Задачи. 1. Сколько ходов будет сделано человеком в игре с машиной, выполняющей предложенную программу? 2. Переделать предложенную программу — включить проверку соблюдения человеком правил игры. Если правила нарушены, то должно выводиться то же число, что и перед неправильным ходом. 3. Составить программу, в которой начальное число спичек п задается человеком, а первый ход делается машиной. Может оказаться, что п=\\т-\-\ при не- котором т, но вдруг человек в какой-то момент сде- лает не лучший ход. 4. Найти выигрышные и проигрышные положения в игре в п сличек при условии, что взявший последнюю спичку выигрывает, 76
5. Составить программу определения за 10 вопросов задуманного человеком целого числа от 1 до 1000. Каж- дый вопрос имеет вид: «Верно ли, что задуманное число больше числа &?», он задается выводом значения k. От- ветом человека должно быть число 0 (нет) или 1 (да). § 2. Обмен сообщениями в диалоге Упоминавшееся в гл. III устройство ввода с перфо- карт непригодно для ввода сообщений человека при выполнении диалоговых программ: в момент обращения к этому устройству перфокарты должны быть на месте, и ожидание невозможно. Если бы даже ожидание и оказалось возможным, использование устройства ввода стало бы очень неудобным из-за длительности подго- товки перфокарт. При выполнении диалоговых программ связь чело- века с машиной происходит через видеотерминал, имею- щий клавиатуру пишущей машинки и телевизионный экран, на котором высвечиваются последовательности знаков. Видеотерминал служит и устройством ввода, и устройством вывода — сообщения набираются человеком на клавиатуре, ответы читаются на экране. Пока человек набирает свое сообщение, программа не выполняется. Ожидание заканчивается только после нажатия специальной клавиши, которая есть на клавиа- туре видеотерминала, — клавиши исполнения. Обсудим средства взаимодействия машины с не- сколькими видеотерминалами. Каждый видеотерминал связан с машиной через отдельный канал ввода-вывода. Каналы пронумерованы числами 1, 2, 3, ... После на- жатия клавиши исполнения в машину поступает сигнал, что через данный канал можно прочесть сообщение. Входной язык машины должен содержать операцию проверки готовности канала. В нашей модели машины эта операция имеет код 061; в адресной части команды указывается номер (в восьмеричной системе) канала ввода-вывода. В результате выполнения этой операции в сумматоре появляется нулевое слово, если сообщение не готово, и появляется слово 77777777 в противном случае. Для ввода и вывода можно использовать прежние операции с кодами 031 и 032. Дополнительно опреде- лим операцию с кодом 062 заявки на канал. После 77
выполнения, например, команды 06200007 каждая опера- ция ввода и вывода будет использовать седьмой ка- нал. Так будет продолжаться до следующего выполне- ния команды с кодом операции 062. После ввода с видеотерминала в сумматоре оказы- вается (записанное в виде заголовка) число введенных машинных слов. Нулевая адресная часть после кода операции заявки на канал означает заявку на ввод с перфокарт и вывод на бумагу с помощью тех устройств, о которых говорилось в гл. III. Эти же устройства под- разумеваются в операциях ввода и вывода до первого появления в программе команды с кодом операции 062. Выполнение следующих команд приводит к ожида- нию появления сообщения в канале ввода-вывода с но- мером 1, чтению этого сообщения и выводу его через канал с номером 5. 00100 00101 00102 00103 00104 00105 06100001 02300100 06200001 03100177 06200005 03200177 ожидание готовности заявка на 1-й канал ввод сообщения заявка на 5-й канал вывод сообщения 1-го канала При решении задач этого параграфа предлагается придерживаться алголоподобной формы записи про- грамм, используя, кроме обычных операторов и функ- ций алгола, оператор заявки на канал dc(n) и функцию проверки готовности канала ready (п) (п — это номер канала). Функция ready(п) принимает значение 1, если через канал с номером п уже можно прочесть сообще- ние, и 0 в противном случае. Перепишем приведенную последовательность команд (передаваемое сообщение считаем целым числом). begin integer k-, L‘. if ready (l) — 0 then go to L; de (/); input (k); de (5); output (fe) end Задачи. 1. Справочная служба дает ответы на поступающие из разных мест вопросы. Упрощенная модель: вопрос представляется целым числом от 1 до п, ответ — тоже целое число (обозначим ответ на вопрос I через ai). Со- 78
ставить программу ответа на вопросы, поступающие че- рез каналы с номерами 1, 2, ..., т. При каждом полу- чении вопроса i через тот же канал должен выдаваться ответ at. Каналы просматриваются в следующем по- рядке: 1, 2, ..., т, 1, 2, т, 1, 2, т, ... Если вопрос через некоторый канал еще не задан, то этот канал пропускается. Просмотр каналов заканчивается, как только через какой-нибудь канал поступит не лежа- щее в диапазоне от 1 до п число. 2. Условие предыдущей задачи изменяется: прервать опрос (просмотр) каналов можно только через 1-й ка- нал. Если число, не лежащее в диапазоне от 1 до п, поступает через какой-нибудь другой канал, то это число возвращается через тот же канал вместо ответа. 3. Упрощенная модель системы продажи авиацион- ных и железнодорожных билетов похожа на упрощен- ную модель справочной службы (см. предыдущие за- дачи). Заказ — это два числа i, j: первое отражает дату, номер рейса и тип места, второе — количество билетов. Если / at, то должно быть выведено число 1 (заказ выполнен), а значение а, уменьшено на /. В противном случае должен быть выведен 0. Остановка происходит после получения через первый канал чисел 0, 0. 4. В модели системы продажи билетов закрепить за первым каналом функцию возврата билетов. Таким об- разом, получение через первый канал чисел i, j ведет к увеличению at на j. 5. В модель системы продажи билетов внести еще одно изменение: канал возврата билетов должен опра- шиваться существенно чаще других. Рассмотреть две возможности: а) порядок опроса всех каналов берется таким: 1, 2, 1, 3, ..., 1, т, 1, 2, 1, 3, ... ; б) порядок опроса: 1, 2, ..., т, 1, 2, ..., т, ..., но перед тем, как дать отрицательный ответ на некоторый запрос, обра- щаются на всякий случай дополнительно к каналу воз- врата. § 3. Многопрограммный режим работы машины Во время ожидания сообщений при выполнении диа- логовой программы машина работает вхолостую. Хо- рошо бы в этом случае заставить машину выполнять другие программы. Это простое соображение может быть реализовано, только если машина оснащена 79
специальной аппаратурой и если входной язык машины содержит некоторые специальные операции, которые по- зволяют составить операционную систему — управляю- щую программу, обеспечивающую многопрограммный режим работы машины. Опцшем средства, необходимые для создания опе- рацпонной системы. Внешняя память. Вычислительная машина снабжает- ся дополнительными хранилищами данных — дисками. Каждый диск может вместить в несколько раз больше слов, чем память машины. Внешняя память состоит из нескольких дисков. Из памяти машины с помощью спе- циальных операций содержимое ряда последовательных ячеек может быть переписано на диск. Аналогично, пор- ция машинных слов может быть считана с диска в па- мять машины. Эти операции называются операциями обмена с внешней памятью; они используются не только в операционной системе, но и в программах обработки больших массивов, которые могут вызываться в па- мять и обрабатываться по частям. Обмен с внешней памятью идет гораздо быстрее, чем ввод с перфокарт, вывод па бумагу, чтение с экрана и вывод на экран видеотерминала. Правда, обмен совер- шается довольно большими порциями: например, по 1024 машинных слова. Прерывания. Примем, что наша модель машины, как и многие настоящие машины, будет находиться в одном из двух состояний и в зависимости от состояния по-раз- ному выполнять программы. В первом состоянии программы выполняются так, как было показано в гл. III. В этом состоянии машина выполняет команды операционной системы. Будем пред- полагать, что операционная система постоянно занимает ячейки 70000—77777. Во втором состоянии машина, в частности, особым образом реагирует на команды ввода п остановки: вме- сто ввода или остановки происходит изменение состоя- ния и безусловный переход к команде в некоторой ого- воренной ячейке, например в ячейке 70000. Продолжи- тельность каждого пребывания во втором состоянии не превышает некоторого фиксированного времени. Мы бу- дем считать, что это время — секунда. Если по прошест- вии секунды выполнение программы не завершилось и не встретились команды ввода, то все равно выполнение 80
программы прерывается, изменяется состояние машины й происходит безусловный переход к команде в ячейке 70000. Во время прерывания в ячейку 77777 попадает адрес команды, на который прервалось выполнение про- граммы. Переход машины из первого состояния во вто- рое может произойти только в результате выполнения специальной команды. Все программы, кроме операционной системы, выпол- няются машиной во втором состоянии; будем пока счи- тать, что они не затрагивают ячеек 70000—77777, позд- нее от этого предположения мы откажемся. Суть многопрограммного режима: машина выполняет каждую программу не сразу от начала до конца, а поэ- тапно. Этап выполнения программы продолжается до прерывания, после которого наступает черед операцион- ной системы: она переписывает во внешнюю память все, что имело отношение к выполнявшейся программе, и восстанавливает (переписью из внешней памяти) со- держимое ячеек, сумматора и регистров таким, каким оно было после прерывания выполнения другой про- граммы. Из первого состояния машина переключается во второе, и загруженная программа начинает выпол- няться с нужной команды. Программы загружаются операционной системой в некоторой очередности. Если диалоговая программа ждет сообщения человека, то до готовности сообщения ее очередь пропускается. Вместо уже выполненных про- грамм берутся новые программы, которые вводятся во внешнюю память заранее в достаточно большом коли- честве. В многопрограммном режиме машина вперемешку выполняет и диалоговые, и обычные программы. Преры- вания по времени не позволят слишком долго задержи- ваться программам, предписывающим длительный счет без вводов величин, и диалоговым программам, само- стоятельно проверяющим готовность сообщения в кана- лах и предусматривающим ожидание. При выполнении машиной отдельной программы процессор не используется не только во время ожида- ния реплик человека, но и во время ввода данных с пер- фокарт и вывода на бумагу. И в этом случае операцион- ная система не позволяет процессору простаивать и по- ручает ему выполнение других программ. 81
Операционная система устанавливает определенную иерархию программ; в частности, возобновление выпол- нения диалоговых программ происходит чаще, чем вве- денных с перфокарт. Благодаря частым проверкам го- товности канала у работающего за видеотерминалом создается впечатление, что он работает на машине один. Когда встречается программа, написанная на ка- ком-нибудь алгоритмическом языке, на долю операцион- ной системы выпадает извлечение сведений из внешней памяти и запуск нужного транслятора. Не только трансляторы, но и сама операционная си- стема не хранится постоянно целиком в памяти машины. Например, после окончания выполнения машинной про- граммы операционная система обычно заставляет ма- шину печатать некоторые сведения о проделанной ра- боте— затраченное время, количество потребовавшейся бумаги и т. д. Часть операционной системы, которая подготавливает печать этих сведений, вызывается в па- мять машины, только когда в этом есть надобность. По- стоянно присутствующая в памяти машины часть опе- рационной системы — ее иногда называют резидентом системы — составляет небольшую долю всей системы. Вся операционная система — программа, полностью рег- ламентирующая работу машины, — настолько велика, что не может целиком уместиться в памяти. Хотя операционная система занимает часть памяти, это не мешает выполнению других программ благодаря мерам, принимаемым самой операционной системой. Часть выполняемой в данный момент программы и со- держимое части ячеек, используемых этой программой, хранятся во внешней памяти. Когда надо, операционная система вызывает порции машинных слов из внешней памяти в память машины с предварительным освобож- дением места путем переписи во внешнюю память. Здесь есть весьм.а трудный момент пересчета адресов при выполнении программы. Вообще, память машины, как физическое устрой- ство, может содержать гораздо меньше ячеек, чем пред- полагается во входном языке машины. Операционная си- стема расширяет физическую память машины за счет внешней памяти, но программист может этим не инте- ресоваться (и может даже не знать о существовании внешней памяти), он имеет дело с так называемой пря- моадресуемой памятью. 82
Задачи. 1. Каждый диск разбит на 1024 листа, и каждый лист может вместить 1024 машинных слова. Считыва- ние в память машины и запись во внешнюю память про- исходят целыми листами. Будем предполагать, что в алгольных программах можно пользоваться операто- рами обмена read (п, т, k, а) и write (п, т, k, а); п — номер диска, т — номер начального листа, k — количе- ство листов (считываемых или записываемых), а — идентификатор массива с количеством элементов, рав- ным 1024&. Написать программу выбора наибольшего элемента из целых чисел, целиком заполняющих диск с номе- ром 5. Числа вызывать в память машины порциями по 4 листа. 2. Используя операторы read и write (см. предыду- щую задачу), написать программу выполнения следую- щего задания. Пусть диск с номером 5 заполнен неотри- цательными целыми числами. Исключить из этих чисел все нули, оставив прежним порядок остальных чисел. Если среди данных чисел есть хотя бы один нуль, то в результате выполнения программы количество чисел уменьшится. Поместить в этом случае в конце получаю- щегося набора чисел —1. Новый набор чисел должен занять тот же диск с номером 5. В память машины по- прежнему можно вызывать не более 4 листов. 3. Пусть машина выполняет в многопрограммном ре- жиме несколько программ, одна из которых диалоговая, а выполнение остальных п программ не требует долгое время ввода и вывода величин. Пусть прерывание про- граммы, загрузка и запуск новой программы занимают а секунд. Пусть для получения ответа на некоторое со- общение при выполнении диалоговой программы тре- буется, чтобы процессор проработал b секунд. Но из-за того, что машиной рассматриваются еще п упомянутых программ, время ожидания ответа равно с секундам. Определить время ожидания ответа на сообщение, требующее Ь/2 секунд работы процессора. 4 Выражаются ли однозначно величины b и с из предыдущей задачи друг через друга? Если да, то ка- ким образом? 5. Пусть 071 — код операции переключения машины из первого состояния во второе, адресная часть соот- ветствующей команды — нулевая. Написать последова- 83
тельиость команд, выполнение которой приводит к пе- реключению машины во второе состояние и переходу к команде, адрес которой получается увеличением на 1 адреса, записанного в адресной части ячейки 77777. Использовать регистры нельзя, так как их содержимое считается восстановленным таким, каким оно было до прерывания программы. Требуемая последовательность команд должна располагаться, начиная с ячейки 77000. * * * Программы, предоставляющие различные удобства программисту и позволяющие рациональнее использо- вать вычислительную машину, образуют программное обеспечение машины. Кроме трансляторов и операцион- ной системы к программному обеспечению относятся еще архивные системы («базы данных»), облегчающие работу с большими массивами данных во внешней па- мяти. К программному обеспечению относятся и диало- говые программы, позволяющие набором на видеотер- минале некоторых инструкций извлекать из архивов во внешней памяти программы, редактировать их (исправ- лять ошибки или что-либо изменять), заставлять машину выполнять программы и т. д. Результат выполнения каждой инструкции появляется на экране видеотерми- нала.
ДОПОЛНЕНИЕ О ДОКАЗАТЕЛЬСТВЕ СВОЙСТВ ПРОГРАММ Во введении отмечалось, что программирование включает в.себя и составление, и исследование программ. Мы обсудим сейчас один метод доказательства свойств программ. Каждое конкретное свойство, о котором будет идти речь, состоит в том, что если относительно исходных данных программы справедливо некоторое фиксирован- ное утверждение, то относительно значений переменных в момент окончания выполнения программы справедливо некоторое другое фиксированное утверждение. Свойство программы может состоять, например, в том, что если исходное целочисленное значение п положительно, т. е. п 1, то в момент окончания выполнения программы для значений переменных р, п выполнено р — п\. Если пере- менная п не изменяет своего значения при выполнении программы, то это свойство означает, что когда выпол- нение программы завершено, мы получаем значение я!; этим значением обладает переменная р. Это свойство принято записывать так: {п >= 1} Р{р — я!}, где под Р понимается рассматриваемая программа. Обладает или нет программа подобным свойством — это может быть важным вопросом о правильности программы. Ради простоты мы будем рассматривать только про- граммы, описанные с помощью тех средств,. которые были предложены в гл. I; более того, мы и из этих средств оставим не всё, ограничась инструкцией при- сваивания, условной и циклической инструкциями: х:=Е, пока а повторять (Рр, R2; ...; Rk), если р, то (Рр, Р2; ...; Р„,) иначе (Q1; Q2, Q„), где Е— некоторое выражение, а, и р — некоторые утвер- ждения о значениях переменных (всюду далее та- кие утверждения обозначаются греческими буквами), 85
Rz, Rk, Py, Pz, Pm, Q1, Qz, ..., Q,I — инст- рукции этих же трех типов. Будет без оговорок предпо- лагаться, что переменные принимают целочисленные значения. Записывая выражения, мы будем позволять себе употреблять традиционные математические обозна- чения операций (что не всегда возможно в алголе). Уточним понятие свойства программы. Определение 1. Программа Р обладает свой- ством {ф}Р {}, где <р и ф—некоторые утверждения о значениях, используемых в программе переменных, если каждым начальным значениям переменных, относитель- но которых справедливо ф, отвечают в момент окончания выполнения программы такие значения переменных, от- носительно которых справедливо ф. Простейшие примеры свойств программ: {п — 0}п :=п -f- 1 [п = 1}, {п k, п2 < 2/У} п :—п + 1 {п k + 1, (« — I)2 < 2й2}, {п < т} п := п -j- k {п < т + &}, {п < т -f- k} п Зп{п < 3 (т -ф- k)}. Менее простой пример дает упоминавшееся свойство программы вычисления факториала m:=l; пока т=£п повторять (m:= m-f- 1; рр • т) {p — nl}. (1) Здесь мы видим не очень сложную программу, но тем не менее доказательство этого свойства уже доставляет хлопоты. С более сложной программой трудностей мо- жет быть больше. Как проводить подобные доказатель- ства? Пересказ словами того, что происходит со значе- ниями переменных при выполнении программы, может оказаться невразумительным. Идея метода, о котором пойдет речь — метода промежуточных утверждений,— состоит в сведении исходного свойства всей программы к некоторым свойствам составляющих ее инструкций, В конечном счете рассматриваемое свойство надо свести к группе свойств инструкций присваивания. И прежде всего, для этого оказывается полезной следующая Теорема 1. Пусть Р и Q — программы, обладающие соответственно свойствами {а}Р{£} и {₽}Q{y}. Тогда имеет место свойство {a}P;Q{y} программы P;Q. 86
Доказательство. Если относительно начальных значений переменных справедливо утверждение а, то по свойству {а}Р{Р} после выполнения Р относительно зна- чений этих переменных справедливо утверждение р, но по свойству {p}Q{y}, если после Р еще выполнить Q, то будет справедливо утверждение у. Пример. Программа n:=n-j-k; п:=3п обладает свойством {п < т} п := п + k; п: = 3п{п < 3 (т -ф &)}. В самом деле, как уже отмечалось, имеют место свойства {п < т} п п -f- k {п < tn + k}, (2) {п < т + п Зп {п < 3 (т + &)}. (3) Осталось применить теорему 1. После рассмотрения этого примера становится понят- ным смысл названия «метод промежуточных утвержде- ний». Между отдельными инструкциями мы фиксируем некоторые «промежуточные» утверждения, каждое из ко- торых, как мы предполагаем, справедливо после выпол- нения одной инструкции и перед выполнением другой. Рассматривая последний пример, мы заметили, что после выполнения инструкции n\=n-\-k справедливо «С < т -ф k. Удачный выбор промежуточных утверждений позволяет сводить свойство сложной программы к свой- ствам более простых. Скорее всего простейшей програм- мой следует признать ту, которая состоит из одной ин- струкции присваивания. Свойства таких программ удоб- но доказывать, опираясь на следующую теорему. Теорема 2. Пусть после выполнения инструкции присваивания а : — f(a, b, с, ..., х) справедливо утверж- дение $(а,Ь,с, х). Тогда до выполнения этой инст- рукции было справедливо утверждение &(а, Ь, с, ..., х) = = fi(f(a,b, с, ..., х),Ь,с, ..., х). И наоборот — для лю- бых значений а, Ь, с, ..., х, для которых справедливо а(а,Ь,с, ..., х), выполнение указанной инструкции при- сваивания приводит к такому изменению переменной а, что оказывается справедливым $(а,Ь,с, ..., х). Доказательств’;). Пусть до выполнения инструк- ции присваивания а := f\a,b, с, ..., х) переменные а, Ь, с, ..., х имели значения Ао, Во, Со, ..., Хо, а после выполнения — Ai, Bi, Сь ..., Хь Ясно, что А] — «= f(Ло, Во, Со, ..., Хо), Bi = Во, Ci = Co, ..., Xl = Xq. 87
Следовательно, если выполнено p(Ai,Bj, СТ, XT), то выполнено Р(/(Л0, Во, Со,..., Хо), Во, Со, Хо). На- оборот, если до выполнения инструкции присваивания имело место p(f(Ло, Во, Со, ..., Х0),В0, Со, Хо), то после выполнения будет иметь место p(4i,B0, Со, ... ..., Х”о) = р(Л], Bt, С,, ..., ХТ). П р и м е р. Применим утверждение теоремы для дока- зательства уже упоминавшихся свойств простейших про- грамм (2), (3). Подстановка в утверждение га<3(/п+&) вместо переменной п выражения Зп дает Зп <' 3 (щ + k), т. е. п < т + k, что доказывает свойство (3). Аналогич- но доказывается (2). Еще один пример. Имеет место следующее свойство: {с = a, d — Ь} а := а + b\ b := а — Ь; a\ — a — b{c = b,d = a}, (4) которое, в силу того, что переменные end не меняют значений при выполнении программы, означает, что вы- полнение выписанных трех инструкций присваивания приводит к обмену значениями между переменными а, Ь. Докажем это свойство. По теореме 2 имеет место свойство {с — b, d = а — Ь} а :== а — b {с — b, d — а}, по этой же теореме имеет место свойство {с = а — b, d — Ь} Ь '.— а — b{c ==b, d — a — b}. Следовательно, по теореме 1 {с = а — b, d — b} b := а — b-, а ;—а — b {с = b, d — a}. По теореме 2: {с = a, d — Ь} а := а b {е а — b, d — Ь}, следовательно, по теореме 1 имеет место (4). Иногда, для того чтобы доказать некоторое свойство, удобно перейти к более сильному свойству и доказы- вать его. Теорема 3. Пусть имеет место свойство {к}Р{р}. Пусть утверждения у и б таковы, что а является след- ствием у (последнее понимается в том смысле, что если для значений переменных справедливо утверждение у, то для них заведомо справедливо и а; обозначаться это будет так: у=^а), а б — следствием р. Тогда имеет ме- сто {у}Р{6}. Доказательство следует из определения свойства про- граммы. 88
Пусть мы хотим доказать свойство {п < т} п := п -f- tn {п ДС 2т}; (5) по теореме 2 имеет место {п сл т}п п + т{п сл 2т}; так как (п -< т)=^(п сл т) и (га см 2гаг)=>(га 2т), то по теореме 3 имеет место (5). Другое доказательство: по теореме 2 имеет место {га < т}п := га т{п < 2т}, так как (га < гаг)=>(га < гаг) и (га -< 2т)=>(га лЛ 2т), то по теореме 3 имеет место (5). Перейдем к условным инструкциям. Надо как-то све- сти свойство {ф} если р, то (Р) иначе (Q) {ф} (6) к свойствам программ Р и Q. Теоре,ма 4. Для того чтобы имело место свойство (6), необходимо и достаточно, чтобы имели место свой- ства {ф, Р}Р{»ф} и {ф, Р}<2{'ф}. Примечание. Утверждение р (читается «не р») со- стоит в том, что р не справедливо. Например, а > b экви- валентно а сС Ь. Доказательство теоремы. Необходимость: пусть имеет место свойство (6); если справедливо р, то, по определению условной инструкции, выполняется инст- рукция Р и, следовательно, должно быть выполнено {ф, р}Р{ф}. Аналогично рассматривается случай, когда р не справедливо, т. е. справедливо р. Достаточность: пусть значения переменных таковы, что справедливы <р и Р; при выполнении условной инструкции если р то (Р) иначе (Q) дело сведется к выполнению Р и, поскольку имеет место свойство {ф, Р}Р{ф}> то после выполнения условной инструкции значения переменных будут удо- влетворять ф. Аналогично рассматривается случай, когда первоначально справедливы ф и р. В качестве примера применения теоремы 4 докажем свойство {х, у — любые} если х > у, то (т :== х) иначе (т у) {т (У х, т (У у} (7) для этого рассмотрим в соответствии с теоремой 4 свой- ства {х, у — любые, х > у} т х {т~^ х, т (У у}, {х, у — любые, х > у} т ;= у {т х, у}, 89
которые можно переписать так: {х > у} тх {т х, у}, {х --Д у} т == у {т х, у}. (8) (9) Применим к первому из этих двух свойств теорему 2. Если подставить в т х, т^у переменную х вместо переменной т, то получим х х, х^ у, что эквивалент- но х у. Поскольку х > у => х у, то по теореме 3 дей- ствительно имеет место свойство (8). Таким же образом (даже не прибегая к теореме 3) можно доказать (9). Циклическая инструкция — это наиболее интересный и трудный случай. Рассмотрим подробно свойство (1). Очевидно, что имеет место свойство {п 1} р : = 1; in,-. — 1 {н 1, р — К т = 1}, поэтому, по теореме 1, для доказательства (1) достаточно было бы доказать свой- ство {п^ 1, р= 1, т — 1} пока т=£-п повторять (m:=m+l; р := р т) {р = п\}. (10) Для этого естественно попытаться провести индукцию по числу этапов выполнения циклической инструкции. Если число этапов равно нулю, то все очень просто: раз одновременно выполнено 1, р = 1, т = 1, /п = п, то m = п — р = 1 и, конечно, р = п\. Однако с переходом от числа этапов, равного Ц/^0), к числу этапов, рав- ному £ + 1, дело обстоит хуже: если мы „вынесем один этап за пределы цикла, т. е. заменим циклическую ин- струкцию последовательностью инструкций m :— m + 1; р := р пг; пока пг^п повторять (in := т + 1; р := р т), то не сможем воспользоваться предположением индук- ции, поэтому после выполнения присваиваний т : = тД-1 и р р-т уже не будет справедливым т = 1. Для доказательства (10) имеет смысл воспользовать- ся теоремой 3 и перейти к некоторому другому свойству той же программы, заменив утверждение п^ 1, р = 1, пг = 1 некоторым его следствием а, таким, что имеет место {а} т :— т + 1; р := р • т {а}. Кроме этого, должно остаться в силе основание индук- ции: все должно быть верно для случая, когда число эта- пов равно нулю, т. е. для случая т == п. 90
Нетрудно убедиться, что в качестве а можно взять р = т\. Если т — п, то из р = т\ следует р = п\ — это основание индукции. Далее, очевидно, имеет место свой- ство {р — т\}т-. — т + 1; р ~ р • т{р = пг\}. Теперь ясно, что верна следующая теорема о цикли- ческой инструкции. Теорема 5. Пусть для утверждения б выполнено 1) a=s-d, 2) (б, у)=>Р, 3) {д}Р{б}. Тогда имеет место свойство {а} пока у повторять (Р) {р} (11) циклической инструкции пока у повторять (Р). (12) Утверждение б, упоминаемое в теореме, оказывается справедливым непосредственно перед каждым выполне- нием и непосредственно после каждого выполнения Р; в этом смысле б — промежуточное утверждение. Теорему 5 можно усилить, заменив условие 3 усло- вием 3') {б, у}Р{б}, так как, выполняется только когда справедливо у. Определение 2. Утверждение б, удовлетворяющее условию {б, у}Р{б}, называется инвариантом цикличе- ской инструкции (12). Таким образом, для доказательства свойства (11) достаточно подобрать удовлетворяющий условиям 1, 2 инвариант циклической инструкции (12). Свойство 3 или 3' можно бы назвать законом сохранения справед- ливости утверждения у. Два примера свойств циклических инструкций и ин- вариантов, подходящих для доказательства этих свойств: {«^1, р=1, пг — п} пока пг^О повторять (р:~ р • т; т:=т — !){/? = «!}, (13) подходящий инвариант — р-т\ ~ п\\ {k 1, т = 1, п = k} пока п~^0 повторять п'.— п-—l){m~2k}, (14) подходящий инвариант — пг2п — 2*. 91
Ясно, что доказательство свойства (11) с привлече- нием инварианта 6 есть, по существу, доказательство индукцией по числу шагов. Но интересно, что проверяя условия 1, 2, 3 или 1, 2, 3х, мы не рассматриваем явно и не упоминаем это число. Примечание. Исследования описанного метода доказательства свойств циклических инструкций пока- зывают, что в некоторых случаях нужный инвариант ока- зывается довольно сложным, и для его описания в свою очередь требуется циклическая инструкция, или нечто подобное. Проверка условий 1, 2, 3 или 1, 2, 3' может стать задачей, эквивалентной по сложности исходной задаче. Но, с другой стороны, как показывают обсуж- давшиеся примеры, применение этого метода часто вы- глядит вполне естественным и не вызывает затруд- нений. Надо отметить, что мы столкнемся с существенными осложнениями, если попытаемся свести к свойствам от- дельных инструкций свойство такой программы, в кото- рой использованы переходы (вроде алгольных go to) — выполнение переходов не ведет к изменению значений переменных, ио их, конечно, нельзя игнорировать при доказательстве свойств программы. Эти осложнения были одной из причин развития в программировании направления, именуемого структурным программирова- нием, одним из принципов которого является отказ от использования переходов в программах. Доказано, что без переходов действительно можно обойтись, если в распоряжении имеются циклические и условные инструк- ции. С другой стороны, разработаны варианты метода промежуточных утверждений, позволяющие иметь дело с переходами. Анализ циклической инструкции ставит еще одну за- дачу— распознавание завершимости выполнения этой инструкции. До' сих пор мы считаем, что выполнение рас- сматриваемых программ заведомо завершается. Но в действительности выполнение циклических инструкций иногда не завершается, потому что для всех возникаю- щих значений переменных справедливы утверждения, за- писанные после пока. Если завершимость выполнения программы не исследована, то доказанное свойство про- граммы мало о чем говорит; вместо р в {«^0} пока п^О повторять (n;=n-j- 1) {р} (15) 92
можно подставить любое утверждение и получится не- которое свойство циклической инструкции. Это соответ- ствует определению свойства программы, в котором есть слова «в момент окончания выполнения программы»; если бы мы захотели показать, что при некотором ут- верждении (В свойство (15) не имеет места, мы должны были бы найти некоторое неотрицательное п, для кото- рого выполнение циклической инструкции завершается, и после завершения не справедливо р, но такого п мы найти не можем. Иногда для установления завершимости выполнения циклической инструкции достаточно рассмотреть харак- тер изменения значений какой-нибудь переменной. Ци- клическая инструкция, входящая в (13), выполнится в п этапов — это видно из рассмотрения изменения значе- ний переменной п. Циклическая инструкция, входящая в (14), выполнится в k этапов. Выполнение циклической инструкции, входящей в программу (1), завершится в п этапов. Но в более сложных программах значения переменных при выполнении могут изменяться немоно- тонно. Рассмотрим следующий пример: пока п> 1 повторять (16) (если п — четное, то (п :=п/2) иначе (п :—п -f- 1)) По ходу выполнения этой циклической инструкции зна- чение переменной п может и уменьшаться, и увеличи- ваться. Оказывается, что выполнение этой циклической инструкции завершается при любом целом значении п. Для доказательства завершимости выполнения в по- добных случаях рассматривают значения не какой-то отдельной переменной, а значения некоторой функции, зависящей от переменных. Теорема 6. Пусть целочисленная функция f, зави- сящая от некоторых переменных программы (12), удо- влетворяет следующим условиям: 1) ее значение поло- жительно, если относительно значений переменных спра- ведливо утверждение у; 2) она убывает при изменении значений переменных в результате выполнения Р. Тогда выполнение (12) завершается. Доказательство следует из того, что не существует бесконечной убывающей целочисленной последователь- ности с положительными элементами. Число этапов вы- полнения циклической инструкции не превзойдет значе- ния f от исходных значений переменных. 93
Подбор функции f, как и подбор инварианта, тре- бует изобретательности. Вернемся к программе (16). Функцию /(«) определим для всех п^1 следующим образом: __ ( 0, если n= 1, = | гаесли га>1. Проверим условия 1, 2, приведенные в теореме 6. 1) Если п > 1, то п— (—1)" п— 1 >0. 2) Рассмотрим раздельно случаи, когда га четно и когда нечетно. Первый случай. Если п > 2, то f(n/2)^ га/2 + 1 < f(n). Если п = 2 и| =1, то f(n/2) = t=O<Zf(n). Второй случай: /'(n) = n-f-l> f(n-[-\)=n. До сих пор не доказана и не опровергнута заверши- мость выполнения пока п > 1 повторять (если п — четное, то (п := га/2) иначе (п Зп -j-1)) для любого натурального п. Задачи 1. Пользуясь теоремами 1, 2, доказать следующее свойство: {с = a, d = Ь} е a-, a:=b; b := е {с = b, d = а}. 2. Пользуясь теоремами 1, 2, выяснить, для каких исходных значений а и b после выполнения программы а :—а — b\ b:—a~ b переменные а и b будут иметь равные значения. 3. Вывести необходимые и достаточные условия того, что имеет место свойство {ср} если р, то (Р){ф). 4. Пользуясь только теоремой 5, доказать, что при любом <р имеет место следующее свойство: {ф} пока р повторять (Р){р). j 5. Доказать, что выполнение циклической инструкции пока п > 1 повторять (если п — четное, то (п :=п/2 + 1) иначе (п := п + 1)) не завершается ни для какого натурального га >• I,
ЛИТЕРАТУРА ДЛЯ ДАЛЬНЕЙШЕГО ЧТЕНИЯ ' 1. Лавров С. С. Универсальный язык программирования. — М.5 Наука, 1972. (Полное изложение языка алгол 60.) 2. Пратт Т. Языки программирования: разработка и реализация,— Мир, 1979. (Обзор наиболее распространенных современных алгоритмических языков.) 3. Нивергельт Ю., Фаррар Дж., Рейнгольд Э. Машинный подход к решению математических задач.—М.: Мир, 1977. (Алго- ритмическая сторона различных математических задач.) 4. Ахо А., Хопкрофт Дж., Ульман Дж. Построение и анализ вычислительных алгоритмов. — М.: Мир, 1979. (Вопросы построе- ния экономических алгоритмов; математические методы анализа ал- горитмов.) 5. Журнал «Квант», начиная с № 9, 1979. (В № 9, 1979 г. открыт по- стоянный раздел «Искусство программирования».) 6. Ершов А. П. Введение в теоретическое программирование (бе- седы о методе).—М.: Наука, 1977. (Подробно рассматриваются две классические задачи теоретического программирования.) 7. В и р т Н. Систематическое программирование; введение. — М.: Мир, 1977. (Вводный курс программирования; значительное вни- мание уделяется доказательству правильности предлагаемых проч грамм.)
Сергей Александрович Абрамов ЭЛЕМЕНТЫ ПРОГРАММИРОВАНИЯ (Серия: «Популярные лекции по математике») Редакторы Н. Н. Васина, В. Д. Поддерюгин Технический редактор Е. В. Морозова Корректоры Т. С. Плетнева, II. Д. Дорохова И Б As 11993 Сдано з набор 22.04.81. Подписано к печати 25.01.82, Т-09328. Формат 84><108'Ы. Бумага тип. № i„ Литературнач гарнитура. Высокая печать. Усл. пэч. 5.04. Уч.-изД- 4.7. Тираж 200 000 экз. Заказ № 1178. Цена 15 коп. Издательство «Наука» Главная редакция фпзихо-математи юской литературы 117071, Москва, В-71, Ленинский проспект, 15 Ленинградская типография Аз 2 головное предпри- ятие ордена Трудового Красного Знамени Ленин- градского объединения «Техническая книга» им. Евгении Соколовой Союзполиграфпрома при Госу- дарственном комитете СССР по делам издательств, полиграфии и книжной торговли. 193352, г. Ленин- град, Л-52, Измайловский проспект, 29

ПОПУЛЯРНЫЕ ЛЕКЦИИ ПО МАТЕМАТИКЕ Вып. 1. А. И. Маркушевич. Возвратные последовательности. Вып. 2. И. П. Натансон. Простейшие задачи на максимум и минимум Вып. 3. И. С. Сомиискнй. Метод математической индукции. Вып. 4. А. И. Маркушевич. Замечательные кривые. Вып. 5. П. Л. Коровкин. Неравенства. Вып. 6. Н. Н. Воробьев. Числа Фибоначчи. Вып. 7. А. Г. Курош. Алгебраические уравнения произвольных степеней. Вып. 8. А. О. Гельфоид. Решение уравнений в целых числах. Вып. 9. А. И. Маркушевич. Площади и логарифмы. Вып. 10. А. С. Смогоржевский. Метод координат. Вып. 11. Я. С. Дубков. Ошибки в геометрических доказательствах. Вып. 12. И. П. Натансон. Суммирование бесконечно малых величин. Вып. 13. А. И. Маркушевич. Комплексные числа и конформные отобра- жения. Вып. 14. А. И. Фетисов. О доказательствах в геометрии. Вып. 15. И. Р. Шафаревич. О решении уравнений высших степеней. Вып. 16. В. Г. Шерватов. Гиперболические функции. Вып. 17. В. Г. Болтянский. Что такое дифференцирование? Вып. 18. Г. М. Мнракьян. Прямой круговой цилиндр. Вып. 19. Л. А. Люстеринк. Кратчайшие линии. Вып. 20. А. М. Лопшиц. Вычисление площадей ориентированных фигур Вып. 21. Л. И. Головина и И. М. Яглом. Индукция в геометрии. Вып. 22. В. Г. Болтянский. Равновеликие и равносоставленные фигуры Вып. 23. А. С. Смогоржевский. О геометрии Лобачевского. Вып. 24. Б. И. Аргунов и Л. А. Скорняков. Конфигурационные теоремы. Вып. 25. А. С. Смогоржевский. Лииейка в геометрических построениях. Вып. 26. Б. А. Трахтеиброт. Алгоритмы и машинное решение задач. Вып. 27. В. А. Успенский. Некоторые приложения механики к матема- тике. Вып. 28. Н. А. Архангельский и Б. И. Зайцев. Автоматические цифро- вые машины. Вып. 29. А„ И. Костове кий. Геометрические построения одним циркулем. Вып. 30. Г. Е. Шидрв. Как строить графики. Вып. 31. А. Г. Дорфман. Оптика конических сечений. Вып. 32. Е. С. Вентцель. Элементы теории игр. Вып. 33. А. С. Барсов. Что такое линейное программирование- Вып. 34. Б. Е. Маргулис. Системы линейных уравнений. Вып. 35. Н. Я. Вилеикин. Метод последовательных приближений. Вып. 36. В. Г. Болтянский. Огибающая. Вып. 37. Г. Е. Шилов. Простая гамма (устройство музыкальной шкалы). Вып. 38. Ю. А. Шрейдер. Что такое расстояние? Вып. 39. Н. Н. Воробьев. Признаки делимости. Вып. 40. С. В. Фомин. Системы счисления. Вып. 41. Б. Ю. Коган. Приложение механики к геометрии. Вып. 42. Ю. И. Любич и Л. А. Шор. Кинематический метод в геометри ческих задачах. Вып. 43. В. А. Успенский. Треугольник Паскаля. Вып. 44. И. Я. Бакельман. Инверсия. Вып. 45. И. М. Яглом. Необыкновенная алгебра. Вып. 46. И. М. Соболь. Метод Монте-Карло. Вып. 47. Л. А. Калужнин. Основная теорема арифметики. Вып. 48. А. С. Солодовников. Системы линейных неравенств. Вып. 49. Г. Е. Шилов. Математический анализ в области рациональных функций. Вып. 50. В. Г. Болтянский, И. Ц. Гохберг. Разбиение фигур иа меньшие части. Вып. 51. Н. М. Бескин. Изображения пространственных фигур. Вып. 52. Н. М. Бескин. Деление отрезка в данном отношении. Вып. 53. Б. А. Розенфельд и К. Д. Сергеева. Стереографическая проек- ция. Вып. 54. В. А. Успенский. Машина Поста. Вып. 55. Л. Беран. Упорядоченные множества. Вып. С. А. Абоамов. Элементы программирования. Вып. 57. В. А. Успенский. Теорема Гёделя о неполноте.