Текст
                    АЛГОЛ


А. Л. БРУДНО АЛГОЛ ИЗДАТЕЛЬСТВО «НАУКА» ГЛАВНАЯ РЕДАКЦИЯ ФИЗИКО-МАТЕМАТИЧЕСКОЙ ЛИТЕРАТУРЫ МОСКВА 1968
518 Б 89 УДК 519.95 Алгол. Б р у д н о А. Л. Книга посвящена изложению алгоритмическо¬ го языка алгол-(:0, который отличается удобст¬ вом, строгостью и обозримостью записанных па нем алгоритмов и программ. Знание алгола необ¬ ходимо всем лицам, занимающимся вычислитель¬ ной математикой и программированием. В этой книге автор изложил «Официальное сообщение об алголе» в форме, удобной для изу¬ чения и использования. Таблиц 4, иллюстраций 4, библиографических ссылок 8. 2-2-4 85-68
ОГЛАВЛЕНИЕ Предисловие . ■ . 5 Глава I. Элементарная часть алгола § I. Знаки и слова алгола 1 Алфавит. Числа. Идентификаторы. § 2. Описание синтаксических таблиц 17 § 3. Простейшие арифметические выражения 12 § 4. Простейшие операторы 15 Присваивания. Перехода. Простейшие булевские выражения. § 5. Условные выражения 21 Арифметические. Булевские. Именующие. § 6. Условные и составные операторы 25 Первая и вторая формы условного оператора. Составной опе¬ ратор. § 7. Переменная с индексами 27 § 8. Оператор цикла 29 Элементы арифметического типа. Типа прогрессии. Типа пере¬ счета. § 9. Стандартные функции. Ввод и вывод 34 Глава II. Описания 33 § 10. Описания переменных 36 Описание простой переменной. Описание массива. §11. Влияние описаний па выполнение операторов и структуру выражений 39 Присваивание. Арифметические и булевские выражения. Ввод и вывод массивов. § 12. Область действия описаний 41 Область действия описаний. Неявные описания меток. Собствен¬ ные величины. § 13. Переключатели 45
Глава III. Процедуры . 48 §14. Процедуры 48 Определение. Отыскание описаний. Образование и выполнение модифицированного тела. Процедуры без параметров. Функции. Рекурсии. Спецификации. Значения. Собственные переменные. Побочный эффект. Код. § 15. Пояснительный текст 62 Варианты запятой. Строки. Примечания. § 16. Подмножество алгола 66 Синтаксические таблицы 67 Литература 71
ПРЕДИСЛОВИЕ 0.1. Алгол отличается удобством, элементарностью, а главное обозримостью вычислительных программ и алго¬ ритмов. Его фундаментальные идеи, благодаря смелости решений, стали основополагающими для алгоритмических языков. Поэтому математику, в первую очередь програм¬ мисту, нужно знать алгол, независимо от собственных вкусов. Авторы алгола опубликовали свою работу в «Официаль¬ ном сообщении»*). Оно содержит целые страницы текста, который приобретает смысл только в конце. Это годится для транслятора, но игнорирует специфику человека, ибо человеку трудно заучивать бессмысленный текст. Есть и об¬ ратные примеры: правила расстановки скобок мы уже зна¬ ем, а для транслятора их приходится определять. В этой книге я попытался переписать «Официальное сообщение» в форме, рассчитанной на человека, а не на тран¬ слятор, и составил синтаксические таблицы. 0.2. До алгола были уже и программирующие программы и автоязыки. Но они давали как бы набор слов, поневоле слишком бедный, чтобы составить из него произвольную фразу. Алгол же дает как бы буквы, которыми можно на¬ писать почти любое слово. Другое выигрышное свойство алгола — в его естественности: не много нужно выучить, чтобы писать и читать на алголе. 0.3. Существуют, разумеется, программы, которые на алголе написать затруднительно. Происходит это не толь¬ ко потому, что алгол не рассматривает содержимое ячей¬ ки как информацию, записанную последовательностью ну¬ лей и единиц. Важнее здесь распределение памяти и взаимо¬ *) Список литературы см. в конце книги.
действие подпрограмм. В алголе легко сказать «запомни», но сложно говорить «забудь»: освобождать ячейки можно только в порядке, обратном тому, в котором они занимались. Сложно в алголе и осуществить засылку передачи управ¬ ления. Но алгол удобен для записи сложных алгорит¬ мов и эффективен для решения вычислительных задач, не слишком трудных для данной ма¬ шины. 0.4. Алгол демонстративно игнорирует специфику от¬ дельных цифровых электронных машин (ЦЭМ). Алголиче- ская программа вводится в любую ЦЭМ и транслятор — программа, построенная специально для данной ЦЭМ,— заставляет ЦЭМ, в конечном счете, выполнить алголиче- скую программу. Все же современные трансляторы обладают такими осо¬ бенностями, что для практической работы нужно просмот¬ реть руководство по данному транслятору. Эта книга не может заменить его. 0.5. Кроме «Официального сообщения» и книг П. Наура, Мак-Кракена, Боттенбруха, Лаврова и Агеева, из которых я заимствовал то, что нашел кратким и ясным, я пользовал¬ ся еще и толстыми руководствами, по которым видел, как не нужно писать. Перечислять их авторов было бы черной небл а года р ностью.
ГЛАВА I ЭЛЕМЕНТАРНАЯ ЧАСТЬ АЛГОЛА § 1. Знаки и слова алгола В алголе имеется твердый перечень знаков, которыми записывается программа. Каждому знаку должна соот¬ ветствовать клавиша вводного устройства *) (а их хочется иметь мало) и каждый знак должен восприниматься маши¬ ной и расшифровываться транслятором. Полный список знаков алгола приводится в табл. 4. При построении фраз одни знаки алгола играют роль букв нашего алфавита, другие — роль иероглифов, обо¬ значающих целые понятия, наконец, роль третьих (знаки арифметических действий, скобки и т. д.) нам представляется промежуточной. Собственно говоря, новыми для нас будут только иероглифы, ио их всего 20 и познакомимся мы с ними постепенно. Сперва займемся знаками, отнесенными к ал¬ фавиту. 1.1. Алфавит алгола содержит: цифры от 0 до 9; два булевских числа да и нет* **); ^большие и малые буквы латинского алфавита. Кроме того, в «Официальном сообщении» было преду¬ смотрено, что, например, русский вариант алгола может содержать русские буквы. Разработчики наших транс¬ ляторов ограничились малыми русскими буквами, имею¬ щими изображение, отличное от латинских. Таким образом, греческих, и готических букс в алголе нет. Все символы алгола пишутся в строку. Нельзя их под¬ черкивать или подчеркивать. Нельзя обычным образом ♦) Или последовательность клавиш, что несколько облегчает дело. •*) Числа да и нет являются самостоятельными знаками алгола, нс имеющими отношения к буквам, которыми они написаны. То же. будет относиться и к иероглифам. Все они, во избежание путаницы, печатаются полужирным шрифтам, а при письме — подчеркиваются. ?
писать степени и ставить индексы снизу или сверху. Пробел или переход на новую строку в алголе не принимается во внимание. Однако для облегчения чтения их можно сво¬ бодно использовать. Из знаков алфавита составляются числа и идентифика¬ торы, играющие роль слов алгола. 1.2. Числа в алголе бывают булевские (да и нет)*) и арифметические. Арифметические числа составляются из цифр. Арифметические числа бывают двух типов: целые и ре¬ альные **). Основное различие между ними в том, что целые числа будут изображаться (и, по возможности, преобразо¬ вываться) в машине точно, а реальные — лишь приближен¬ но. Таким образом, введя в машину реальное число три, мы обязаны считаться с тем, что фактически ввели число, быть может, чуть меньшее или большее тройки. 1.2.1. Целые числа изображаются, как обычно, строкой цифр. Впереди ставят знак -|- или — (+ не обяза¬ телен). Запрещается ставить запятые или точки (например, для отделения разрядов). Примеры записи целых чисел верно 0 6 +400 — 1234 1000 7000000 неверно 17.38 14.0 14,0 14. 1.000 123456789000 Последнее число может оказаться недопустимо велико; многие трансляторы требуют, чтобы целые числа \ имели меньше десяти знаков. 1.2.2. Реальные числа могут быть написаны в при¬ вычной форме, только целая часть от дробной отделяется в алголе не запятой, а точкой. Преимущество этого может оценить каждый, кому случалось писать перечень деся¬ тичных дробей. Запреицается ставить эту точку в конце *) В других руководствах по алголу булевские числа обозначают словами истина и ложь. **) По традиции в Москве их иногда называют действительными, а в Ленинграде — вещественными. 8
числа. Кроме того, реальное число можно записать умножен¬ ным на целую (обязательно ц е л у ю!) степень десяти. В этом случае число 10 пишется опущенным ниже строчки *), за ним следует показатель со знаком или без него. Сформулируем это точнее. Реальное число записывается строкой цифр со знаком впереди (+ не обязателен). Перед цифрами, или между ними, можно поставить точку, отде¬ ляющую целую часть от дробной. Вслед за этой строкой или без нее может идти опущенная десятка с целым показателем степени. Знак + перед показателем не обязателен. Примеры записи реальных чисел О1 2 3 4 —200.53 — .083ю-02 177 -|-О7.431о8 -107 .538 9.341О+Ю ю—4 —|—.0730 2,0—4 +ю+ 5 Таким образом, реальное число может, в частности, изо¬ бражаться в форме целого, но не наоборот. Например, О.32,о2 или 0.0 не могут изображать целых чисел. Контрольное упражнение. Половина ни¬ жеследующих примеров представляет запись реальных, чи¬ сел, а половина — не представляет. Какие записи верны? 1) —.008 2) 4-13.47io+18 3) 4хю2 4) (16.20) 5) -юЗ 6) 2ю3.0 7) -88,0-7 8) 1.24юЗ 9) 13.411732 10) 2.48,оп И) 0.0,01 12) 12.ю8 Ответ. Верны записи 1, 2, 7, 8, 9, 11. Упражнение. Напишите нижеследующие числа, не используя «опущенной десятки»: 1) +7.293ю8 3) ю+З 5) —10—6 2) 98.12ю+2 4) —.1834,0—5 6) —4.8,03 1.3. Идентификаторы. Из букв и цифр алгола можно составлять идентификаторы, которые служат для обозначения различных объектов — например для величин, нужных в программе. *) Опущенная десятка — не индекс, а самостоятельный знак алгола. у
Идентификатором может служить любая {не пустая) по¬ следовательность букв и цифр, начинающаяся о буквы. Примеры идентификаторов: Ах ВЗ a a\bc2c3dAe5 ЬЗ Alpha Moskwa diagonal Индексы, как нижние, так и верхние, запрещаются. Ограничений на длину идентификатора нет. Выбор идентификаторов находится полностью в руках программиста. Удобно выбирать идентификаторы, указы¬ вающие на смысл объекта. Например, для обозначения х в квадрате и pi для числа л. Заметим еще, что большие и малые оуквы — буквы раз¬ ные, так что А и a; Alpha и alpha или aLpha для алгола различны. Идентификатор ВЗ сам по себе не бу¬ дет восприниматься ни как В X 3, ни как В в кубе, ни как Вз5 Некоторые ограничения на выбор идентификаторов на¬ кладывают общепринятые обозначения стандартных функ¬ ций, например sin, с которыми мы встретимся далее. В математике величина, как правило, обозначается од¬ ной буквой. Но есть и исключения: sin Л, Г х, Гу, Ср, Cv. Обозначение sin л никто не воспринимает как произведение букв. В разложении гх, гу вектора г по координатным осям буква х не может принимать никаких значений. Таким об¬ разом, обозначения алгола — его идентификаторы, состоя¬ щие из нескольких букв и цифр — не так уж нам непри¬ вычны. Но, забегая вперед, заметим, что в алголе нельзя пропускать знак умножения. Действительно, запись ab будет восприниматься как обозначение нового объекта, от¬ личного от а или b и от их произведения а X Ь. Контрольное задание. Какие из нижесле¬ дующих записей могут служить идентификаторами? 1) 4.711 4) гамма 7) а + b 2) РРРЗ 5) начало счета 8) х (3) 3) ЗРРР 6) + epsilon 9) х [3] Ответ: 2, 4, 5. Пробел в записи (идентификатора 5) никакой роли в алголе не играет, 10
§ 2. Описание синтаксических таблиц То, что было описано в § 1 — это, к сожалению, почти все, что можно было описать, не излагая всей системы опре¬ делений алгола. Любое другое понятие алгола, во всей его общности, определяется только через все остальное. Это создает особые трудности как для изложения, так и для изу¬ чения алгола. Авторы алгола разделили его грамматику на синтаксис и семантику, т. е. на правила построения фраз и па описа¬ ние смысла фраз. 2.1. Сема нтика алгола описывается обычным об¬ разом, а для описания синтаксиса авторы алгола употребляют специальный язык Бэкуса. Проще всего объ¬ яснить этот язык на следующем примере. Понятие «иденти¬ фикатор», с которым мы познакомились в § 1, определяет¬ ся на языке Бэкусадак: (идентификатор) I <'буква) |(идептификатор><буква)|(идентификатор><цифра) Уголки < > сами по себе ничего не означают, в них заключаются отдельные понятия, чтобы избежать путаницы при слитном чтении. Уголки — не знаки алгола. Они ис¬ пользуются, чтобы писать про алгол, а не писать и а ал¬ голе. Стрелка *) читается ^<по определению есть». Тонкие черточки (в данном случае вертикальные) читаются «или». Все определение читается так: «Идентификатор по определению есть: или буква, или идентификатор (то есть то, что уже является (иден¬ тификатором)), вслед за которым написана буква, или (идентификатор), за которым написана цифра». Таким образом, определение Бэкуса, это — задание спо соба построения объекта. Мы видим, что (а) есть иденти' фикатор, ибо это буква; (сш> — тоже идентификатор, ибо это идентификатор <а), за которым написана буква <и). Строка <cz^2) — тоже идентификатор и т. д. В данном слу¬ чае легко сообразить, что (идентификатор) — это любая *) В языке Бэкуса стрелок нет и вместо них пишется знак : : —. Но в этой книге всюду пишутся стрелки. 11
строка букв и цифр, начинающаяся с буквы. Но не всегда определение Бэкуса так просто перевести, а главное понять. 2.2. Обозначения синтаксических таблиц. Рассмотрите первую (синтаксическую таблицу (только не пытайтесь пока ее разбирать). В ней при первом упоминании понятие пишется полностью, в дальнейшем— сокращенно, с точкой на конце или без точки. Например: ОПЕРАТОР или ОПЕР, или ОПЕР Кроме этого случая точки употребляются в таблицах толь¬ ко при перечислении (три точки) в смысле «и так далее». Например, запись переменная I простая -> идентификатор с индексом I (идент) [(арифметическое выражение),...,(ар. выр.)] означает: (переменная) по определению есть (простая) или (с индексом). В первом случае это (идентификатор). Во втором—это «идентификатор, за которым в квадрат¬ ных скобках написана строка арифметических выражений, разделенных запятыми»; упомянутая строка не может быть пустой; если она состоит из одного арифметического выра¬ жения, то запятых не будет. § 3. Простейшие арифметические выражения Выражение, грубо говоря,— это формула, по которой можно вычислить значение выражения (когда заданы зна¬ чения нужных переменных величин). Основные определения выражений находятся в табл. 2. Познакомьтесь с нею, не вникая в суть дела. Что такое (вы¬ ражение), мы узнаем позднее. Пока заметим, что выраже¬ ния бывают разных классов и характеров. Класс бывает арифметическим, булевским или именующим. Харак¬ тер — безусловным или условным. Чтобы условное выра¬ жение сделать безусловным, надо заключить его в скобки. 3.1. Согласно сказанному, арифметическое выражение бывает условным или безусловным. Условными мы зай¬ мемся позже. Теперь прочтите в табл. 2 определение (бе¬ зусловного арифметического выражения). Там встре¬ чаются два новых понятия: (арифметическая переменная) 12
и (арифметическая функция). Эти понятия определены в табл. 1 и 3. Однако понятие функции для нас еще слиш¬ ком сложно, а под (арифметической переменной) будем пока что понимать идентификатор (в дальнейшем это будет уточ¬ нено). Таким образом, для нас временно арифметическое вы¬ ражение будет иметь смысл, определяемый рис. 1. арифметическое выражение) (безусловное арифметическое выражение) Формула, построенная из: арифметических чисел арифметич. переменных —>идентификаторов безусл. арифм. выраж. круглых скобок и знаков арифметических действий X / -т- (разделить нацело)! (возвести в степень) два арифметических знака не должны стоять рядом Рис. 1/Временное определение арифметического выражения. 3.2. Простейшие арифметические выражения строятся как обычные алгебраические формулы из арифметических чисел и переменных с помощью знаков арифметических дей¬ ствий и круглых скобок. Запрещается употреблять иные знаки. Нельзя пропу¬ скать знак умножения или обозначать его точкой. Деление нельзя изображать двоеточием или дробью с горизонтальной чертой. Запрещается вместо круглых скобок писать квад¬ ратные или фигурные. Вычисления выполняются, вообще говоря, в порядке сле¬ дования, слева направо. Но нужно, как и обычно, учитывать скобки и старшинство действий. Младшие действия — это + , —; старшие X,/, н-; самое старшее f . Если подряд идут несколько действий одного старшинства, то выполня¬ ются они в порядке следования. Это правило будет уточнено в конце § 14.12. 3.3. Примеры арифметических выражений 16.48 fi Зю—5 а+ 2.83 — volt alb X с означает (alb) X с, но не a!(b X с) 13
Примеры обычной записи и записи на алголе величина верно неверно — аь — - a f b или — a f (&) (-a)t b сгь а\ — Ь аЪ+с а\(Ь + с) а] Ь + с 10-4.7 10 f (—4.7) ю-4.7 1Q4.7 10 j 4.7 104-7 или io4." А-В А X В АВ или А • В Л-(- В) Ах {—В} Ах—В аъС a t Ф | с) а | b | с (аъГ a f b | с или (a f ft) j с а \ Ь х с а-Ъ c-d а х b / (с х d) а х b/ex d а-104 а X ю4 Яю4 3.4. Действия + , —, X дают результат типа целый, к да оба аргумента — целого типа; в противном случае — ре¬ зультат будет иметь тип реальный. Деление /всегда дает ре¬ альный результат. Деление нацело (-—) определено только для целых аргументов и дает результат, равный целой ча¬ сти частного. Точнее: целой части а/b, когда (а//?)>0 —целой части | а/b |, когда (a/b) <Z О Сложнее обстоит дело с возведением в степень. Возве¬ дение в степень с показателем типа целый понимается как умножение соответствующего числа нужных сомножителей. Например, 2.75 f (— 3) = (1/2.75) X (1/2.75) X (1/2.75) Результат возведения в степень бывает целым только в случае целого основания и целого неотрицательного, по¬ казателя степени. Возведение отрицательного числа в ре¬ альную степень не определено. Неопределено и 0 f 0. 3.5. Остается указать на разницу между числом 314ю—2 и выражением 314 X 10 f (—2). Запись 314ю—2 указывает транслятору, чтобы он сделал нужные вычисления и в дальнейшем пользовался резуль¬ татом как готовым числом. В противоположность этому запись 314 х 101(—2) может побудить некоторые тран¬ 14
сляторы пересчитывать выражение заново всякий раз, как оно понадобится. Замечание. Обычно в алгебре принято пользовать¬ ся скобками разного вида: внутренние скобки зачастую пишут круглыми, внешние — квадратными, еще более внешние — фигурными и т. д. Но если в алгебраической формуле все скобки заменить на круглые, то можно заметить, что смысл выражения не пострадает. Таким образом, достаточно и одних круглых скобок (которые для этой цели приняты в алголе). Скоб¬ ки, разумеется, должны быть расставлены правильно — каждой открывающей должна соответствовать закрываю¬ щая и т. д. (нет нужды выписывать эти правила — они из¬ вестны из школы). § 4. Простейшие операторы Работа по программе алгола состоит в выполнении опе¬ раторов. Операторы бывают (см. табл. 1): безусловные, условные, цикла. Безусловный оператор, в свою очередь, бывает: основным, составным, блоком. Наконец, основной оператор бывает: пустым, присваивания, перехода и про¬ цедуры. Пустой оператор не вызывает действий и никак не обозначается. Полезность его выяснится в дальнейшем. Изучение операторов начнем с оператора присваивания. 4.1. Оператор присваивания в простейшем случае имеет вид переменная : == выражение и означает: вычислить выражение, стоящее справа, и полу ченное значение (число!) присвоить переменной, стоящей слева. Если выражение справа является числом, то, разу¬ меется, вычислять ничего не надо. Знак присваивания : = лучше всего понимать как «присвоить значение» или «в дальнейшем считать (таким-то) числом». Напомним, что для нас в настоящее время переменная —это идентификатор. Важный принцип алгола. Прежде чем двигаться дальше, отметим, что алгол — язык арифметики, а не алгебры: оператор : = присваивает переменной слева именно число, а никак не алгебраическое выражение, стоящее справа. В алголе нельзя «обозначить через х произведение перемен¬ ных а и &». Оператор х : — а х b 15
перемножит числовые значения а и & и присвоит букве х значение произведения. Если к моменту выполнения опера¬ тора переменные а или Ь не будут еще иметь численных зна¬ чений, то оператор присваивания не сможет выполниться. Вот несколько примеров присваивания: Обычно На алголе Р = с j Ъ~Х beta '• = +.’51х -х) /(С + D х х) Fy — 4k— kik2 Fy : = 4 X k— k\ X k2 Здесь идентификаторы переменных алгола выбраны так, чтобы они напоминали обычные обозначения. Но их, разу¬ меется, можно было взять любыми. Вот три неверные записи: —/п: = 3.14 2/1 : = Д;+ А а X х 2 b X х —с : = О Действительно слева должен находиться идентификатор переменной. Он должен начинаться с буквы (не может на¬ чинаться со знака минус или цифры). Не может он содер¬ жать и знаков арифметических действий, как в последнем примере. Эти утверждения, впрочем, забегают вперед, ибо мы еще не определили понятия переменной в общем случае. С помощью оператора присваивания можно задать зна¬ чение переменной, которая еще не имеет значения. Но мож¬ но и изменить значение переменной, которая уже имеет зна¬ чение. Например, k : = k—\ уменьшит значение k на единицу. Здесь хорошо видно отличие знака присваивания от знака равенства. С помощью оператора присваивания можно одно и то же значение присвоить нескольким переменным. Пи¬ шется это так: переменная : = пер : = ...: = пер : = выражение «Многократное» присваивание не эквивалентно тем же присваиваниям, выполненным поочередно. Именно — а : = 1; b : =[1; а : = b : = а + b присвоит переменным а и b одно и то же значение 2, в проти¬ воположность строке операторов а : = 1; b : = 1; а : = а + b; Ь : = а 4- Ь которая положит а : = 2, но b : = 3. 16
У п раж нения. Написать на алголе и = a-b + cd — (2х)3, I = h n2J 0 14]3, 2 = f = ~—x~w~- ' 3+^- + 5 н (Зл)2 Между символами алгола можно оставлять пробелы и писать их в разных строках, что никак не влияет на смысл написанного. Этим пользуются, чтобы человеку было легче прочесть программу. Но нельзя повторять знаки действий при переносе выражения в новую строку (как принято в ма¬ тематике). Вот удобное, неудобное и неверное решение по¬ следнего примера 1) - х/(1+х| 2/(3+;'(2 х х) f 2/ (5+ (3 XX) 1'2))); 2) /: = х/( 1 + 2/(3 +(2 X х) t 2/(5 + (3xx) ] 2))); 3) /:=х/(1+х|2/(3 + +’(2хх) j 2/(5 + (3хх) f 2))); Это замечание не мешает нам ставить, как обычно, лиш¬ ние скобки, которые помогают человеку читать формулу. Например, h \ = (а X х + и) + (& X у + у) + (с X z + w). 4.2. Метки и операторы перехода. Про¬ грамма алгола записывается последовательностью опера¬ торов, отделенных друг от друга'точкой с запятой (;). Обыч¬ но операторы выполняются в порядке следования слева направо. Чтобы изменить порядок выполнения операто¬ ров, употребляются, в частности, метки (см. табл 2) и опе¬ раторы перехода (см. табл . 1). Меткой может служить как идентификатор, так и целое число без знака. В последнем случае нули слева не считают¬ ся, т. е. метки 025 и 25 считаются одинаковыми. Перед любым оператором можно поставить метку. В этом случае говорят, что оператор помечен (помечен данной мет¬ кой). За меткой обязательно ставят двоеточие (:), отделя¬ ющее ее от оператора: метка: оператор 2 Л. Л. Брудно 17
Вот несколько примеров 7И : х : = х + 1; для малых t: s: = s i v X t; вариант 25: x : = х|2; у : = ^{2/2 Метка перед оператором никак не влияет на его выпол¬ нение. При выполнении программы она пропускается. Оператор перехода имеет вид иди (именующее выражение) где иди — иероглиф алгола, а под именующим выражением мы будем пока что понимать только метки. После опера¬ тора перехода будет выполняться оператор, помеченный данной меткой. Поэтому метку, написанную вслед за иди, называют меткой передатчиком, а метку, написанную перед оператором,— меткой приемником. Простейшим употреблением оператора перехода являет¬ ся возвращение машины к началу программы. Например, программа s : = 0; п •. = 1; М : s : = s + 1//гф 2; п : = п + 1; иди М будет вычислять бесконечную сумму s = 1/12 -j- 1/22 + ... Пустой оператор тоже может быть помечен, например, * 1 Так как помеченный оператор тоже является операто- ром, то и перед ним можно поставить метку. Впрочем, по¬ добная конструкция и : аЬ : для малых t : s : == k возникает редко. 4.3. Простейшие булевские выраже¬ ния. 4.3.1. Мы уже ввели два булевских числа да и нет. Др у* гим источником булевских чисел служат сравнения безу¬ словных арифметических выражений (см. табл. 2). Напри¬ мер. 5 )> 3; 7 х 3 | 2 ■= 3 + 5; х + а <2 3 х у Первое сравнение является числом да, второе — нет. Значение третьего сравнения зависит от текущих значений целых или реальных величин х, а, у. 18
Вообще говоря, конструкция У оезусловное х А арифметическое \ выражение ' / знак \ / \сравнения / \ безусловное \ арифметическое \ выражение ' определяет булевское число (да или нет). Знак сравнения — это один из 6 знаков <<=+>> 4.3.2. Простейшие булевские выражения строятся из булевских чисел и переменных с помощью круглых скобок и знаков булевских действий (см. табл. 2) подобно тому, как строились арифметические выражения. Знаков булевских действий в алголе пять: = => V А И Называются они так: совпадает, влечет, или, и, не. При¬ ведены они в порядке возрастания старшинства, которое нужно учитывать при определении порядка выполнения дей¬ ствий. Это правило будет уточнено в конце § 14.12. Значения булевских действий дает рис. 2. а да да нет нет Ъ да нет да нет а = Ь да нет нет Да ajb да нет да да a\Jb да да да нет a/\b да нет нет нет ~]а нет нет да Да Рис. 2. Мы установили строгий порядок старшинства булев¬ ских действий. Тем не менее читателю рекомендуется не жалеть скобок и не пользоваться знаками, к которым он не привык. Употребительных знаков всего три VA~"1 и остальные через них выражаются легко. Например, а ~ b 19
можно записать так: (аД6)7(ПаДДЬ). Скобок здесь можно было и не писать. 4.3.3. С помощью оператора присваивания можно при¬ своить значение булевского выражения одной или несколь¬ ким переменным переменная : = ... переменные : = булевское выра¬ жение. Правила при этом действуют те же, что и в случае ариф¬ метического выражения. Пример. Присвоить величине у значение да, если О < х < 1, и значение нет в противном случае. Решение. у: = 0 < х Д х < 1 Пр и м е р. Пусть х и у имеют булевские значения. Положить f равным да, если к и у совпадают или если они различны, но к равно да. В остальных случаях положить f равным нет. Приведем четыре решения: f- = = да); / : = (х = да) V (у = нет); f : = (х = у)\/ х; f- =х\/^\у. Упражнение. Найдите значение b в результате выполнения программы га : = 7.5;‘7л;.’= 5; rb : = Зхга— 2х ш; b : = rb^>ia /\ ia Д> га га: = (га — ia) — 1; b : = — ra'^>ia\y b; bb : = (b = rb > ia) Д га Д rb\ b : =: Д ф = bb) Решение. Напишите таблицу переменных и после каждого оператора заносите в нее новое значение вычислен- 20
ной переменной (см. рис. 3). Нужно приобрести навык в такого рода выполнениях программ на бумаге. га ia rb Ъ ЪЪ 1) 7.5 5 2) 12.5 3) нет 4) 4 5) нет 6) нет 7) нет Рис. 3. § 5. Условные выражения Найдите в табл. 2 определение условного выражения, а в табл. 1 — определение условия. Согласно этим опре¬ делениям условное выражение любого класса (арифметиче¬ ского, булевского или именующего) задается конструкцией / булевское \ / безусловное . если Хвыоажепие/ т0 \ вожение \ х 1 хлюоого классал иначе /Выражение^ этого же \ \ класса ' Здесь если, то и иначе — иероглифы алгола. Заметьте, что после то идет обязательно безусловное выражение. Запом¬ ните, что в алголе запрещено писать подряд то если. Если выражение, написанное между если и то, имеет зна¬ чение да (нет), то условное выражение заменяется выраже¬ нием, написанным между то и иначе (соответственно: заме¬ няется выражением, написанным после иначе). Условные выражения могут «вставляться» друг в друга, ибо между если и то, а также после иначе могут опять идти условные выражения. 21
Что делать, если по самому смыслу задачи выражение, идущее после то, является условным ? Надо взять его в круглые скобки —от этого оно станет безуслов¬ ным! Теперь рассмотрим по отдельности арифметические, бу¬ левские и именующие условные выражения. 5.1ЯУ с л о в н о е арифметическое выраже¬ ние. Пусть выражение должно, равняться 0, если b имеет значение да, и единице, если Ь имеет значение нет. Это выражение можно записать так: если b то 0 иначе 1 Также легко написать выражение, равное 3 при х<5 и равное 7 при х 5: если % < 5 то 3 иначе 7 В правой части оператора присваивания (см. табл. 1) стоит числовое (т. е. арифметическое или булевское) выра¬ жение. До сих пор мы могли справа писать только безуслов¬ ные выражения. Теперь наши возможности расширились. Пусть х и у имеют арифметические значения и нужно положить z = /гах (х, у). Это можно сделать оператором 2 : = если х > у то х иначе у Прочтите еще раз определение безусловного ариф¬ метического выражения на табл. 2 и ответьте на Контрольный вопрос. Допустимо ли ариф¬ метическое выражение а + если х у то х иначе у Ответ: недопустимо. В арифметическом выражении слагаемым может быть только безусловное выражение, Необходимо было писать скобки а + (если х > у то х иначе у) Контрольный вопрос. Чему равно выражение если 5 j> 3 то 0 иначе 1 + 3 Ответ: нулю. Действительно, это выражение расшиф¬ ровывается только так: если 5Д>3 то 0 иначе (1 + 3) Если бы мы хотели написать (если 5>3 то 0 иначе 1) + 3 го необходимо было писать скобки. 22
Задача. Задать у условиями при х < 1 у ~ max (а, х) при х > 1 у = 1 Решен и е можно записать так: у: = если х<1 то (если «>х то а иначе х) иначе 1 и скобки в этом выражении опустить нельзя. 5.2. Аналогичным образом пользуются и у с л о в- н ы м и булевскими выражениями. Только сами выражения могут выглядеть запутаннее. Рассмотрим несколько примеров. Пусть •х: = если k<Z \ то s"^>w иначе //<. с Найдите значение х в следующих трех случаях (см. рис. 4). k s W h с ! X 1 -1 2 2 3 пет 2 2 2 2 4 3 нет 3 1 4 5 2 2 да Рис. 4. Ответы помещены в колонке х. Найдите значение у после выполнения оператора: у: = если 3 < 5 то да иначе да Д нет Ответ: у принимает значение да. Наш оператор эк¬ вивалентен записи у : = если 3 < 5 то да иначе (да Д нет) но не записи у: = (если 3<5 то да иначе да) Д нет ибо знаки логических действий (подобно арифметическим знакам) ставятся лишь между безусловными выражениями. Рассмотрим более сложное выражение если если а то b иначе если с то d иначе е то да иначе если f то нет иначе да где переменные от а до f принимают булевские значения. Для расшифровки такого выражения нужно выделить груп¬ пу идущих подряд если то иначе, за которыми стоят безус¬ 23
ловные выражения. Эту группу надо заключить в скобки и снова искать такую группу. В нашем примере сперва найдутся группы если с то d иначе е если f то нет иначе да и выражение примет вид если если а то b иначе (если с то d иначе с) то да иначе (если f то нет иначе да) Теперь можно выделить группу если а то Ь иначе (если с то d иначе с) Выражение примет вид если (если а то b иначе (если с то d иначе г)) то да иначе (если f то нег иначе да) Можно его переписать и так: если А1 то да иначе Л 2 где, в свою очередь, Л1 есть если а то b иначе ЛЗ ЛЗ есть если с то d иначе е А2 есть если f то нет иначе да 5.3. Условные именующие выражения. Пусть на некотором этапе решение задачи раздваивается. При х 0.05 нужно закончить вычисления с помощью одного оператора, а при больших — с помощью другого. Пусть эти операторы помечены метками L и М, Тогда такое раздвоение можно осуществить с помощью условного именующего выражения, написанного за оператором иди иди если 0.05 то L иначе М 5.4. Приведем несколько распространенных примеров трудночитаемых выражений. Следует все же предупредить читателя, что с помощью скобок их можно было написать гораздо яснее. Сделайте это сами. Арифметические выражения 1) если 5 7 = 7 + 5 то 5 + 7 иначе если 3 > 2 то 3 + 2 иначе 1 + 2 2) если q > 0 то s + 3 х q[a иначе 2 х s + 3 X q 3) если а > 0 то и + v иначе если а х 6 > 17 то ufv иначе если k у то v}u иначе 0 24
Булевские выражения 4) если если если а то Ь иначе с то d иначе f то q иначе h <4 k Ответы: 1) если (5 < 7 = 7 > 5) то (5 + 7) иначе (если (3/>2) то (3+2) иначе (1 + 2)) Отсюда видно, что выражение равно 12 2) если (7 > 0) то (s 4- 3 X q/a) иначе (2 х s + 3 х q) 3) если •(+>()) то (^+f) иначе (если (ах£4>17) то (a/vY) иначе (если k =f= у то (t>+) иначе 0) 4) если (если (если а то b иначе с) то d иначе/) то q иначе (/z <4 k) 5) q ЕЕ (((Г» Л б/\Пс)) => СИ/)) § 6. Условные и составные операторы Прочтите определение условного оператора в табл. 1, опустив конструкцию с оператором цикла. Таким образом, условный оператор пока что может иметь две формы. 6.1. Первая форма условного опера¬ тора: если /булевское \ т0 /безусловпыйХ Двыраженпе/ \ оператор / или короче если В то Р Действует этот оператор так: если В имеет значение да, то Р выполняется, а если нет, то Р пропускается. После этого выполняется оператор, написанный вслед за Р (если, разумеется, при выполнении оператора Р не произойдет отсылка к какому-либо иному оператору). Поясним это двумя примерами. Рассмотрим если В то х : = a; Q При В, равном да, произойдет, а при В, равном нет, будет пропущено присваивание х : = а, после чего в обоих слу¬ чаях будет выполняться оператор Q. В операторе если В то иди Л4; Q при В^нет будет выполняться Q, а при В^.да выполнится оператор иди М 25
программа перейдет к оператору с меткой Л4 и, может быть, никогда не вернется к оператору Q. Упражнение. Положить х шах (а, Ь) Решение. х : = а\ если b а то х : == b Неверно было бы писать решение так: если b > а то х : = Ь; х : а 6.2. Вторая форма условного опера- т о р а имеет вид если В то Р иначе Q Здесь В — булевское выражение, Р — безусловный опе¬ ратор, Q —любой оператор (в том числе и условный). Действует этот оператор так. При В=Еда выполняется Р, а при В=нет выполняется Q. После этого выполняется оператор, написанный вслед за Q (если, разумеется, сам выполненный оператор не содержал отсылки). Пример. Положить х -■= max (а, Ь). Решение. если b а то х : = b иначе х : ~ а 6.3. Составной оператор. В условном опе¬ раторе если В то Р при В=~нет пропускается ровно один оператор, следующий за то. Как быть, если нужно пропустить несколько опера¬ торов? Для этого их нужно объединить в один составной оператор с помощью операторных скобок на¬ чало и конец. Пусть, например, при с <С 0 нужно положить х : = 0; у := с, а при с >0 надо положить х : = 1; у : = — с. Сделать это можно так: х : ~ 0; у : — с; если с > 0 то начало х : = 1; у : =— с конец Или, используя вторую форму условного оператора, если с <Г 0 то начало х : = 0; у : с конец иначе начало х : — 1; у : = — с конец Между оператором и скобкой конец можно не ставить точку с запятой (;). Замечание. Операторные скобки начало коней имеют смысл индивидуальных знаков алгола, не имеющих отношения к буквам, которыми мы их пишем. В этой книжке 26
наравне со скобками начало конец будут употребляться фигурные скобки ( }. Если составной оператор не велик (умещается на одной строке), то мы его будем заключать в операторные скобки { }. Если же он не помещается в одной строке, то будем писать скобки начало конец. При этом удобно писать соот¬ ветствующие пары начало и конец друг под другом, сдви¬ гаясь вправо по мере перехода к внутренним скобкам. Пример ы. 1) х : = 0; у : ~ с; если с > 0 то начало ы = 1; у : = — х конец 2) х : = 0; у : = с; если с > 0 то Iх : '== I; у : — с} 3) если В1 то начало если /32 то начало Pl; Р2; если S3 то {РЗ; с : 0} иначе Р4 конец конец Здесь В1 —S3 — булевские переменные, а Р\ —Р4 — операторы. § 7. Переменная с индексами В математике часто употребляются переменные с индек¬ сами, например щ, czz, а,,/ ,... В алголе буквально так на¬ писать нельзя. В алголе список индексов заключается в квад¬ ратные скобки и индексы отделяются друг от друга запя¬ тыми'. а [4], а [/], a [f, 7.1. -Прочтите определение переменной в табл. 1, обратив внимание на определение переменной (с индексами). Перечитайте определения безусловных арифметических и булевских выражений в табл. 2, понимая под (арифметиче¬ скими переменными) и (булевскими переменными) пока что (переменные). Согласно этим определениям безусловные выражения могут строиться не только из простых переменных, но и из переменных с индексами. Кроме того, из определений вид¬ но, что индексом может служить не только число или про¬ стая переменная, но и любое арифметическое выражение, в частности снова переменная с индексами. 27
Вот несколько примеров переменных с индексами: обычно &17 на алголе а [17] j Л ая+1, ik а [2 х 1, /[/г]] Но на алголе индексы могут иметь и более сложный вид a[i/k, если и )> Т то 5.2 иначе j [/]] В тот момент, когда потребуется вычислить фактическое значение индекса, он будет вычислен по обычным правилам и затем округлен до ближайшего целого *). 7.2. В связи со сделанными обобщениями понятия пе¬ ременной оператор присваивания может оказаться недо¬ определенным. Действительно, выполним строку операто¬ ров /е: = 2; a [k + 1 ] : = k : - k -|- 2 (*) В результате k станет равно 4, но какой переменной: а [31 или а [51 нужно присвоить значение 4? Это не ясно. При выполнении оператора присваивания в алголе полагается сперва вычислить индексные выражения у переменных, которым присваивается значение, а затем выполнять при¬ сваивание. Тогда (*) даст k : = 4; а [31 : =4. При дальнейшем расширении понятия выражения (за счет привлечения (функций) и вызываемого ими побочного эффекта) и это доопределение может иногда оказаться не однозначным. Поэтому сразу же приведем окончательное определение. Оператор присваивания а : = = и : = А (где а,..., и — переменные, а А — выражение) выполняет¬ ся в три приема: (1) все индексные выражения, встречающиеся у пере¬ менных а,..., и, вычисляются в порядке следования (слева направо); (2) вычисляется выражение А; (3) полученное значение А присваивается переменным а, ..., и с теми значениями индексов, которые вычислены на шаге (1). *) В отличие от деления нацело -н, где берется целая часть, а не ближайшее целое. 28
§ 8. Оператор цикла Оператор цикла, пожалуй, самая изящная конструкция алгола. Прочтите его определение в табл. 1: для х : =а, (3,..., v цикл Р Здесь для и цикл — иероглифы; х — переменная (простая или с индексами), которую называют параметром цикла; сс, р,... — элементы цикла; Р — оператор. Оператор цикла заставляет выполниться оператор Р нуль или более раз для каждого элемента цик¬ ла, в порядке следования этих элементов. При этом все время может происходить изменение параметра х. Как это делается, определяется типом элемента цикла. Элементы цикла бывают трех типов (см. табл. 1) — они называются арифметическим, прогрессии и пересчета и имеют вид 1) А 2) А шаг D до В 3) А пока V где Л, Z), В — арифметические выражения, а V — булев¬ ское. Эти типы могут идти в списке а, р,... вперемежку, в любом порядке. Знаки шаг, до, пока — иероглифы алгола. 8.1. Короче всего определить оператор цикла, заменив его набором уже известных операторов, по следующему правилу: 1) Вместо каждого арифметического элемента написать оператор (с соответствующим выражением Л) х : = Л; Р; 2) Вместо элемента прогрессии написать оператор х: = А; М\ если sign (В — х) X D > 0 то {Р; х : = х + D; иди М}\ *) 3) Вместо элемента пересчета написать оператор М: х: = А; если V то {Р; иди М}; где Л, B,D, V — выражения из соответствующих элементов цикла. К этому нужно только добавить, что по исчерпании ссех элементов цикла значение параметров цикла считает- вя неопределенным. *) sign, т. е. знак, определяется так: sign (х) = 1, 0, —1 при х>0, х _ 0, х < 0 соответственно. В алголе принято условие sign (В — х)Х X D 0 вместо (В — х) X D 0, потому что при малых (В — х) и D произведение (В — х) X D может обратиться в нуль с точностью сче¬ та машины. Впрочем, на некоторых машинах по этой же причине может обратиться в нуль и разность В — х. 29
Так, например, оператор цикла для х: = А1, Л2, ЛЗшаг А4 доЛ5, А6 пока В1, А1 шаг Л8 до А9, А10 цикл Р где А1 —А10—арифметические выражения, В1—булевское, заменяется последовательностью операторов (где х, А1 — ЛЮ, В1 и Р заменены соответствующими переменными, выражениями и операторами, написанными на алголе): х : = Al; Р; х : = А2; Р; х : = АЗ; Ml: = если sign (А5 — х) X А4 >> 0 то {Р; х: х + А4; иди М1}; х : = Л6; Л42: если В1 то {Р; иди М2}; х : = А1; М3: если sign (ЛЮ — х) X Л8>0 то {Р; х : = х + Л8; иди /ИЗ}; х : = ЛЮ; Р; значение х не сохраняется; Если определение 8.1 показалось Вам недостаточно яс¬ ным, вернитесь к нему после 8.2—8.4. 8.2. Для каждого элемента арифметического типа оператор Р выполняется один раз. Переменной х присваивается значение арифметического выражения Л, после чего выполняется оператор. На этом элемент считает¬ ся выполненным. Это можно описать так: х : Л; Р; Вот пример цикла, состоящего из элементов арифмети¬ ческого типа, для х : = 2.5, 1.1 + 0.9, 2 X х + 0.5 цикл у : ~ х|2 Оператор у : = х|2 будет выполняться три раза: для х = 2.5, для х = 1.1 + 0.9 = 2 и для х = 2 X х + 0.5 = 4.5. Легко может случиться, что выполнятся не все элемен¬ ты цикла, а оператор цикла прекратит работу. Например, для х: = 1, 2, 3 цикл {у : = х]2; если х Д> 1 иди М[ Здесь выполнятся только два элемента. При выполнении второго элемента программа уйдет на метку М. 8.3. Элемент типа прогрессии вызывает не¬ сколько (в том числе и ни одного) выполнений оператора Р. Работу по выполнению этого элемента приблизительно можно описать так. Сперва переменной х присваивается значение выражения Л и выполняется оператор Р: х : — Л; Р Затем значение х увеличивается на величину D и опять вы¬ полняется оператор Р: х : = х -г D; Р Снова х увеличивается на D и опять выполняется Р. И так до тех пор, пока значение х не выйдет за границу значения зо
В. Таким образом, оператор Р будет выполнен для х пробе¬ гающего значения от Л до В с шагом D. Нужно только иметь в виду, что значения шага D и границы В вычисляются на¬ ново перед каждым увеличением х и проверкой окончания (на случай, если они изменились при выполнении операто¬ ра Р или при вычислении!) и В) и что х сразу же может оказаться вне границ А, В. Рассмотрим несколько примеров. Сложить два вектора: с [Z] : = а [£] + b [Z] для i от 1 до 5:. для i : = 1 шаг 1 до 5 цикл с [i] : = a [Z] + b [£] Сосчитать сумму квадратов нечетных чисел от 3 до 15: s : = 0; для i : = 3 шаг 2 до 15 цикл s : = s + Z | 2 Сосчитать ту же сумму в обратном порядке: s : = 0; для i : = 15 шаг — 2 до 3 цикл s : = s + i f 2 Последние два примера показывают, что надо уточнить фразу «пока параметр цикла не перейдет границу значе¬ ния В». В алголе элемент типа прогрессий для х : = ... А шаг D до В... цикл Р выполняется до тех пор, пока разность В — х имеет тот же знак, что и шаг D (включая случаи, когда В —х или D рав¬ но нулю). Контрольный вопрос. Сколько раз выпол¬ нится оператор Р в операторах 1) для i : = 5 шаг — 1 до 6 цикл Р 2) для i : = 5 шаг 1 до 5 цикл Р Ответы: нуль и один (в предположении, что сам опе¬ ратор Р не меняет значения Z). В элементе типа прогрессии шаг и граница могут быть и не целыми числами. Могут они быть и переменными. На¬ пример, оператор s : =0; для i : = 1 шаг i до 64 цикл s : = s + i сосчитает сумму s = 1 +2 + 4+ ... + 64. Контрольный вопрос. Сколько раз выпол¬ нится оператор Р в цикле для i : = 1 шаг 3—2 X i до 5 цикл Р Ответ: один раз. Действительно, на второй раз будет i = 2 и шаг 3—21 = — 1 получит знак, обратный знаку разности 5 — i = 3, так что оператор Р выполняться не будет. При выполнении оператора цикла циклически выпол¬ няется ровно один оператор, написанный вслед за иеро¬ глифом цикл. Если нужно, чтобы выполнялось несколько 31
операторов, то их объединяют в один составной оператор с помощью операторных скобок начало конец. Задача. Перемножить две квадратные матрицы а Н, k\, b [Z, k] порядка /г, т. е. вычислить с['. k\ : = 2 а'':> /1 >< ЬИ, /г1 /=1 Решение. для i : = 1 шаг 1 до п цикл для k : = 1 шаг 1 до п цикл начало с U, k] : = 0; для j : = 1 шаг 1 до п цикл с [Z, k] : = с [f, k] + a [f, j] X b [/, /г] конец 8.4. Элемент типа пересчета х : = ... А пока V ... цикл Р полагает переменную х равной значению выражения А и вы¬ полняет оператор Р. Затем снова полагает х равной значе¬ нию А и опять выполняет Р. И так до тех пор, пока V име¬ ет значение да. В частности, V может сразу принять значе¬ ние нет и тогда оператор Р не выполнится ни разу. Примеры. 1) Сосчитать s = 22 + 42 + ... + 102 s : = i : = 0; для i : = i + 2 пока i 10 цикл s : = s + Р[2 2) Для извлечения квадратного корня у = ]/х часто пользуются алгоритмом Герона: г/1 = Ц25; Уп+1 = + / 2 Сделайте программу, продолжающую вычисления до до¬ стижения точности *|<е- Решение. у : = 1; для г : = у пока у\2 —х ^>eps\/ х — у] 2 ;> eps цикл у : = (х/у + у)/2 Любопытно, что неверно решение: для у : = 1, у пока у |2 — х > eps\/x — y | 2 > eps цикл у : = (х/у + у)/2 Действительно, по окончании работы оператора цикла пара¬ метр у станет неопределенным. 32
8.5. Несколько примеров. Требуется выпол. нить оператор Р для всех х — 0,0.1, ..., 1, кроме х= 0.3- Предостережем от неверного решения для х : — 0 шаг 0.1 до 1 цикл если х=£= 0.3 то Р Действительно, реальное число 0.1 записано приблизи¬ тельно. Поэтому мало надежды, что на четвертом цикле х будет точно равно 0.3. Да и на одиннадцатом цикле может оказаться х > 1. Верное решение будет, например, таким: для у : = 0 шаг 1 до 10 цикл если у =f= 3 то {х : = £//10; Р} Выражения в элементах цикла могут быть и условными. Пусть оператор Р надо выполнить для х, изменяющегося от 0 до 10 через 1, а от 10 до 100 через 5. Решение для х : = 0 шаг если х <С 10 то 1 иначе 5 до 100 цикл Р Возможны и другие решения: 1) для х : = 0 шаг 1 до 10,15 шаг 5 до 100 цикл Р 2) для х : = 0, х + 1 пока х <Z 10,10 шаг 5 до 100 цикл Р 3) для х : = 0, х + 1 пока х 10,15 шаг 5 до 100 цикл Р Но неверны решения: 4) для х : = 0, шаг 1 до 10, х + 5 пока х 100 цикл Р 5) для х : — 0 шаг 1 до 9, х + 5 пока х 100 цикл Р ибо в случае 4) оператор Р будет выполнен для х = 0,1‘,..., 10, 16,‘21, ..., 96 а в случае 5) — для х = 0,1,..., 9, 15, 20, ..., 100 Происходит это потому, что согласно 8.1 элемент цикла типа прогрессии для х : = ... A rnarD пока В ... цикл Р меняет параметр х вплоть до первого значения, вышедшего за границу В. Таким этот параметр и достается следую¬ щему элементу цикла. Это же обстоятельство надо учиты¬ вать и для элементов типа пересчета. Но и оператор цикла может входить в условный опера¬ тор (см. определение оператора (условный) в табл. 1). За¬ метьте, что оператор цикла не может находиться между то и иначе. Если это потребуется, то оператор цикла придется взять в операторные скобки { }. От этого он станет состав¬ ным оператором и, следовательно, безусловным (см. табл. 1). 3 А. Л. Трудно 33
§ 9. Стандартные функции. Ввод и ВЫВОД ' 9.1. В алголе имеются следующие стандартные функции (Л — арифметическое выражение): abs (Л) — абсолютное значение А sign (А) — знак А, равный соответственно + 1,0,— 1 для Л > 0, Л = 0, Л < 0 sqrt (Л) — квадратный корень из Л sin (Л) — синус, аргумент в радианах cos (Л) — косинус, аргумент в радианах arctan (Л) — главное значение (от — л/2 до + nz2) In (Л) — натуральный логарифм ехр (Л) — экспонента, т. е. еА entier (Л) — целая часть Л (читается — антье)— наи¬ большее целое, не превышающее значения Л Функции sign (Л) и entier (Л) дают ответ типа целый, остальные — типа реальный. Аргумент функции нужно обязательно заключать в скобки. Нужно, например, писать sin (х), ибо запись sinx воспринимается алголом не как функция, а как иден¬ тификатор. Контрольный вопрос. Чему равно entier (2.0) Ответ: не ясно. Число 2.0 — число реальное, в ма¬ шине записано приблизительно. Поэтому entier (2.0) мо¬ жет оказаться 1 или 2, в зависимости от машины и трансля¬ тора. Стандартные функции могут использоваться в арифме¬ тических выражениях (как (арифметические функции)— см. табл. 2). Тем самым мы еще раз расширяем понятия (выражения). Вот примеры, содержащие стандартные функции: а : = sin (3.14/4); fi : = arctan (у/х [5]) если abs (х — у) <( eps то иди М ехр (если х <) у то х иначе у) Аргументы функций являются выражениями и, следо¬ вательно, могут снова содержать стандартные функции. Например, а : sin (а + b cos (у/х))
Если одна и та же функция встречается несколько раз, на¬ пример, а : = (а X sin (х) + b)/(c X sin (х) t 2 -г d) то для ускорения счета лучше вычислить ее однажды и за¬ помнить: sin х: = sin (х); а : = (а X sin х + b)/(c X sinx\2 -L d) Обратите внимание на разницу между идентификатором sin х и функцией sin (х). 9.2. Процедуры для ввода и вывода в алголе не были определены, так как они слишком связа¬ ны с составом оборудования конкретной машины (по мне¬ нию авторов алгола). Потом эти процедуры дорабаты¬ вались. И прежде чем пользоваться ими практически, необходимо прочесть описание транслятора, с которым придется работать. В этой книге мы ограничимся процедурами ввода — вы¬ вода, широко бытующими в учебной литературе, но недо¬ статочными для практической работы: ввод (х, у, г); вывод (а, Ь, ..., с) Будем пока что считать х, у, ... переменными (простыми или с индексами); а, Ь, ... — числовыми (т. е. арифметическими или булевскими) выражениями. Предполагается, что про¬ цедура ввода введет с перфоленты нужное количество оче¬ редных чисел и присвоит их значения переменным х, у, ...; процедура вывода вычислит значения выражений а, Ь, ... и отпечатает эти значения подряд на бумаге. Примеры использования ввода — вы¬ вода 1) ввод (а, й, с) 2) k : = 3; ввод (а, b [й], с [5]) 3) для k : = 3 шаг 1 до 7 цикл ввод (а [й]) 4) вывод (1.7ю —2) 5) й : = 3; а [й] : = 3.14/й; вывод (йф2 X sin (а [й]/7.1)) Программа 3 введет с перфоленты 5 очередных чисел и присвоит их значения переменным а [3], ..., а [7].
ГЛАВА II ОПИСАНИЯ §10. Описания переменных Программы, которые мы до сих пор писали, не являются на самом деле программами алгола. Это были всего лишь части программ. В действительности в алголе все иденти¬ фикаторы должны быть описаны. И ни один идентификатор не может описываться более одного раза в начале данного блока. Только в трех случаях идентификаторы не нуждаются в описаниях: 1) идентификаторы стандартных функций {sin, cos, ...) и процедур ввода — вывода не описываются. Ими можно пользоваться всюду; 2) метка не имеет явного описания; 3) не описываются формальные параметры в описаниях процедур. С этими случаями мы встретимся в дальнейшем. Познакомьтесь с определением блока в табл. 1. Заметьте, что в начале блока идут (описания), разделенные точкой с запятой (;). 10.1. Прочтите (описание простой переменной), в табл. 3. Начало блока с этими описаниями может, например, выгля¬ деть так: 1) {целый i', ... 2) {целые i, j, k; реальное напряжение, х; ... Иероглифы целый, реальный, булевский пишут в любом роде и числе (целый, целое, целая, целые и т. д.) —воспри¬ нимаются они все равно одинаково. Порядок описаний про¬ изволен. После иероглифа можно перечислить все простые переменные этого типа. Но можно и повторить иероглиф. Равносильны описания: 1) {целые i, j, k; булевский ьперед; ... 2) {целый i; целые /, k; булевский вперед; ... 3) [целый z, /; булевский вперед; целый k; ... 36
Пусть, для примера, нужн® вычислить и отпечатать а= 1 4--1/2 + h 1/Ю. Раньше мы сделали бы это так: а : = 0; для k : = 1 шаг 1 до 10 цикл а: = а + 1/А; вывод (а) Теперь мы видим, что идентификаторы а и k должны быть описаны и что программу нужно оформить в виде блока: начало реальный а; целый k; а : = 0; для k.: = 1 шаг 1 до 10 цикл а : = а + 1/&; вывод (а) конец Описания указывают транслятору, что после входа в блок через начало и до выхода из блока он должен резер¬ вировать ячейки для запоминания определенных величин. Попутно они дают ему и другие сведения, вытекающие из характера описаний (целый, булевский,...). После выхода из блока все эти ячейки (вообще говоря) освобождаются, а величины — исчезают. Выход из блока может произойти либо через его конец, либо с помощью оператора перехода. 10.2. Описание массива. Если у нас есть три (простые переменные) х, у, г, то нужно описать все три идентификатора: х, у, г. Но если мы пользуемся тремя ре¬ альными (переменными с индексами) х[1], х [2], х [3], с общим идентификатором, то они образуют массив и только один идентификатор — идентификатор массива — нуж¬ дается в описании. В описании массива (см. табл. 3) указывается тип пере¬ менной и границы значений его индексов. В нашем случае описание массива может выглядеть так: {реальный массив х [1 : 3],... Впрочем, иероглиф реальный перед массив можно опустить. Если переменная имеет несколько индексов, то в описа¬ нии будет несколько граничных пар. Массив целых чисел п [/, k\t где j меняется от —3 до 17, а А* от 6 до 8, описывает¬ ся так: {целый массив п 1— 3: 17, 6 : 81; ... Граничные пары — не обязательно целые числа. Они могут быть любыми арифметическими выражениями. Надо только иметь в виду следующие обстоятельства: (1) При входе в блок программа должна фактически вычислить значения граничных пар. Поэтому переменные, встречающиеся
в граничных парах, должны к этому моменту иметь значе¬ ния*). (2) После соответствующих вычислений полученные значения граничных пар будут округлены до ближайшего целого. (3) Левая граница пары не должна быть больше правой — иначе соответствующий индекс не сможет при¬ нимать никаких значений. Приведем заведомо экзотическое описание начало реальный а; а : = 3.14/2 X 0.8; {массив и [sin (а) :2 X sin (а) / cos (а)]; Несколько массивов можно описать совместно, если они имеют одинаковый тип. Например, описание 1) целый массив i [— 5 : 15], I [3 : 17,6 : 8] равносильно строке описаний 2) целый массив i [—5 : 15]; целый массив I [3 : 17,6 : 8]; Заметьте, что в первом случае массивы разделяются за¬ пятой (а не точкой с запятой). Если при этом несколько (идущих подряд) массивов имеют одинаковые границы ин¬ дексов, то граничные пары можно указывать однажды — за последним из них. Например, описание массив i [— 5 : 15], k, I [3 : 17,6 : 8], г [1 : 3]; равносильно описанию массив i [—5 : 15], k [3 : 17,6 : 8], I [3 : 17, 6 : 8], г [1 : 3] П р и м е р 1. Пусть надо определить треугольную мат¬ рицу a [t, /1 для i = 1,2, ..., 10; j = 1,2, ..., i. Как опи¬ сать этот двухиндексный массив на алголе? Ответ: никак. На алголе можно описывать только прямоугольные массивы. Пример 2. Образовать массив а [&] : = 1/&, k = 1, 2, . . . , 10, затем вычислить и отпечатать сумму ci = а [ 1 ] -j- ci [ 2 ] -[-••• и- [ 10 ] Вот недопустимое! решение: начало целое k; реальное а; массив all: 10] для k : = 1 шаг 1 до 10 цикл а [й] : = 1/&; а : = 0; для k : = 1 шаг 1 до 10 цикл а : = а + а [£]; вывод (а) конец *) Или быть функциями, для которых определены правила вычи¬ слений. 38
Ошибка в том, что идентификатор а оказался описанным дважды (как реальная переменная и как массив) в начале одного блока. Выполнить наше задание буквально — за¬ труднительно. Проще сменить идентификатор а на b для про¬ стой переменной. §11. Влияние описаний на выполнение операторов и структуру выражений 11.1. Описание переменной влияет на зна¬ чения, присваиваемые этой переменной. Происходит это как при выполнении оператора присваивания, так и при присваивании значений параметру цикла (при выполнении оператора цикла). 11.1.1. Если переменная описана как булевская, то ей могут присваиваться только булевские значения, если как реальная или целая — то только арифметические (т. е. ре¬ альные и целые). 11.1.2. Если переменная описана как реальная, то ей при¬ сваиваются реальные значения. Таким образом, программа {реальная f; i : = 0; ... может присвоить переменной i значение, и чуть большее и чуть меньшее нуля. О причинах этого мы уже говорили в§ 1.2. Пример. Чему будет равно а после выполнения про¬ граммы {реальные a, k\ а : = 0 для k : = 1 шаг 1 до 10 цикл а : = а + k; ... Ответ: неизвестно, ибо k— переменная реальная. На десятом цикле она может оказаться чуть больше деся¬ ти, и оператор а : = а + k выполнится 9 раз (а не 10). 11.1.3. Переменной, описанной как целая, присваи¬ ваются значения типа целый. Если присваиваемое значе¬ ние окажется реальным, то оно будет предварительно округ¬ лено до ближайшего целого. 11.1.4. Согласно правилам алгола при выполнении про¬ граммы (неверной!) {целый k; реальный a; k \ =■- а : = 1.2; ... переменным k и а должны быть присвоены одинаковые зна¬ чения. Но в результате должно стать k = 1, а = 1.2. Как же быть? Авторы алгола вышли из затруднения, запретив употреб¬ лять в одном операторе присваивания переменные разных 39
типов (т. е. типа реальный и целый). Это и написано в конце табл. 1. Цена, разумеется, слишком дорогая. Программа {целый k\ реальный a; k : = а : = 0; ... в алголе недопустима. Нужно писать раздельно* (целый k; реальный a; k : = 0; а : = 0; ... В некоторых трансляторах оператор присваивания с пе¬ ременными разного типа все же разрешен. 11.2. Теперь мы можем еще раз уточнить понятие (выра* жения>. Прочтите определение (безусловного арифмети¬ ческого выражения) в табл. 2. Обратите внимание на (ариф¬ метическую переменную). Это — переменная (простая или с индексами), чей идентификатор описан как арифметиче¬ ский, т. е. как целый или реальный. Аналогичный смысл имеет и понятие (булевской переменной) в определении (безусловного булевского выражения). 11.-3. В процедурах веод (х, у, ..., г) вывод (а, Ь, ..., с) мы договорились считать параметры х, у, ... переменными (простыми или с индексами); а, Ь, ... — числовыми выра¬ жениями (арифметическими или булевскими). Теперь до¬ полнительно разрешим этим параметрам быть идентифика¬ торами массивов. Если среди параметров ввода встретится идентификатор массива, то будем считать, что с перфоленты введется нужное количество очередных чисел и их значе¬ ния присвоятся всем элементам массива. Сколько нужно ввести чисел (т. е. сколько этих элементов), указано в опи¬ сании массива. Пример. Пусть на ленте идут подряд числа 1, 2, .., Тогда программа начало целый f, массив а [1 : 2]; ввод (Z, а); ... присвоит значения i : = 1; а [1] : = 2, а [2] = 3. Если идентификатор массива встретится среди парамет¬ ров вывода, то будут отпечатаны подряд текущие значе¬ ния всех переменных с индексами, составляющие этот массив. Порядок вво :а — вывода элементов многомерного мас¬ сива ясен из следующего примера: G-Ц? ^12> &in> &21 > ^22» ••• 40
§ 12. Область действия описаний Область действия описаний — одно из самых сильных решений задач теории программирования, сделанных ав¬ торами алгола. Оно существенно облегчает организацию программирования, хотя и вносит свои трудности в реше¬ ние задач с большой информацией. Прочтите определения программы, блока и составного оператора в табл. 1. В на¬ чале блока идут описания — это отличает его от составно го оператора. Заметьте, что блоки или не пересекаются, или один целиком содержится в другом. Область действия описаний мы определим последова¬ тельно, начиная с самых внешних блоков (т. е. не содержа¬ щихся в других блоках) и переходя ко внутренним. Во внешнем блоке программы, но вне его подблоков действуют те объекты, идентификаторы которых описаны в начале этого блока. Пусть далее некоторый блок А непосредственно содержит блок В (т. е. не существует блока, содержащегося в А и со¬ держащего В). Тогда в блоке В, но вне его подблоков дей¬ ствуют следующие объекты: 1) описанные в начале В; 2) действующие в Л, если только их идентификаторы не описаны в начале В. Внутри блока можно пользоваться только объектами, которые в нем действуют. Все операторы блока работают только с этими объектами. 12.1. Рассмотрим программу {целый i, j; ... {целый /, /г; . . . }: ... {целый?п\ . .; ...} A Bl Bl В2 А содержащую всего три блока A, Bl, В2. Пусть в этой про грамме описаны только те идентификаторы, которые мы привели. Какова область действия переменных? Переменная i действительна во всей программе — в бло¬ ке А и обоих его подблоках В1 и В2. Переменная т действи¬ тельна только в блоке В2. Буквой k фактически обозначены дне совершенно раз¬ личные переменные. Переменная k, описанная в В1 — на¬ зовем ее для краткости речи kBl —действительна только в блоке В1. ГТо выходе из этого блока kBl перестает существовать. Также ведет себя переменная kB2 в бло¬ ке В2. 41
Буквой j тоже обозначены две переменные — jA и jBl- Переменная jA действительна всюду вне блока В1. На вре¬ мя работы блока В1 переменная jA как бы получает иное наименование, не встречающееся в программе, и сохраняет свое значение. В блоке В1 действительна переменная /В1, к ней относятся действия операторов блока В1, если они содержат переменную /. После выхода из блока В1 пере¬ менная jBl исчезает, а переменная jA снова приобретает свое наименование j и действует, в частности, в блоке В2. 12.2. Идентификатор метки считается описанным в ми¬ нимальном блоке, охватывающем метку-приемник. По¬ этому в любом блоке, вне его подблоков, может быть только одна метка-приемник с данным обозначением. Она не доступна для операторов, находящихся вне этого блока. Следовательно, войти в блок можно только через его на¬ чало. Заметим, что в составной оператор войти извне можно. Кроме того, в алголе запрещено входить извне внутрь оператора цикла. 12.3. Несколько примеров. Что отпеча-' тают нижеследующие программы? 1) {целый /*; k : = 1; {целый k; k : = 2; вывод (k)}] 2) {целый k; k : = 1; {целый /г; k : = 2; вывод (&)); ВЫВОД (k)} 3) {целый /г; {целый /г; k : = 3; вывод (&)}; вывод (k)\ Ответы. Программа 1 — неверная. Оператор k : = 1 работает с переменной, которая не описана. Программа 2 отпечатает 2 и 1. Программа 3 неверная. Последний вывод (k) выполнить нельзя, ибо во внешнем блоке переменная k не получила значения. Какой метке передаст управление оператор иди в ниже¬ следующей программе, если все скобки { } обозначают блоки и иных блоков в программе нет: {...Л4 :...{...{... иди Л4; ...{... М : М : 1 2 3 4 4 355 21 Ответ: самой правой. Действительно, метка М блока 4 считается описанной в нем и не доступна оператору блока 3. Самая левая метка М не доступна оператору блока 3 потому, что в блоке 2 уже есть метка-приемник М. Эта последняя метка считается описанной в блоке 2 и ее описа¬ ние прекращает в блоке 2 действие метки М из блока 1. Если какой-нибудь из примеров 12.3 Вы сделали не¬ верно, то вернитесь к началу § 12. 42
12.4. Пусть в большой программе используются пере¬ менные х, у, г, и, v. Пусть, далее, выделены две части за¬ дачи. В одной части по у должно находиться и = и [у). В другой — по г находится v (г). Эти части поручаются двум сотрудникам. Первому сообщают, что к моменту входа в его блок переменная у получит определенное значение, и ука¬ зывают алгоритм для вычисления и = и (у). Второй полу¬ чает аналогичные сведения про z и v. Теперь оба сотрудника могут работать независимо друг от друга (и от составителей всей программы). Им могут в процессе работы понадобиться дополнительные перемен¬ ные, которые каждый волен обозначать любым образом. До¬ полнительные обозначения будут, описаны в своих блоках. Не беда, если они окажутся одинаковыми у обоих сотруд¬ ников и если снова встретится обозначение х. Величина х общей программы от этого не пострадает. 12.5. Перед описанием типа какой-либо величины мож¬ но поставить дополнительно иероглиф собственный. При выходе из блока значение собственной величины сохра¬ няется неизменным, вплоть до повторного входа в этот же блок (в отличие от несобственной величины, значение ко¬ торой при выходе из ее блока теряется). Чтобы использовать эту особенность собственной вели¬ чины, нужно при первом входе в ее блок присвоить ей зна¬ чение, а при повторных — обойти это присвоение. Сделать это можно только с помощью значения какой-либо величины, меняющейся во внешнем блоке. Например, начало целый i; для i : = 1 шаг 1 до 10 цикл начало ссбственный реальный s; если i == 1tos: = 0;s: = s|2 + 1/7; если i = 10 то вывод (s) конец конец При первом входе во внутренний блок переменной s бу¬ дет присвоено значение 0. В дальнейшем присваивание будет обходиться и новые значения s будут получаться из старых. Если опустить собственный, то программа станет неверной. Нижеследующие примеры иллюстрируют использова¬ ние алгола для написания программ и могут служить чи¬ тателю в качестве упражнений с ответами. 1) Вычислить и напечатать таблицу значений полиномов Чебышева 7\(%) = cos (п X arccos х) для п = 0,1, ..., 10 и 43
х = 0,0.1,..., 2. Воспользоваться рекуррентной формулой: То (х) = 1; 7\ (х) = х, 7\.г2(х) = 2х7\Л (х) —7\(х). Решение. начало целые i, п; реальные a, b, с, х' для i : = 0 шаг 1 до 20 цикл начало х : = Z/10; вывод (1); вывод (х); а : = 1; b : = х; для п : = 2 шаг 1 до 10 цикл {с : = 2 х х X Ь — а; а : = b; b : = с; вывод (с)} конец конец 2) Сосчитать и отпечатать число сочетаний СО /^0 /^1, <-10 О, ' Ь10, пользуясь рекуррентной формулой qq 1. Qin п — т 1 Решение. начало целое п; реальное с\ для п : = 0 шаг 1 до 10 цикл начало с : = 1; вывод (с); для т : = 1 шаг 1 до п цикл {с = (п — т-\- l)/m X с; вывод (с)/ конец конец 3) Сосчитать и отпечатать таблицу значений функции /о (х) = (Х’2)2 , (х/2)« (ПУ- (2!)' для х = 0, 0.01, ..., 3.00. Вычисление ряда продолжать, пока очередной член станет меньше накопленной суммы, умноженной на 10~6. Решение. начало целое k\ реальное у; для k : = 0 шаг 1 до 300 цикл начало у : = /г/200; у : = у X у\ начало целое реальное a, s; k : = 1; а : = s : = 1 ; для k : = k + 1 пока abs (а) <Г io — 6 X s цикл {а : =— а X y/(k X k); s : = s + a} конец; вывод (s) конец конец 44
4) Вычислить и отпечатать (для х ■= 0.8; а = 3.5; b = 4.5) 1 аУа2 + Ь2 arctan а\х У ci2 -J- Ь2 ' Р е ш е и и е. начало реальные г, у; г : = sqrt (3.5|2+4.5f2); у : = 1/(3.5 X г) X arctan (3.5 X 0.8/г); вывод (у) конец § 13. Переключатели 13.1. После иероглифа иди должно стоять именующее выражение (см. табл. 3). В общем случае именующее выра¬ жение составляется не только из меток, но и из переключа¬ телей (см. табл. 2). Оператор перехода спереключателем имеет вид иди Р [Л] (1) где Р — идентификатор (данного переключателя), А — арифметическое выражение. Переключателю (1) соответ¬ ствует оп ис а н ие пер ек л юч ател я (см. табл. 3): переключатель Р : = I,J, К, ..., М (2) где переключатель — иероглиф алгола, Р — идентификатор того же переключателя (1), I, J, ... — переключательный список, состоящий из именующих выражений, разделенных запятыми. Работа оператора состоит из трех действий: (1°) Вычисляется значение А и округляется до ближай¬ шего целого (об округлении напоминают квадратные скоб¬ ки). Пусть для примера получено число 3. (2°) Отыскивается (2) — описание данного переключате¬ ля Р. В его переключательном списке находится член с нуж¬ ным номером (считая слева направо). В нашем случае номер равен 3 и искомый член есть К. (3°) Выполняется воображаемый оператор иди К (3) Это требует трех уточнений. Во-первых, описание (2) отыскивается в начале блока, охватывающего оператор; если таких описаний несколько, то берется то, которое в ми¬ нимальном блоке. Короче говоря, описание данного пере¬ ключателя находится по тем же правилам, что метка-прием¬ ник. Во-вторых, воображаемый оператор (3) выполняется так, как если бы он был первым оператором в блоке, где 45
найдено описание (2) (а не так, как если бы оператор (3) сто¬ ял на месте оператора (1), что иногда не одно и то же). В-третьих, если действия Г и 2° не приведут к результату, то оператор (1) считается неопределенным и пропускается. Это случится, если целое число [Д] окажется неопределен¬ ным, будет < 1 или превзойдет число членов переключа¬ тельного списка (2). Может быть, не лишне отметить, что выбранное именую¬ щее выражение К может оказаться не меткой, а переключа¬ телем (с тем же идентификатором Р или иным), и тогда вы¬ полнение (3), в свою очередь, отошлет к описанию соответ¬ ствующего переключателя. Описание переключателя (2) само по себе никаких дей¬ ствий не вызывает и при выполнении программы пропускает¬ ся (как метки-приемники и описания переменных). Только оператор перехода (1) заставляет работать описание (2). 13.2. Вот несколько примеров (иероглиф переключатель в этой книге мы иногда пишем сокращенно пер): 1) начало целый k; переключатель Р : = L, М, N; иди Р [2]; L: иди Р [А + 2]; Л4: k : = 1; иди Р [£?; N :конец Сперва иди Р [21 через описание переключателя Р отош¬ лет на М, Потом Р [/е] через описание переключателя Р отошлет на L. Наконец, Р [k + 2] посредством описания Р отошлет на N. 2) начало целый /?; пер Р : = Л4, q [Al; пер q S, Т; М: k : = 1; Т: иди Р [если k = 1 то k + 1 иначе 1 ]; S : конец Порядок действий можно описать так: k : = 1, иди Р [2], пер Р, иди q [1], пер q, иди S, S 3) Что отпечатает нижеследующая программа? начало целый k; пер Р : ~ М, Q [А]; пер Q : = R, S; k : = 1; {целый A; k : = 2; иди Р [Al; R : вывод (1)} иди А;; М: вывод (2); иди R; S: вывод (3); R : конец Ответ: ничего. Сменив обозначение k внутренней пе¬ ременной на А1, мы сможехм так описать порядок действий: k : = 1, k\ : = 2, иди Р [А1], пер Р, иди Q [Ad пер Q, иди А?; А? : конец «Воображаемый» оператор иди Q [А] выполнялся так, как будто он написан во внешнем блоке. Поэтому его ар¬ гумент k = 1. По этой же причине воображаемый оператор иди R отослал к метке-приемнику R внешнего блока. 46
13.3. Применение переключателей. Пусть программа должна содержать пять непересекающих- ся блоков с метками (7, Л, 73, С, D . {... (7: { }; Л: { }; В: { }; С: { }; Г): { }; ...} Вначале работает блок [7, а затем один из блоков Л —D. Какой именно — выясняется при выполнении блока U. Если это выясняется в конце блока (7, то естественно соче¬ тать «выяснение» с нужным переходом. Но легко предвидеть задачи, в которых выяснение произойдет в середине блока (7, когда переходить еще рано. Сперва нужно будет закончить блок U. Тогда придется запомнить, куда именно следует перейти после блока (7. Как это сделать? Вот естественное, но не допустимое для алгола решение: В конце блока U поставить иди М. Если в середине (7 вы¬ яснится, что перейти нужно будет к Л, то тут же метке■ М присваивается значение Л с помощью оператора /И : = Л. Это решение неверно, ибо оператор присваивания работает с арифметическими или булевскими переменными, с именую¬ щими выражениями он работать не может. Правильное решение может быть таким. Введем пере¬ менную i и будем присваивать ей значения 1, 2, ... в слу¬ чаях, когда перейти нужно будет к меткам Л, В, ... Переход произведем с помощью операторов, написанных в конце блока U. Эти операторы можно написать по-разному. Вот самый громоздкий способ: если f = 1 то иди Л иначе если Z 2 то иди В иначе если i = 3 то иди С иначе иди 77; Вот более короткий: если i = 1 то иди Л; если i — 2 то иди В; если i = 3 то иди С; иди D Вот еще вариант: иди если i = 1 то Л иначе если i = 2 то В иначе если г = 3 то С иначе D Но если таких блоков U окажется в программе несколь¬ ко, то лучше в начало программы ввести описание переклю¬ чателя переключатель Р : = А, В, С, D и выход из блока U закончить оператором иди Р Id Вся программа примет вид начало пер Р : — Л, В, С, D; {целый i; ... иди Р Id}; Л :{ } ; В : { } ; С : { }; D : { } конец 4^
ГЛАВА III ПРОЦЕДУРЫ § 14. Процедуры По целому ряду причин, ясных для программиста, воз¬ никает необходимость пользоваться подпрограммами, напи¬ санными вне тех мест, где этими подпрограммами пользу¬ ются, н употребляющими иные обозначения переменных, чем введенные в местах пользования. Авторы алгола решили эту проблему с максимальной универсальностью. 14.1. Чтобы обратиться к подпрограмме, в алголе исполь¬ зуется оператор процедуры, а сама подпрограмма задается описанием соответствующей процедуры. Прочтите в табл. 1 второе определение (процедуры) и в табл. 3 второе определение (описания процедуры), иг¬ норируя все, что относится к (строкам), (значениям), (спецификациям), (коду) и (замене запятых). Таким образом, для нас сейчас обращение к подпро¬ грамме осуществляется оператором процедуры вида Р (А, В, ...., £) (1) где Р — идентификатор данной процедуры, за которым в круглых скобках идет список фактических параметров — выражений, разделенных запятыми. Нужная подпрограмма сейчас задается описанием про¬ цедуры вида процедура Р (U, V, : .., W); Q (2) где процедура — иероглиф алгола; Р — тот же идентифи¬ катор, что и в (1), за которым в круглых скобках идет спи¬ сок формальных параметров — попарно различных иденти¬ фикаторов, разделенных запятыми; наконец, Q — оператор, называемый телом процедуры. Фактических параметров в(1) должно быть столько же, сколько формальных па¬ раметров в (2). 48
Описание процедуры (2) само по себе никаких действий не вызывает. При выполнении программы оно пропускается целиком (вместе с телом Q). Работу описания (2) вызывает оператор процедуры (1). Оператор процедуры (1) выполняется так: Г. Отыскивается описание (2) и фактические параметры ставятся в соответствие формальным параметрам в порядке следования. 2°. В операторе Q формальные параметры заменяются фактическими параметрами. Оператор Q после замены назы¬ вается Q — модифицированным телом процедуры. 3°. Выполняется Q, как если бы он стоял на месте опера¬ тора процедуры (1). В сложных случаях это требует многих уточнений, которые мы отложим до 14.3—14.5. 14.2. Проиллюстрируем применение оператора проце¬ дуры на простейших примерах. 1) Пусть мы хотим иметь подпрограмму, переводящую прямоугольные координаты в полярные в правой полупло¬ скости, т. е. дающую по двум числам х^>0, у величины г = Ух2+г/2, ср = arctan (у!х). Описание этой процедуры можно сделать таким: проц полярные (х, у, г, fi); {г : = sqrt (xf 2 4- у]2); fi : — arctan (z//x)} (3) Если теперь встретится оператор полярные (<7, b, R, F) (4) то переменным R и F будут присвоены значения R : = УcFA-b'1; F : — arctan (b/a) Предполагается, конечно, что в блоке оператора (4) уже действуют переменные a, b, R, F и что переменным а,Ь уже присвоены арифметические значения. Но оператор процедуры может иметь и более сложный вид. Например, полярные (а — b, — d, го, psi) При его выполнении будут сделаны нужные замены в теле (1) и переменные го, psi получат нужные значения. Все произойдет так, как если бы выполнялся оператор 4 АЛ. Брудпо 49
(модифицированное тело) ro\ = sqrt {{а — Ь)\2 + (—d)t2) ; psi: = arctan ( — d! (a—b)) В этом примере при замене формальных параметров факти¬ ческими мы ввели дополнительные скобки. Предполагается, что нужные скобки действительно вводятся при образова¬ нии модифицированного тела. Идентификаторы некоторых формальных параметров могут совпадать с фактическими. Это не исказит резуль¬ тата. Оператор процедуры полярные (у, х, F, г) выполнится как F : = sqrt (у\2 + х|2); г : ■-= arctan (х/у) Оператор процедуры полярные (х, х, г, F) выполнится как г : = sqrt (х|2 + х|2); F : arctan (х/х) Наконец, оператор полярные (<7, Ь, и + v, f) не сможет быть выполнен, ибо в модифицированном теле возникнет недопустимая конструкция и + v : = sqrt (а]'2 + Ь\2)\ 2) Опишем процедуру для суммирования элементов ка¬ кого-либо массива а [г], i = 1, 2, ... проц S2 (at п, S); {целый k; S : = 0; для k : = 1 шаг 1 до п цикл S := S + а [А]} Теперь оператор S2 (&, 3, и) №.1 I и : = b [ 1 ] 4- b + b [2] [3] если только в массиве b имеются соответствующие члены. Оператор процедуры S2 (&, й, й) тоже выполнится верно и даст и : = fell] 4~ fe[2] 4~ ... 4~ blk] Ясно, что во время этого вычисления идентификатор k из оператора процедуры (который заменит п в описании про¬ цедуры) и идентификатор k, описанный в самом теле проце¬ дуры, должны считаться различными. 50
3) Для вычисления сумм типа 53 = а [т] 4" я I/п 4" 11 4" ••• 4~ aln! процедура S2 не годится. Придется ввести более общую проц S3 (a, т, и, s); {целый k; s : = 0; для k : = т шаг 1 до п цикл s : = s + а Ш} 4) Процедура S3 суммирует члены подряд. Можно по¬ строить процедуру, свободную от этого ограничения. Нужно только параметр цикла ввести в число формальных пара¬ метров проц S4 (a, kt tn, п, s); {s : = 0; для k : = т шаг 1 до п цикл s : = s -|- а} п Чтобы найти S = 2 а ^1/к этому описанию нужно обратиться оператором 54 (a [A], k, m, и, s) Но теперь можно найти и сумму S = а [2] + а 14] + ... 4 а 12 х г] Ее доставит оператор S4 (а [2 X i], i, 1, г, s) при выполнении которого в описании процедуры S4 воз¬ никнет модифицированное тело {s : = 0; для i : = Гшаг 1 до г цикл s : = s 4- а [2 X Н} Введение параметра цикла в число формальных парамет¬ ров — прием мощный и неожиданный. Тщательно разбе¬ рите описание процедуры S4. Убедитесь, что суммы S, рав¬ ные п п 2(2/-Н)3; x[i]x yli]-, i=m п т 2 а [«] х х | i; « [Л /1 х b [j, /г]; Z=0 /=1 доставляются соответственно операторами S 4 ((2х i + 1) t з, i, т, п, s) S 4 (х [il X у [i], i, m, n, s) S 4 (a [il X x]i, i, 0, n, s) S 4 (a [i, /1 x b [j x k}, j, 1, m, s) Контрольный вопрос. Что отпечатает про¬ грамма? начало целый i; реальный s; проц V (s); s : = 0; (s: = 1; для i : = 1 шаг 1 до 3 цикл s : = s + i}; V(s); вывод (s) конец 4* 51
Ответ: нуль. Действительно, тело процедуры V состоит из оператора s : = 0 и только из него. Вообще-то говоря, в этой программе три оператора: в фигурных скобках, V и печать. Так что первым выполнялся оператор в фигурных скобках. Затем оператор процедуры — он отослал к опи¬ санию процедуры, где выполнилось тело s : = 0. Потом про¬ изошла печать. 14.3. Уточним порядок, в котором отыскивается описа¬ ние процедуры. Описание процедуры (2) отыскивается в на¬ чале какого-либо блока, содержащего оператор процедуры (1). Если таких описаний окажется несколько, то берется то, которое в минимальном (т. е. так же, как отыскивается метка-приемник). 14.4. Уточним образование и выполнение модифициро¬ ванного тела. Неясности здесь могут возникнуть главным об¬ разом потому, что различные (описанные в разных блоках) объекты программы могут оказаться обозначенными одина¬ ковыми идентификаторами и метками. 14.4.1. Предварительно разобьем объекты тела на три группы: локальных, формальных и прочих. И запомним про каждый объект, в какую группу он попал. Разбиение проведем так: (1°) Локальны е. Это объекты, описанные в самом теле. Сюда же отнесем метки, помечающие операторы тела. Тело процедуры всегда считается блоком, а упомянутые мет¬ ки считаются описанными в нем. (2°) Формальные. Сюда отнесем объекты тела, обозначенные идентификаторами формальных параметров, если только эти объекты не попали уже в группу локаль¬ ных. (3°) Прочие — не попавшие в. предыдущие две группы. Таким образом, сперва выделяются локальные объекты, а уже среди оставшихся — формальные. Приведем примеры определения локальных, формальных и прочих объектов тела процедуры: 1) процедура {целый k; k : =--= 1; х : = i + k} В теле этой процедуры: k — локальный, х — формаль¬ ный, i — прочий. 2) процедура /2 (х); {k : 1; {целый /?; х : = i + к}} Здесь: k (во внутреннем блоке) — локальный; х — формаль¬ ный; k (во внешнем операторе); i — прочие. 3) процедура /3 (х); {целый xi х : = i 4- к} 52
Здесь: х — локальный, f, k — прочие 4) процедура /4 (х); {{целый х; х : = A; k : = 2 X х}; х : k} Здесь: х (во внутреннем блоке) — локальный, х (во внешнем операторе) — формальный, k — прочий. 5) процедура f5 (Л4); если В то N : и : = 5 иначе иди М 6) процедура f6 (Л4); если В то М : и : = 5 иначе иди М В теле /5 метка М — объект формальный, а в теле /6 :— ло¬ кальный (так как помечает оператор тела) 14.4.2. Перейдем к образованию модифицированного тела: а) Все формальные объекты тела и только они заменяются фактическими параметрами (при этом добавляются нужные круглые скобки). Объекты, вставленные в тело процедуры в результате этой замены, понимаются в том смысле, кото¬ рый действует там, где расположен оператор процедуры. б) Обозначение вставленного объекта может иногда со¬ впасть с обозначением локального объекта тела. Но и тогда эти объекты следует считать различными. в) Прочие объекты должны быть действенны там, где расположено описание процедуры. И понимаются именно в этом смысле. Обозначение прочего объекта может, конечно, совпасть с обозначением некоторого объекта, действующего там, где расположен оператор процедуры. Но если эти объ¬ екты различны, то их следует считать различными. И с этой целью нужно временно сменить обозначение объекта, дей¬ ствующего в расположении оператора процедуры. После этих преобразований модифицированное тело выполняется так, как будто оно находится на месте опера¬ тора процедуры. Таким образом, в настоящее время в алголе-60 принято половинчатое решение: прочие объекты тела понимаются в смысле, действующем в блоке, где находится описание про¬ цедуры, но выполняется модифицированное тело так, как будто оно написано на месте оператора процедуры. Вот несколько запутанных примеров программ с проце¬ дурами: 7) начало процедура f (х); х : = /; целый i : = 0; {целые I, у, i : = 1; f (у); вывод (у)};... конец Эта программа отпечатает 0, ибо переменная i в теле про¬ цедуры — прочая. Она отлична от переменной i, описанной во внутреннем блоке. 53
8) начало процедура f (x); х : = z; {целые z, i : = 1; f (z/); вывод (z/)}; ... Эта программа ошибочна. «Прочая» переменная i тела про¬ цедуры не действует в блоке, где находится описание про¬ цедуры. 9) Операторы процедур (L) и /6 (Л), будучи помещены в блоки описаний процедур примеров 5 и 6, приведут соот¬ ветственно к образованию модифицированных .тел: если В то N : и : = 5 иначе иди L если В то М : и : = 5 иначе иди М 10) Что отпечатает программа начало целый z; проц F (и); иди zz; i : = 0; иди Т; М: вывод (z); иди zz; Т: {целый k; F (Л4); М : k :=1; вывод (&)}; и : конец Ответ: единицу. Действительно, сперва выпол¬ нится оператор i : = 0 (а не иди zz, являющийся телом про¬ цедуры F). Затем оператор иди Т. Теперь на месте опера¬ тора процедуры F (М) должно выполниться модифициро¬ ванное тело иди М где М — метка, вставленная в тело вместо формального па¬ раметра. Эта метка имеет смысл, действующий в блоке опе¬ ратора процедуры F (Л4). Поэтому модифицированное тело отсылает к оператору k : = 1. 11) В противоположность предыдущему примеру про¬ грамма начало целый z; проц F (zz); иди /И; z: = 0; иди Т; М*. вывод (z); иди zz; Т:{целый k; F (Л4); 7И : k : = 1; вывод (£)}; zz : конец отпечатает 0. Выполняться она будет в таком порядке: I: = 0; иди Т; целый k\ F (Л4) и модифицированное тело иди М с прочим объектом М ото¬ шлет к оператору Л4: вывод (z). 14.5. Процедуры без параметров. Проч¬ тите первое определение оператора процедуры в табл. 1 и первое описание процедуры в табл. 3. Они определяют: процедуру без параметров, которая для нас пока имеет вид Р и ее описание процедура Р\ Q 54
где Р — идентификатор процедуры, a Q — ее оператор. Эта процедура вовсе не имеет фактических (а ее описание — формальных) параметров. Все объекты тела Q — локальные и прочие. 14.6. Пример применения процедуры без параметров. Пусть на протяжении некоторого расчета часто бывает нужно вычислять полярные координа¬ ты г, f по декартовым х > 0, у. При этом полярные коорди¬ наты всегда будут обозначаться г, f, а декартовы х 0, у. Меняться от случая к случаю будут только их числовые значения. Тогда удобно ввести описание процедуры без параметров процедура поляр; {г : = sqrt (х]2 + г/ф2); f : = arctan (у!х)} и обращаться к нему коротким оператором процедуры поляр Пусть надо вычислить и отпечатать z=10 Я = П 1=1 10 /=1 где п, А — полярные координаты вектора с декартовыми координатами Xi = 1/(1 + I] 2); У; = 1 / I Это можно сделать программой начало реальные х, уу г, f проц поляр; {г : = sqrt (х|2 + y\ty', f • = arctan (у/х)}\ начало целый /, реальные R, F; R: = 1; F : = 0; для I : = 1 шаг 1 до 10 цикл качало х : = г/(1 + г|2); у : = 1/1: поляр; R : = R X г; F : = F + f; конец; вывод (7?, F) конец конец Остается заметить, что оператор процедуры без пара¬ метров пишется в форме Р, а отнюдь не Р ( ), с пустыми скобками. Аналогичную форму имеет и описание процедуры без параметров. 14.7. Ф у н к ц и и. Оператор функции по виду не отли¬ чается от оператора процедуры. Отличаются они по их ис¬ пользованию в программе и по виду их описаний. 55
В описании функции перед процедура пишется тип: целый, реальный или булевский. И это уже является описа¬ нием простой переменной с идентификатором функции. Ни в программе, ни в теле процедуры-функции описывать ее уже больше не надо. Заметим, что функция, подобно проце¬ дуре, может быть с параметрами или без них. Оператор функции (с соответствующим набором пара¬ метров) может употребляться в арифметических и булев¬ ских выражениях (см. табл. 2) также, как переменная. Если переменная арифметическая, то в описании функции перед процедура должен быть тип целый или реальный. Если переменная булевская — то булевский. Тем самым мы (в последний раз) расширили понятие выражения. Когда в некотором выражении встречается функция, то программа находит соответствующее описание. В теле опи¬ сания вычисляется значение функции и программа исполь¬ зует полученное значение. Поэтому в теле функции должно выполняться одно (или несколько) присваиваний определенных значений иденти¬ фикатору функции. В теле функции ее идентификатор пока что разрешим писать только слева от оператора присваи¬ вания. Иначе это вызовет рекурсивное обращение к описа¬ нию функции (см. следующий раздел). Рассмотрим описание функции без параметров реальная процедура г; {реальный rl; rl : = xf2 + у\2; г : = А1г\} Имея его, можно писать оператор и : = г/ (1 + г'\ 2) + А X sqrt (г) если только и описано как целое или реальное, а перемен¬ ные х, у, А уже имеют значения. Заметьте, что тело этой про¬ цедуры нельзя писать так: {г : = х{2 + г : = А/г} ибо во втором операторе присваивания идентификатор про¬ цедуры встретился в правой части. Как пример вычислений, эти программы составлены неразумно, но нам важно пояс¬ нить как используются функции. Описание функции для суммирования и S = 2 i=tn где а — идентификатор массива, можно приготовить таким: 56
реальная процедура S (t, т, п, а); {реальный si; si : = 0; для i : = т шаг 1 до п цикл si : = si -|- a; s : = si} И здесь по указанной причине нельзя собирать сумму сразу в S. Использоваться функция S может, например, в опера¬ торе и : - exp (S (г, 1, 10, \/i f 3) + С <S (z, 1, 10, х [z] х у [f])) 14.8. Рекурсии проц е д у р. Модифицирован¬ ное тело из описания процедуры может само содержать опе¬ раторы процедур (как иных, так и той же самой). При вы¬ полнении модифицированного тела эти операторы будут выполняться, по обычным правилам для операторов проце¬ дур. Таким образом, модифицированное тело само обра¬ тится к описаниям соответствующих процедур. Если при этом повторно встретится та же самая (еще неоконченная) процедура, то все произойдет так, как будто мы обрати¬ лись к другому экземпляру (копии) ее описания. Рекурсии в процедурах возникают или из-за вида опера¬ тора процедуры, или из-за структуры самого описания процедуры. 14.8.1. Рекурсивное использование процедур. Рассмотрим описание функции для суммиро- п вания S = .2 а' реальная процедура S (f, tn, п, а); {реальный si; si : = 0; для i : = т шаг 1 до п цикл si : = si + a; s : = si} Если в этом блоке встретится оператор U : = S (k, 2, И, fef 2) то будет вычислено и : = 22 + 32+... + 1 12. Но если упо¬ требить оператор U\ : =LS (/, 1, 8, S (k, 2, 11, sqrt (/{2 + 6j2))) то описание S рекурсивно обратится само к себе и будет вычислена двойная сумма /=1 /?=2 Рекурисивные обращения к процедурам вызывают и вся¬ кого рода операторы типа U2 : = cos (п X sin (т X cos (х))) 57
14.8.2. Рекурсивные процедуры. Про¬ стой пример дает рекурсивное вычисление факториала. Вот описание этой функции: целая процедура факториал (и); если n > 1 то факториал : = п X факториал (п — 1) иначе 1 Если теперь употребить оператор функции и : = факториал (А) с целым значением А, то будет получено и = k\. Рассмотрим подробнее, как это произойдет. Если k = 1, то модифици¬ рованное тело присвоит идентификатору (факториал) зна¬ чение 1. Если k = 2, то модифицированное тело если k > 1 то факториал : = k X факториал (k — 1) иначе 1 снова обратится к описанию функции факториал. Все про¬ изойдет так, как будто обращение произошло ко второму экземпляру этого описания. В результате образуется вто¬ рое модифицированное тело если k — 1 > 1 то факториал : = (/г — 2) X факториал (k — 3) иначе 1 При его выполнении идентификатор (факториал) получит значение 1. Это значение будет подставлено в первое моди¬ фицированное тело для (факториал (/г — 1)> и даст окон¬ чательно: факториал : = 2. При больших значениях k ре¬ курсивных обращений будет больше. Конечно, транслятор не обязан фактически образовы¬ вать копии процедур — он может обойтись и одним экзем¬ пляром, специально составленным и дающим тот же ре¬ зультат. Вот более трудный пример. Пусть t [1], t [2],...,/ [лг] — десятичные цифры и уже имеется процедура F (I, п), пе¬ чатающая число {/ [1] I[2] . . . t [/г]}, изображенное после¬ довательностью этих цифр. Тогда нижеследующая про¬ грамма (точками обозначено тело процедуры F) отпечатает все целые числа от ООО до 999: начало целый п; п : = 3; начало массив /11 : /?]; проц F (t, п); ...; проц счетчик (/); для t If] : = 0 шаг 1 до 9 цикл если i <Г п то счетчик (f + 1) иначе F (t, п); счетчик (1) конец конец 58
Не обращая внимания на простоту задачи, тщательно про¬ делайте на руках эту программу, выписывая все модифи¬ цированные тела. Здесь хорошо видны возможности рекур¬ сивных процедур. 14.9. С п ец и ф и к а ц и и. Аргументы в описаниях проце¬ дур (т. е. формальные параметры) не имеют описаний. Нуж¬ ные сведения о них возникают автоматически, после замены формальных параметров фактическими. Но чтобы облег¬ чить работу транслятора, можно заранее указать характер некоторых формальных параметров. Для этого служат спе¬ цификации (см. табл. 3). Спецификации похожи на описа¬ ния. Но видов здесь больше: в спецификациях, например, есть иероглиф метка, а в описаниях его нет, ибо метка не име¬ ет явного описания. Кроме того, в спецификациях массивов не указываются граничные пары. В спецификациях проце¬ дур и функций не указываются формальные параметры (т. е. пишется лишь идентификатор процедуры или функции). Спецификации формальных параметров должны соответ¬ ствовать типам фактических параметров. Вот описание функции суммирования вместе со специ¬ фикациями реальная проц S (/, т, п, f); целые i, т, п реальное f; начало реальное si; si : = 0; для i: = т шаг 1 до п цикл si : = si + /; S : = si конец Обозначение S помещать в спецификации не надо — его тип уже указан в начале описания функции. Спецификации ограничивают возможности оператора процедуры. Так, на¬ пример, приведенное описание процедуры суммирования не¬ пригодно, если мы хотим в операторе процедуры исполь¬ зовать f как функцию (имеющую свое собственное описа¬ ние). Для этого случая спецификацию «реальное /» нужно заменить на «реальная процедура /». 14.10. Значения. В описании процедуры (см. табл. 3) может иметься перечень формальных параметров, объявленных (значениями); параметры-значения обязатель¬ но должны иметь спецификации. Список значений изменяет правила для выполнения опе¬ ратора процедуры следующим образом: 1) Создается блок, охватывающий тело. 2) В начале этого блока описываются обозначения фор¬ мальных параметров, попавших в список значений. Этим обозначениям присваиваются значения соответствующих 53
фактических параметров. Такие присваивания выполняют¬ ся однажды, перед входом в тело. 3) При модификации тела формальные параметры, по¬ павшие в список значений, сохраняют свои обозначения (т. е. не заменяются на фактические параметры). В список значений можно заносить только такие формаль¬ ные параметры, у которых фактические параметры вообще способны принимать значения, т. е. являются выражения¬ ми или массивами. Значением массива считается соответствующая после¬ довательность арифметических или логических чисел. Зна¬ чением именующего выражения считается метка. Не принимает значений, например, идентификатор пе¬ реключателя или процедуры (не функций). Помещение формального параметра в список значений имеет следующий смысл: 1) Ускоряется работа оператора процедуры в том слу¬ чае, когда соответствующий фактический параметр являет¬ ся сложным выражением. 2) «Защищается» соответствующий фактический пара¬ метр, так что можно быть уверенным, что он не изменится при выполнении оператора процедуры. 3) Допускается использование формального параметра в качестве внутренней «работающей» переменной в теле процедуры. Обычно в список значений заносят «входные» пара¬ метры процедуры, которые целесообразно вычислить за¬ ранее. Проиллюстрируем применение значений. проц Е (Л, В, С); значения А, С; реальные А, В; целое С; начало целое k; А : = А^2; В : = 0; для k :=1 шаг 1 до С цикл В : = В + 4х(В + 1) конец Если к этому описанию обращаются оператором Е (а, Ь, п х (п— 1 )/2) то можно опустить (значения Л,С>. Однако в этом случае значение переменной а изменится, а выражение п (п — 1)/2 будет вычисляться на каждом шаге (ибо при каждом уве¬ личении k должно проверяться неравенство k п (п —1)/2, правая часть которого, вообще говоря, могла бы зависеть от k или В). 60
Но если к описанию Е обращаются оператором Е (и v, Ь, с) то (значение Л> необходимо— иначе в модифицированном теле возникнет недопустимая конструкция и + v : = (и + у) f 2 14.11. Собственные объекты. Чтобы . за¬ кончить уточнение правил для выполнения оператора процедуры, надо сказать, как будет пониматься объект, описанный в теле как собственный. Будет он принадле¬ жать описанию процедуры и сможет меняться при каж¬ дом обращении к описанию или будет свой для каждого оператора процедуры и будет сохраняться, пока «его» оператор не обратится к описанию. Этот вопрос в алго¬ ле 60 пока еще не уточнен. 14.12. Побочный эффект. Оператор процедуры или функции обращается к своему описанию, которое в конечном счете выполняется как подпрограмма. Вполне естественно, что эта подпрограмма может менять значения различных переменных. Так, например, описание функции реальная процедура г/(х); у : = х : = 1 + х не только вычисляет у : = 1 + х, но и изменяет аргумент. От этого значения s в операторах 1) s : = х + у (х) 2) s : = У (х) + х оказываются различными. Программисты к этому привык¬ ли, но новичку такая некоммутативность кажется дикой. Еще «коварнее» описание функции реальная проц г; {г = sqrt (xf2 + у f 2); а : =- х У*у} Здесь при выполнении операторов s : = г + а s : = а + г изменение а происходит как бы без ведома «потребителя». Нужно учитывать, что г — не простая переменная, а функ¬ ция и при ее вычислении может смениться значение а, В связи с возможной некоммутативностью арифметиче¬ ских действий в алголе принят следующий жесткий порядок. При вычислении арифметических выражений всегда выпол¬ няется первое (считая слева направо) арифметическое действие, которое можно выполнить в данный момент в силу GI
расстановки скобок и старшинства действий. Так, напри¬ мер, в арифметическом выражении а + b + с X d\e — f сперва выполнится сложение а + Ь, затем возведение в сте¬ пень d]et потом умножение с X (d]e), потом сложение (а + b) + (с X d]e) и, наконец, вычитание. Аналогичные правила употребляются при вычислении булевских и име¬ нующих выражений. 14.13. Т е л о процедуры, согласно определению (табл. 3), может быть не только оператором (этот случай мы уже разобрали), но и кодом, т. е. программой, написан¬ ной не на алголе. Это дает возможность написать часть про¬ граммы непосредственно в командах машины особо тща¬ тельно. § 15. Пояснительный текст 15.1. В а р и а н т ы зап я т ой. В списке фактиче¬ ских или формальных параметров параметры можно разде¬ лить не тол ко запятыми, ио и поясняющими конструкция¬ ми вида (см. табл. 1 и 3) ) текст : ( Так, например, оператор функции Р = R X T/v P(R, Т, v) можно написать в любом из трех видов: 1) Р (/?) температура: (Т, а) 2) Р (/?, Т) объем: (у) 3) Р (R) температура: (Т) объем: (у) Те же самые (или иные) пояснения можно сделать и в опи¬ сании этой функции. 15.2. Строки. Для печати текста используются (стро¬ ки) (см. табл. 3), а оператор вывода строят так, чтобы напи¬ санное в строчных кавычках печаталось буквально. При¬ менение этого иллюстрируется программой {целый а; а : = 3; вывод (‘а = \ с/)} которая напечатает а — 3, в отличие от программы {целый а; а : = 3; вывод (а)} которая напечатает только число 3. Строка может быть фактическим параметром процедуры. В теле она заменит формальный параметр. Если модифици¬ рованное тело тоже содержит оператор процедуры, то стро¬ ка может «перекочевать» в тело и этого оператора. Но в конечном счете строка должна попасть в оператор вывода 62
или в код. Внутри строки может применяться значок — для пробела печати. 15.3. Примечая и я. В программу алгола можно вставлять примечания — пояснительный текст, пользуясь следующими правилами: КОНСТРУКЦИЯ ПРИМЕЧАНИЯ ЕЕ ЭКВИВАЛЕНТ комментарий (последовательность символов до ближайшего знака ; включительно) {комментарий (последовательность символов { до ближайшего знака; включительно) } (последовательность символов } до ближайшего знака ; или} или иначе не включая этого знака) Здесь комментарий — еще один иероглиф алгола, а эк¬ вивалентность означает, что примечание и его эквивалент выполняются в программе одинаково (если только приме¬ чание не стоит внутри (строки)). Замена примечаний «эк¬ вивалентами» должна выполняться в порядке следования слева направо. Таким образом, после знака} можно сразу писать при¬ мечание, а после знака ; или { надо сперва помещать иерог¬ лиф комментарий, а потом уже примечание. Внутри приме¬ чания нельзя пользоваться знаком;, а иногда и знаками} и иначе. С помощью примечания после иероглифа конец удобно указать, что именно окончено. Так, например, программу функции п п PS удобно написать с комментариями: реальная процедура PS (а, п); значение п; целое п; массив cz; начало целые f, /; реальные si, s2; si : == 1; для i : = 1 шаг 1 до п цикл начало s2 : 0; для / : ~ 1 шаг 1 до п цикл s2: — s2 + a 1Z, /I; si : = si X s2 конец i; PS :: = si конец PS; Процедуры алгола регулярно публикуются в журна¬ лах и сборниках (см. [4]). Приведем несколько примеров процедур: 63
1) Процедура cheb вычисляет полином Чебышева для заданных х и п по рекуррентной формуле То (х) — 1; Ту (х) — х; Тп+2 (х) = 2хТп+1 — Тп. реальная процедура cheb (п, х)’ значения п, х; целое п; реальное х; начало целое f; реальные а, Ь, с; а : = 1; b : = х; если п = 0 то с : = 1 иначе если п = 1 то с : = х иначе для п : = 2 шаг 1 до п цикл {с : = 2 X х X b — а; а : = b ; b : = с); cheb : = с конец cheb\ 2) Процедура max находит строку i и столбец /, где рас¬ положен максимальный по модулю элемент матрицы а по¬ рядка п X п. процедура max (а, п, i, значение /г; целые n, f, /; массив а\ начало целые Л, /1; реальное 1\ i : = j : = 1; t : = abs (a [1, 1]); для fl : = 1 шаг 1 до n цикл для /1 : = 1 шаг 1 до п цикл если abs (a If, /1) < t то {i : = fl; j : = /1} конец; 3) Нахождение корней функции методом деления интер¬ вала пополам. Процедура bisec 1 вычисляет значения функ¬ ции на концах заданного интервала (а, Ь). Если знаки этих значений совпадают, то процедура bisec 1 отправляет к метке signal. Если знаки разные, то процедура вычис¬ ляет значение функции в середине интервала, выбирает полуинтервал, где функция меняет знак, и т. д. Процесс прекращается в трех случаях: (1) когда длина интервала станет меньше eps; (2) когда вычисленное значение функции окажется по модулю меньше eps 1; (3) когда интервал пере¬ станет убывать (в результате исчерпания точности счета машины). В первых двух случаях полученное значение ар¬ гумента выдается в качестве корня функции. В третьем слу¬ чае процедура отправляет к метке signal 2. Чтобы процедура bisec 1 работала, надо, разумеется, что¬ бы программа содержала требующуюся процедуру-функ¬ цию. Хотя метод bisec 1 относится к самым медленным, он 64
применим к любой непрерывной функции. Это делает про¬ цедуру очень надежной. процедура bisec 1 (a, b, eps, eps 1, /, si, s2) result', (x); значения a, b; реальные a, b, eps, eps 1, x; реальная процедура f; метки s1,s 2; начало реальные у, z, t, /1; процедура fun (z/); реальное z/; {z/ : = f (x); если abs (z/) < eps то иди fin }; x : = a; fun (z/); x : = b; fun (г); если sign (у) =[sign (z) то иди si; t : = abs (b — a); iter', если t < eps 1 то иди fin; tl : = t; x : = (a + b)/2; fun (z/); если sign (z/) = sign (z) to b : = x иначе a : = x; t : = abs (b — a); если / > /1 то иди s2 иначе иди iter; fin: конец bisec 1; 4) Пусть уже описаны две процедуры-функции у (х) и delta (х, eps) такие, что delta (х, eps) > 0 при eps > 0 и |х1 —х| < delta (х, eps) влечет \у (xl) — у (х)| < eps. Составьте описание функции delta 2 (х, eps) такой, что delta 2 (х, eps) > 0 при eps > 0 и |х 1 — х | < delta 2 (х, eps) влечет | у (xl) \2 — у(х) f 21 < eps. Решение. реальная проц delta 2 (х, eps); реальные х, eps; delta 2 : = delta (х, (если eps <Z 1 то eps иначе 1) / (1 + 2Х abs (у (х))) Действительно, полагая у = у (xl) и z/() = у (х), имеем 1 . min (eps, 1) 1 i \у Уо 1 < 1 + 2 I у01 < 1 + 2 I у. I ’ откуда I?/2 — ^1 = \У-Уо\-\У — У<> + 2'/о|< <i+WT(1 +2Ы) = eps- Внимательный читатель может заметить, что обычное доказательство непрерывности квадрата непрерывной функции нисколько не короче. 5 Л. Л» Врудио 65
§ 16. Подмножество алгола В настоящее время выпущено подмножество алгола Это — вариант алгола, облегченный для аппаратуры вво. да — вывода и для составителей трансляторов. Всякая- программа, написанная на подмножестве^ является про¬ граммой и для алгола, но не наоборот. Возможно, что подмножество алгола получит широкое распространение. Поэтому не стоит без нужды нарушать его ограничений. Основные отличия подмножества от алгола в следующем: 1. Исключены большие буквы А, В,... 2. Идентификаторы различаются по первым шести симво¬ лам (если у двух идентификаторов эти символы совпа¬ дут, то идентификаторы считаются одинаковыми). 3. Исключено деление нацело (~н). 4. Возведение целого основания в целую степень опреде¬ лено только для целого показателя без знака. 5. Параметр цикла должен быть простой переменной (без индексов). 6. Именующие выражения разрешаются лишь безуслов¬ ные и не заключенные в скобки. 7. Переключательный список должен состоять только из меток. 8. Запрещены целые в качестве меток. 9. Исключено понятие собственный. 10. Запрещены рекурсивные процедуры и рекурсивное ис¬ пользование процедур. 11. Запрещены описания функций, вызывающие побочный эффект. 12. Все формальные параметры должны иметь специфика¬ ции. 13. Идентификаторы не должны появляться раньше своих описаний (в алголе идентификатор прочего параметра тела может встретиться раньше, чем описание этого идентификатора). 14. Фактические параметры, вызываемые по наименованию (т. е. не содержащиеся в списке значений), могут быть только идентификаторами или строками (в алголе они, кроме того, могут быть переменными с индексами и вы¬ ражениями). 66
OHH41fU0(i иэи ИИИ Ul'IlfUU ООП онпнэиэН 911 OJ. ‘QOMObhMlOW^Ju ОИНОЖЬЧЖИ 1Д1С0Э ;_ЭЮ1ЭИЭЁЛ9 &1чннэиэс1ои 01 ‘о6лэЙ0к^9 эинэзие’сГгШ ИИНтаЖЗЙсШ 3 иеол s CQ 43 Sf s U3 < H tu s 3^ U UJ T s: u < H X CJ Оч 'D О Н К ЕГ о 'Чн ай>эс0 5Т ПЭ Я VD В won я BowMinewdoEoo он WdO.LVd^io я иоиийощйМро ©н и ‘SdOlVddilO Я0И8Л Й ин йоривйэад 1&S 'эюп яи doivasuo йонеуаюоэ о*е - ташоал
< я s [Д < н с ильене а ивинэьонгиее и‘иироиэ лех.пнеи-яедэээа 4 и , ииьбнс HGdoioM~S4WbjifB яокояииэ^^ЖгэхвйоУ -aifoou оде - елобдд'"••нэдогвдиьо эгГвяэиэ ик^н цМодои я ‘йфйп чдэончЕэдеаоУэЕэон И1ги ЗодвлифйдпэЯи оде - елдэи « о о W о PQ аз о
Т А Б Л И Ц А з Все идентификаторы (кроме меток и аргументов в описаниях процедур) должны быть описаны в начале блоков, где они употребляются. Перед описанием можно дополнитель¬ но поставить садстбемный. Обозначение метки считается описанным в начале минимального. р.выр сать ( о ПхГ СО X CD Д Д СО S •• д О -S- СО О X/ х'Х к CD . X О д • • PQ Ен S Д Л О к х/ Д X со Я м д /X о со • МО Ен X сО М о СО «" д • о 3 л Д Д СО Л я Ен СО 03 3 CD Л д о х д 3 д X/ О О X о СО * •» CD Д >е< д • • Д А s X • ♦ СО Д д о • • CD CD д * • К Ен С X & О СО Н W О X/ — и S к о ZX и к к д д • о СО CD д Д и СО Д д СО СО О CD • » X/ Q. о о х • • И Ен X со к & W О д д CD > со д 3 О а XZ со CD д в «• к Д д Ен X СЭ Ен Ен Ен CD Д Д X • X д (D CD CD CD Ен Д Д 02 Д X/ S S К X X CD 1 3 Ен Ен Д §! си S д X CD X О о д д Д Д СО CD S о д Cj £ S о Ъ ъ 1 К X д '^.5^ & 1 09
Т Л Б л И Ц Л 4 Список знаков алгола Большие и малые латинские буквы Малые русские буквы (в русском варианте алгола) Десятичные цифры, десятичная точка, опущенная десятка Булевские числа да и нет Разделительные знаки , : ; : — Скобки ()[]{}*’ вместо скобок { } можно писать иероглифы начало конец (begin end) Знаки арифметических действий -j- — X / -т- | Знаки сравнений <У =£ > Знаки булевских действий = Z) V Л ~1 Двадцать иероглифов в русской и английской записи если if для for целый integer то then шаг step реальн ый real иди go to до until булевский Boolean иначе else пока while массив array цикл do переключатель switch метка label значение value процедура procedure строка string собственный own комментарий comment СТРУКТУРА ПРИМЕЧАНИЙ КОНСТРУКЦИИ ПРИМЕЧ АНИИ ЕЕ ЭКВИВАЛЕНТ 1) ; комментарий <последовательность символов ; до ближайшего знака; включительно) 2) {комментарий (последовательность символов { до ближайшего знака; включительно) 3) } (последовательность символов } до ближайшего знака; или} пли иначе не включая этого знака) Замена примечаний «эквивалентами» должна выполняться в поряд¬ ке следования слева направо.
ЛИТЕРАТУРА 1. Алгоритмический язык алгол-60, под ред. П. Наура, Русский пере¬ вод под ред. А. П. Ершова и др., «Мир», 1965. 2. Н а у р П., Курс программирования алгол-60, Русский перевод № 26585, Бюро* ВИНИТИ. 3. А г е е в М. И., Основы алгоритмического языка алгол-60, ВЦ АН СССР, 1964. л 4. А г е е в М. И., Алик В. П., Г а л и с Р. М., Алгоритмы (1—50), (51—100) и (101 — 150), ВЦ АН СССР, 1966 и 1937. 5. Б о т т е и б р у х Г., Структура алгол-60 и его использование, ИЛ, 1963. 6. М а к - К р а к е и Д ж., Программирование на алголе, «Мир», 1964. 7. ЛавровС. С., Универсальный язык программирования (Алгол-60), изд. 2, «Наука», 1967. 8. Сообщение о подмножестве алгола-60, Сборник «Современное програм¬ мирование», «Советское радио», 1966.
Александр Львович Брудно АЛГОЛ М., 1968 г., 72 стр. Редакторы: М. М. Горячая и Р. С. Гутер Техн, редактор /<. Ф. Брудно Корректор 3. В. Автонеева Сдано в набор 17/V 1967 г. Подписано к печати 20/ТХ 1967 г. Бумага 84х 108/3i< Физ. печ. л. 2,25.Условн. печ. л. 3,78. Уч.-изд. л.3,63. Тираж 49000 экз. Т-12523 Цепа 23 коп. Заказ 2778. Издательство «Наука» Главная редакция физико-математической литературы Москва, В-71, Ленинский проспект, 15 Набрано во 2-й типографии «Наука*. Москва, Шубинский пер., 10 Отпечатано в Моск. тип. № 15. з. 220
Цена 23 коп.