Текст
                    
ФОРТРАН
11/1 fl I I /' 1 I
ш - ______ _____
X' T\ j A I 'J* | I 1 /1 1 I

ФОРТРАН ПРОГРАММИРОВАННОЕ УЧЕБНОЕ ПОСОБИЕ Под редакцией чл.-кор. АН УССР Е. Л. Ющенко ИЗДАНИЕ ВТОРОЕ, ПЕРЕРАБОТАННОЕ И ДОПОЛНЕННОЕ Допущено Министерством высшего и среднего специального образования УССР в качестве учебного пособия для студентов вузов, обучающихся по специальности ^Прикладная математика* КИЕВ ГОЛОВНОЕ ИЗДАТЕЛЬСТВО ИЗДАТЕЛЬСКОГО ОБЪЕДИНЕНИЯ .<ВИЩА ШКОЛА» 1980
ББК 32.973 6Ф7.3 Ф80 УДК 681.3.06(07) Фортран: Программированное учебное пособие. / Под. ред. чл.-кор. АН УССР Е. Л. Ющенко.— 2-е изд., перераб. и доп.— Киев : Вища школа. Головное изд-во, 1980.— 400 с.— 30502. 1502000000 Книга является пособием по языку ФОРТРАН — одному из наибо- лее распространенных и широко признанных языков программирования в сфере научных и научно-технических приложений. Простота языка, эффективность получаемых при трансляции с него рабочих программ, наличие развитых средств редактирования информации обеспечили ФОРТРАНу особое место среди многих языков программирования. Настоящее пособие является программированным и позволяет само- стоятельно изучить предмет, чему способствует наличие комплекса при- меров и задач, иллюстрирующих языковые средства ФОРТРАНа и много- образие их использования. По сравнению с предыдущим изданием, пособие переработано и дополнено с учетом реализации языка на ЕС ЭВМ. Пособие может быть использовано для различных категорий чита- телей — от студентов вузов до слушателей курсов профессионально- технической подготовки. Табл. 43. Ил. 40. Список лит.: 3 назв. Рецензенты: д-р физ.-мат. наук Э. 3, Любимский и канд. физ.-мат. наук В. В Мартынюк Редакция литературы по кибернетике, электронике и энергетике Ф XmS i95~so 1502000000 Издательское объединение «Вища школа», 1976 ©Издательское объединение <Вища школа», 1980. с изменениями
ПРЕДИСЛОВИЕ Одной из наиболее характерных особенностей научно-техниче- ского прогресса в нашей стране является проникновение методов и тех- нических средств кибернетики в самые широкие сферы человеческой деятельности. ЭВМ уже стали незаменимыми помощниками ученых и специалистов при решении научных, экономических и технических задач, широко используются при проектировании, планировании и управлении технологическими процессами, транспортными система- ми, отдельными стройками и предприятиями, целыми регионами и от- раслями. Ведутся работы по созданию отраслевых республиканских и общегосударственных автоматизированных систем планирования и управления. Не удивителен поэтому тот факт, что в учебные планы всех технических, экономических, педагогических и многих других вузов включены в большем или меньшем объеме программы, преду- сматривающие изучение тех или иных средств общения с ЭВМ— язы- ков программирования. Одним из подобного рода языков, нашедшим широкое распрост- ранение и внедрение, является язык ФОРТРАН, простота и общность средств которого снискали ему заслуженное всеобщее признание. ФОРТРАН — один из наиболее ранних языков (его первая версия относится к 1954 году, США). Со времени своего появления ФОРТРАН развивался, пополнялся новыми возможностями. В результате поя- вился целый ряд основанных на нем систем автоматического программи- рования (реализаций языка), более или менее программно несовмес- тимых между собой из-за наличия в них языковых различий. Для уни- фикации и стандартизации языка, имеющей своей целью создание базы для программной совместимости систем программирования, основанных на ФОРТРАНе, был разработан стандарт ФОРТРАНа (1966 г., США). Следует отметить тот неоспоримый факт, что из огромного числа предложенных языков программирования (порядка нескольких тысяч) лишь немногие из них, оказавшиеся в силу своих положительных ка- честв наиболее «живучими», подверглись стандартизации. В СССР к настоящему времени приняты стандарты на языки АЛГАМС, КОБОЛ, ФОРТРАН и Базисный ФОРТРАН (подмножество ФОРТРАНа). 1* 5
Со времени выхода в свет первого издания настоящего пособия (Киев, Вища школа, 1976 г.), посвященного изложению средств стан- дарта языка ФОРТРАН, широкое распространение в СССР получила серия вычислительных машин ЕС ЭВМ, на которой реализован язык ФОРТРАН IV (в настоящей книге названный ФОРТРАН/EC), явля- ющийся расширением указанного стандарта. Учитывая важность указанного расширения с позиций удобств использования языка и повышения эффективности использования тех- нических и общесистемных средств, предоставляемых ЕС ЭВМ, а также возросший уровень использования ЭВМ и квалификации пользова- телей, авторы внесли во второе издание книги существенные измене- ния и дополнения. Прежде всего, в связи с утверждением в нашей стране стандарта на язык ФОРТРАН («Язык программирования ФОРТРАН», ГОСТ 23056-78) были устранены некоторые терминологические расхож- дения1. Более существенные изменения и дополнения связаны с вклю- чением в книгу описания всех средств языка, обусловленных реали- зацией ФОРТРАН/EC. При этом описание синтаксиса и семантики этих средств сопровождается рассмотрением ряда типовых примеров и задач, в которых вскрываются особенности реализации, позволяю- щие создавать на ФОРТРАН/EC программы, обеспечивающие более эффективное использование машинных ресурсов и более экономное выполнение рабочих программ. Существенное место в пособии уделено общей методике обучения программированию, в частности, методике построения программ из программных модулей, методам представления результатов в форме, удобной для обозрения (в виде таблиц, графиков) и т. д. Изложение сопровождается пояснениями и большим количеством примеров. Последние подобраны так, что для усвоения материала настоящего пособия достаточно подготовки в объеме курса средней школы. Книга может быть использована при подготовке пользовате- лей различных категорий: от студентов вузов до слушателей курсов профессионально-технической подготовки. Следуя первому изданию^ авторы сохранили программированный способ изложения учебного материала, подтвердивший свои преиму- щества на практике. Размер учебных порций, их содержание, примеры и задания к ним делают пособие пригодным для использования в качестве одной из учебных компонент в автоматизированных системах подготовки поль- зователей ЭВМ. В частности, на материале настоящего пособия созда- ется система обучения языку ФОРТРАН в рамках автоматизированной системы программирования обучающих курсов СПОК/ЕС, разрабо- танной Институтом кибернетики АН УССР и НИИ ВШ и принятой МВССО СССР в качестве базовой для автоматизированного обучения. 1 Государственный стандарт языка ФОРТРАН утвержден 7 апреля 1978 г. Госкомитетом стандартов СССР и введен с I января 1979 г. 4
Авторы надеются, что книга будет способствовать повышению квалификации специалистов, применяющих в своей работе вычисли- тельные машины, а также культуры программирования и, в конечном счете,— эффективности использования ЭВМ. Отзывы просим направлять по адресу: 252054, Киев-54, ул. Го- голевская, 7, Головное издательство издательского объединения «Ви- ща школа» КАК РАБОТАТЬ С ПОСОБИЕМ Текст учебника по языку ФОРТРАН разделен на отдельные пор- ции. После большинства порций предлагается одно или несколько заданий для проверки усвоения этого материала и закрепления навы- ков, необходимых для выполнения дальнейшей работы. Учебник по- строен таким образом, что для выполнения любого задания, входящего в порций), вполне достаточно сведений, содержащихся в этой порции и ей предшествующих. Чтобы усвоить язык ФОРТРАН, необходимо строго соблюдать сле- дующие правила работы с программированным пособием: 1. Все задания выполняйте самостоятельно. Не заглядывайте в от- вет раньше, чем задание будет выполнено. 2. Обязательно записывайте ответы в свою тетрадь, даже в тех случаях, когда они кажутся очевидными. 3. Когда ответ записан, сравните его с приведенным в книге. Если допущена ошибка, не ограничивайтесь ее исправлением. Очень важно выяснить причину ошибки. Для этого, возможно, придется еще раз прочитать последнюю порцию, а иногда и несколько предыдущих. 4. В ряде случаев на одно и то же задание могут быть даны различ- ные правильные ответы и тогда может оказаться, что Ваш ответ верен, хотя он и не совпадает с приведенным в учебнике. Свидетельством хорошего понимания изучаемого материала будет служить Ваша уверенность в эквивалентности обоих ответов. 5. Приступайте к изучению новой порции только после усвоения предыдущей и правильного выполнения содержащихся в ней заданий. Соблюдая указанные требования, Вы сможете хорошо усвоить ФОРТРАН и решать широкий круг задач с помощью ЕС ЭВМ.
Глава I ПРЕДСТАВЛЕНИЕ ОБЪЕКТОВ ОБРАБОТКИ В ФОРТРАНЕ Порция 1 Программа на ФОРТРАНе Для того, чтобы использовать вычислительную машину для реше- ния какой-либо задачи, алгоритм решения этой задачи необходимо представить в виде соответствующей программы. Программа — это конечная последовательность четко определенных инструкций (операторов), «понятных» машине, смысл и порядок выпол- нения которых строго установлен. Составление программы на языке машинных операторов, т. е. управляющих кодов, непосредственно воспринимаемых и выполняемых машиной, является трудоемким и утомительным процессом. Программирование задач значительно уп- рощается при использовании специальных языков программирования, одним из которых является ФОРТРАН. Язык ФОРТРАН предназна- чен для решения широкого круга научных и инженерных вычисли- тельных задач. Программа, написанная на ФОРТРАНе, может быть выполнена на любой машине, снабженной транслятором с этого языка. Трансля- тор — это программа, которая переводит программу, написанную на ФОРТРАНе, на язык конкретной машины. В функции транслятора входит не только перевод с одного языка на другой, но и указание некоторых ошибок, допущенных програм- мистом при написании программы. Программа на ФОРТРАНе назы- вается исходной относительно транслятора, или ФОРТРАН-програм- мой, а полученная в результате работы транслятора эквивалентная программа на языке конкретной машины — рабочей программой. ФОРТРАН-программа может состоять из одного головного модуля и нескольких других программных модулей, каждый из которых может быть так называемым процедурным модулем (внешней функцией или подпрограммой) и модулем-блоком данных. Единицами языка, из которых составляются программные модули, являются предложения и примечания. Последние включаются в про- грамму в качестве комментариев и на ход ее выполнения никакого влияния не оказывают. Предложения ФОРТРАНа подразделяются на два класса: выпол- няемые (или операторы) и невыполняемые (или объявления). Опера- 6
торы определяют действия, связанные с преобразованием данных, их вводом, выводом, или предназначены для определения очередного под- лежащего выполнению оператора программы. Объявления предназна- чены для описания характеристик данных (объектов обработки); спо- собов их организации; информации, используемой для редактирования Таблица 1 Тело модуля Порядок следования предложений в головном модуле Объявления форматов Объявления спецификаций Объявления начальных данных Объявления внут- ренних функций Операторы Заключительная строка END Раздел операто- ров данных; классификации программных модулей и подразделяются со- ответственно на: 1) объявления спецификаций; 2) объявления начальных данных; 3) объявления формата; 4) объявления внутренних функций; 5) объявления заголовков модулей. Таблица 2 Тело модуля Порядок следования предложений в процедурном модуле Объявление заголовка модуля Объявления форматов Объявления спецификаций Объявления начальных данных Объявления внут- ренних функций Операторы Заключительная строка END Раздел операто- ров Каждый программный модуль состоит из заголовка модуля (кроме головного модуля, у которого заголовок отсутствует) и тела модуля. Тело любого модуля составляет последовательность предложений, завершающуюся специальной заключительной строкой END. Тело головного (или главного) и процедурных модулей обязатель- но включает раздел операторов, которому могут предшествовать объяв- ления спецификаций и форматов. 7
Головная программа Процедура । Процедура Процедура i . j. ! J; i-- Процедура Процедура Процедура ГТ Процедура р J Процедура Процедура ,. Раздел операторов должен содержать по крайней мере один опера- тор и может содержать объявления внутренних функций, форматов и начальных данных. При этом объявления внутренних функций долж- ны предшествовать всем операторам, а объявления начальных данных и форматов могут размещаться в любом месте раздела операторов. Табл. 1 и 2 иллюстрируют порядок следования предложений в голов- ном и процедурном модулях. Таким образом, все объявления спецификаций должны распола- гаться до объявления внутренних функций, которые, в свою очередь, должны предшествовать первому оператору. Объ- явления формата можно располагать в любом месте модуля между за- головком и заключитель- ной строкой. Объявле- ния начальных данных могут стоять в любом месте раздела операто- ров. В процессе выполне- ния ФОРТРАН-прог- раммы головной модуль может вызывать к испол- нению другие процедур- ные модули, которые, в свою очередь, также могут обращаться к другим процедурным моду- лям (однако, не к головному модулю); при этом никакой из процедур- ных модулей не может обращаться сам к себе как непосредственно, так и посредством других модулей. (В этом случае говорят, что в языке недопустимо рекурсивное выполнение программных модулей). Выпол- нение каждой вызванной внешней процедуры завершается возвратом в вызвавший ее программный модуль. Схематически структуру ФОРТРАН-программы можно изобразить в виде схемы, пример ко- торой представлен на рис. 1, где сплошными стрелками показаны воз- можные обращения одного программного модуля к другому, а рядом проходящими пунктирными линиями показаны возвраты, следующие после их выполнения. Задание. 1. Что такое исходная и рабочая программа? 2. Какие функции выполняет транслятор? 3. Из каких компонент может состоять ФОРТРАН-программа? 4. На какие классы подразделяются предложения ФОРТРАНа? 5. В чем различие структуры головного и процедурного модулей? 6, Назовите типы объявлений в языке ФОРТРАН. Рис. 1 8
Порция 2 Алфавит ФОРТРАНа Литеры языка программирования — это основные, неделимые зна- ки, в терминах которых пишутся тексты на этом языке. Некоторый фиксированный набор литер, используемых для построения компонен- тов языка, называется алфавитом этого языка. Алфавит стандарта ФОРТРАНа включает три группы литер: 1) Буквы — все прописные буквы латинского алфавита 1: А, В, С, D, Е, F, G, Н, I, J, К, L, М, N, О, Р, Q, R, S, Т, U, V, W, X Y Z ’ 2)’ Цифры: 012345678 9. 3) Специальные литеры: Литера Название литеры пробел 2 + плюс — минус ♦ звездочка / косая черта = равно , запятая точка ( левая скобка ) правая скобка $ денежный знак Перечисленные литеры и только они используются для записи ФОРТРАН-программ. Порядок, в котором перечислены литеры языка, специального значения не имеет. Заметим, что пробел, за исключением особо оговоренных случаев, самостоятельного значения не имеет и может использоваться свободно для удобства чтения. Из литер составляются более сложные конструкции, имеющие опре- деленный смысл в языке программирования. В ФОРТРАН/EC денежный знак задается символом Q и отнесен к буквам. Для записи текстовых констант и примечаний в ФОРТРАН/EC мож- но использовать буквы русского алфавита. В алфавит ФОРТРАН/ЕС введены дополнительно литера & (коммерческое И) и ’ (апостроф). 1 В некоторых реализациях языка для отечественных машин набор буквенных литер расширен посредством включения в него букв русского алфавита, отличных по написанию от латинских. В других реализациях буквы русского алфавита можно использовать только для записи текстовых констант и примечаний. При изложении языка в настоящем пособии мы также будем использовать буквы русского алфавита в текстовых константах и примечаниях. 2 В некоторых случаях при написании программ пробел графически задается символами i_j или Ъ. 9
Таблица 3 Ключевые слова языка ФОРТРАН Хе п/п На ФОРТРАНе Транскрипция Значение 1 ASSIGN ТО s'sainta] присвоить 2 АТ* det] 'baek'speis] начиная с (от) 3 BACKSPACE шаг назад 4 BLOCK DATA 'bbk'deito] блок данных 5 CALL ko:l] вызвать 6 COMMON 'komon] общий 7 COMPLEX 'kompbks] kan'tinju] комплексный 8 CONTINUE продолжать 9 DATA 'deita] di:'bAg ] данные 10 DEBUG * отладить 11 DEFINE FILE * di'fain'fail] di'menjn] объявить файл 12 DIMENSION размерность 13 DISPLAY * dis'plei] вывести 14 DO du:] выполнить 15 DOUBLE PRECISION 'dAbl pri'si?an] повышенная точность 16 END end] конец 17 ENDFILE 'endfail] конец файла 18 ENTRY* 'entri] вход 19 EQUIVALENCE i'kwivalans] 'era] эквивалентность 20 ERR* ошибка 21 EXTERNAL eks'tarnl] внешний 22 FIND* faind] найти 23 FORMAT 'fa : meet] формат 24 FUNCTION 'fAT]kJan] функция 25 GO TO 'gouta] перейти к 26 IF [if] если 27 IMPLICIT * im'plisit] неявный 28 INIT * i'nijal] контроль присвоения 29 INTEGER 'intad^a] целый 30 LOGICAL 'bdBikal] логический 31 NAMELIST ♦ 'neimlist] список имен 32 PAUSE pa:z] пауза 33 PRINT * print] печатать 34 PUNCH* pAntj] перфорировать 35 READ ri:d] читать 36 REAL 'rial] вещественный 37 RETURN ri'ta:n] возвратить 38 REWIND rkwaind] перемотать 39 STOP stop] стоп 40 SUBCHK * 'sAb. skript'tfek] контроль индекса 41 SUBROUTINE ['sAbru:'ti:n] подпрограмма 42 SUBTRACE * [ 'sAbru: 't i :n'tre is] контроль вызовов п/п 43 TRACE * [treis] прокрутка 44 TRACE OFF* ['treis of] выключить прокрутку 45 TRACE ON * ['treisbn] включить прокрутку 46 UNIT* r'ju:nit] устройство 47 WRITE [rait] писать 10
Таблица 4 Логические операции На ФОРТРАНе Транскрипция Значение .AND. .NOT. .OR. [aend] [not] [э:] логическое умножение (А) логическое отрицание (1) логическое сложение (V) Таблица 5 Логические значения На ФОРТРАНе Транскрипция Значение .FALSE. [fo:is] ЛОЖЬ .TRUE. [tru:] истина Таблица 6 Операция отношения На ФОРТ- РАНе Полный текст Транскрипция Значение .EQ. .GE- .GT. .LE. .LT. .NE. EQUAL GREATER OR EQUAL GREATER THAN LESS OR EQUAL LESS THAN NOT EQUAL ['i :kwal] ['greitaroir'kkwal] ['greita dan] ['lesor'i:kwel] ['les dan] [not'kkwal] равно (=) больше или равно (» больше (» 'меньше или равно (^) меньше «) не равно (=/=) Цифра 0 (нуль) в ФОРТРАН/EC в отличие от буквы О перечер- кивается косой чертой (в). Задание. 1. Сколько специальных литер имеется в ФОРТРАНе? Назовите их. 2. Каковы различия в основных литерах между стандартом ФОРТРАНа и его реализацией на ЕС ЭВМ? Порция 3 Ключевые слова В языке ФОРТРАН выделен некоторый набор ключевых (служеб- ных) слов, которые имеют фиксированное начертание и в определенном контексте имеют фиксированное значение. Используя ключевые слова, необходимо придерживаться их точ- ного написания, определенного языком. Кроме того, ключевые слова 11
нельзя заменять другими (синонимами). Так, например, слово LOGICAL не может быть заменено словом BOOLEAN, а слово SUB- ROUTINE словом SUBPROGRAM. В табл. 3 приводится перечень ключевых слов языка ФОРТРАН/ЕС, их транскрипция и русский перевод. Ключевые слова перечислены в алфавитном порядке. Звездочкой отмечены ключевые слова ФОРТРАН/EC, отсутству- ющие в стандарте. Ключевые слова используются при построении различных пред- ложений языка — операторов и объявлений. Как правило, предло- жения начинаются соответствующими ключевыми словами, чем облег- чается определение видов предложений ФОРТРАНа. Специальные слова используются для обозначения символов логи- ческих операций, операций отношения и логических значений. Такие слова, в отличие от ключевых, выделяются с обеих сторон точками. Список этих слов приведен в табл. 4—6. Задание. 1. Сколько ключевых слов используется в стандарте ФОРТРАНа? Сколько таких слов в языке ФОРТРАН/ЕС? 2. Как обозначаются логические операции и логические значения в ФОРТРАНе? 3. Какие операции отношения используются в языке ФОРТРАН и как они обозначаются? Порция 4 Типы данных Данные в ФОРТРАН-программах могут быть представлены в виде констант или обозначений — имен переменных (или идентификато- ров). Стандартом допускаются данные шести типов: целые вещественные двойной (повышенной) точности комплексные логические текстовые Первые четыре типа составляют группу числовых данных (чисел). Каждый из типов данных имеет свой собственный смысл и может иметь различные способы машинного представления. Для каждого из типов данных определен набор элементарных операций. Данные целого типа являются точным представлением целых чисел; данные вещественного типа являются приближенным значением вещественных величин, данные повышенной точности также являются приближенным значением вещественных величин, однако степень приближения их выше, чем степень приближения для вещественных. 12
Данные всех этих трех типов могут быть положительными, отри- цательными или равными нулю; нуль не является ни положительным, ни отрицательным. Данные комплексного типа представляются в форме упорядочен- ной пары вещественных чисел. Первое из них представляет действи- тельную, а второе — мнимую часть комплексного числа. Стандарт языка не определяет диапазон и точность представления числовых значений; в каждой конкретной реализации они могут быть различными. Данные логического типа могут принимать одно из двух значений: .TRUE, или .FALSE, (истина или ложь). Текстовые данные представляют собой последовательности сим- волов, которые могут включать любые символы, допустимые данной версией транслятора. Понятие вещественной величины (и, соответственно, повышенной точности и комплексной) в языке ФОРТРАН отличается от общеприня- того. Так, иррациональные числа, периодические дроби и точное пред- ставление последних через обыкновенные дроби в ФОРТРАНе не рас- 2 сматриваются. Разумеется, можно записать, например, -х- в виде 2/3 или J/2 в виде SQRT (2.), однако такие записи являются в ФОРТРАНе не константами, а выражениями, так как они содержат знаки операций (/) или обозначения функций (SQRT). Кроме перечисленных типов данных в ФОРТРАН/ЕС введены шестнадцатеричные константы, которые широко используются в ЕС ЭВМ для представления адресов памяти, содержимого регистров и др. В виде шестнадцатеричных констант (кодов) печатаются также так называемые дампы — содержимое памяти в момент прерывания выпол- нения программы (которое может быть вызвано, например, при попытке деления на нуль) и т. п. Задание. Перечислите типы данных, используемых в языке ФОРТРАН. В ФОРТРАН/ЕС. Порция 5 Константы. Константы целого типа Константа — это данное, которое появляется в программе в явном виде. Константы представляются в языке в виде некоторых последова- тельностей образующих их литер, определяющих как тип, так и зна- чение константы. Например, константа 2.718282 представляет вещест- венное десятичное число с фиксированной точкой с одним знаком в целой части и шестью знаками после десятичной точки; константа 273 является целым десятичным числом, представленным тремя зна- ками (цифрами). 13
В ФОРТРАН-программе разрешается использовать шесть типов констант: це/1ые, вещественные, повышенной точности, комплексные, логиче- ские, текстовые. В ФОРТРАН/EC имеется еще один тип констант — шестнадцате- ричные константы. Константа целого типа записывается в виде непустой строки цифр, перед которой может стоять знак плюс или минус. Целая константа обозначает целое десятичное число *. Знак плюс перед положительными константами можно опускать; перед отрицательной константой обязательно должен стоять знак ми- нус. Таким образом, запись констант целого типа в ФОРТРАНе не отличается от общепринятой записи целых десятичных чисел. Однако абсолютное значение целой константы для каждой ЭВМ имеет свой верхний предел. Так, для ЕС ЭВМ это —231 < i < 231 — 1 = 2 147 483 647. Задание. 1. Какие данные называются константами? 2. Можно ли определить по написанию константы ее тип? 3. Определяет ли написание константы ее значение? 4. Какие константы называются константами целого типа? Порция 6 Вещественные константы Имеется две формы представления вещественных констант: форма F и форма Е. Форма F — это форма представления вещественной константы с фиксированной десятичной точкой. В форме F вещественная константа записывается так же, как деся- тичные дроби, только вместо десятичной запятой, отделяющей целую часть числа от дробной, ставится точка (запятая же в ФОРТРАНе имеет другое назначение и в записи чисел не употребляется). Примеры записи вещественных констант в форме F: 25. .36 г.256 2.5 25.г 6.25 2.718282 Десятичная точка в записи вещественной константы в форме F может стоять в начале или в конце числа, то есть целая или дробная часть, равная нулю, может быть опущена, но не обе одновременно, например: число нуль может быть записано в виде: Q.&-, г.; .г, а числа 125.г и г.537, соответственно, в виде 125. и .537. Форма Е. Иногда в математике пользуются изображением чисел с помощью десятичного порядка, т. е. масштабного множителя, выра- женного в виде целой степени десяти. Например, число 3,14159 можно 1 В двух операторах стандарта языка ФОРТРАН: STOP и PAUSE, исполь- зуются восьмеричные (не более чем 5-разрядные) константы. 14
записать как 3141.59 X 10“3, а число 15000000 можно записать в виде 1.5 X 107. Порядком, или масштабным множителем, числа 3141.59 X X КГ3 является 10“3, мантиссой — 3141.59, а числа 1.5 X 107, соот- ветственно, 107 и 1.5. В ФОРТРАНе допускается аналогичная запись вещественных кон- стант и называется формой Е, или формой с плавающей запятой. Особенности записи вещественных констант в форме Е: 1),для обозначения десятичного порядка, вместо 10, употребляется специальный символ — буква Е; 2) знак умножения между десятичным порядком и мантиссой опус- кается; 3) мантиссой может быть как целое число, так и десятичная дробь, представленная в форме F; 4) показатель степени может быть одно- или двузначным целым по- ложительным или отрицательным числом; 5) наличие как мантиссы, так и показателя степени в форме Е обяза- тельно (даже в том случае, когда мантисса равна единице, а показа- тель степени равен нулю или единице); 6) отсутствие знака (числа или порядка) обозначает, что этот знак плюс; 7) вещественная константа в ФОРТРАНе не может быть представ- лена одним порядком (без мантиссы). Форма Е удобна для представления больших и малых вещественных чисел. Примеры правильной записи вещественных констант в форме Е: 2.5Е—12; 1.7Е19; 314Е1; 3.14Е##; 3.14Е#; 273Е£3; .273E3; 2718.Е—1; —1.71Е—7; —1.2Е15. Заметим, что форма Е используется для изображения (записи) только вещественных (а не целых) констант. Константы 12Е2,12.Е2,12.0ЕФ2— являются вещественными (12&&.&), а не целыми (12-&Ф), и эти числа (12Е2 и 12В''&) не взаимозаменяемы, поскольку формы представления целых и вещественных чисел в памяти ЭВМ и способы выполнения над ними арифметических операций различны. Следует иметь в виду, что только определенное количество цифр вещественной константы может быть представлено в памяти конкрет- ной ЭВМ. Если требуется представить вещественную константу с коли- чеством цифр большим, чем это допустимо для данной ЭВМ, ее пред- ставляют в форме константы повышенной точности (обычно для пред- ставления такой константы в памяти ЭВМ отводится дополнительное поле памяти). Заметим, что вещественные константы имеют две формы изобра- жения (форма F и форма Е) только во внешнем представлении чисел при записи программы, а во внутреннем (в памяти ЭВМ) они автомати- чески представляются одинаково — в виде мантиссы и порядка. Так, записи констант 314.159Е—2; .314159Ев1; 3.14159E# и 3.14159 пред- ставляют собой равные константы и эквивалентны по внутреннему 15
представлению в памяти машины. Они отличаются только внешним представлением. В табл. 7 приведены примеры допустимой и недопус- тимой записи вещественных констант. . Задание. 1. Запишите следующие числа в виде вещественных кон- стант в форме F и форме Е: а) 347; б) 74,32; в) —5100; г) 1015; д) 0,0000000834; е) —20; ж) —45,21“12. Таблица*7 Правильная запись вещественных констант Недопустимая запись вещественных констант Ошибки 4-15.#16 —5.£Е+6 -1.2E1# 6.2#5Е12 25.32Е+5 —9.Я2Е4- 2Е1 85Е## 3.75 —2.1Е—2 + 15,#16 —5.#Е+6.5 —1.2Е2#3 6.2#5Е83 Е+5 —9.#2Е 2Е.—1 85Е#.# 3.75. —2.1.Е—2 запятую употреблять нельзя показатель степени должен быть целым показатель степени не может быть трехзначным числом число слишком велико для большинства ЭВМ нет мантиссы нет порядка лишняя точка показатель степени должен быть целым лишняя точка лишняя точка 2. Все приведенные ниже записи неприемлемы в качестве вещест- венных констант. Почему? а) —235,&&&; б) 2Е+4.1; в) 4,78256Е — 12; г) +2856; д) ЗЕ—43.; е) 25.-04Е98. 3. Определите, являются ли в каждом случае две рядом стоящие кон- станты записью одного и того же числа: а) 16.9 + 16.9; б) 23000. 2.3Е4; в) 2.5Е02 250; г) 25Е1 .025ЕЗ; д) 3543.Е—3 3.543; е) .3543Е04 3.543Е#. П о р ц и я 7 Константы повышенной точности Вещественные константы могут представляться с обычной (форма Е) и повышенной точностью (форма D). Для изображения вещественных чисел повышенной точности и используется форма D (повышенной точности — DOUBLE PRECISION). Число в форме D записывается следующим образом: после целой или вещественной константы (ман- тиссы) ставится буква D и любое одно- или двузначное целое положи- тельное или отрицательное число (показатель степени). Например, число е в форме F записывается как 2.718282, а в форме D — как 2.718281828459045D0. В остальном правила записи констант в форме D те же, что и для вещественных констант с плавающей запятой (фор- 16 16
ма Е). Константы повышенной точности употребляются тогда, когда необходимо производить вычисления с повышенной точностью. Точ- ность приближения для константы повышенной точности стандартом ФОРТРАНа не определяется, она должна быть больше, чем для ве- щественной. Комплексные константы. Комплексная (COMPLEX) константа за- писывается в виде двух вещественных констант, разделенных запятой и заключенных в круглые скобки. Первая константа является записью действительной части комплексного числа, а вторая — мнимой. При- меры записи комплексных констант: Комплексное число Представление в ФОРТРАНе 14-1 (1Л,1Л) или (1,1.) 5.3 4-4.21 (5.3,4.2) 4Z (£.,4.) 5 (5., Q.) i 1 (1..-&.) Обе части комплексной константы подчинены правилам записи вещественных констант с плавающей или фиксированной запятой. Ни мнимая, ни действительная часть комплексного числа не может быть представлена константой типа повышенной точности. Например, запись (.64D8, —25.3) или (.6475621D7, 23.4534D8) недопустимы, а также недопустимы записи (Я, 1.), (1.,1), (1,1) и (-&,1), так как в них действительная или мнимая часть комплексного числа (или обе) пред- ставлены константами целого типа. В ФОРТРАН/EC этих ограничений нет. Логические константы. Имеются две логические константы: .TRUE, (истина) и .FALSE, (ложь). При написании этих констант точки справа и слева от слов TRUE и FALSE обязательны. Текстовые константы. Текстовая константа записывается в виде: пН^... tn Здесь Н — литера алфавита, служащая признаком константы текс- тового типа; п — целая константа без знака, значение которой равно количест- ву символов, составляющих данную текстовую константу; /i t2 ... tn — значение текстовой константы, представленной ука- занной записью, где каждое (i = 1, 2, ..., п) — любая литера, до- пустимая в данной версии транслятора. Пробел является значащим символом в текстовой константе. При- меры записи текстовых констант: Запись на ФОРТРАНе Значение текстовой константы 5ННОМЕР НОМЕР 19НЗНАЧЕНИЯ ЗНАЧЕНИЯ^ПЕРЕМЕННЫХ 17
ПЕРЕМЕННЫХ 5HX2(_j = Х2Ш = Lj 4Н1234 1234 - Текстовые константы могут быть использованы в объявлениях формата и начальных данных (см. порции 21, 49) и в списках фактиче- ских параметров в операторе CALL (см. порцию 73), а в ФОРТРАН/ЕС и в указателе функции. В ФОРТРАН/EC текстовые константы, кроме того, используются в объявлениях типа, так как эти объявления могут совмещаться с объявлением начальных данных. В отличие от стандарта, допускающего только одну вышеприведен- ную форму записи текстовых констант, в ФОРТРАН/EC допускается еще одна форма: текстовая константа заключается в апострофы, на- пример, ’СТРОКА’. Если в строке необходимо задать апостроф как значащий символ, его представляют двумя апострофами. Например, значение константы ’’’СТРОКА’” есть ’СТРОКА’. Длина текстовой константы в символах в ФОРТРАН/EC не долж- на быть больше 255. Шестнадцатеричные константы. Шестнадцатеричная константа представляется в ФОРТРАН/EC строкой шестнадцатеричных цифр, которой предшествует литера Z. Шестнадцатеричная константа не считается числовым данным и, следовательно, не может иметь знака. По этой же причине в шестнад- цатеричной константе ведущие нули являются значащими. В этом смысле шестнадцатеричные константы аналогичны текстовым и, как и текстовые, не могут служить операндами в выражениях. Однако, в от- личие от текстовых констант, шестнадцатеричные константы не могут быть использованы в качестве фактических параметров процедур. Примеры записи шестнадцатеричных констант: Z'Q’IA, Z128CA. Шестнадцатеричные константы могут использоваться только для задания начальных значений переменных в объявлениях начальных данных и явного описания типа (см. порц. 17,21). При присвоении шестнадцатеричная константа выравнивается на позиции принимаю- щего поля ^право; если она содержит больше цифр, чем может быть размещено в поле переменной, избыточные левые цифры теряются (усекаются); если цифры константы не заполняют всего поля перемен- ной, его левые позиции заполняются шестнадцатеричными нулями. Задание. 1. Запишите на ФОРТРАНе вещественную константу 3.14159265358979 в форме D. 2. Запишите на ФОРТРАНе следующие комплексные числа: а) 5,2 +_ 3,7/; б) 3 + 4/; в) 3 X 10“2 + 0,757; г) 1,5 — г, д) 5 — — 57; е) /3 ц ж) V2. 3. Сколько имеется логических констант? Запишите их. 4. Запишите следующие последовательности символов в виде тек- стовых констант: а) ТАБЛИЦА; б) РЕЗУЛЬТАТЫ ВЫЧИСЛЕНИЙ; в) СИМП- 18
ЛЕКС-МЕТОД; г) МЕХ. ШМАТ. ШФ-Т.; д) Y=; е) Z (2,3) ==; ж) SIN (2) = 5. Запишите приведенные в предыдущем задании последователь- ности символов в виде текстовых констант, используя обе допустимые в ФОРТРАН/EC формы. Порция 8 Имена (идентификаторы) Для обозначения (именования) объектов, из которых строится и которыми оперирует программа на ФОРТРАНе, используются спе- циальные языковые конструкции, называемые именами (или иденти- фикаторами). Имя — это последовательность букв и цифр, начинающаяся с бук- вы; общее число литер, составляющих имя, в ФОРТРАНе не должно превышать шести. Имя выбирается составителем программы по его усмотрению. По- этому рекомендуется выбирать имена так, чтобы они по возможности указывали на естественный смысл обозначаемых объектов. Например, XI, Х2 — координаты точки, S# — начальное расстояние. За некоторыми объектами — основными внешними и встроенными функциями — закреплены определенные имена. Однако, если в не- котором программном модуле та или иная из этих функций не исполь- зуется, ее имя в этом модуле может быть использовано для обозначе- ния какого-либо другого объекта. Очевидно, имена различаются не только литерами, входящими в них, но и позициями, занимаемыми этими литерами. Например, имена АВС, САВ, ВАС и СВА — различны. Между литерами внутри имени допускается использование про- белов, которые могут повысить читабельность программы. Например, последовательности литер METOD1, METOD^jl и М^Е^Т^О^О ( 11 обозначают одно и то же имя. При вводе программы в память ма- шины пробелы сохраняются лишь в текстовых константах и автомати- чески опускаются в остальных позициях. Синтаксис языка ФОРТРАН допускает использование в качестве имен ключевых слов (разумеется, с учетом того, что размер имени не может превосходить шести литер), что, однако, может значительно ухудшить наглядность программы. Поэтому пользоваться ключевыми словами как именами не рекомендуется. Два или несколько различных имен без специальных на то ука- заний не могут быть использованы для обозначения одного и того же объекта, так же как и одним именем не могут быть обозначены в одном программном модуле различные объекты. Вместе с тем, если одно и и то же имя используется в разных программных модулях, оно, во- обще говоря, обозначает различные объекты. Для того, чтобы такое 19
имя обозначало один и тот же объект, необходимы специальные ука- зания — в объявлении COMMON или через аппарат параметров про- цедур. Эти же средства позволяют один и тот же объект, используемый в разных программных модулях одной и той же программы, обозна- чать различными именами. Примеры имен СК GAMMA6 Ml Fl MIN А12 SUM T5 MAX A213 BIG2 MINIM D IF REAL Ниже приведены последовательности литер, недопустимые в ка- честве имен в языке ФОРТРАН: Последовательности литер Ошибка 2СК М4/3 Начинается не с буквы Содержит литеру, не яв- ляющуюся ни буквой, ни цифрой М-21 MAXIMUM » » Содержит более шести литер Задание. 1. Из приведенных ниже последовательностей литер вы- берите те, которые допустимы в качестве имен в языке ФОРТРАН: RUNGKT, R, KI, IK, R.—К., R.K, С * 5, DITTO, AMODX, NUM (1), PROG, SYMPl-jI, DUMP, ERRSET. Порция 9 Память ЭВМ Важнейшим понятием в современных ЭВМ является понятие памя- ти, которое находит свое четкое преломление в языках программиро- вания. Память современных ЭВМ представляет собой некоторую физиче- скую среду, приспособленную для хранения кодов, которыми могут быть как представленные в некоторой системе кодирования данные (целые, вещественные и т. д.), так и программы (алгоритмы). Как было отмечено ранее, для выполнения на ЭВМ любого задания соответствующий алгоритм должен быть представлен, в конечном сче- те, на машинном языке, непосредственно интерпретируемом данной машиной. Если возникает необходимость в описании алгоритма на не- котором более удобном для данного случая языке программирования, то процесс решения задачи расчленяется на несколько этапов (шагов): например, трансляция на некоторый промежуточный язык и получе- ние объектного модуля; загрузка и получение загрузочного модуля и др. 20
По характеру связи с процессором (переработчиком информации) различают два вида памяти: внутреннюю (или оперативную) и внешнюю. Отличительной особенностью внутренней памяти является воз- можность непосредственного доступа к ее отдельным полям со’стороны процессора. Минимальные из этих полей называются байтами. Обыч- но их объем составляет 8 двоичных разрядов. Как правило, байты могут коммутироваться в более крупные еди- ницы: полуслова (два байта), слова (4 байта), двойные слова (8 бай- тов). При этом объединяться могут не любые поля, а физически распо- ложенные определенным образом в непосредственном соседстве друг с другом. Для обращения к полям памяти — посылки в них кодов (режим записи) или снятия копий с содержащихся в них кодов (режим чте- ния) — полям памяти присваиваются номера — адреса, коды которых используются при записи программ на машинных языках и выполне- нии программ. Эквивалентом понятия адреса в языках программирования явля- ется понятие имени. Для хранения констант, значений переменных и массивов в памяти ЭВМ отводятся поля соответствующих размеров. Коды, размещаемые в эти поля, расшифровываются процессором согласно с типом вели- чин, поскольку один и тот же набор нулей и единиц в ячейке с двоич- ным кодом, рассматриваемый, например, как текстовая константа или вещественное число, обозначает разные значения. Таким образом, наличие в языке различных объектов (целых, вещественных и т. д.) вызывает необходимость распознавать тип дан- ного по его идентификатору. С этой целью используется концепция объявления (описания) типов имен, реализованная в ФОРТРАНе частично (для целого и ве- щественного типов) неявным образом. Описание имен простых переменных или массивов в программе в некоторых объявлениях (или их появление в программе согласно неявному определению типа) служит информацией для выделения соответствующих полей данным, обозначаемым (идентифицируемым) этими именами. Появление описаний используется для резервирова- ния полей памяти, но оно в ФОРТРАНе не определяет никаких зна- чений у данных. Тем не менее наличие описаний может служить доста- точной информацией для того, чтобы сделать вывод о невозможности решения задачи посредством размещения всех ее программных моду- лей во внутренней памяти, если размер «заказанных» полей в сумме окажется превосходящим общий объем внутренней памяти, отводи- мой для данных. Эта информация может быть выявлена транслятором и использована для сегментации программы или сообщена пользовате- лю в качестве указания на необходимость сегментации данных, т. е. разделения их на части, размещаемые во внешней памяти и вводимые во внутреннюю память по мере надобности. В последнем случае может 21
возникнуть необходимость во внесении надлежащих изменений в алго- ритм выполнения задания. Внешняя память (иначе, внешняя среда) обладает своими поло- жительными качествами: она удобна для длительного хранения инфор- мации, отличается большой емкостью и возможностью отделения от машины (магнитные ленты, сменные диски, перфокарты). При этом, если данные предполагается в дальнейшем использовать для внутрен- ней обработки, эти данные на внешних носителях (во внешней среде) могут храниться в форме внутреннего машинного представления, ко- торое во многих случаях не совпадает с внешним представлением, пред- назначенным для обозрения человеком выводимых данных на печати (вставка пробелов для удобочитаемости, гашение ведущих нулей у целой части чисел и др.). Определив имя (описав его в случае недостаточности неявного за- дания), можно использовать это имя в записи операторов при состав- лении программы. Однако при этом следует иметь в виду, что какова бы ни была величина, она остается неопределенной до тех пор, пока не будет выполнено присвоение ей значения: отведенное ей поле памя- ти «свободно» и чтение из него (снятие копий) запрещено (не имеет смысла), пока в это поле не будет заслано некоторое значение соответ- ствующего типа. Вместе с тем, на что мы обращаем особо Ваше вни- мание, у однажды определенной величины в процессе выполнения программы значение может не только переопределяться, но в некото- рых случаях может стать снова неопределенным. Задание. 1. Какие виды памяти Вы знаете? 2. Какие режимы обращения к памяти определены в программи- ровании? 3. Что называется байтом? 4. Как может быть использована транслятором информация об именах переменных и массивов? Порция 10 Внутреннее представление объектов в ЕС ЭВМ Память ЕС ЭВМ организована в виде последовательности зануме- рованных 8-битовых байтов. Каждые четыре байта с последователь- ными номерами, первый из которых имеет номер, кратный 4, состав- ляют слово — основную единицу обработки в данной серии машин. При выполнении отдельных операций машина также может опери- ровать с полусловами (2 байта) и двойными словами (8 байтов). Целые неотрицательные константы представляются в слове памя- ти прямыми шестнадцатеричными кодами от (0) до 7FFFFFFF16 (231 — 1); отрицательные — дополнительными кодами от FFFFFFFFle (—1) до (—231). .22
Вещественная константа обычной точности задается в виде харак- теристики и мантиссы в следующем формате: байт] Шт 2 байтЗ байт 4 Uum 7 Мантисса Подразумевается, что точка, отделяющая целую часть от дробной, фиксирована перед первым байтом мантиссы. Порядок числа указы- вает истинное положение точки. Отрицательный порядок обозначает сдвиг точки влево, положительный — вправо на указываемое им коли- чество шестнадцатеричных разрядов. Порядок числа Р определяется по следующей формуле: Р — характеристика — 44Jle, где 4# — шестнадцатеричное представление десятичного числа 64. Для получения десятичного представления Р нужно перевести харак- теристику (прямой код) в десятичное представление и вычесть 64. Таким образом, код 41 представляет десятичное число!# (знак числа — «+», порядок равен 41—4#, т. е. 1; сдвинув точку на один шестнадцатеричный разряд вправо, имеем А1в = 1О1о). Каждый символ из набора, используемого в ЕС, кодируется ком- бинацией из восьми двоичных разрядов (т. е. комбинаций двух шест- надцатеричных цифр), и для хранения символа в памяти используется один байт. Следовательно, поле памяти можно интерпретировать как последовательность символов. Следует, однако, помнить, что хотя имеется возможность кодирования 256 различных символов (28), мно- гие восьмибитовые коды не используются. Для целых, вещественных обычной точности и логических констант в ФОРТРАН/EC отводится одно слово памяти. Для констант повышен- ной точности и комплексных отводится двойное слово. Текстовые кон- станты представляются последовательностями байтов и хранятся как. значения элементарных данных или массивов любого другого из опре- деленных в языке типов. Текстовые константы, используемые в ка- честве фактических параметров, размещаются транслятором в массиве двойных слов. Логическая константа .TRUE, представляется транслятором шест- надцатеричным кодом ####### 1, константа .FALSE.— кодом ########. Для внутреннего представления констант повышенной точности под мантиссу отводится дополнительное слово памяти, всего 14 шестнад- цатеричных разрядов: байт I 6айт2 байт3 дайт4 байт5 байта байт! байт8 “sr | , । , । , । . । . । ~т 16um 7бигпо8 Мантисса 23
Комплексные числа занимают два слова памяти и состоят из двух вещественных констант обычной точности: Действительная уасть Мнимая часть | Слобо 1 | Слобо 2 Порция 11 Переменные Операции могут выполняться не только над константами, но и над значениями переменных. Переменные в языке — это некоторым образом обозначенные объек- ты, значения которых в процессе выполнения программы могут из- меняться. В ФОРТРАНе имеется два вида переменных: простые переменные, переменные с индексами. Простые переменные обозначаются именами. Переменные с индек- сами обозначаются также именами, за которыми в круглых скобках указывается список индексов. Примеры записи простых переменных: Al, Х2, Т, R, LOG. Примеры записи переменных с индексами: А (2), Z (2, М + 1), Т (2, 1, 4), S (К, L, 1) Понятие переменной с индексами связано с понятием массива. Массивы и переменные с индексами В случае, когда программа оперирует над упорядоченными сово- купностями величин, например, компонентами векторов, элементами матриц, введение независимых обозначений для каждого из такого рода элементов оказывается неудобным. В математике в подобных случаях прибегают к использованию так называемых индексов, запи- сываемых мелким шрифтом непосредственно после обозначения, об- щего для всей упорядоченной совокупности величин, подстрочно. Например, записи S3, Clifh понимаются как третья координата вектора s; элемент, находящийся на пересечении Z-й строки и &-го столбца в матрице а, соответственно. Это понятие индексирования, с помощью которого, задавая упо- рядоченную последовательность значений индексов и обозначение для всей упорядоченной совокупности значений, можно определить ее любой отдельный элемент, широко используется в программировании. Упорядоченные совокупности величин одного и того же типа, от- 24
дельные элементы которых идентифицируются индексами, в програм- мировании принято называть массивами, а каждая отдельная из этих величин называется элементом массива. Общее для всех элементов массива обозначение, в качестве которого служит некоторое имя, на- зывается именем массива. Таким образом, имя массива обозначает все упорядоченное множество его элементов в целом. Отдельные эле- менты массива обозначаются переменными с соответствующими ин- дексами, которые, в отличие от принятой в математике формы их под- строчной записи, в ФОРТРАНе указываются после имени соответст- вующего массива в круглых скобках и разделяются между собой запятыми (если их более одного). Введем понятие обращения к переменной. Обращением к простой переменной или переменной с индексами называется извлечение ее значения или присвоение ей значения, которое может быть первичным значением переменной или новым значением. При работе с массивами в ФОРТРАНе можно обращаться к их отдельным элементам посредством соответствующих переменных с индексами (которые еще называются индексированными переменными) или ко всему массиву — ко всему множеству его элементов. В послед- нем случае указывается непосредственно имя массива (без каких- либо индексов). Следует, однако, иметь в виду, что обращение ко всем элементам массива одновременно допускается лишь в некоторых предложениях, например, в операторах ввода-вывода. Например, если, А — имя некоторого массива, представляющего собой вектор с де- сятью координатами, aS — идентификатор прямоугольного массива (матрицы) с 5-ю строками и 8-ю столбцами, то записи А (7), S (2, 8) обозначают соответственнб седьмую координату вектора А и восьмой элемент во второй строке матрицы S. Таким образом, переменная с индексами является именем отдель- ной переменной, входящей в состав соответствующего массива. Имя, используемое в записи переменной с индексами, является именем мас- сива, один из элементов которого представляет данная переменная с индексами. Стандарт языка допускает только одно-, дву- и трехмерные масси- вы (т. е. векторы, матрицы и тензоры) любых из допустимых в языке типов. ФОРТРАН/ЕС допускает массивы также любых типов размерности п, где п 7. Число индексов у переменной с индексами равно числу измерений массива, которому она принадлежит. Существенно, что в качестве индексов могут быть использованы не только целые константы, но и переменные целого типа, а также некоторые арифметические выражения, принимающие целые положи- тельные значения и называемые индексными выражениями. В таких случаях одна и та же запись в виде переменной с индексами может обозначать тот или иной элемент соответствующего массива, позиции 25
которого в массиве определяются текущими значениями соответ- ствующих индексных выражений. Так, если в некоторый момент выпол- нения программы значение переменной К равно 2, а переменной М равно 4, то переменная с индексами R (К+2,2*М—5) обозначает тре- тий элемент в четвертой строке матрицы R (так как К + 2 = 4, 2*М — 5 = 3). Индексы переменных должны принимать целые положительные зна- чения, не превосходящие некоторых максимальных значений, на- зываемых верхними границами индексов. Последние указываются в так называемых описателях массивов, задаваемых в объявлениях размерности (DIMENSION), объявлениях типа и объявлениях общих объектов (COMMON). Нижняя граница индексов всегда подразуме- вается равной I. Описатель массива представляет собой имя массива, за которым в круглых скобках указываются верхние границы соответствующих измерений, разделенные (в случае многомерных массивов) запятыми. Верхние границы массивов могут быть заданы в виде положительных целых констант или простых переменных целого типа. Описатель мас- сива может быть задан в одном из указанных видов объявлений, на- пример, в объявлении размерности или в объявлении общих блоков данных. Примеры описателей массивов: А (5, N), В (2, 3, 10), С (К, L). С одним и тем же именем массива в данном программном модуле может быть связан только один описатель типа. В случае, когда значения индексных выражений выходят за гра- ницы индексов данного массива, значение соответствующей перемен- ной с индексами считается неопределенным и оно не может быть ис- пользовано в вычислениях. Возникновение подобной ситуации сви- детельствует о наличии ошибки в программе. Имени переменной в машинной интерпретации соответствует на- звание (адрес) фиксированного поля памяти, а значением переменной в каждый момент вычислительного процесса является содержимое этого поля. Аналогично, имени массива в машинной интерпретации соответ- ствует последовательность полей памяти одинакового размера, коли- чество таких полей равно произведению верхних границ индексов. Названия отдельных полей определяются посредством имени данного массива с последующими за ним индексными выражениями, заклю- ченными в круглые скобки, т. е. посредством переменных с индексами. Следует иметь в виду, что для элементов массивов выделяются поля, расположенные одно за другим: элементы одномерных массивов раз- мещаются в порядке возрастания их индексов, двумерных массивов — в следующем порядке: за элементом с индексами (1, 1) размещается элемент с индексами (2, I), затем с индексами (3, 1) и так далее до элемента с индексами (n, I), где п — верхняя граница первого индек- са, т. е. сначала в память заносится первый столбец массива. За- 26
тем аналогичным образом размещается второй, третий столбец и т. д. вплоть до элемента (п, /и), где п — верхняя граница первого,, а т — верхняя граница второго индекса. Другими словами, в языке- ФОРТРАН элементы двумерных массивов располагаются в памяти ма- шины по столбцам. При размещении в памяти трехмерных массивов, как и двумерных, первый индекс изменяется быстрее, а третий мед- леннее остальных. Максимальное значение индекса одномерного массива равно числу элементов, содержащихся в этом массиве. Для двумерных и трехмер- ных массивов число содержащихся в нем элементов равно произве- дению верхних границ всех его индексов. Пример. Элементы массива (матрицы) с описателем Т (2, 3) будут расположены в памяти ЭВМ в следующем порядке: Т (1, 1), Т (2, 1),Т (1, 2), Т (2, 2), Т(1,3),Т (2,3), а элементы массива (тензора) с описателем RR (2,3,2) в порядке: RR (1, 1, 1), RR (2, 1, 1), RR (1, 2, 1), RR (2, 2, 1), RR (1, 3, 1), RR (2, 3, 1), RR (1, 1, 2), RR (2, 1, 2), RR (1, 2, 2), RR (2, 2, 2), RR (1, 3, 2), RR (2, 3, 2). Задание. 1. Какие виды переменных имеются в ФОРТРАНе, как они обозначаются? 2. Что называется массивом и элементом массива? Как они обо- значаются? 3. Как определяется размерность массива? 4. Что называется описателем массива? В каких предложениях языка он может быть указан? ‘ 5. Что называется границами индексов? Чему равна нижняя гра- ница индексов любого массива в ФОРТРАНе? 6. В чем состоит различие понятий описателя массива и переменной с индексами? Чем синтаксически может отличаться переменная с ин- дексами от описателя массива? 7. Описатель массива имеет вид А (2, 3). Перечислите все элементы этого массива в том порядке, в котором они размещены в памяти ма- шины. 8. Для чего служат переменные с индексами? 9. Могут ли индексные выражения принимать отрицательные, дробные или равные нулю значения? 10. Какие из приведенных ниже конструкций могут быть исполь- зованы для обозначения а) простых переменных; б) переменных с ин- дексами; в) описателей массивов: 1) Q [5, 3], 2) А (4; 2), 3) М(1, М), 4) Fx 5) Y (21), 6) А (М + 10), 7) Z(15), 8) 15Z, 9) L(K(1)), Ю) R2>3, 11) ARR(J5), 12) N (2 ♦ L + 3, M), 13) D(l. 2), 14) SUM, 15) A.B4(— 1), 16) CQ, 17) M(— 12), 18) BIO. 27
11. Что соответствует в машинной интерпретации имени простой переменной? ее значению? переменной с индексами? значению пере- менной с индексами? 12. Каков смысл понятия обращения к переменной? Порция 12 Правила записи индексов. Приведенный индекс В процессе выполнения программы одна и та же переменная с ин- дексами может обозначать различные элементы массива в зависимости от текущего значения входящих в индексные выражения переменных, что весьма существенно для реализации программ, в которых элементы массивов обрабатываются аналогичным образом. Естественно, индексные выражения строятся в соответствии с пра- вилами для построения арифметических выражений, однако в стан- дарте ФОРТРАНа разрешены только следующие виды индексных вы- ражений: Виды арифметических, выражений (допустимых в качестве индексных выражений) Пример индентификатора переменной с индексами J A(J) т А (10) J + т A(J+ 10) J — т A(J—10) А(10 * J + 5) m*J — k A(10*J —5) В приведенных примерах т, k — константы целого типа; J — пере- менная целого типа. Изменение порядка следования компонент в ин- дексных выражениях недопустимо. Примеры выражений, недопус- тимых в качестве индексных в стандарте языка: А (1& + J); В (I * 2 — 3); К (М * 2) В стандарте ФОРТРАНа не разрешается использование индекси- рованных индексов. Это значит, что переменные с индексами вида А (К (L)) не могут быть использованы. В качестве индекса переменной в ФОРТРАН/ЕС может исполь- зоваться любое арифметическое выражение целого или вещественного типа (а не только ограниченные виды выражений, допустимые стан- дартом). Если в качестве индекса используется выражение вещест- венного типа, то значение выражения автоматически преобразуется к целому типу путем отбрасывания дробной части числа. В качестве индексов допускаются индексированные переменные. В некоторых случаях требуется определить позицию того или ино- го элемента массива в линейно упорядоченном множестве его эле- ментов в памяти, называемую приведенным индексом этого элемента. 28
Для вычисления значения приведенного индекса можно восполь- зоваться табл. 8, в которой приняты обозначения: а, Ь, с — индексные выражения; Л, В, С—размеры массива по соответствующим размерностям. Максимальное количество размерностей в ФОРТРАН/EC равно 7. Приведенный индекс J элемента многомерного массива в ФОРТРАН/EC вычисляется по формуле i k J = i1+Yl Пад„+1-1), k=l /=] где 1 I 6; ik — индекс элемента по k-му измерению; Rj — гра- ничные значения по измерениям 1, ..., k (1 k /, 1 I 6). Таблица 8 Размер- ность Список верхних границ индексов Индекс Значение приведенного индекса Максималь- ное значение приведенного индекса 1 (Л) (а) а А 2 (А, В) (а, Ь) а + А-(Ь — \) А • В 3 (Л, В, С) (а, Ь, с) а-\-А • (Ь — 1) + А- В • (с— 1) А В • С Транслятор ФОРТРАН/EC в отдельных случаях выдает диагнос- тическое сообщение об ошибке, состоящей в выходе за границы допус- тимых значений индексов, когда индекс задан в виде константы. Одна- ко транслятор не реагирует на ситуацию, когда индекс, задавае- мый выражением, принимает значения вне указанного интервала (результаты вычислений, вообще говоря, могут оказаться непред- сказуемыми). Этой особенностью можно воспользоваться, когда удобными ока- зываются нулевые или отрицательные индексы. Задание. 1. Что называется приведенным индексом? 2. Чему равно максимальное значение приведенного индекса мас- сива, описатель которого задан в виде А (4, 4)? 3. Вычислите по приведенной в таблице 8 формуле значение при- веденного индекса элемента А (7, 2, 3) трехмерного массива, имею- щего описатель А (8, 8, 8). 4. Перечислите элементы трехмерного массива В (2, 3, 2) в том порядке, в котором они фиксируются в последовательности полей машинной памяти. 5. Допустимо ли стандартом ФОРТРАНа следующее представле- ние переменной с индексами: А (1-0, 2, КХ (I) + 2, 3) 6. Ответьте на предыдущий вопрос в случае использования языка ФОРТРАН/ЕС. 29
Порция 13 Спецификация массивов Если в ФОРТРАН-программе используются переменные с индек- сами, то в ней должна содержаться и некоторая дополнительная инфор- мация. Необходимо указать: 1. Какие имена поставлены в соответствие массивам (т. е. к каким переменным необходимо обращаться с помощью индексов)? 2. Каков тип переменных, составляющих каждый из массивов? 3. Сколько индексов имеет каждая из переменных? 4. Сколько элементов содержится в каждом из массивов, и каковы границы каждого индекса? Ответы на эти вопросы дают специальные предложения специфи- кации языка ФОРТРАН: объявление размерности DIMENSION объявление типа объявление общих объектов COMMON, в которых указываются описатели массивов. Описатели всех массивов, используемые в данном программном модуле, должны быть упомянуты в том же программном модуле в одном из указанных объявлений, а сами эти объявления должны в нем пред- шествовать использованию имен массивов или соответствующих пере- менных с индексами. Одно объявление DIMENSION может содержать сведения о не- скольких массивах. В программе можно употреблять любое количество объявлений DIMENSION (а также объявлений COMMON или объявлений типа). При трансляции ФОРТРАН-программы на машинный язык выделя- ются поля для хранения значений каждой новой константы и простой переменной (как мы отмечали ранее, размеры этих полей стандартны для всех величин данного типа). Для выделения памяти под массивы необходимо задать их размеры (помимо задания типа входящих в них элементов), по которым будет определен объем необходимой памяти. Последний определяется по- средством описателей массивов по содержащимся в них границам ин- дексов. Формат объявления DIMENSION следующий: DIMEN SION (список-описателей) Элементами (списка-описателей) являются описатели массивов. Размерности массивов в описгтелях могут быть представлены целыми константами без знака или именами переменных целого типа. Заметим, что размерности массивов, задаваемые в головной программе, не могут указываться именами, а должны быть заданы в любом случае только целыми положительными константами. Размерности массивов в про- 30
цедурах могут задаваться константами или именами переменных целого типа. Задание. Какую информацию содержит предложение DIMENSION и для чего она используется транслятором? Порция 14 Объявление DIMENSION Допустим, что массив МАС1 является двумерным и состоит из шести столбцов и пяти строк. Тогда соответствующее объявление DIMENSION, которое должно появиться в записи программы до появления какой-либо другой ссылки на имя MACI, будет записано так: DIMENSION МАС1 (5, 6). При'распределении памяти для массива МАС1 будет предусмотре- но 30 ячеек (5x6). Если в программе содержится объявление DIMENSION МАС1 (2, 3d), МАС2 (5, 3d), МАСЗ (3, 3d), то при распределении памяти будет отведено 60 ячеек для массива МАС1 (2 X 30), 150 ячеек для массива МАС2 (5 X 30) и 90 ячеек для массива МАСЗ (3 X 30), т. е. всего 300 ячеек. При составлении программы программист должен использовать только такие обращения к элементам массивов, при которых индексы соответствующих переменных не выходят за границы, указанные в опи- сателе этого массива (в данном случае, в объявлении DIMENSION). Напомним, что нижняя граница индекса по умолчанию всегда подра- зумевается равной единице. Если имя массива не задано в объявлении типа, а его описатель указан в объявлении DIMENSION (или COMMON), то тип элементов массива, как и для простых переменных, определяется неявно, т. е. в зависимости от первой литеры имени, может быть целым или вещест- венным (см. порцию 16). Задание. 1. В приведенных ниже записях элементов массивов зна- чение каждого из индексов является граничным. А (6, 17), G(3, 4), D(3), DX(6, 2, 2) Напишите соответствующее объявление DIMENSION для описания массивов с указанными именами. 2. Укажите ошибки в приведенных ниже записях объявлений DIMENSION: a) DIMENSION А (3, 3) В (5) N (2d) б) DIMENSION XX (N + 1, 2d) в) DIMENSION N (Id, N) г) DIMENSION Q (—Id, 2d) 31
Порция 15 Объявления типа В стандарте ФОРТРАНа используются пять типов переменных, массивов и функций. Тип указанных объектов задается явно посред- ством объявления типа, или, в случае вещественного и целого типа, неявно, посредством надлежащего выбора первой литеры имени. Формат объявления типа имеет вид: foi, v2, ..., vn Здесь: t — один из описателей типа: INTEGER (целый) R Е AL (вещественный) DOUBLE PRECISION (повышенной точности) COMPLEX (комплексный) LOGICAL (логический) ц. — имя переменной или имя массива, или имя функции, или описатель массива (i = 1, 2, ..., и). Объявления типа являются одним из видов объявлений специфи- каций и в программном модуле должны предшествовать разделу опе- раторов, как было указано в порции 1. Действие объявлений типа распространяется только на тот про- граммный модуль, в котором они заданы. Примеры INTEGER A, Bl, В2, D REAL L (5, 6), MIN, N COMPLEX R (12) Приведенные предложения определяют переменные A, Bl, В2, D как переменные целого типа или, быть может, массивы целого типа, если в данном программном модуле определены их описатели (в объяв- лениях размерности или общих объектов), L как вещественный дву- мерный массив размерности 5x6 (матрица из 5 строк и 6 столбцов), a MIN и N как вещественные переменные и R как комплексный одно- мерный массив, содержащий 12 элементов. В объявлениях типа внутри одного и того же программного модуля любое имя может появиться только один раз. Это значит, что следую- щие последовательности предложений: REAL КАР, МАС, В INTEGER MAC, BTG, В (3, 4) или REAL KIKS, IKS, KS REAL KS, LONG в языке ФОРТРАН недопустимы. 32
Задание. 1. Сколько типов переменных допустимо в языке ФОРТРАН? 2. В некотором программном модуле приведено следующее объяв- ление типа: REAL КА, КВ, S21 (4, 3) Можно ли утверждать, что имена КА и КВ используются в этом модуле в качестве имен простых переменных вещественного типа? Ответьте на тот же вопрос в отношении имени S21. 3. Допустима ли следующая последовательность объявлений LOGICAL Al, Cl, IX (4), Т (12, 4) REAL Q, Cl (16), IX 4. В программном модуле приведено следующее объявление типа: INTEGER А, В, СШ и известно, что в этом модуле отсутствуют объявления размерности и общих объектов. Можно ли утверждать, что имена А, В, С1в исполь- зуются в этом модуле в качестве имен простых переменных целого типа? Порция 16 Объекты целого и вещественного типов Стандарт ФОРТРАНа предусматривает два способа указания це- лого и вещественного типов объектов — явный и неявный. Каждый из этих способов имеет силу только в том программном модуле, в котором он определен. Имена объектов всех остальных типов должны быть указаны явно в объявлении типа в каждом программном модуле, в котором они ис- пользуются. Объекты целого типа 1. Если имя переменной, массива или функции не указано в данном программном модуле в объявлении типа и начинается с одной из букв I, J, К, L, М, N, то оно относится к целому типу. Такой способ указания типа называ- ется неявным. Примеры допустимых имен переменных целого типа при неявном указании их типа: J, INTER, LI, MIN, MAX, J2. 2. Если имя определено в программном модуле описателем INTEGER, то связанный с ним объект в данном программном модуле считается целого типа, независимо от первой буквы этого имени. 2 9-2712 33
Пример явного описания объектов целого типа: INTEGER XLET, AVT, Bl, R22, NR, IS. Объекты вещественного типа Имена вещественных переменных, массивов и функций, как и це- лых, могут быть описаны двумя способами. 1. Если первая буква имени объекта отлична от I, J, К, L, М, N и это имя не указано в данном программном модуле в объявлении типа, то тип объекта считается вещественным. Это неявный способ указания типа. При неявном задании типа трансляторы ФОРТРАНа по первой букве имен определяют принадлежность объекта к целому или вещест- венному типу. Примеры допустимых имен вещественных переменных при неявном указании их типа: APL, X, Z3, FIX, SIN, ВЪ СВ. 2. Если имя объекта в начале программного модуля определено описателем REAL, то такой объект считается вещественным, незави- симо от первой буквы его имени. Таким способом тип описывается яв- но (и отменяет неявное описание типа). Пример явного описания вещественного типа: REAL МАХ, КОМ, J, 13. Порция 17 Логические, комплексные и повышенной точности объекты Имена логических, комплексных и повышенной точности объектов (LOGICAL, COMPLEX, DOUBLE PRECISION) составляются по об- щим правилам написания имен (т. е. содержат от 1 до 6 буквенно- цифровых литер и начинаются с буквы) и обязательно должны быть указаны в том программном модуле, в котором они использованы, в объявлении типа. Язык не допускает неявного указания типа этих объектов. Примеры описания типов: DOUBLE PRECISION FOX, FOY, A COMPLEX U, V, W, Z LOGICAL Y, Zl, PX, PY Среди переменных, допустимых стандартом языка ФОРТРАН, нет переменных текстового типа; то же касается и шестнадцатеричных данных, допустимых в ФОРТРАН/ЕС. Действия над этими типами данных ограничены; в частности, с текстовыми данными они сводятся лишь к вводу-выводу текстов, используемых для придания нагляднос- 34
ти выводимой информации, для выдачи заготовленных комментариев и реплик машины в диалоговых системах. Текстовые и шестнадцатеричные данные можно определить как данные нейтрального типа. Нейтральные данные характеризуются следующими двумя свойствами: 1. Их можно хранить в полях памяти, отведенных для переменных или массивов любого типа. 2. Для сохранения значений эти данные не должны подвергаться никаким преобразованиям. Значения текстовых и шестнадцатеричных констант можно при- сваивать переменным или массивам любого из имеющихся в языке типов (целым, вещественным, повышенной точности, комплексным, логическим). При этом, поскольку комплексным значениям и данным повышенной точности обычно отводятся в памяти поля двойного раз- мера, переменным этих типов можно присваивать текстовые и шест- надцатеричные значения размера, соответственно в два раза большего. Присвоение текстовых и шестнадцатеричных значений можно осущест- вить операторами ввода или в объявлениях начальных данных —пред- ложениях DATA (см. порцию 21). Задание. 1. Сколько типов данных определено в языке ФОРТРАН? Перечислите их. 2. Сколько типов переменных определено в языке ФОРТРАН? Перечислите их. 3. К какому типу должен быть отнесен идентификатор для того, чтобы можно было присвоить ему значение текстовой константы? 4. Почему для констант не требуется описаний типа? 5. Опишите переменные W, Z2 как комплексные, Gl, G2 как логи- ческие, Al, А2 как переменные повышенной точности. Порция 18 Нестандартные данные в ФОРТРАН/ЕС В системе программирования ФОРТРАН/EC предусмотрена обра- ботка некоторых данных, отличных от допустимых стандартом языка ФОРТРАН, что позволяет в более полной мере использовать возмож- ности системы программирования. Такими нестандартными данными являются: короткие целые, длинные вещественные, комплексные по- вышенной точности, короткие логические. Короткие целые хранятся в полусловах памяти: левый бит отво- дится под знак, остальные 15 — под цифровую часть числа. Значения коротких целых должны принадлежать отрезку [—215; 215 —1], т. е. I—32768; 32767]. Пользоваться этим типом данных, позволяющим более экономно расходовать память, можно в том случае, когда заведомо из- вестно, что значения целой переменной не выходят за указанный диа- пазон. 2* 35
Длинные вещественные хранятся в двойных словах памяти и экви- валентны по внутреннему представлению вещественным повышенной точности. - Стандартные комплексные данные также занимают двойное слово. Комплексные повышенной точности занимают поля из двух двойных слов. Первое двойное слово отводится для хранения действительной части, второе — для мнимой. Таблица 9 Короткие логические зани- Тип Стандартный размер (в байтах) Нестандарт- ный размер (в байтах) мают по одному байту: кон- станта .TRUE, представляется шестнадцатеричным кодом ST, .FALSE.— кодом 0&. Как Целый Вещественный Комплексный Логический 4 4 8 4 2 8 16 1 и короткие целые, короткие логические используются для экономии памяти. Однако, так как короткая логическая кон- станта ^занимает один байт памяти, переменную такого типа можно использовать для хранения символа и интерпретировать как символ. Текстовые данные можно хранить в качестве значений переменных и массивов любого типа; однако использование для этой цели коротких логических позволяет обращаться к отдельным лите- рам как к соответствующим элементам массива. В табл. 9 приведены размеры полей памяти, выделяемые допусти- мым данным в ФОРТРАН/ЕС. Порция 19 Объявление типа данных в ФОРТРАН/ЕС Принцип определения типа переменной, принятый в стандарте ФОРТРАНа, может быть представлен схемой, изображенной на рис. 2. Обращаем Ваше внимание на то, что, как это следует из приведенной схемы, значение переменной целого типа считается меткой, если это значение было присвоено оператором ASSIGN (см. порцию 30). Таким образом, в одном и том же программном модуле одна и та же переменная в одни моменты выполнения программы может иметь своим значением некоторое значение определенного для нее типа, а в другие — текстовые или шестнадцатеричные, а переменная целого типа, кроме того, может иметь в качестве своего значения метку. Ка- кого типа значение присвоено переменной (и каково оно) зависит от последнего имевшего место в процессе выполнения программы присва- ивания. Для описания нестандартных данных набор объявлений типа в ФОРТРАН/ЕС расширен за счет введения описателей размера (в бай- тах), имеющих вид * I 36
где I — целое без знака, а именно: 2 и 4 — для коротких и стандартных целых 8 и 4 — для длинных и стандартных вещественных 16 и 8 — для комплексных повышенной точности и стандартных 1 и 4 — для коротких и стандартных логических. Например, предложение REAL*8 А (14), К22 в некотором про- граммном модуле означает, что А является именем одномерного вещест- венного массива, содержащего 14 элементов, каждый из которых зани- мает 8 байтов, а К22 — переменной вещественного типа (или именем вещественного массива, если его описатель задан в объявлении DIMENSION или COMMON) также размером 8 байтов. Отсутствие в объявлении описателя размера означает его стандартное значение, принятое для данного типа. Формат объявления DOUBLE PRECISION в ФОРТРАН/ЕС не отличается от описанного в стандарте. Формат остальных объявлений типа может быть представлен в более общем виде: t * I (список) Здесь: t — один из описателей типа (INTEGER, REAL, COMPLEX или LOGICAL); ♦/ — описатель размера; 37
(список} — это один или несколько элементов, разделенных запя- тыми, каждый из которых может быть: а) именем переменной, за которым может (не обязательно) следовать После литеры * допустимый для данного типа размер, за которым мо- жет (не обязательно) следовать заключенная в косые черты константа, присваиваемая данной переменной в качестве начального значения; б) именем массива, за которым может следовать после литеры * допустимый для данного типа размер, за которым могут (не обязатель- но) следовать заключенные в круглые скобки границы этого массива, за которыми могут (не обязательно) следовать заключенные в косые черты константы, являющиеся списком начальных значений элементов данного массива; число констант должно соответствовать числу эле- ментов массива; порядок записи констант должен соответствовать по- рядку размещения элементов массива в памяти ЭВМ по возрастанию приведенного индекса; если в списке констант несколько непосредст- венно следующих друг за другом элементов одинаковы, допускается их сокращенная запись за счет использования так называемого коэф- фициента повторения, записываемого перед константой в виде целого, равного числу повторений константы и отделяемого от нее литерой *; в) именем функции, за которым может (не обязательно) следовать после литеры * допустимый для данного типа размер. Имеется три способа определения размера данного в объявлении типа: 1) персональное указание для одного объекта — в этом случае описатель размера указывается непосредственно за именем объекта; 2) общее указание — в этом случае описатель размера указывается непосредственно за указателем типа и предписывается всем элементам списка, не имеющим специальных персональных описателей размера; 3) по умолчанию — при отсутствии персонального или общего ука- зания данному предписывается стандартный размер, соответствующий его типу. Примечания. 1. Информация о границах индексов массива может следовать после имени массива только в том случае, если этот массив не был описан в объявлении размерности DIMENSION или в объяв- лении общих объектов COMMON, находящихся в данном программном модуле перед объявлением типа. 2. Тип констант, используемых в качестве начальных значений, задаваемых в объявлении типа, должен соответствовать типу соответ- ствующих переменных и массивов. 3. Имени функции начальное значение присвоено быть не может. 4. Значения текстовых и шестнадцатеричных констант могут при- сваиваться переменным и массивам любого типа. Примеры объявлений типа: 1. REAL *8 PI /3.14159265/, Е /2.718281828/ Это объявление описывает переменные PI и Е как вещественные раз- 38
мером 8 байтов. Кроме того, перед выполнением программы им при- сваивается начальное значение. 2. INTEGER L /5/, J /55/, А (6) /3*#,3*1/ Это объявление описывает переменные L, J, А как целые стандартно- го размера (4 байта). Перед выполнением программы переменной L присваивается начальное значение 5, переменной J — 55; первым трем элементам массива А присваивается значение Я, остальным — значение 1. 3. REAL*8 В, D/3*#., 3*1./ Это объявление описывает объекты В и D как вещественные размером 8 байтов. Кроме того, массиву D (описатель которого должен быть ука- зан в объявлении DIMENSION или COMMON), содержащему 6 эле- ментов, этим объявлением задаются начальные значения. 4. INTEGER*2 М/25/, U, V Это объявление описывает переменные М, U, V как целые размером 2 байта и перед выполнением программы переменной М присваивается значение 25. 5. INTEGER Р (3,3), L*2/7/ Это объявление описывает массив Р целого типа, элементы которого имеют стандартный размер. Переменная L описана как целая размером 2 байта, которой присваивается значение 7. Задание. 1. Допустимы ли следующие последовательности объяв- лений в одном программном модуле? Если нет, то почему? 1) DIMENSION А (6, 8, 8), KSI (3, 2) REAL KSI (3, 2), А *8 (6, 8, 8) /384*#./ 2) REAL М (4, 2), N (3, 2), R *8 /'РЕЗУЛЬТАТ^РЕШЕНИЯ^ ЗАДАЧИ', 3*#./ DIMENSION R (6), М (4, 2), N (3, 2) 2. Определите тип переменных или массивов, размер и значение (если оно присваивается), задаваемые следующими объявлениями типа: 1) COMPLEX U, V (3, 3)75 ♦(!.#, 1.#), 4* (#., 1.)/ 2) REAL К (18)718*8.8/, А (5, 5)/15*3.2Е—5, 1-8*1.#/ 3) REAL*8 X, RE /2.7536796522/, МАС1 *4 (3, 4) /2.5, 3.5, 4.5, 5.5, 8*1./, ТЕКСТ(9)/'ПОНЕДЕЛЬНИКВТОРНИК СРЕДА^^^ЧЕТВЕРГ^ПЯТНИЦА^СУББОТА^ВОСКРЕСЕНЬЕ Порция 20 Объявление IMPLICIT В ФОРТРАН/ЕС имеется возможность задать распределение букв, ответственных за выбор типа по соглашению, отличному от опреде- ленного стандартом. С этой целью язык дополнен объявлением IMPLICIT (неявный). В объявлении IMPLICIT можно задавать определение типа по первой букве имени не только для целого и вещественного типов, 39
но и для остальных допустимых в ФОРТРАН/ЕС типов, за исключением типа DOUBLE PRECISION. Для определения переменных этого типа могут быть использованы данные типа REAL*8. - Формат объявления типа IMPLICIT: IMPLICIT <список-соглаьиенийу Здесь: (список-соглашений) — это одно или несколько соглашений, разделенных запятыми; каждое соглашение состоит из описа- теля типа (INTEGER, REAL, COMPLEX или LOGICAL), за которым может (не обязательно) следовать описатель размера, за которым в круглых скобках записываются диапазоны, каж- дый из которых — это одна буква или две буквы, разделенные знаком «—» и определяющие диапазон букв в упорядоченном списке алфавита, с которых в данном программном модуле будут начинаться неявно объявляемые имена переменных ти- па, заданного описателем. Если буква из какого-либо из указанных диапазонов использует- ся в качестве первой в имени, тип которого не определен явно в объяв- лении типа, то это имя именует переменную типа, указанного для дан- ного диапазона объявлением IMPLICIT. Пример IMPLICIT INTEGER (R), REAL *8 (A — M), COMPLEX (S —U, W) В программном модуле, содержащем данное объявление, неопи- санные явно имена, начинающиеся с буквы R, именуют переменные и массивы целого типа (стандартного размера); начинающиеся с букв от А до М — вещественного типа размером 8 байтов, а с буквы W и от S до U — комплексного. В каждом программном модуле допускается использование только одного объявления IMPLICIT. В головном модуле это объявление должно быть первым предложением, а в процедурных модулях оно должно непосредственно следовать за заголовком модуля. Очевидно, что буквы должны быть распределены по типам одно- значно. Подчеркнем разницу между операторами явного описания типа и оператором IMPLICIT. В операторах явного описания типа исполь- зуются имена объявляемых объектов, а в объявлении IMPLICIT — начальные буквы имен, по которым тип объекта при неявном его объяв- лении определяется транслятором. Естественно никакие другие атри- буты (размерности массивов и данные) нельзя указывать в операторе IMPLICIT (даже и в том случае, -жогда имя состоит из одной буквы). Таким образом, ФОРТРАН/ЕС допускает три способа объявления типа переменных: 1. Явное задание типа (объявлениями типа). 2. Неявное по соглашению — объявлением IMPLICIT. 3. Неявное — по умолчанию (только для целого и вещественного типов). 40
Явное объявление типа имеет высший приоритет. Это значит, что эти объявления подавляют действие объявления IMPLICIT и правила умолчания. Следующим приоритетом обладает объявление IMPLICIT, которое подавляет действие правила умолчания. Если тип пе- ременной не указан в этих объявлениях, то действует правило низ- шего приоритета — принцип умолчания. Пример. Пусть в некотором программном модуле переменные TU104, TU124, TU134, TU144, TU154, Tl, Т2, ТЗ, Т4, Т5 — целого типа, а переменные Ml, М2, М3, М4, М5, Мб, М7, М8, М9, MIN, МАХ — вещест- венного типа, тогда вместо двух предложений явного объявления типа INTEGER TU 1^4,TUI24, TU134, TU144, TU154, TI, Т2, ТЗ, Т4, Т5 REAL Ml, М2, М3, М4, М5, Мб, М7, М8, М9, MIN, МАХ, можно записать одно пред- ложение неявного объявле- ния типа: IMPLICIT INTEGER (Т), REAL (М) Если в том же программ- ном модуле переменные ТОМ, TIM, TAU— вещест- венные, а переменные МО, МА, МТ — целого типа, то Рис. 3 тип всех используемых в модуле переменных может быть задан объ- явлениями: IMPLICIT INTEGER (Т), REAL (М) REAL ТОМ, TIM, TAU INTEGER МО, MA, MT Общие правила определения типа переменной, принятые в ФОРТРАН/EC, иллюстрируются схемой (рис. 3), в которую для пол- ноты изложения включено еще не рассмотренное нами использование данных целого типа в операторах присвоения метки (операторах ASSIGN). 41
Задание. 1. Допустимы ли следующие предложения в записи про- граммы на ФОРТРАН/ЕС? Если нет, то почему? 1) IMPLICIT REAL (Е— N), REAL (L—Р), INTEGER (S) 2) IMPLICIT LOGICAL И (В — C), DOUBLE PRECISION (K) 2. В программном модуле имеются предложения: IMPLICIT COMPLEX (Z), INTEGER *2 (S —U) REAL K, L, SWING Определите тип и размер следующих переменных, встречающихся в этом программном модуле при отсутствии их явного описания: ZON, BOOL, Tl, SWING, L, L2. 3. Сформулируйте с помощью IMPLICIT принцип умолчания. Порция 21 Объявление DATA Объявление DATA, называемое еще объявлением начальных данных, используется для задания начальных значений, как числовых, так и текстовых, переменным или элементам массивов. Важной особен- ностью этого объявления является то, что присвоение начальных зна- чений переменным осуществляется во время трансляции, а не во время выполнения рабочей программы. Объявлением DATA удобно пользо- ваться в следующих случаях: I. Составленная из ряда знаков константа используется в некотором программном модуле многократно; присваивая ее значение некоторой переменной, мы освобождаем себя от необходимости записи «длинной» константы (например, констант л, е и т. д. с большим числом знаков) в последующих операторах, получая возможность указывать вместо этой константы имя соответствующей переменной. В данном применении объявление DATA выполняет фактически те же функции, что и операторы присваивания. Однако использование объявления DATA позволяет выполнить присваивание значений це- лому ряду переменных, т. е. уменьшить количество операторов в дан- ном программном модуле. Последнее особенно удобно, когда несколь- ким переменным присваивается одинаковое значение. 2. Объявление DATA позволяет присваивать переменным текстовые значения (а в ФОРТРАН/ЕС и шестнадцатеричные), что нельзя сде- лать оператором присваивания; поэтому его можно с успехом исполь- зовать для выдачи заголовков таблиц и другой текстовой информации, не зависящей от конкретного условия (варианта) задачи. Объявление DATA имеет формат: DATA kjdj, k2/d2!, k3/d3!, ..., kn/dn/ Здесь в каждой паре kjdj-. kt — список идентификаторов простых переменных или перемен- ных с индексами, заданными в виде констант; 42
di — список констант; значения которых присваиваются пере- менным, перечисленным в списке Пример записи объявления DATA: DATA Р1/3.1416/, Е/2.718/, М(1)/72/ Элементы списков (как и их пары) разделяются запятыми. Списки имен и списки констант в каждой паре kL (dz) должны быть согласованы по числу элементов и их типам. Однако текстовым константам могут соответствовать в списках имена любого типа. Смысл объявления DATA поясним на примере. Пример DIMENSION AL (2, 3) LOGICAL R, Rl COMPLEX P DATA Al, A2/12.7, 13.7/, KI, K2/7, 3/, R, Rl,/.FALSE., 1 .TRUE./,AL (1, 1), P/2.1, (5., 6.5)/ (Обращаем Ваше внимание на то, что первый символ 1 в последней строке приведенного фрагмента является символом продолжения, т. е. он должен быть записан в шестой позиции строки бланка програм- мы (см. порцию 26). Для большей наглядности в этом и в последующих примерах, где встречается символ продолжения, между предполагае- мыми шестой и седьмой позициями будет проведена вертикальная черта). Приведенное в примере объявление DATA перед выполнением данного программного модуля присвоит переменным вещественного типа А1 и А2 значения 12.7 и 13.7 соответственно; переменным целого типа К1 и К2 значения 7 и 3, переменным логического типа R и R1 значения .FALSE, и .TRUE, соответственно, переменной комплекс- ного типа Р — значение (5., 6.5), а элемент массива AL (1, 1) получит значение 2.1. Списки переменных в объявлении формируются произвольным образом, необходимо только соблюдать соответствие их элементов элементам списка констант. Кроме того, в этот список не могут быть включены формальные параметры и имена функций, о которых будет идти речь в гл. IV. Например, объявление DATA, приведенное в пре- дыдущем примере, можно записать следующим образом: I DATA Al, А2, KI, К2, AL (1,1)/12.7,13.7, 7,3, 2.1/, 1 I R, Rl, Р/. FALSE.,.TRUE., (5., 6.5)/ Если нескольким элементам списка переменных в объявлении DATA присваиваются одинаковые значения, то вместо многократного повторения соответствующей константы перед ней можно поставить повторитель вида /*, где i — целая положительная константа, ука- зывающая, сколько раз должна быть повторена данная константа в списке начальных значений. 43
Пример DIMENSION В (10) DATA X, В (2), В (3), В (8), В (10)/5* 1.0/ Перед выполнением программы для переменной X и четырех элементов массива В будут установлены значения, равные 1.0. Как отмечалось выше, объявления DATA могут задавать пере- менным не только значения числовых констант, но и текстовых. Пример DATA А, В, С /4НСИЛА, 4НТЯГА, 4НУГОЛ/ В результате этого объявления в поле памяти с именем»А будет поме- щена текстовая константа СИЛА, в поле с именем В — константа ТЯГА, в поле с именем С — константа УГОЛ. Рассмотрим пример использования объявления DATA в ФОРТРАН/ ЕС, считая, что тип данных А, В, С, М задан неявно. Тогда значения, присвоенные переменным А, В, С, М (1), М (2), М (3) объявлениями: DIMENSION М (3) DATA А, В, С, М (1), М (2), М (3)/4НМАСС, 4НИВ^Д, 4НАННЫ, 4НХи_1ТИ, 4НПА^Р, 4HEAL_J, будут такими: Переменная А В С М(1) ,М(2) М(3) Начальное значение МАСС ИВшД АННЫ ХшТИ ПАшК EALlj Правила использования объявления DATA. 1. Объявления начальных данных используются для задания на- чальных значений простым переменным или элементам массивов, чис- ло которых должно быть равно числу констант в каждой из пар kjdj с у четом коэффициента повторения. 2. Переменная или элемент массива, которым присваиваются зна- чения объявлением DATA, не могут находиться в непомеченном общем блоке. Начальные значения переменных или элементов массивов, на- ходящихся в помеченных общих блоках, могут быть определены с по- мощью объявления DATA только в модуле-блоке данных BLOCK DATA (общие блоки и модули-блоки данных описаны в главе IV). Та- ким образом, с помощью объявления DATA, помещаемого в каком- либо программном модуле (не в модуле-блоке данных BLOCK DATA), могут задаваться только начальные данные переменным, не входящим в общие блоки. 3. Объявление DATA может находиться в любом месте программ- ного модуля между последним объявлением типа и заключительной строкой END. 4. Списки переменных в объявлении DATA не должны содержать формальных параметров, а также имен функций. 44
5. Индексы переменных в списке переменных объявления DATA должны быть целыми положительными константами. 6. Единице памяти в выполняемой программе может быть задано начальное значение только один раз. В отличие от стандарта, согласно которому список в объявлении DATA может содержать только простые и индексированные перемен- ные, ФОРТРАН/ЕС в этом списке допускает имена массивов. Указан- ное в таком случае имя массива представляет последовательность всех элементов массива, определенную соответствующим описанием (например, в объявлении DIMENSION): DIMENSION X (3) DATA X/3 *6.6666/ Однако имена массивов в объявлении DATA должны указываться не- посредственно перед списками соответствующих им констант. Если размер текста превышает размер переменной или соответст- вующего массива, то литеры размещаются, начиная с левой границы поля, и выходящие за правую границу поля теряются. В подобных слу- чаях транслятор выдает предупреждающее сообщение ILF&38I SIZE WRN. Рассмотренное выше присваивание текстовых констант (строки ли- тер «МАССИВ ДАННЫХ ТИПА REAL») в ФОРТРАН/ЕС может быть записано несколько проще: DIMENSION М (3) DATA А, В, С, М/'МАСС', 'ИВ^Д', 'АННЫ' 'Х^ТИ', 'ПАШР', 'EALlj'/ Задание. 1. Найдите ошибки в приведенных ниже объявлениях начальных данных и напишите варианты правильных объявлений: a) DATA А, В, С, D/2.7, 2 *4.-0/ б) DATA SIN (R), MIN, MAX/3.3, 2*2/ в) DATA R, X/2.-0, -0.-0/, A (1), A (2), A (K)/3 * 1.-0/ 2. В массив А, состоящий из шести элементов, нужно заслать объяв- лением DATA следующую текстовую константу: 46НЗНАЧЕНИЯ ПЕРЕМЕННЫХ ПОСЛЕ ВЫПОЛНЕНИЯ ПРОГРАММЫ Запишите на ФОРТРАН/ЕС объявление DATA для присвоения эле- ментам массива соответствующих значений. 3. Чему равны значения переменных I и М после выполнения сле- дующей последовательности операторов: I = 5 DATA Г1-0/ М=1 45
Порция 22 Функции и их указатели Всякая вычислительная процедура, позволяющая по заданным зна- чениям ее аргументов, называемым в программировании фактическими параметрами, и, быть может, по некоторым значениям других пере- менных, не выделенных в качестве параметров, определить некоторое значение, может рассматриваться как функция своих аргументов. При описании тех или иных алгоритмов часто возникает необхо- димость в определении значений подобных функций в различных точ- ках вычислительного процесса, в связи с чем в языках ^программиро- вания представляется естественным определение соответствующих средств для задания таких вычислительных процедур, безотноси- тельно к конкретным значениям их аргументов, с помощью так назы- ваемых формальных параметров. Кроме того, определяются способы «обращения» к этим процедурам, позволяющие указывать конкретные значения аргументов — фактические параметры, при которых должны быть вычислены соответствующие значения функций. В ФОРТРАНе различается несколько видов функций: встроенные, внутренние и внешние. Из внешних особо выделяется класс так назы- ваемых основных внешних функций. Имеются некоторые различия в способах описания и использования этих видов функций. Так, алго- ритмы вычислений встроенных и основных внешних функций обеспе- чиваются транслятором и пользователю языка нет необходимости их описывать. За этими функциями закреплены соответствующие имена. Все прочие виды функций (внутренние и внешние, отличные от основных) вводятся составителем программы, который должен выби- рать для них имена и описывать алгоритмы вычисления их значений. Для обращения к алгоритмам, вычисляющим значения любых из определенных в языке функций, используется языковая конструк- ция, называемая указателем функции. Указатель функции представляет собой имя этой функции, за ко- торым в круглых скобках указаны аргументы, или фактические пара- метры, разделенные между собой, если их несколько, запятыми. Та- ким образом, аргументы функции в ФОРТРАНе всегда заключаются в скобки. Так, выражение sin х + cos х на ФОРТРАНе должно быть записано в виде SIN (X) + COS (X). Указатель функции является носителем вычисленного значения и используется в выражениях в качестве первичного выражения. Фактическими параметрами могут быть: константы, переменные (простые и с индексами), указатели функций, имена массивов и про- цедур, а также допустимые в языке выражения. Примеры указателей функций: A1(#,.TRUE.); XX(l.l); М(SIN (X + .1)); S22 (X (Т + 1)); SIN(2.1 *F, R + 5) 46
Заметим, что тип параметров для каждой функции в ФОРТРАНе фиксируется и их число может быть любым, но не меньше одного. Исключение составляют встроенные функции для вычисления мак- симума и минимума, число параметров которых может быть произ- вольным, но не менее двух. Другими словами, функции без параметров (допустимые в других языках, например, в АЛГОЛ-60) в ФОРТРАНе не рассматриваются. ФОРТРАН не содержит средств задания проце- дур с переменным числом параметров. Внешние функции. Основные внешние функции Своим названием «внешние» этот вид функций обязан тому, что описания процедур вычисления их значений оформляются в виде от- дельных модулей, внешних по отношению к другим модулям. Тем самым язык разрешает употреблять указатели этих функций (т. е. обращаться к выполнению этих процедур) в любых других программных модулях. Имеются некоторые ограничения, касающиеся возможностей исполь- зования указателей внешних процедур, о которых речь будет идти далее. В табл. 35 на стр. 343 приведены имена основных внешних функ- ций, их тип, число параметров и тип последних. Примеры указателей основных внешних функций: Запись на ФОРТРАНе Обычная запись TANH(X+3.) th(x-\-3) ATAN (2.0) arctg2 SIN (A * X + В) sin (ax + b) EXP (1.-0) e EXP (2.) e2 SQRT(5.-0) V5 EXP (EXP (X)) e'x Примеры указателей, недопустимых для основных внешних функ- ций: ЕХР (5); SQRT(I); TANH(K); SIN (-0.1,0.2) В первых трех примерах тип параметров, а в последнем их число не соответствует требуемому. Следует иметь в виду, что, хотя за основными внешними функциями закреплены определенные имена (см. табл. 35), этими именами в тех программных модулях, в которых данные внешние функции не исполь- зуются, могут быть обозначены другие объекты программы. Так, если в некотором модуле не используется функция синус, в нем можно 47
именем SIN обозначить, например, одномерный массив, сделав соответ- ствующее объявление. В этом случае выражение SIN (М) будет обо- значать переменную с индексом, а не указатель функции синус. Встроенные функции Большинство реализаций ФОРТРАНа предусматривает некоторый набор так называемых встроенных функций. От описания процедур вычисления этих функций, как и основных внешних, составитель про- граммы на ФОРТРАНе полностью освобожден. Процедура на фортране актора соответствующей vea программы SUBROUTINE ALPHA(R,5,l) • • • • *••••••• SUBROUTINE ALPHA(R,S,I) X-AMINlCROhB^^RlZjvRflOj^B/T ФУНКЦИЯ AM!Nl(R( 1) ,B,R(2) ,R(7) ,R(f 0)) В’АМ1М1(К(1),\(2)Л(3)И(4)м7У * AMIN! = RETURN * X=AMIN1(R(1) ,B,R(2),R(7),R(IO))*B/T • • ••••••••••••••• RETURN END ФУНКЦИЯ AMINf(R(f),R(2),R(3)) • • • • •AM1N1 = B-AMIN1(R(1),R(2),R(3))-R(4)*7.0 RETURN RETURN END Рис. 4 Свое название «встроенных» эти функции получили в связи с особым способом их реализации: в каждом из тех мест программы, где тре- буется вычислить значение встроенной функции, транслятор непосред- ственно записывает («встраивает») необходимую машинную программу (что не вызывает большого удлинения рабочей программы, поскольку алгоритмы этих функций весьма просты). При реализации других видов функций транслятор создает одну необходимую последователь- ность машинных команд — подпрограмму, выполнение которой вызы- вает каждое употребление указателя этой функции. Принцип подключения встроенных функций схематически показан на рис. 4. 48
Документация каждой реализации языка ФОРТРАН содержит полный список встроенных функций с подробными пояснениями, со- держащими указание точности вычисления значений функции, формы представления аргументов, единиц их измерения. Список встроенных функций приведен в табл. 36 на стр. 346. Внутренние функции и внешние, отличные от основных внешних, будут рассмотрены несколько позднее (см. порции 62, 67, 68, 69, 70). Задание. 1. Для чего в программах используются указатели функ- ций? 2. Какие из приведенных ниже записей могут быть использованы в качестве указателей функции? (тип переменных описан неявно). 1) SIN X 6) SQRT (AN)V 2) COS 2 7) SQRT (1.0 + AN) 3) ALOG 10 (I)*7 8) SIN (X**2 + A, Y + 1) 4) SQRT (N) 9) COS (SIN (B (1,1))) 5) SQRT (I + N)'/ 10) TANH (SIN (X**2)) Какие из них могут служить указателями основных внешних функций? 3. При каком условии конструкция SIN (N) обозначает указатель основной внешней функции SIN? Какой другой объект она может обо- значать? Порция 23 Выражения. Арифметические выражения В языке ФОРТРАН допустимы два вида выражений: арифмети- ческие и логические. Термин «выражение» используется в ФОРТРАНе в обычном алгеб- раическом смысле. Выражение может состоять из констант, перемен- ных, переменных с индексами, указателей функций, которые могут быть связаны между собой символами арифметических операций (+ —- сложение,-----вычитание, * — умножение, / — деление, * * — воз- ведение в степень) и скобками. Каждая из перечисленных компонент является частным случаем выражения. Выражение — это правило для определения одного числового или логического значения. Если в выражение входят переменные, то при определении его значения используются текущие значения этих пе- ременных. Арифметические выражения Арифметическим выражением называется правило для вычисления одного числового значения. Арифметическое выражение в ФОРТРАНе является аналогом алгебраического выражения в математике. 49
Первичными арифметическими выражениями называются: целое или вещественное число без знака, комплексная константа, переменная (простая или с индексами), указатель функции, арифметическое выра- жение, взятое в круглые скобки. Первичное арифметическое выражение является частным случаем арифметического выражения. Примеры первичных арифметических выражений: U; 37.4; SIN (2. * X + В (1)); COS (SIN (X — 1.2)); Al; 385; EXP (SIN (X)**2); ALOG (X + 2.5); Q (1,5); (1.5, 25E-01); (SIN (X * X) + COS (X)); (A — В); С (M, N). • Таблица 10 Тип арифметического выражения для операций +, —; *, / Тип 1-го операнда Тип 2-го операнда Целый Вещественный Повышенной точности Комплексный Логи- ческий Целый Целый — — — — Вещественный — Вещественный Повышенной точности Комплексный — Повышенной точности — Повышенной точности Повышенной точности — — Комплексный — Комплексный — Комплексный — Логический — — — — — Арифметические выражения строятся из первичных арифмети- ческих выражений путем надлежащего соединения их знаками ариф- метических операций и круглыми скобками. При написании арифметических выражений программист должен соблюдать следующие правила, которые следуют из определения ариф- метического выражения: 1. Недопустима последовательная запись двух знаков операций. А*—В — выражение не имеет смысла. А * (—В) — допустимо. 2. Скобки в выражениях, как это общепринято в математике, ис- пользуются при необходимости для указания очередности выполнения операций; допускается использование лишних скобок. 3. Порядок выполнения непосредственно следующих друг за другом операций возведения в степень должен быть указан скобками. На- пример, выражение вида Ав<? следует писать со скобками: (А * * В) **С или А**(В**С) соответственно тому, что необходимо вы- числить. 50
В ФОРТРАН/EC последовательное возведение в степень можно записывать без скобок, например: А * *В**С* * К, что в этом языке равносильно записи А** (В** (С** К)), то есть в ФОРТРАН/EC эти операции выполняются справа налево (остальные операции равного приоритета выполняются слева направо). 4. Если очередность выполнения операций в выражении не опре- делена скобками, то операции выполняются в следующем порядке: 1) Вычисление значений функций. 2) Возведение в степень. 3) Умножение и деление в порядке их следования слева направо. 4) Сложение и вычитание в порядке их следования слева направо. Таблица 11 Тип арифметического выражения для операции ** Тип основания Тип показателя Целый Вещественный Повышенной точности Комплек- сный Логи- ческий Целый Целый — — — — Вещественный Вещественный Вещественный Повышенной точности — — Повышенной точности Повышенной точности Повышенной точности Повышенной точности — — Комплексный Комплексный — — — — Логический — — — — — SR S Таким образом, выражение S/T * R означает -у-, но не a S — Т + R означает (S — Т) + R, но не S — (Т + R). В ФОРТРАН/EC, в отличие от стандарта, вычисление выражений производится слева направо по мере возможности их выполнения. Например, выражение а + b — с X d будет вычисляться так, как это показано ниже: 1) а + b 2) с X d 3) (а + Ь) — (с х а) 5. Стандарт ФОРТРАНа накладывает некоторые ограничения на использование данных различных типов в одном и том же арифмети- ческом выражении. Табл. 10 и 11 иллюстрируют правила определения типа значения результата арифметических операций. Недопустимые сочетания опе- рандов отмечены в таблицах знаком «—». 51
Как видно из таблиц, с данными целого типа в арифметическом вы- ражении не могут быть использованы данные никакого другого типа. Исключение составляет операция возведения в степень: данное любо- го числового типа может быть возведено в целую степень. Данные комплексного типа могут встречаться в одном выражении только с данными вещественного и комплексного типа и не могут быть использованы в качестве показателя степени. Таблица 12 Тип первого операнда Тип второго операнда INTEGER (2) INTEGER (4) REAL (4) REAL (8) COMPLEX (8) COMPLEX (16) INTEGER (2) INTEGER (2) INTEGER (4) REAL (4) REAL (8) COMPLEX (8) COMPLEX (16) INTEGER (4) INTEGER (4) INTEGER (4) REAL (4) REAL (8) COMPLEX (8) COMPLEX (16) REAL (4) REAL (4) REAL (4) REAL (4) REAL (8) COMPLEX (8) COMPLEX (16) REAL (8) REAL (8) REAL (8) REAL (8) REAL (8) COMPLEX (16) COMPLEX (16) COMPLEX (8) COMPLEX (8) COMPLEX (8) COMPLEX (8) COMPLEX (16) COMPLEX (8) COMPLEX (16) COMPLEX (16) COMPLEX (16) COMPLEX (16) COMPLEX (16) COMPLEX (16) COMPLEX (16) COMPLEX (16) В отличие от стандарта арифметические выражения в ФОРТРАН/ ЕС могут содержать операнды различного типа. Если операция свя- зывает операнды различных арифметических типов, то операнд низ- шего типа преобразуется к высшему типу. Расположение типов от высшего к низшему следующее: комплексный повышенной точности, комплексный, вещественный повышенной точности, вещественный, целый, короткий целый. Табл. 12 иллюстрирует правила определения типа и размера значе- ния результата арифметических операций в зависимости от типа и раз- мера операндов. 6. Скобки в выражениях обозначают очередность выполнения опе- раций, а также используются для указания аргументов — фактических параметров функций. В частности, между скобками символ умноже- ния опускать нельзя. Так, выражение (А ♦ В) (С * D) недопустимо в ФОРТРАНе. Оно должно быть записано в виде (А * В) * (С * D). 62
В табл. 13 приведены примеры арифметических выражений в обще- принятой записи и на ФОРТРАНе. 7. Показатель степени должен быть первичным арифметическим вы- 1 ражением, например, вместо X""2 следует писать X **. (—2), ах3 следует записывать в виде X * * (1./3.), а не как X ♦ ♦ 1./3.. Таблица 13 Общепринятая запись выражения Соответствующая запись на ФОРТРАНе Запись неправильная или не соответствующая исходной Ct , X- О* в . н4 а % о- 1 + ’Ч" М । в 4- 1 * Т X * + п + • • t + ЛЗ + 4 §• 5 2 1 °- 1 1 W - А*В X ** (-Y) (X 4- Y) *♦ £.2 или (X + У) * ♦ (1./5.) ((А + В) / (С - D)) ** ♦* (М — 1) В+ ш. В ♦* (С + 2.-0) ♦ D А * B/(C*D) ((А + В) / С) **4.3 D * (В * (X ** 2 4~ + A)-D) АВ (пропущен знак операции) X ** — У (два символа опе- раций стоят рядом) (X 4- У)** 1/5 ((А 4- В) / (С — D)) ** М — 1 (_(а + ь\т Л B4-1# (компоненты операции сложения разного типа) В ** С + 2.-0 * D (= Ьс+ 2d) А ♦ B/C * D (= а 4 ) (А + В)/С »» 4.3 (— D * (В * (X ** 2 4- А) — D (нет соответствия между скоб- ками) Сделаем некоторые замечания о правилах выполнения действий в арифметических выражениях, несоблюдение которых является ис- точником труднообнаруживаемых ошибок. Замечание 1. Результат деления двух целых операндов всегда будет целым — дробная часть отбрасывается. Поэтому значением выражений 13/4 и 15/4 будет 3, а 13./4. = 3.25 и 15./4. = 3.75. Результатом вы- числения выражения 4/5 * 1-0 будет нуль. Замечание 2. Операция возведения в степень при вещественном ос- новании определена как для целого показателя степени, так и для ве- щественного (табл. 11), однако выполняется она по различным алго- ритмам. Пример: X * * 3 означает X * X * X; операция определена для любых X; X ** 3. означает ЕХР (3. * ALOG (X)); операция определена только для положительных X (и выполняется медленнее, чем в преды- дущем случае). 53
Задание. 1. В каждом из следующих выражений укажите последо- вательность выполнения операций (согласно стандарту ФОРТРАНа); а) А + В + С в) X * У + А/В б)А*В + С**2 r)A"hB“|-C*D4"X**3 2. Даны выражения на ФОРТРАНе: 1) А + В/С + D 2) А * * 2 + В/С * D 3) Р/2. * 3. Укажите, каким из записанных ниже выражений они соответствуют 1) 2) 3) , a + b а' c-\-d а) а2 + ^- а) -^Р б) a + -^ + d б) 1 cd 6)f 3. Представьте в виде арифметических выражений на ФОРТРАНе следующие алгебраические выражения: a ) eV2x б ) 7 1 — <7 ч 1 z 1 + sin х2 в) -77- In -гп-----5- 1 2 1 + cos2 х г) е~х2 + е*' fa (х2 + У1 + х2 + х4) ’ У1 + х2 + х4 е) еох sin2 (ах + у) ж) b sin (2х)2 + с cos2 (Зх)2 з) 1g (1 + tgx2) 5 г-------. ------- и) У х -|- V 1 + У1 4- х2 к) а(А • bki 4. Вычислите значения арифметических выражений: 1) I + К/М; 2) М/К * I, если а) I = 1; К = 4; М = 2, б) I = 2; К = 8; М = 3; в) I = 3; К = = 13; М = 4. 5. Считая, что г, и, v, w — переменные комплексного типа, запи- шите на ФОРТРАНе (стандарт) выражения: а) (2 + i) и2 — 2v + iw б) 24-~z2> 4-3,2cstn(?) z “Г 4 в> (2 + «)» . (5,2 —3,7i)2 г) ХЗ"+3~2> M~3t^ + «)2 2/ (w — и) ‘ 5 . W2 , го3 е) W 2Г + 3! 5? ж) еаг sin z + e~b2 cos г v (a sin2 г din г) 3' c + d 64
Порция 24 Логические выражения Логическое выражение — это правило для вычисления одного ло- гического значения. Первичными логическими выражениями явля- ются логические константы логические переменные (простые или с индексами) указатели логических функций отношения любые логические выражения, заключенные в скобки. Первичные логические выражения являются частным случаем логи- ческих выражений. Логические выражения в общем случае образуются из первичных логических выражений, знаков логических операций .NOT., .OR., .AND. и скобок. Отношения Отношением называется два арифметических выражения, связанные операцией отношения. Комплексные выражения не могут быть операн- дами операций отношения. Таблица 14 Операция отношения Название операции Пример использова- ния операции Результаты выполнения операции .TRUE. .FALSE. .LT. Меньше с. LT. d если с <d если с > d .LE. Меньше или равно с. LE. d если с < d если с > d .EQ. Равно с. EQ. d если с = d если с =/= d .NE. Не равно с. NE. d если с Ф d если с = d .GT. Больше с. GT. d если с> d если с d .GE. Больше или равно с. GE. d если с > d если с < d Стандарт языка накладывает еще одно ограничение на отношения: если один из операндов целого типа, то и второй должен иметь целый тип. В языке ФОРТРАН/ЕС это ограничение отсутствует. Отношение является частным случаем логического выражения и, следовательно, может принимать значение .TRUE, или .FALSE.. Значением истинности отношения является .TRUE., если условие, выраженное операцией отношения, выполнено, и .FALSE., если это условие не выполняется. В табл. 14 приведены знаки операций отношения, допустимые в в языке ФОРТРАН, а также правила получения значений истинности их результатов. Буквами с и d обозначены допустимые арифметические выражения. 55
В табл. 15 приведены допустимые сочетания типов операндов опе- рацией отношения. Знаком + отмечены допустимые комбинации ти- пов арифметических выражений (операндов), связываемых операциями отношения. Таблица 15 Допустимые сочетания типов операндов операций отношения Тип левого операнда Тип правого операнда Целый Веществен- ный Повышенной точности Комплексный Целый + Вещественный — + + — Повышенной точности — + — Комплексный — — Ниже приведены примеры допустимых и недопустимых записей отношений (в предположении неявного объявления типа переменных и массивов). Допустимые Недопустимые X.EQ.2. X.LT.K A*B.LE.C(1,3) I.GT.5.2 А/В — D**2.LE.-&.-& M.NE.U(N) X.GT.5.3 AL.EQ.1 Примеры отношений: 1. Отношение у 2х + 1 на ФОРТРАНе записывается в виде: Y.LE.2. *Х + 1.-& и принимает значение .TRUE, для всех пар (X, Y), для которых выполняется указанное неравенство; при геометрической интерпретации на плоскости такими парами являются координаты всех точек, лежащих на прямой у = 2х + 1 и ниже ее. 2. Отношению х > 0, записываемому на ФОРТРАНе в виде X.GT.#., удовлетворяют координаты всех точек правой полуплос- кости, исключая точки оси Y. 3. Отношение у2 = х (на ФОРТРАНе— Y ** 2.EQ.X) прини- мает значение .TRUE, только для координат точек, лежащих на пара- боле у2 = х. 4. Условие принадлежности х отрезку 1а, Ь] обычно записывается в виде: а х Ь. На ФОРТРАНе это условие можно записать в виде A.LE.X. AND.X. LE.B Записи A.LE.X.LE.B или B.GE.X.GE.A в языке недопустимы. 56
Логические операции В табл. 16 приведены логические операции, допустимые в языке ФОРТРАН, и таблица истинности результатов. Буквами а и b обо- значены операнды типа LOGICAL. Таблица 16 Обозначе- ние логи- ческой операции Название операции Пример использо- вания операции Таблица результатов .NOT. Логическое отрица- ние «не» .NOT. а а .NOT. a .TRUE. .FALSE. . .FALSE. .TRUE. .AND. Логическое умно- жение «и» (конъ- юнкция) a. AND. b а b .TRUE. .FALSE. .TRUE. .TRUE. .FALSE. .FALSE. .FALSE. .FALSE. .OR. Логическое сложе- ние «или» (дизъюнк- ция) a. OR. b а b .TRUE. .FALSE. .TRUE. .TRUE. .TRUE. .FALSE. .TRUE. .FALSE. В табл. 17 приведен размер результата логического выражения в ФОРТРАН/EC (в байтах) в зависимости от размера операндов логи- ческих операций. Правила записи логических выражений 1. Для указания необходимой последовательности выполнения опе- раций в логическом выражении можно употреблять скобки. Допус- кается использование лишних скобок. Например: (X — 1.-0.LE.<&.-&. AND.Y — l.e.GT.>&.).OR.((X.GT.^.).AND.Y.LE.e) Это логическое выражение принимает значение .TRUE, в точках, принадлежащих заштрихованной области (рис. 5). 57
2. Внутри скобок/а также если скобки вообще отсутствуют, опера- ции выполняются в следующем порядке: 1) арифметические операции в последовательности: вычисление значений функций, возведение в степень, умножение и деление, сло- жение и вычитание; 2) операции отношений; 3) логические операции в последовательности: .NOT., .AND., .OR., Несколько одинаковых логических операций, идущих непосредствен- Таблица 17 Размер 1 4 1-го операн- да 2-го операнда 1 1 4 4 4 4 но друг за другом, выполняются слева направо в порядке следования. 3. Два символа логических операций не могут стоять рядом. Исключение со- ставляют последовательности операций .OR..NOT. и .AND.. NOT. Например: пусть переменные L1 и L2 описаны в объ- явлении типа описателем LOGICAL, тог- да допустимо следующее логическое вы- ражение: L1.OR..NOT.L2.AND.X.GT.#.# Напоминаем, что последовательности литер, обозначающие знаки логических операций и операций отношения, должны обязательно выделяться с обеих сторон литерой точка. Примеры логических выражений 1. Написать логические выражения, .TRUE, лишь при выполнении следую- щих условий: а) переменная N целого типа при- нимает четное значение; б) переменная N целого типа прини- мает нечетное значение; в) переменная N целого типа делится без остатка на число 7; г) переменная N целого типа делится без остатка на 3 и 5; д) переменная N целого типа делит- ся без остатка на 3 или на 5. Решение: a) N/2 * 2.EQ.N б) N/2 * 2.NE.N в) N/7 * 7.EQ.N г) N/3 * 3.EQ.N.AND.N/5 * 5.EQ.N д) N/3 * 3.EQ.N. OR. N/5 * 5.EQ.N 2. Написать логическое выражение, принимающее значение .TRUE., если точка на плоскости с координатами (х, у) принадлежит прямоугольнику (—2 х 2, —1 у 1), и .FALSE, в против- ном случае. 58
Решение: (X.GE. (—2.).AND.X.LE.2.).AND.(Y.LE.1..AND.Y.GE. (— 1.)) 3. Написать логическое выражение, которое принимает значение .TRUE, при условии, что из отрезков заданной длины А, В, С можно построить треугольник. Решение: (А + B).GT.C.AND.C.GT. (В — А) Рис. 6 Рис. 7 Рис. 8 4. Определим на плоскости XOY область, содержащую все те и только те точки (х, у), в которых логическое выражение Х**2 + Y ** 2.GT. 1.-&.OR. (X.GE.-G.-&.AND.Y.LE.-&.#) принимает значение .TRUE.. Укажем порядок выполнения операций в заданном выражении: а) вычисление значения арифметического выражения X ** 2 + Y ** 2 б) вычисление значений истинности отношений Х**2 + Y**2.GT.1,0 x.GE.e.e Y.LE.-0.0 в) вычисление истинности выражения (X.GE.•#.•&.AND. Y.LE.-&.&) г) вычисление истинности заданного выражения. Первому из отношений, приведенных в п. б), удовлетворяют коор- динаты точек, лежащих вне круга единичного радиуса с центром в на- чале координат, исключая точки его границы. 59
Второму из них удовлетворяют координаты точек правой полуплос- кости XOY, включая ось OY. Третьему — точки нижней полуплоскости, включая ось ОХ. Согласно определению логической операции конъюнкции (л) вы- ражение, приведенное в п. в), будет истинно для координат всех тех и только тех точек (х, у), которые принадлежат одновременно правой полуплоскости и нижней полуплоскости XOY, т. е. для всех точек, принадлежащих правой нижней четверти плоскости XOY (IV квад- ранту), включая ее границы. Искомая область изображена на рис. 6 (область заштрихована); граничные точки области, лежащие на осях координат, принадлежат этой области, а лежащие на окружности не принадлежат ей. Примечание, Следует обратить внимание на неединственность опи- сания области с помощью логического выражения. Так, выражение .NOT. (X.LT.d.tf.OR.Y.GT.tf.#). OR.X**2 + Y**2.GE. 1 ,Q или .NOT. (X.LT.tf.a.OR.Y.GT.tf.tf). OR..NOT. (X*X + Y* Y.LT. 1.Я) описывает ту же область, что и заданное в примере 4 выражение. 5. Рассмотрим логическое выражение X *X + Y * Y.EQ. l.e.OR. (X.GT.tf.e.AND.Y.LE.#.#) представляющее собой дизъюнкцию двух компонент: X * X +Y* Y.EQ. 1Л и (X.GT.a.e.AND.Y.LE.0.#) Нетрудно убедиться в том, что область, состоящая из всех тех и и только тех точек, для координат которых заданное выражение при- нимает значение .TRUE., является областью, изображенной на рис. 7 и включающей точки единичной окружности, но не включающей гра- ничные точки, принадлежащие координатным осям. Задание, 1. На рис. 8 заштрихована область, ограниченная прямой у = х и параболой у2 = х. Составьте логическое выражение, прини- мающее значение .TRUE, во всех тех и только тех точках плоскости 60
XOY, которые принадлежат заштрихованной области, включая ее границу. 2. На рис. 9 заштрихована область, границами которой являются ось ОХ и парабола у = —х2. Составьте логическое выражение, при- нимающее значение .TRUE, во всех точках этой области, включая криволинейную границу и исключая границу, лежащую на оси ОХ. 3. На каждом из рис. 10—12 изображена некоторая (заштрихован- ная) область. Определите, какие из этих областей состоят из тех и и только тех точек, для координат которых заданные выражения при- нимают истинные значения: а) (X ** 2+ Y ** 2.GE.1.#.AND.X.LT.#..AND.Y.GT.#.).OR. (X ** 2 + Y ** 2.EQ.1.0.AND. (X.GT.#.#.OR.Y.LT.#.#)) б) X ** 2 + Y ** 2.LE.1.#.OR.X.GE.#.#.OR.Y.EQ.#.# в) .NOT. (X ** 2 + Y ** 2.LT.1.#.OR.X.GT.O.O). OR.X. eq.#.# 4. Для каких значений переменной N целого типа отношение N/5 * * 5.EQ.N принимает значение .TRUE.? 5. На каждом из рис. 13—15 изображена некоторая (заштрихо- ванная) область. Определите, какие из этих областей состоят из тех и только тех точек, для координат которых заданные выражения при- нимают значения .TRUE.. а) (X ** 2 + Y ** 2.LE.1..AND.Y ** 2.LE.X).OR.X ♦♦ 2 + Y ** 2.EQ.1.OR.Y ** 2.EQ.X б) .NOT. (X **2 + Y ** 2.LE. l.).AND.X.LE.#.#.AND. Y. GT.#.# в) .NOT. (Y.LE. (—X ** 2).OR.Y.GE.#.#).OR.X.EQ.#.# 6. Составьте логическое выражение на ФОРТРАНе, принимающее значение .TRUE, во всех точках заштрихованной области, изобра- женной на рис. 16 и включающей свои граничные точки. 61
Глава II ОПЕРАТОРЫ ЯЗЫКА ФОРТРАН Порция 25 Бланк ФОРТРАН-программы Текст ФОРТРАН-программы записывается на специальных блан- ках, что облегчает их чтение и перфорирование. Число литер, состав- ляющих одно предложение ФОРТРАНа, ограничивается форматом бланка. На рис. 17 изображен бланк ФОРТРАНа. Каждое предложение ФОРТРАНа записывается на бланке с новой строки. В строке бланка пронумеровано 80 позиций. В одной позиции строки может быть указана только одна литера. В записи предложе- ний пробелы между литерами значения не имеют. Один и тот же опе- ратор А = В ** 2 С — D ** 2 на бланке можно записать по-разному (рис. 18). Исключение состав- ляют записи текстовых констант, в которых пробелы являются зна- чащими литерами и вставлять или опускать их нельзя. Пробелы в строках исходной программы могут использоваться для наглядности записи и удобочитаемости. Первая колонка ФОРТРАН-программа может сопровождаться различного рода примечаниями (комментариями), предназначенными, например, для тех или иных пояснений или сведений. Комментарии можно разме- щать в любом месте программы, однако не внутри предложений, а только между ними. На бланке (рис. 19) первая колонка выделена пунктиром. Буква С, записанная в этой позиции, показывает, что вся строка занята коммен- тарием. Текст комментария, который может быть записан со 2-ой ко- лонки, транслятором не воспринимается и может содержать любой на- бор литер, допустимых данной версией транслятора. В одной строке можно поместить текст комментария, не превышающий 71-го символа. Если размер комментария более 71-го символа, его запись можно про- должить в следующих строках, поставив в первой позиции каждой из этих строк литеру С. Текст комментария перфорируется на картах, 62
Задача Программист \Дата \ Страница - д Номер предложен. тМо№ШШ ПРЕДЛОЖЕНИЯ ФОРТРАНА 7 ю 20 30 40 50 60 __ . 70 Иденти- фикация ао Mil 1 1 I 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 М 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 „1 11 11 Lx 1111 I 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 f 1 1 1 1 1 1 1 1 1 1 1 1 Н 1 1 1 1 1 11 11 1 1 ..11.11 1111111111111111Л । п 111111111111111111111111111 ш 111111111 и 1.1. । 111111.1. Рис. 17 Задача Программист [ Дата 1 Страница ндюгрдди^ dan он 3 ~ о 1 ПРЕДЛОЖЕНИЯ ФОРТРАНА = 7 /0 20 30 40 50 60 70 Идентифи- кация 80 -| 111 А =8**2+C-D**2 _J 1 1 11 1 I 1 1 1 1 | 1 1 1 1 1 I 1 । t । 11 1 1 । । 1 I 1 1 I 1 1 । । 111 I । 11।।।1 1 11 । । 1 । । ।।1 । । ।।1। । 11 11 । । । 111 А = 8**2 + С - Р**2 1 । । 1 । | । । 1 । I | । 1 1 I 11 1 I । । 11 I । । 1 1 1 । 1 11 I । । 111 1 1 111 1 1 1 1 1 I 1 । 11 । । । 1 1 । । । 1 I । 11 111 । 4-i.ii. А = 8**2+C-D**2 1 । । 1 । । 1 1 1 1 । । 1 1 1 1 11 1 । । । । 1 । । । । 1 । । । 11 । । । । 11 । । 111 । । । 1 । । । । 11 । । । 1 । । । 11 । 111 1111 । 1111 _ А = 8**2 + С - Б*#2 . 1 1 । 1 1 । I । 1 1 । । 1 1 11 । । 1 । । । । 1 1 । । । 11 1 । 11 । I I 111 । । 111 I । I 1 11 I 1 11 । । । 1 । । 1 11 । 111 111 । Jill - 1 1 । 1 1 1 1 1 1 1 1 1 1 1 I 1-1 । 1 । I I 1 1 1 । 1 1 1 I I 1 I 1 1 1 1 । 11 1 1 । 1 1 1 1 । 1 । । 1 1 11 । । । h . । । 1 । 111 111 । -И11111 1111 1 1 1 1 1 1 1 1 1 । । 1 1 1 1 I 1 1 1 1 I 1 1 1 1 । 1 11 1 1 11 1 । । । 1 1 1 । । 1 । । । । 11 । । । 1 । jjJ_LU_L Рис. 18 Задача Программист [Дата [ Страница л I । ПРЕДЛОЖЕНИЯ ФОРТРАНА I-7 10 20 30 40 50 60 70 Идентифи- кация 80 0^1 w, /чтт. тм ш а л w ют .mi, 111111 । CiiW< } W11111111111111111111111111111111111111111111111111111111111111 111111 । 1 1111 111 M¥i н AWi 1111111111 и 11111111111111111111111111111111111111 1111111 1 J11.1 1 1 1 Iх! 1 1 1 Г1 I1! 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 I । 1 1 1111111 ^(Е^1Н1Т|Ь| MW. 1 AWA’i fi |Ш А Ш >, m , m i i 11111 Im 11 1 1 1 I гЧ°1 I2!0! 1 1 J| Г1 1 I 1 1 1 1 1 1 1 1 1 1 1 I 1 I 1 1 1 I 1 1 i 1 i 1 1 I : I 1 1 1 1 ! i 11 1 1 1 1 1 1111111 1 pill- .111111111 1 1 iVJiVi i^m’i^i^i’m^I 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 i 1 I 1 1 I I i i 1 1 1 1 i I i 1111111 ' to 1 111 ii-i 1111 AMi n Ji 11V1V1 iiniiiiiii i..i. i n 1111111 и 11111111 i 111111111111 1111111 Рис. 19 63
размещается в памяти ЭВМ и выводится на печать вместе с текстом про- граммы. Для наглядности программы можно пользоваться пустыми комментариями: в первой колонке строки проставляется литера С, а остальные остаются свободными. При распечатке программы вместо строки пустого комментария будет выдана пустая строка. На рис. 19 приведен пример записи примечаний к программе. Колонки меток (1—5) Как Вы узнаете из дальнейшего, в некоторых случаях возникает необходимость в записи одного предложения упомянуть некоторое другое предложение. Это может быть сделано посредством введения наименований предложений, называемых в языках программирова- ния метками (или, как мы будем иногда говорить, путем присвоения меток предложениям). ФОРТРАН допускает присвоение меток любым предложениям программ. Однако нет необходимости снабжать мет- ками те предложения, которым не передается управление и которые вообще не комментируются (например, в примечаниях или печатном тексте). В программах на машинных языках роль таких меток играют адреса ячеек, в которых размещаются машинные операторы програм- мы — команды. Каждому предложению в ФОРТРАН-программе можно присвоить (приписать перед его началом) одну метку. Метка — это конструкция, состоящая не более чем из пяти десятичных цифр. Метки выбираются программистом произвольно и записываются в 1—5 колонках бланка. Таким образом, любая метка имеет вид натурального десятичного числа в диапазоне от 1 до 99 999, т. е. любого пятиразрядного числа, от- личного от нуля, однако она не является числом, а является только именем (маркером) предложения. Предложение, имеющее метку, на- зывается помеченным. Правила присвоения меток 1. Предложению можно присвоить только одну метку. 2. Две метки, отличающиеся ведущими нулями (т. е. нулями, запи- санными слева от первой, отличной от нуля цифры), считаются одина- ковыми. Например, метки -&1, 1 — одинаковы. 3. Два предложения в одном программном модуле не могут иметь одинаковые метки. 4. Расположение меток в программе в порядке возрастания их но- меров не обязательно. На рис. 20 изображен фрагмент программы, иллюстрирующий пра- вила записи меток предложений. В примере а) операторы, записанные во второй и четвертой строке, не имеют меток, и после оператора с меткой 21 они будут выполнены в том же порядке, в котором они записаны в программе. Однако, как 64
мы увидим далее, наличие меток 15 и 6 у операторов, записанных в третьей и пятой строках, позволяют так составить программу, что при необходимости может быть начато выполнение данного фрагмента с оператора с меткой 15 (а первые два оператора будут пропущены) или с оператора с меткой 6 (а первые четыре будут пропущены). -“Г 1 Номер 1 ^оператора J7 10 20 7 2/ 1111 А - 2J. 7 . J i i 11 11 111111 1 1 I 11 _|_1 1 L _ В - 11.21 i i i I l I i 1 I l i 11 I I I 11 1 /5 1 1 1 L _ C - А««2+5аят(А+в) - 1111 1 111 1 1111 11111 j.-. D = C*(A+B)**2 . i i 1 1 1 i i 111 111 1 111 i I в till . 11 1111 1111 111 11111 J..111 - -Uli 1.1 111 Ш1 1111 1. а пион a 57 10 20 TT iiii A «25.7 . _j 11111111 11111111 ll 1 QI lilt 3=//.2f _ _i 11111111 1111111111 I 15 | 1 1 L_ C = A*»2*SQKT(A*S) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 i7 111 I D - C*(A+B) , - 1111 11111 i 1111111 11 Fr j 11 l- _ji 11 i i i 11 i 111111111 1111 JLUlUU 1 1.1 1 11 1 11 1J 5 Рис. 20 Пример б) иллюстрирует ошибку в присвоении меток: два оператора в одном программном модуле не могут иметь одинаковые метки. Признак продолжения предложения Если предложение состоит из большого числа литер и не помеща- ется на одной строке бланка, то в следующей строке в 6-ю колонку помещается литера продолжения, которой является любая литера, отличная от с_| и в, например цифра 2, и далее на строке продолжается запись предложения. Таким образом, шестая колонка на бланке является колонкой про- должения. Если имеется необходимость еще в одной строке,, то ее также разрешается использовать, поставив в ней, в колонке 6, неко- торую литеру, отличную от । , и Q. В ФОРТРАНе разрешаются пред- ложения, которые могут занимать до 20 строк. Заметим, что метка предложения ставится только перед его первой строкой (не имеющей литеры продолжения). Таким образом, между, меткой и предложением на бланке остается один пробел (в шестой позиции) или несколько. Позиции для записи предложений Для представления предложения ФОРТРАНа выделяются 66 позиций — с 7-й по 72-ю включительно. Поскольку выше было ука- зано, что для любого предложения ФОРТРАНа может быть использо- вано до двадцати строк, то отсюда следует, что предложение ФОРТАНа может содержать до 20 X 66 = 1320 символов.
Напоминаем, что при записи предложения ФОРТРАНа в каждой позиции бланка может быть записана только одна литера языка; в тек- стовых константах и комментариях могут быть использованы, помимо литер ФОРТРАНа, и другие литеры, допустимые данной версией транслятора. Позиции с 73 по 80 включительно Эти позиции предназначены для идентификации отдельной перфо- карты или программы. Информация, помещаемая в этих позициях, транслятором игнорируется. Поэтому они могут использоваться про- граммистом для нумерации перфокарт, необходимой, например, в больших программах для обеспечения правильного их расположения перед вводом в запоминающее устройство ЭВМ. В большинстве случаев эти колонки будут оставаться пустыми, поскольку совсем необязательно в них что-либо помещать. В дальнейшем при записи предложений, фрагментов и программных модулей на ФОРТРАНе будет подразумеваться, что метки, литеры продолжения и текст предложений записаны в надлежащих позициях. Задание. 1. Сколько литер может быть записано в одной позиции бланка? 2. Каким образом можно указать транслятору, что некоторая стро- ка занята комментарием? 3. Как обозначается продолжение предложения на следующую строку при его записи на бланке? 4. Запишите на бланке ФОРТРАНа следующие операторы: 25 А = 15.37 15 Q = 2. * А ** 2 — 422. 8 * А/3.8 — 1.7 5. Для какой цели используются колонки 73—80? 6. Обязательно ли запись предложения начинать с седьмой колонки бланка, а комментария со второй? 7. Сколько строк бланка ФОРТРАНа может быть занято коммента- рием? 8. Различны ли метки, представленные следующими литерами, указанными в колонках 1—5 бланка: 1 2 3 4 5 6 7 8 9 L_J i—i 2 i—j 5 2 i—i 5 i—> i—i 2 5 i_i i—i i—i 1 2 l—l •— i—i 5 9. Различны ли следующие две константы: 5375246 и 5_j375_j246? 66
Порция 26 Оператор присваивания Одной из наиболее употребительных групп операторов ФОРТРАНа являются операторы присваивания, с помощью которых вычисляются новые значения переменных. Знак «=» используется в ФОРТРАНе для обозначения операции присвоения и истолковывается не так, как в элементарной алгебре. Рассмотрим, например, запись — пример оператора присваива- ния: К = К+ 1 В алгебре эта запись не имеет смысла. Действительно, если К имеет значение, равное 2, то получается равенство 2 = 2 + 1, т. е. 2 = 3. Обычно знак «=» означает «равняется» и, следовательно, все то, что стоит слева от этого знака, должно иметь то же числовое зна- чение, что и справа. В языке ФОРТРАН литера «=», использованная в операторе при- сваивания, имеет следующий смысл: вычислить значение выражения, стоящего в правой части оператора, и сделать его значением перемен- ной, стоящей в левой части. Таким образом, оператор А = В + С — это предписание вычис- лить сумму значений переменных В и С и сделать ее значением пере- менной А. Оператор К = К + 1 — это предписание увеличить преж- нее значение переменной К на единицу. Когда мы говорим: «значение переменной», то мы имеем в виду по- следнее значение, которое было присвоено ей перед началом действия данного оператора. В приведенном ниже примере представлены последовательно рас- положенные в программе операторы М= 3 М = 2*М+ 14 После того, как вычислительная машина выполнит эти операторы, переменной М будет присвоено значение 20. Посмотрите, как это происходит: вначале М присваивается числовое значение 3, т. е. в ячейку вычислительной машины, отведенную для переменной М, за- писывается число 3. Выполнение второго оператора означает следую- щее: значение, присвоенное переменной М, умножается на 2 и к полу- ченному результату прибавляется число 14. Окончательный результат 20 становится новым значением М, заме- няющим первоначальное значение 3. Таким образом, если имя какой-либо переменной встречается и в левой и в правой частях оператора присваивания, то к моменту выпол- нения данного оператора этой переменной уже должно быть присвоено 3* 67
некоторое «старое» значение, которое и используется при вычислении значения выражения, составляющего правую часть оператора; вы- численное значение правой части присваивается имени переменной, составляющему левую часть оператора, т. е. становится «новым» значением этой переменной. Порция 27 Оператор присваивания (продолжение) В зависимости от типа присваиваемого значения операторы при- сваивания в ФОРТРАНе подразделяются на: арифметические, логи- ческие, операторы присваивания меток. Вначале будут рассмотрены первые два вида операторов присваи- вания: арифметический и логический. Оператор присваивания метки будет рассмотрен вместе с оператором GO ТО по предписанию, для которого он является сопутствующим. Арифметический оператор присваивания Формат этого оператора имеет вид и = а Здесь v — переменная (простая или с индексами) одного из число- вых типов: INTEGER, REAL, DOUBLE PRECISION, COMPLEX или имя внешней функции одного из тех же типов; а — арифметиче- ское выражение. Действие арифметического оператора присваивания состоит в следующем:v 1. Вычисляется значение а и, если тип значения а не совпадает с типом переменной у, преобразуется к типу переменной о; 2. Переменной v присваивается полученное на первом шаге зна- чение. Приведем правила записи арифметических операторов присваи- вания. 1. Левая часть арифметического оператора присваивания ФОРТРАНа (слева от знака «==») должна быть: именем переменной (простой или с индексами) одного из допустимых в языке числовых типов; именем внешней функции в теле процедуры этой функции (и не может быть никаким другим выражением, именем массива, константой или указателем функции). Поэтому записи D = В ** 2 — 4. ♦ А ♦ G A(2)=xX*Y B(3,4) = X/Y представляют сооой синтаксически правильные операторы присваи- 68
вания, а записи А + В = 2. *SIN(X)**3 3.14 = 4. *(1. — 1./3. — 1./5. — 1./7. + 1./9. + ...) на языке ФОРТРАН бессмысленны. 2. При записи выражений в правой части арифметического опера- тора присваивания должны соблюдаться общие правила построения арифметических выражений (см. порцию 23). Таблица 18 и Целый Веществен- ный Повышенной точности Комплексный Целый допустимо допустимо допустимо недопустимо Вещественный допустимо допустимо допустимо недопустимо Повышенной точнос- ти допустимо допустимо допустимо недопустимо Комплексный недопустимо недопустимо недопустимо допустимо 3. Тип переменной, стоящей в левой части оператора присваива- ния, может отличаться от типа, определяемого выражением, стоящим в правой части оператора. В этом случае вычисление значения выра- жения производится по правилам арифметики того типа данных, из которых состоит выражение, но результат вычислений будет преобра- зован согласно типу переменной левой части перед присваиванием по- лученного значения этой переменной. Табл. 18 иллюстрирует правила сочетания типов арифметического выражения в правой части и переменной в левой части оператора присваивания. Указанное свойство оператора присваивания может быть исполь- зовано в ФОРТРАНе для преобразования типа величин. Рассмотрим несколько примеров, поясняющих это положение (предполагаем, что тип переменных задан неявно). L = 5 X = 5*L —4 Выражение в правой части последнего оператора имеет значение 21. Но так как X является вещественной переменной, то полученный результат будет преобразован и представлен вычислительной машиной как 21.#. 69
Следующий пример: Х= 1.7 Х = 5.0*Х + 1.4 Как нетрудно проверить, значение X после проведенных вычислений будет равняться 9.9. Теперь предположим, что у нас имеются следую- щие операторы вместо рассмотренных выше: X = 1.7 М = 5.0 *Х+ 1.4 Таблица 19 Исходная формула Оператор присваивания / 1 1 \*/> и (х) =1 sin — + C0S~Z] и = (SIN (1 ./X) + COS (1 ./X)) •• (1 ./X) з f (х) => у/ cos х — у cos Зх F = SQRT (COS (X)) — COS (3. * X) ». »* (i./з.) Fl (х) = е 4- V"x/2 Fl = EXP (1./5.) + EXP (X/4.) с~ 4 AN = N (преобразование целого в ве- щественное) С = (А ♦» (l./AN) 4-В». *» (l./AN))/4. или С = (А »* (1 ./FLOAT (N)) 4- В »» о= (1 4- x)<g‘* ♦* (1./FLOAT (N)))/4. V = (1. + X) ** ((SIN (X)/COS (X)) .. »» 2) 1 = (cos ах) cosax — 1 U1 = COS (A . X) ». (1 ./(COS (A » X) — -I-)) На первый взгляд может показаться, что в результате выполнения приведенных операторов получим М = 9.9. Однако это не так, по- скольку М является целой переменной и примет значение-целой части полученного числа, т. е. 9. Заметим, что здесь не производится округ- ление; дробная часть перед присваиванием отбрасывается. Возможностью преобразования данных целого типа в веществен- ные и обратно при выполнении операторов присваивания приходится пользоваться довольно редко, но в случае необходимости она создает ощутимые удобства. ФОРТРАН/ЕС допускает любые сочетания типов и размеров левой и правой частей арифметических операторов присваивания. При этом в случае их различия осуществляется преобразование типа и размера значения правой части оператора к типу и размеру левой части. В слу- 70
чае, когда левая часть имеет целый или вещественный тип, а значение правой части является комплексным, мнимая часть последнего в опе- рации не участвует; если, наоборот, происходит присваивание целого или вещественного значения комплексной переменной, мнимая часть результата получается равной нулю. Заметим, что одним оператором присваивания в ФОРТРАНе можно присвоить некоторое значение (или изменить его) только одной пере- менной. Так, если требуется значение выражения Сеах cos fix присво- Таблица 20 Арифметический оператор присваивания Ошибка Y = 2.X4- А**3 D = (R-J-S *A)(SIN(2.*A) X = 1,624ЯЯ9 —К = (L + 1) ** А отсутствует ♦ (знак умнож.); нарушено соответствие между скобками, отсутству- ет знак умножения; запятые в константе употреблять нельзя; целую величину нельзя возводить в вещественную степень; переменная в левой части должна быть без знака ить переменным U, V, Т, то нужно записать три оператора присваи- вания, причем для экономии записи и времени вычислений это можно сделать посредством следующих операторов: U = С * EXP (А * X) * COS (В * X) Y = U Z = Y При необходимости для облегчения чтения, сокращения записи и времени выполнения исходной программы, используя оператор при- сваивания, можно вводить промежуточные переменные. Например, требуется вычислить значение х по формуле: _ — Ь -Ь V Ь2 — 4ас Х~ 2а Оператор для вычисления х можно записать в виде: X =(— В + SQRT(B **2 —4. * А*С))/(2. ♦ А) Введя промежуточную переменную, мы можем записать необходимые действия следующим образом: RDCL = SQRT (В ** 2 — 4. * А * С) X =(— В + RDCL)/(2. * А) В табл. 19 приведены примеры правильно написанных арифмети- ческих операторов присваивания и эквивалентные им алгебраические равенства в общепринятой форме. Имена переменных выбраны про- извольно. Кроме того, предполагается, что всем переменным, встреча- ющимся в правой части операторов присваивания, к моменту выполне- ния операторов присвоены некоторые значения. Каждый оператор табл. 20 содержит по меньшей мере одну ошибку. 71
Задание. 1. Определите значение А (типа REAL) и I (типа INTEGER), которые они получат в результате выполнения операторов присваивания: а)А = 2 + 3*4 б) А = 2/5 в) А = 6.2 * 2.Q г) I = 12 * 13/4 д) I = 12 * (13/4) 2. Эквивалентен ли В = А? е) А = (13/4) « 2 ж) А = (13./4.) * 2.-В з) А = 3.-0 * (1.-0Е2/2.0) и) А = 3.-е * 1.ВЕ2/2.е к) I = 2/5 оператор присваивания А = В оператору 3. Какие значения получат переменные А и В в результате выпол- нения следующих операторов присваивания: X = —з.е А = X ♦* 4 • В = —X ** 4 4. Напишите операторы присваивания для вычисления значений переменных по следующим формулам. Для имен переменных исполь- зуйте те буквы и обозначения, которые имеются в формулах: \ ° , ах a) v = —.. . arctg . ’ ЬУ& + Ь* 6 V х2 + а2 б) V = ~nR2H О в) и = ±-п(Ъ* + г* + К-г)Н О г) у = 2 sin3 (5х)2 + 3 cos2 (2х)3 д) а = "И Ь2 + с2 — 2bc cos А 5. Задать с помощью операторов присваивания вычисления по фор- мулам: a) cij = ciikbkj б) Cij — 01-Н.2 • £>2,/4-1 \ х в) и =---------2— ; ч (и 4- v)n г) W = , - + 3“-” где v = 1 +*2 + !/2 3 -tF х2+{/2 ’ ,, _ >z х2 + У2 1 + X2 + у2 • 6. Запишите последовательность операторов присваивания, резуль- татом выполнения которых будет обмен значениями переменных А и В. Введите одну дополнительную переменную. 72
Порция 28 Логический оператор присваивания Логический оператор присваивания выполняет операцию присваи- вания значения логического выражения, стоящего справа от знака «=», логической переменной, стоящей слева от этого знака. Формат логического оператора присваивания следующий: v = I Здесь v — имя переменной (простой или индексированной) логическо- го типа или имя логической функции; I — логическое выражение. Предположим, что переменные LI, L2, В1, В2 и ВЗ описаны в дан- ном программном модуле описателем LOGICAL (тип остальных пе- ременных задан неявно). Тогда в этом программном модуле могут быть записаны, например, следующие логические операторы присваивания; В2 = L1.OR..NOT.B1 ВЗ = (Х**2— l.£).LT.5.0.AND. (X + 3.0).LT.ia.2 Bl = .NOT.B3.AND..NOT.L1.OR.L2 Выражения в правой части логического оператора присваивания должны подчиняться правилам записи логических выражений. Напо- минаем, что значением логического выражения могут быть только ло- гические константы (.TRUE, и .FALSE.). Задание. 1. Запишите на языке ФОРТРАН следующие логические выражения: а) — х2 V У>0 б) х2 + r/2< 1 /\у2^х и операторы присваивания их значений логическим переменным AL и BL. 2. В некоторых из приведенных ниже операторов присваивания допущены ошибки. Укажите их. Переменные U, V, W в этих опера- торах являются логическими, идентификаторы остальных встречаю- щихся в них переменных описаны не явно: 1) U = V.OR.W; 5) Y == К ** 2 + U; 2) К = U; 6) Y = В + U ** 3; 3) W = U + В; 7) К = X ** 2 + С; 4) W = B 8) V = . NOT.W.AND.U. 3. Запишите операторы присваивания, в результате выполнения которых логической переменной U будет присвоено значение .TRUE., если точка М (х, у) принадлежит заданной (замкнутой) области D, и значение .FALSE. — в противном случае (см. рис. 21 (а, б, в, г)). 4. Запишите оператор присваивания, при выполнении которого ло- гической переменной W присваивается значение, совпадающее со зна- чением истинности заданного высказывания: 73
а) Вещественное значение переменной х не больше вещественного значения переменной Y. б) Значение а является либо наибольшим, либо наименьшим из трех попарно различных вещественных значений а, Ь, с. в) Хотя бы одна из четырех логических переменных VI, V2, V3, V4 имеет значение .TRUE.. г) Логическая переменная U имеет значение .FALSE.. 5. Пусть в некотором программном модуле дано объявление LOGICAL L, U, V, W; тип остальных переменных задан неявно. Вы- числить значения логических переменных L, U, V, W после выполнения следующих операторов присваивания: 1) X = 1.5 Y = 3.2 L = X.LT.Y.AND.X.GT.1.0 U = Х**2 + Y**2.LT.4..OR. Y.LT.X V = L.OR.U.AND..NOT. (X — Y.GT.O.O) W= U.AND.L.AND.V.OR. (X.GT.Y) 2) V = .TRUE. A = 2.0 В = 5.0 W = A — B.GE.2.0.OR.V.AND.B.LT.A 3) W = .FALSE. U = .TRUE. V = W.OR..NOT.U L = V.AND.W.OR.U W = W.OR.L.AND.U.AND.V U = U.AND.W.OR.L.AND.V 4) L = .TRUE. W= .FALSE. U = L.OR.W V = L.AND.W L = V.OR.L.AND..NOT.V.OR.W V = L.OR.V.AND..NOT.W W= V.AND.L.AND.W U = L.AND..NOT.V.AND.W.OR.U 74
Порция 29 Операторы перехода Операторы ФОРТРАНа в программном модуле могут выполняться последовательно в порядке их записи, когда предшествующий опера- тор передает управление следующему за ним в программе оператору. Такой порядок выполнения операторов называется естественным. Для изменения естественного порядка выполнения операторов служат операторы перехода. В языке ФОРТРАН имеется 3 вида операторов перехода, или опе- раторов GO ТО: 1. Безусловный оператор перехода. *2. Вычисляемый оператор перехода. 3. Оператор перехода по предписанию. Выполнению последнего вида операторов перехода должно пред- шествовать выполнение оператора «присваивания метки» — опера- тора ASSIGN. Рассмотрим каждый из этих операторов. Безусловный оператор GO ТО Безусловный оператор GO ТО — это наиболее простой из всех опе- раторов перехода. Формат оператора следующий: GO ТОп Здесь п — метка некоторого оператора, содержащегося где-либо в том же программном модуле. Действие оператора состоит в том, что после него следующим будет выполняться оператор программы, метка п которого указана в операторе GO ТО. В этом случае принято говорить: управление последовательностью выполнения операторов программы (или, короче, управление) передается оператору с меткой п (или, короче, оператору и). В качестве примера рассмотрим фрагмент программы: А = в.597 *Ъ’ К = А GO ТО 15 14 К = К+ 1 АК = К 15 Y = А/3. т 4. * В Здесь сначала присваивается значение переменной А, затем оно пре- образуется в данное целого типа, обозначаемое именем К. Далее сле- дует оператор GO ТО 15, который указывает, что следующим должен выполняться оператор 15 (а не 14). Оператор с меткой /г, указанной в операторе GO ТО и, может встречаться в программном модуле до или после данного оператора 75
GO TO; причем в языке нет никаких особых ограничений на метки, которыми можно снабжать операторы; напомним только требование: в Данном программном модуле никакие два оператора не могут быть помечены одинаковыми метками. Правила использования безусловного оператора перехода: 1. Метка в операторе GO ТО должна быть меткой некоторого опера- тора, а не объявления. 2. Если за безусловным оператором GO ТО в программном модуле следуют еще какие-либо операторы, то первый из них должен быть помеченным. В нашем примере оператору, следующему за GO ТО, присвоена метка 14. Посмотрите, что произошло бы, если бы оператор, следующий за безусловным GO ТО, не был помечен. При выполнении оператора GO ТО управление было бы передано оператору 15, а непомеченный опе- ратор, который следует непосредственно за оператором GO ТО, никогда не выполнялся бы, так как непомеченному оператору может передать управление только непосредственно предшествующий ему оператор. Исключение составляют: первый оператор в записи программного модуля, которому переда- ется управление при вызове данного модуля; первый оператор так называемого тела цикла, которому может пе- редавать управление конечный оператор этого тела. Если оператор помечен, то ему может быть передано управление по его метке какими-либо операторами перехода, в которых исполь- зуется эта метка. Вычисляемый оператор GO ТО Вычисляемый оператор GO ТО позволяет осуществлять развет- вления в программах. Формат оператора имеет вид GO ТО (и), т где п — список меток операторов, т — имя простой переменной це- лого типа, называемой управляющей переменной; область допустимых значений управляющей переменной составляют целые положительные числа от 1 до /, где / — число меток в списке п оператора GO ТО. Пример: GO ТО (12, 29, 34 , 2), К Выполнение этого оператора состоит в выборе одной из возможных ветвей вычислений, а именно: если К = 1, осуществить переход к опе- ратору с меткой 12; если К = 2, перейти к оператору с меткой 29, если К = 3, перейти к оператору с меткой 34 и при К = 4 перейти к выполнению оператора с меткой 2. В общем случае вычисляемый оператор GO ТО осуществляет пере- дачу управления оператору, метка которого занимает ту позицию 76
в списке меток данного оператора, порядковый номер которой в спис- ке меток равен значению управляющей переменной. При использовании вычисляемого оператора GO ТО необходимо соблюдать следующие правила: 1. Список меток операторов, которым возможна передача управ- ления вычисляемым оператором GO ТО, должен быть заключен в скоб- ки. Л^етки в списке должны быть разделены запятыми. 2. Запятая должна быть проставлена и после скобки. 3. Управляющая переменная должна быть целого типа. Эта пере- менная может принимать различные положительные целочисленные значения, максимальное из которых определяется количеством п эле- ментов в списке меток этого оператора, т. е. она может принимать зна- чения в диапазоне от 1 до л и тем самым определять метку для передачи управления. Если управляющая переменная в момент выполнения вычисляемого оператора GO ТО принимает значение вне указанного диапазона значений, то этот оператор считается неопределенным (и результат его действия непредсказуем). 4. Как и в случае безусловного оператора перехода, если за выпол- няемым оператором перехода в программном модуле записаны какие- либо операторы, первый из них должен быть помеченным. Пример 1. Пусть переменная целого типа М может принимать одно из значений 25, 26 или 27. Если М = 25, то управление должно быть передано оператору 35; если М = 26 — оператору 4Я; если М = 27 — оператору 15. Указанное разветвление в программном модуле можно осуществить посредством следующих двух операторов: J = М — 24 GO ТО(35, 48, 15), J Пример 2. В программном модуле вычисляется некоторое целое AL При этом требуется в зависимости от того, дает ли деление W на число 5 в остатке 0, 1, 2, 3 или 4, перейти соответственно к одному из опера- торов, помеченных метками 4, 12, 2, 7, 3 Требуется составить фрагмент программы, обеспечивающий над- лежащее разветвление. Введем переменную целого типа N5 и присвоим ей значение сле- дующего выражения: N — N/5 * 5 + 1 Обращаем Ваще внимание на то, что согласно определению операции деления для целых выражение N/5 * 5, вообще говоря, не равно N, а равно разности числа N и остатка от его деления на 5. Таким обра- зом, фрагмент программы для решения этой задачи можно записать 77
так: N5 = N —N/5*5+ 1 GO TO (4, 12, 2, 7, 3), N5 Как было описано выше, по стандарту вычисляемый оператор GO ТО определен только для тех значений целой переменной т, которые принадлежат диапазону 1 tn и, где п — число меток, указанных в этом операторе. В ФОРТРАН/ЕС, если tn не определяет метку в пе- реключательном списке, вычисляемый оператор GO ТО эквивалентен пустому оператору, т. е. передает управление следующему в записи программы оператору (который тем не менее должен быть помечен- ным). Например, при выполнении следующего оператора GOTO (5, 1в), INT 4................. управление будет передано по метке, 5, если значение переменной целого типа INT равно 1, по метке 1Ф, если оно равно 2. Если же INT примет значение меньше I или больше 2, управление будет передано следующему оператору, т. е. оператору с меткой 4. Задание. 1. Определите ошибки в записи вычисляемых операторов GO ТО и напишите операторы правильно: a) GO ТО 3,24 INT в) GO ТО (3, 4, 5), AL б) GO ТО (3,2) INT г) GO ТО (3, 4.), К1 2. Пусть переменная К может принимать только значения 1, 2, 4, 8. Напишите «корректирующий» фрагмент программы, не допуска- ющий неверного использования переменной К. Если значение К равно одному из допустимых, оно должно сохраняться на данном от- резке программы, в противном случае переменной К нужно присвоить значение Q. Порция 30 Оператор присвоения метки ASSIGN Сам по себе оператор ASSIGN не является оператором передачи управления, но результат его выполнения может быть использован оператором перехода по предписанию. Общий формат оператора ASSIGN следующий: ASSIGN п ТО tn Здесь tn — кмя простой переменной целого типа; п — метка одного из операторов, входящих в состав того же программного модуля. Действие приведенного оператора ASSIGN состоит в присвоении переменной tn значения «метка и». 78
Например, результатом выполнения оператора ASSIGN 10 ТО К является присвоение переменной К значения «метка Ш». Программа может содержать несколько операторов ASSIGN, при- сваивающих те или иные значения одной и той же переменной. Тем самым один и тот же оператор GO ТО по предписанию, содержащий данную переменную, будет определять переход на тот или иной опера- тор программы в зависимости от ее текущего значения. Имя т, используемое в каком-либо из операторов перехода по предписанию в некотором программном модуле, может быть исполь- зовано в этом же модуле как имя некоторой переменной целого типа. Однако эти два вида использования — в операторах перехода по пред- писанию и каких-либо других операторах — по существу различны и каждому из них должно предшествовать разного вида присвоение значения: для оператора GO ТО по предписанию — посредством оператора ASSIGN; для других операторов— прочие виды опреде- ления (например, через арифметический оператор присваивания или оператор ввода). Таким образом, после присваивания переменной т значения метки посредством оператора ASSIGN эта переменная может быть исполь- зована только в операторах GO ТО по предписанию до тех пор, пока ей не будет присвоено некоторое значение, например, посредством оператора ввода или оператора присваивания. С другой стороны, если переменной присвоено значение посредством, например, оператора ввода, она не может быть использована в операторе GO ТО по предпи- санию, пока ей не будет присвоено значение некоторой метки опера- тором ASSIGN. Оператор GO ТО по предписанию Формат оператора GO ТО по предписанию имеет вид: GO ТО т, (пр и2, ..., м/) Здесь т — имя переменной целого типа; пъ п2, ...» п} — список меток тех операторов, которым возможна передача управления данным оператором GO ТО по предписанию. Метки из указанного списка (и только эти метки) могут встречаться в соответствующих операторах ASSIGN, связанных с данной перемен- ной т, называемой управляющей переменной этого оператора. Оператор GO ТО по предписанию передает управление оператору с той меткой, которая в последний раз была присвоена одним из опе- раторов ASSIGN переменной т. Если в момент выполнения некоторо- го оператора GO ТО по предписанию значение переменной т не сов- падает ни с одной из меток, имеющихся в списке этого оператора, последний считается неопределенным. Список меток в операторе GO ТО по предписанию может содержать любое число меток. 79
Примеры использования операторов ASSIGN и GO ТО по предпи- санию: ASSIGN 20 ТО N1 GO ТО NI, (2d, 21, 22) ASSIGN 10 ТО М СО ТО 5 10 ................ ASSIGN 11 ТО И G0 ТО 5 11 ............... ASSIGN 12 ТО М 60 ТО 5 12 .......................... _ GOTO 13 5 ......................... GO ТО М,(10,11,12,13,14) 13 /4 ASSIGN 13 ТО М 60 ТО 5 ASSIGN 14 ТО М 60 ТО 5 STOP END Рис. 22 б) ASSIGN 5 ТО К35 Следующим после оператора GO ТО будет выполнен оператор с меткой 2i, если между этими двумя операторами не выполнялся никакой другой оператор ASSIGN или оператор перехода. Кроме того, между указанными операторами также не должны выполняться никакие операторы, присваивающие переменной NI какие-либо значения. На рис. 22 схематически показано использование операторов ASSIGN и GO ТО по предписанию для обращения к некоторому участку программы с после- дующим возвратом из него. Задание. В каждой из следующих последовательностей операторов ASSIGN и GO ТО по предписанию допущена ошибка. Найдите ее и запишите эти опе- раторы правильно: a) ASSIGN 3 ТО I GO ТО I (1, 2, 3, 4, 5) г) IR = 3 GO ТО IR, (1, 2, 3, 4) д) ASSIGN 3 ТО М GO ТО К35, (3, 15, 23, 53) F = М + 1 в) ASSIGN 5 ТО A GO ТО М, (1, 2, 3, 4, 5) GO ТО А, (19, 2d, 5, 7, 3) Порция 31 Сравнение вычисляемого оператора перехода и оператора перехода по предписанию Оба оператора перехода содержат заключенные в скобки непустые списки меток некоторых операторов, принадлежащих тому же про- граммному модулю, в котором записан каждый из этих операторов 80
(естественно, список должен содержать не менее двух меток; опера» торы с одной меткой М равносильны оператору безусловного перехода GO ТО М). В каждом из этих операторов используется имя простой перемен- ной целого типа (в операторах перехода по предписанию оно следует непосредственно после служебного слова GO ТО, в вычисляемых опе- раторах перехода — после заключенного в скобки списка меток). Однако переменная в вычисляемом операторе GO ТО является обыч- ной переменной целого типа, которая может быть использована наря- ду с оператором GO ТО и в других операторах (если, конечно, этому использованию не будет предшествовать оператор ASSIGN, присвоив- ший ей значение метки). Например, вполне допустима такая последовательность операто- ров: I = 1 5 К = I + 3 I = I + М GO ТО (14, 2, 8, 11), I От этой переменной при ее использовании в вычисляемом опера- торе GO ТО требуется лишь, чтобы она принимала одно из значений 1, 2..., и, где п — количество меток в списке такого оператора. Зна- чение этой переменной само не является меткой, а лишь определяет позицию той метки в их списке, по которой должно быть передано управление. Очевидно, что следующая последовательность операто- торов в языке ФОРТРАН является недопустимой: I = 2 ASSIGN 4 ТО I GO ТО (2, 4, 7, 12), I поскольку использованию переменной I в операторе перехода по вы- числению не может предшествовать присвоение ей значения операто- ром ASSIGN. С другой стороны, переменная в операторе GO ТО по предписанию, как было отмечено в предыдущей порции, является особой переменной, использованию которой должно предшествовать присвоение ей зна- чения метки оператором ASSIGN. Напомним, что это значение должно совпадать с одной из меток, составляющих список соответствующего оператора перехода. Задание. 1. Изменится ли смысл оператора GO ТО по предписанию при перестановке местами входящих в его список меток? А смысл вы- числяемого оператора GO ТО? 2. Изменится ли смысл оператора GO ТО по предписанию, если одну из входящих в его список меток приписать к этому списку? А смысл вычисляемого оператора GO ТО? 81
3. Определите, допустимы ли раторов на ФОРТРАНе: следующие последовательности опе- GO ТО К, (12, 11, 13) б) К = 3 в) L = 3 ASSIGN 5 ТО К ASSIGN 6 ТО I ASSIGN 7 ТО М GO ТО (К, I, М), L а) К = 3 GO ТО (12, 11, 13), К 4. Определите, какие из приведенных пар операторов эквивалентны: a) GO ТО К, (12, 13, 14) в) GO ТО (12, 13), К GO ТО К, (14, 12, 13) GO ТО (12, 13, 12), К 6) GO ТО (12, 13, 14), К г) GO ТО К, (12, 13, 12) GO ТО (14, 13, 12), К GO ТО К, (12, 13) Имеет ли смысл наличие одинаковых меток в вычисляемом опе- 5. раторе GO ТО? в операторе GO ТО по предписанию? Порция 32 Условные операторы Условные операторы, или операторы IF, предназначаются для ор- ганизации разветвлений вычислительного процесса, а также для про- пуска или выполнения некоторого оператора в зависимости от истин- ности данного условия. В языке имеется две разновидности условных операторов: арифметический оператор IF (условный арифметический оператор); логический оператор IF (условный логический оператор). Арифметический условный оператор. Арифметический оператор 1F позволяет передавать управление одному из трех операторов в за- висимости от знака некоторого арифметического выражения типа це- лого, вещественного или повышенной точности. Общий формат оператора IF следующий: IF (а) м2, п3, где а — арифметическое выражение любого типа, отличного от комп- лексного; п1У п2, п3 — метки операторов. Действие оператора сводится к следующему: если значение арифме- тического выражения в скобках отрицательно, то управление переда- ется оператору с меткой если это значение равно нулю — опера- тору с меткой п2; если оно положительно, то управление передастся оператору с меткой п3. Как и в случае ранее рассмотренных операторов перехода, если в программном модуле за арифметическим условным оператором сле- 82
дуют какие-либо другие операторы, первый из них должен быть по- меченным. Если оператор IF снабжается меткой, то эта метка не долж- на совпадать ни с одной из меток nlf п2, п3 во избежание «зациклива- ния» — передачи управления самому себе. Пример. Предположим, что по ходу выполнения программы необ- ходимо вычислить z как функцию х и у по одной из следующих формул: z = х2 — у2, если х < у, х2 + у2, если х = у\ х • г/, если х > у. Соответствующий фрагмент программы может быть представлен в виде: IF(X — Y)35, 4г, 45 35 Z = X*X —Y*Y GO TO 55 4-е Z = X*X-)-Y*Y GO TO 55 45 Z - X * Y . 55 < продолжение программы > Обращаем Ваше внимание на необходимость двух операторов GO ТО 55, включенных в приведенный фрагмент программы. Действи- тельно, при отсутствии, например, первого из них, после оператора с меткой 35 выполнялся бы оператор с меткой 40, что при х < у при- водило бы к неверному результату. Таким образом, с помощью арифметического оператора IF в общем случае обеспечивается разветвление программы на три ветви, однако, если требуется выполнить разветвление только по двум ветвям, одна из меток в этом операторе должна быть повторена дважды. Например, функция f (х) задана соотношением: /(%)= х I 1, если х = 0. С помощью арифметического оператора IF разветвление в програм- ме может быть сделано следующим образом: IF (X) 27, 28, 27 27 F = SIN (Х)/Х GO ТО 31 28 F = 1.0 31 {продолжение программы) 83
Рассмотрим еще один пример. Дужно написать фрагмент програм- мы для вычисления значений функции, f(x) = х + 3, если х 0; х • sin. (Зх), если 0 < х < х2—1, если 1,5 ^х 5, если 2,5 = х; х -|- cos (х + 0,5), если х > 2,5. если х^О; если 0 < х < 1,5; если 1,5^х< 2,5; если 2,5 = х; Необходимый фрагмент может быть представлен в виде: IF (X) 3, 3, 6 3 F = X + з.-е GO ТО 22 ; 6 IF (X — 1.5) 9, 12, 12 9 F = X * SIN (3.* X) GO ТО 22 12 IF (X — 2.5) 15, 5, 18 5 F — 5. GO TO 22 15 F = X * X — i.e GO TO 22 18 F = X + COS (X + 0.5) 22 {продолжение программы) Заметим, что в этом примере наличие всех четырех операторов GO ТО 22 является необходимым и обеспечивает выход в одну и ту же точку программы, на ее продолжение, независимо от того, на какую из ветвей (на какой оператор присваивания) было передано управление в результате выполнения одного из арифметических операторов IF. Обращаем Ваше внимание на то, что каково бы ни было значение X, переход будет осуществлен только по какой-либо одной из этих ветвей. Следовательно, если мы хотим сделать разветвление с помощью арифметического оператора IF более чем на три ветви, потребуется несколько таких операторов. В ФОРТРАН/ЕС в арифметическом операторе IF могут использо- ваться также арифметические выражения отсутствующих в стандарте типов INTEGER * 2 и REAL * 8. Задание. 1. Напишите фрагменты программы для вычисления значений следующих функций: х— 1, 1) f(x) = Зх2 + 4, если х < 10; если х = 10; 7,1х — 5,6, если х> 10. 2х + 5, если х < 0; 2) f{x)— х2—2,3, если 0^х< 1; , х — 0,5, если х > 1. 84
3) Цх) = х2 + У2, если х2 + у2^. 4; у2 — х2, если х2 + у2 > 4. 2. Напишите фрагмент программы, выполняющий присвоение пе- ременной г меньшего из значений величин х и у (г = min (х, у)). Порция 33 Условный логический оператор Условный логический оператор, или логический оператор IF, предназначен для пропуска или выполнения одного указанного в нем (внутреннего) оператора в зависимости от истинности некоторого условия. Логический оператор IF имеет формат: IF(₽)s. Здесь (3 — логическое выражение; s — любой оператор ФОРТРАНа, кроме DO (о нем будет речь далее) и логического IF. Логический оператор IF выполняется следующим образом: сначала проверяется истинность логического выражения 0, содержащегося в скобках в формате оператора. Если значение логического выражения истинно (.TRUE.), то следующим выполняется оператор s. Если логи- ческое выражение ложно (.FALSE.), то оператор s пропускается и управление передается следующему в записи программы оператору. В последнем случае логический оператор IF равносилен пустому опе- ратору (в первом случае — оператору s). Примеры. Предполагается, что переменные U и V — логического типа; тип остальных переменных объявлен неявно: IF (A.NE.B) R = (R + S)** 2 IF(A.GE.B)GO ТО 215 IF (.NOT. (U.OR. V)) A = A + e. 1 В том случае, когда логическое выражение, содержащееся в логи- ческом операторе IF, является отношением, этот оператор может быть заменен двумя операторами, одним из которых является арифмети- ческий оператор IF. Например, первый оператор в приведенном выше примере можно заменить двумя операторами: IF (А —В) 1, 2, 1 1 R = (R + S)** 2 2 <продолжение программы> 85
Ниже приведены два фрагмента программ, реализующие вычисле- ние значения функции: fix, у) — х2 — у2, если ху, если у sin (Зх), если х 4- у, если х> О л У > 0; х < 0 Д у > 0; хг + У2 < 1 Л У 0; г + у2 > 1 л у < о при заданных ее параметрах. По своему функциональному действию эти два фрагмента эквивалентны. 1) IF(X.GE.#..AND.Y.GT.#.) GO ТО 5 IF (X.LT.#.#.AND.Y.GT.#.) GO TO 1# IF(X*X + Y*Y.LE.l..AND.Y.LE.#.)GO TO 15 F = X + Y GO TO 2# 5F=X*X - Y*Y GO TO 2# 1# F = X * Y GO TO 2# 15 F = Y * SIN (3. * X) 20 (продолжение программы) 2) IF (X.GE.#..AND.Y.GT.#.) F = X * X — Y * Y IF (X.LT.#.#.AND.Y.GT.#.) F = X * Y IF (X * X + Y * Y.LE.1..AND.Y.LE.#.) F =Y * SIN (3. * X) IF (X * X + Y * Y.GT.l..AND.Y.LE.#.) F = X + Y (продолжение программы) Эквивалентность второго фрагмента первому следует из того, что логические выражения, используемые в его операторах IF, являются взаимно исключающими: только одно из них может быть истинным, каковы бы ни были входящие в эти выражения значения X и Y. По- этому из числа операторов присваивания, входящих в логические опе- раторы IF, только один будет выполнен. Вместе с тем заметим, что, хотя второй из приведенных фрагментов короче по записи, по времени выполнения в среднем он менее экономи- чен, так как при его выполнении осуществляется проверка истинности всех логических выражений, входящих во все операторы 1F, даже после того, когда какое-либо из этих выражений окажется истинным. Задание 1. Напишите на языке ФОРТРАН фрагмент программы для решения следующей задачи: Если результат логического умножения переменных L1 и L2 ра- вен .TRUE., выполнить оператор А = А + 1. и перейти к выполнению оператора с меткой 2; если он равен. FALSE. — непосредственно пере- йти к оператору с меткой 2. 2. Напишите фрагмент программы для вычисления значения сле- 86
дующей функции, используя логический оператор IF: | 2х— cosx, если х> 12,7; а) ~ | х2 + 4х, если х < 12,7. б) /(*) = х sin х, если х < 3,25; 3 — х2, если х = 3,25; x2sm2x2, если х> 3,25. 3. Какой из приведенных шести фрагментов является решением задачи вычисления значения функции sinx . л -----, если х=#0; 1, если х = 0; 1) IF (X.NE.0.0) Y = SIN(X)/X v = 1.0 {продолжение программы) 2) IF(X.NE.0.0) Y = SIN (Х)/Х IF (X.EQ.0.0) Y = \ .Q {продолжение программы) 3) IF (X.NE.0.0) GO TO 15 IF (X.EQ.0.0) GO TO 25 15 Y-SIN (X)/X GO TO 35 25 Y = 1.0 35 {продолжение программы) 4) Y = SIN (X)/X 1F(X.EQ.00) Y = 1.0 {продолжение программы) 5) IF(X.NE.0.0)GO TO 10 IF (X.EQ.0.0) Y = 1. GO TO 15 10 Y = SIN (X)/X 15 {продолжение программы) 6) IF(X.NE.0.0)GO TO 150 Y = 1.0 GO TO 255 150 Y - SIN (X)/X 255 (продолжение программы^ У = Порция 34 Операторы остановки В ФОРТРАНе имеется два оператора остановки — операторы PAUSE и STOP. Первый из них используется для временной остановки выполнения программы, второй — для завершения работы программы. Оператор PAUSE Формат оператора PAUSE следующий: PAUSE п или PAUSE 87
Здесь п — целое восьмеричное число без знака, состоящее не более чем из пяти цифр. Примеры PAUSE 1 PAUSE 12 Оператор PAUSE вызывает прерывание (паузу) выполнения про- граммы. В момент прерывания по оператотру PAUSE на консоль оператора или системное устройство печати выводится целое без зна- ка и, указанное в этом операторе. В приведенных примерах при оста- новке будут выданы записи: 1 12 После прерывания выполнения программы по оператору PAUSE можно либо снять программу, либо продолжать ее выполнение с прер- ванного места. Заметим, что решение о возобновлении выполнения про- граммы не находится под управлением самой программы и должно исходить извне. Другими словами, непосредственно в языке ФОРТРАН нет средств для задания этого решения. Оно должно исходить от опе- рационной системы, под управлением которой выполняется данная программа. • Оператор PAUSE чаще всего используется для выполнения ручных действий в процессе выполнения программы (замена входного файла, включение устройств вывода и др.). В отличие от стандарта, ФОРТРАН/EC допускает использование в операторе PAUSE десятичных констант, содержащих до пяти цифр, и текстовых констант (размером до 255 литер), заключенных в апост- рофы. Оператор PAUSE может иметь одну из следующих форм записи: PAUSE PAUSE п PAUSE 'а' где п — не более чем 5-разрядное целое без знака; а — текстовая константа (заключается в апострофы). В результате выполнения указанных операторов на устройство SYSLOG (см. порц. 134) выдается соответственно текст: PAUSE (в операционной системе ОС при использовании оператора PAUSE без параметра выдается текст PAUSE#), PAUSEn или PAUSEa. Если SYSLOG соответствует устройство связи с оператором, то в результате выполнения оператора PAUSE организуется пауза; для продолжения выполнения программы (с прерванного места) опе- ратор должен ввести директиву КТ (см. порц. 133). Если SYSLOG назначено устройство печати, то действие оператора PAUSE ограничи- вается выдачей соответствующего сообщения (пауза не организуется). 88
Оператор STOP Оператор STOP завершает работу программы и передает управле- ние программе-монитору (диспетчеру). Формат оператора STOP: STOP п или STOP где п — целое восьмеричное число без знака, содержащее от одной до пяти цифр. При остановке программы по оператору STOP на стандартное устройство вывода выдается запись и. Примеры записи оператора: STOP 15 STOP Таким образом, целое, указанное в операторе STOP, может быть ис- пользовано, как и в операторе PAUSE, в качестве признака, когда в программу включается несколько таких операторов, для определе- ления того, по какому из них произошел останов. Операторы STOP являются всегда последними выполняемыми опе- раторами программы, поэтому наличие хотя бы одного оператора STOP в головном модуле обязательно. Если за оператором STOP в программном модуле следуют еще какие-либо операторы, то (как и в случае операторов перехода) первый из них должен быть помеченным. В ФОРТРАН/EC в операторе STOP могут использоваться и деся- тичные целые числа без знака, содержащие не более пяти цифр. Если в операторе STOP указан параметр и, то на устройство связи с опера- тором выдается текст STOP п Заключительная строка END Каждый программный модуль должен завершаться заключитель- ной строкой END, указывающей транслятору конец модуля. В заклю- чительной строке в колонках с 7-ой по 72-ую в любых позициях запи- сываются символы Е, N, D в указанном порядке, а в остальных (в том числе и между буквами Е, N, D) проставляются пробелы. В каждом программном модуле должна быть, и при том единствен- ная, заключительная строка. Эта строка не может быть помечена. Порция 35 Оператор цикла Оператор цикла, или оператор DO, позволяет в удобной форме описывать повторения некоторых участков программы, называемых телом цикла. Переменные с индексами и оператор DO облегчают 89
программирование вычислений, связанных с массивами, элементы кото- рых обрабатываются одной и той же последовательностью опера- торов. Для иллюстрации применения оператора цикла рассмотрим задачу вычисления суммы 20 элементов массива х = {хъ х2, х20}, т. е. 20 $ = S Задача может быть решена последовательным суммирова- '=1 нием: «1 = $2 = $1 + -^2» s3 = s2 + х3; sk = sk—\ + S20 — S19 4“ *20- Рекуррентная формула для вычисления суммы любого конечного чис- ла N элементов имеет вид: s0 = 0; Sfc = Sfe—1 + xk. где k = 1, 2, 3, ...» /V. На языке ФОРТРАН этой формуле соответству- ют операторы: s = e.o S = S + X(I) второй из которых должен быть выполнен N раз при I = 1, 2, 3, ... N. Задавая I значения от 1 до 20 и выполняя второй оператор при каждом новом значении I, получим сумму 20 элементов массива. Фраг- мент программы может быть представлен в виде DIMENSION Х(2О) S = &.& 1= 1 18 S = S + X (I) 1 = 1 + 1 IF (1 — 2+) 18, 18, 1& 10 (продолжение программы) Аналогично по рекуррентной формуле: Ро = 1; Pk = Pft-i • ak, где k = 1, 2, ... , п, решается задача вычисления произведения конечного числа элементов 90
массива а = {ор а2, ...» ап\, т. е. рп = аг • а2 • ... • ап = П ак k=l Приведем фрагмент программы, реализующий эту рекуррентную фор- мулу при W = 20 DIMENSION А (20) Р = 1 К = 1 28 Р = Р ♦ А (К) К = К + 1 IF (К — 20) 28, 28, 28 2-0 (продолжение программы) В частности, n! = I, 2. З...п может быть вычислен в результате выполнения следующего фрагмента программы: INTEGER FN N = (заданное целое положительное число)1 FN = 1 К = 2 38 FN = FN ♦ К К = К+ 1 IF (К — N) 38, 38, 28 10 (продолжение программы) Применяя оператор DO, сумму можно вычислить с помощью сле- дующей более короткой программы: DIMENSION Х(20) s = 0.0 DO 18 J = 1,20 18 S=S+X(I) 10 (продолжение программы} В этом фрагменте объявление DIMENSION устанавливает, что переменная X имеет один индекс, максимальное значение которого равно 20. Сначала мы присваиваем S исходное значение, равное нулю, а затем выполняем оператор DO, в котором указана метка оператора 18. Последняя означает, что операторы программы после DO до оператора с меткой 18 включительно будут выполняться повторно. В нашем слу- чае после DO стоит всего один оператор — оператор с меткой 18, ко- торый и будет повторно выполняться. Сначала этот оператор выполня- ется при J = 1, так что на этот раз к значению переменной S прибав- ляется значение Хг Затем значение J увеличивается на 1 и оператор с меткой 18 выполняется уже при J = 2, так что к предыдущему зна- чению переменной S прибавляется значение Х2. Этот процесс будет продолжаться до тех пор, пока J не достигнет значения 20, указанного в операторе DO, после чего значение переменной S окажется равным 1 Значение п! растет очень быстро. Например, в ЕСЭВМ при п > 12 возни- кает переполнение переменной типа INTEGER. 91
сумме всех двадцати чисел. После этого управление передается опе- ратору, следующему за оператором с меткой 18, т. е. оператору с мет- кой 10. Используя оператор цикла, можно фрагмент программы вычисле- п ния р = Па£ записать в виде: DIMENSION A (2Q) Р = i.e DO 38 J = 1,2 Q 38 Р = Р * A (J) 2Q (продолжение программы) и для вычисления п\ — в виде: INTEGER FN N = (заданное целое положительное число) FN = 1 DO 38 J = 2, N 38 FN = FN * J 15 (продолжение программы) Формат оператора DO Имеется два формата оператора DO: 1) DO п i = т19 т2 (использован в наших примерах) 2) DO п i = т2, т3, здесь n — метка оператора, расположенного в том же программном модуле после соответствующего оператора DO; i — простая переменная целого типа, называемая управляющей переменной; тъ т2, т3 — простые переменные целого типа, принимающие толь- ко положительные значения, или целые положительные константы. Областью действия оператора цикла, называемой телом цикла, является последовательность операторов, расположенных в записи программы после этого оператора вплоть до оператора с меткой п (включая последний, называемый также конечным, или терминальным, оператором тела цикла). т1 — значение, которое принимает управляющая переменная в начале циклического процесса (т{ = 1 в нашем примере), т. е. перед первым выполнением тела цикла; это значение называется начальным параметром; т2 — конечное значение управляющей переменной, называемой конечным параметром; тг всегда должно быть не больше т2, т3 — приращение, на которое увеличивается значение при каждом очередном повторении тела оператора цикла; называется параметром $2
приращения. Если значение т3 не задано, то подразумевается, что оно равно 1 (как в рассмотренном примере). Действие оператора DO состоит в следующем: при i = т1 выпол- няются операторы тела цикла. Если управление передается конечному оператору (с меткой и), i увеличивается на величину т3 и последова- тельность вычислений повторяется. Повторные выполнения операто- ров цикла продолжаются до тех пор, пока значение i не превысит зна- чение i = т2 (если выход из области не будет совершен посредством какого-либо оператора перехода). После этого управление передает- ся оператору, следующему в записи программы за оператором с мет- кой п. Тело оператора DO может содержать в себе операторы перехода, передающие управление как на операторы, содержащиеся в нем, так и на внешние, однако находящиеся в том же программном модуле. Последнее может привести к тому, что число выполнений тела цикла может оказаться меньшим максимального, равного Г "*2 — 1 [ J L J ’ где [а] — целая часть числа а. Задание. 1. Пусть n-мерные векторы х и у заданы координатами х = {хь х2, ...» хл) и у = {уъ у2, ..., уп). Скалярное произведение векторов вычисляется по формуле: sp = (х, у) = S х(у(, fc=l а модуль векторов по формуле: И = Составить фрагменты программ для вычисления: а) скалярного произведения векторов; б) модулей векторов, используя оператор DO и без него. 2. Два одномерных массива А и В содержат каждый по 50 элемен- тов. Напишите фрагмент программы для вычисления суммы: 50 SUM = S А, . Вы_6 Г=1 используя оператор DO и без него. 3. Составить фрагмент программы для вычисления суммы произве- дений трех последовательных элементов одномерного массива, содер- жащего 3 п элементов, т. е. s = аг • a-i • а3 4- а4 • а3 • ae -J- • • • азп^2 • азп—i • йзл 93
Порция 36 Вложенные циклы Тело оператора цикла может содержать в себе другие операторы цикла. В таком случае тела внутренних операторов цикла должны пол- ностью покрываться телами внешних, а управляющие переменные опе- раторов цикла, находящихся на разной глубине получаемого гнезда, должны быть различными. Самыми внутренними операторами цикла Правильно Неправильно Рис. 23 в таком гнезде называются те из них, тела которых не содержат операторов цикла (см. рис. 23). Чтобы лучше понять действие вложенных операторов DO, рассмотрим задачу транспо- нирования 1 матрицы. Предположим, дана матрица, имеющая 10 строк и 12 столбцов. Если обозначить первоначальный матричный массив через А, а новый через В, то для по- лучения, например, элемента матрицы В, сто- ящего в третьей строке и четвертом столбце, следует записать оператор: В(3, 4) = А (4, 3) Последняя запись означает, что элемент, стоящий на пересечении 3-й строки и 4-го столбца новой матрицы, равен элементу исходной матри- цы А, располагающемуся на пересечении 4-й строки и 3-го столбца. Поэтому в общем случае задача сводится к выполнению оператора при- своения В (К, J) = A (J, К) для значений J и К, изменяющихся от 1 до 10 и от 1 до 12 соответственно. Блок-схема алгоритма решения этой задачи представлена на рис. 24. Рассмотрим эту блок-схему. Сначала мы полагаем J = 1, затем К = 1, а потом переходим непосредственно к выполнению оператора: В (К, J) = A(J, К) Так как во время первого витка цикла J и К равны единице, мы фактически присваиваем значение А (1,1) переменной В (1,1). Далее К увеличивается на единицу (теперь значение К равно 2). Так как на этом этапе К < 12, возвращаемся к началу внутреннего цикла для продолжения вычислений, но на этот раз выполняется оператор: В(2, 1) = А(1, 2) Этот процесс продолжается до тех пор, пока значение К не превысит число 12; тогда осуществляется возврат к началу внешнего цикла после увеличения J на единицу. Поэтому новое значение J будет равно 2. 1 Под транспонированием понимается процесс образования новой матрицы, строки которой являются столбцами исходной матрицы. 94
Затем К вновь присваивается первоначальное значение, равное еди нице, и таким образом выполняется оператор: В(1, 2) = А(2, 1) Далее производятся действия по внутреннему циклу, которые повто- ряются до тех пор, пока К не достигнет значения 12. Это означает, что фактически оператор присвоения В (К, J) = A (J, К) выполняется 120 раз (один раз для каждого элемента матрицы, общее количество которых равняется числу строк, умноженному на число столбцов). Ниже представлен эквивалент приведенной блок-схемы на языке ФОРТРАН, использующий операторы DO: DO 1 J= 1,1# DO 1 К = 1,12 1 B(K, J) = A(J, К) Необходимо помнить, что самый внутренний цикл организуется последним, а выполнение его завершается всегда первым. Идея такой организации распространяется также и на случай трех, четырех или большего количества циклов, которые могут быть вложены один в другой. При организации вложенных операторов DO не- обходимо соблюдать следующее правило: вложен- ные циклы должны располагаться таким образом, чтобы отдельные циклы «перекрывались» (но не пересекались). На рис. 23 схематически представ- лены примеры допустимой и недопустимой органи- зации вложенных циклов. В(к,1) ~А(1,К) -.....-L_____ Увеличить К на единицу Увеличить I на единицу Q Конец Рис. 24 Пример. Предположим, что для симметричной матрицы А = (а£/) (/ = 1, n; j = 1, п) вычислены значения всех элементов, расположен- ных на главной диагонали и над нею. Нужно присвоить значения эле- ментам, находящимся ниже главной диагонали. Вариант 1 DO 15 I = 2,N М = I — 1 DO 15 К = 1,М 15 A(I, К)= А(К, I) {продолжение программы) Вариант 2 М = N —- 1 DO 15 I = 1,М L = I + 1 DO 15 К = L, N 15 А (К, I) = А (I, К) {продолжение программы) В варианте 1 заполнение части матрицы, расположенной ниже главной диагонали, происходит по строкам: сначала заполняется единственное 95
свободное место второй строки (1 = 2, К = 1), затем два свободных места третьей строки (I = 3, К = 1, 2) и т. д. Во втором варианте за- полнение элементов ниже главной диагонали происходит по столбцам. В первом варианте введена дополнительная переменная М целого ти- па, поскольку управляющая переменная К внутреннего цикла не мо- жет быть выражением; аналогично, во втором варианте с этой же целью введены переменные М и L. Задание. 1. Двумерный массив А содержит 15 строк и 15 столбцов. Одномерный массив X содержит 15 элементов. Составьте фрагмент программы для вычисления 15 элементов одномерного массива В по формуле (умножения матрицы на вектор): 15 = S Ап • X»; 1= 1, 2, 3, .... 15. /=1 2. Задана квадратная матрица А порядка п. Составить фрагмент программы для транспонирования матрицы А на занимаемой ею па- мяти, использовав при этом лишь одну переменную-посредницу. Порция 37 Правила использования оператора DO Оператор DO ’позволяет строить весьма компактные программы, но при его использовании необходимо соблюдать определенные пра- вила: 1. Конечный оператор цикла записи программы должен следовать после оператора DO и находиться с ним в одном и том же программном модуле. Конечный оператор не может быть никаким оператором пере- хода GO ТО, оператором RETURN, STOP, PAUSE, DO, арифмети- ческим оператором IF, а также логическим оператором IF, содержащим перечисленные выше операторы управления. 2. Начальное значение параметра цикла не должно быть большим конечного его значения. После выхода из области оператора DO в ре- зультате выполнения оператора GO ТО или условного оператора IF параметр цикла остается определенным и его значение равно последне- му присвоенному ему значению. 3. Никакой оператор в области действия DO не должен каким- либо образом изменять значения параметров, указанных в этом опера- торе и определяющих значения управляющей переменной; это значит, внутри области действия оператора DO недопустимо присвоение зна- чений переменным f, т19 m2i т3 посредством операторов присвоения и ввода. Например, недопустима следующая организация цикла DO: DO 2 К = 1, М, 2 А (К) = 1.7 ♦ SIN (F (К)) К = К+ 1 2 М = М —- 3 96
так как К и М (переменные, указанные в операторе DO) не могут из- меняться в его области. Никаких других ограничений на указанные переменные не накладывается. 4. Если цикл завершается исчерпанием значений управляющей переменной, то значение параметра цикла не определено. 5. Передача управления во внутрь тела оператора DO из какого- либо оператора, лежащего вне этого тела, запрещена. Это правило запрещает также передачу управления из тела внеш- него DO в тело внутренних DO, но оно, однако, управления из тела внутреннего DO в тело внешнего DO. При этом управление переда- ется от оператора, лежащего внутри тела внеш- него DO, другому оператору, также лежаще- му внутри него. Схематически это правило проиллюстрировано на рис. 25. Квадратными скобками на рисунке обозначены тела опе- раторов DO; стрелки изображают передачи управления. Имеется исключение из правила, запреща- ющего передачу управления извне внутрь тела оператора DO, связанное с организацией расширенной области DO. Расширенной об- ластью DO называется последовательность не запрещает передачу Допустимо Недопустимо Рис. 25 операторов, выполняемая между выходом из области самого внутреннего DO гнезда DO и возвратом в область это- го же DO при соблюдении следующих правил: а) ни один из параметров оператора DO, имеющих силу в данной области, не может быть изменен; б) расширенная область не может содержать другого оператора DO, имеющего расширенную область; в) между точками выхода и возврата не может находиться опера- тор, являющийся конечным области действия оператора DO. Допустимая глубина вложенности тел циклов ничем не ограничена (она может ограничиваться в отдельных реализациях языка), однако для любых операторов цикла, содержащихся в телах других операто- ров цикла, встретившийся конечный оператор любого из них должен следовать за конечными операторами всех внутренних по отношению к нему операторов цикла или совпадать с ними. После выполнения конечного оператора некоторого цикла получает соответствующее приращение параметр самого внутреннего оператора DO, ссылающегося на этот конечный оператор. Если при этом значение изменившегося параметра не превышает его конечного значения, то повторяется выполнение тела соответствующего оператора DO (т. е. тела DO, параметр которого получил приращение). После того как параметр цикла получает значение, превышающее его граничное значение, соответствующий оператор цикла считается 4 9-2712 97
завершенным. В этом случае значение его параметра становится неоп- ределенным. Если на данный конечный оператор ссылаются несколько опера- торов DO, то после его выполнения получает приращение параметр ближайшего внешнего к завершенному оператору; действия повторя- ются до тех пор, пока все операторы DO, ссылающиеся на данный конеч- ный оператор, не будут завершены; после их завершения выполняется оператор, следующий за этим конечным оператором. Область действия оператора DO может быть расширена в том слу- чае, если выполняются оба следующие условия: 1. Внутри области самого внутреннего оператора DO (назовем ее область-1) имеются операторы GO ТО или арифметические операторы IF, которые могут передать управление во внешнюю область DO (на- зовем ее область-2) по отношению к области самого внешнего из объем- лющих область-! операторов DO. 2. В области-2 существуют операторы GO ТО или арифметические операторы IF, которые передают управление в область-1. При выполнении этих условий расширенной областью оператора DO считается последовательность всех операторов, которые могут быть выполнены между всеми парами операторов управления, указанными в правилах 1 и 2. Правило, запрещающее изменение значений управляющих пере- менных и параметров цикла в его теле, имеет силу и для расширенных областей оператора DO. Существенно, что никакой*отг?ратор GO ТО или арифметический оператор IF не может передавать управление в область действия опе- ратора DO в том случае, когда он не выполняется как часть расширен- ной области. Пример использования расширенной области оператора приведен в порции 38 (пример 1). В процессе выполнения области цикла допускается обращение к процедурам (о которых будет речь идти далее). При этом считается, что все действия, связанные с выполнением любой процедуры, включаются (временно) в данную область цикла. Если некоторый оператор является конечным оператором несколь- ких областей операторов DO (более чем одного), то метка этого опера- тора может быть использована в операторах GO ТО или условных опе- раторах только в том случае, когда эти операторы встречаются внутри самого внутреннего оператора DO, ссылающегося на данный конечный оператор. Завершение цикла Для завершения цикла DO руководствуются правилом, заключаю- щимся в том, что конечный оператор тела любого оператора цикла должен быть оператором ФОРТРАН а, не вызывающим передачи уп- равления. Не имеет смысла, например, запись вида: 98
DO 7 L = 1,3# A (L) = В (L) * C (L + 2) 7 GOTO 8 Действительно, данный фрагмент предписывает вычислительной ма- шине выполнить тело (два последних оператора) при L = 1, получив значение А (1), а затем перейдет к выполнению оператора с меткой 7, который указывает на передачу управления оператору с меткой 8, находящемуся где-либо в программе (в данном программном модуле). Но по определению оператора DO при выполнении его конечного опера- тора параметр цикла L должен получить приращение и цикл должен повториться. Поэтому транслятор должен указать на ошибку. Но иногда возни- кает необходимость поместить некоторый оператор управления GO ТО в конце тела DO. Например, нужно поместить оператор GO ТО по вы- числению в конце цикла, с тем чтобы можно было выйти из него не- сколько ранее, если выполнится определенное условие. При этом вычис- ляемый оператор GO ТО должен быть последним выполняемым опера- тором тела цикла. Правила написания ФОРТРАН-программы требуют при этом применения специального оператора CONTINUE, который будет рассмотрен в следующей порции. Задание. 1. Какова допустимая глубина вложенности операторов цикла? 2. Могут ли несколько операторов DO ссылаться на один конечный оператор? В При gflimy х£дрвиях^бдас1*м*№вия оператора DO может быть расширена? 4. Какие ограничения наложены на конечный оператор цикла? Порция 38 Оператор продолжения CONTINUE Оператору CONTINUE в рабочей программе не соответствуют ни- какие действия. Он используется в качестве конечного в области опе- ратора DO во избежание окончания тела цикла операторами GO ТО, PAUSE, STOP, RETURN, арифметическим оператором IF или логи- ческим оператором IF, содержащим любой из перечисленных здесь операторов, или в любой ситуации, когда требуется пометить опе- ратор, не выполняющий фактически никаких действий. Оператор CONTINUE имеет следующий формат: п CONTINUE Здесь п — метка, присвоенная оператору CONTINUE. Обращаем Ваше внимание на то, что последним оператором области DO может быть логический оператор IF, который в этом случае не дол- жен содержать оператора управления. Например, допускается следую- щий цикл DO: 4 99
DO 5 I = 1,30 5 IF (A (I). NE.O.) A (I) = A (I) + В Этот цикл эквивалентен следующему: DO 5 I = 1,30 IF (A (I)) 1,5,1 1 A (I) = A (I) + В 5 CONTINUE Таким образом, в случае истинности логического выражения выпол- няется оператор, указанный в логическом операторе IF. Если логи- ческое выражение ложно, то этот оператор IF выполняется как опера- тор CONTINUE. И в том и в другом случаях цикл возобновляется под управлением I. Пример 1. Составить фрагмент программы, определяющий мини- мальный элемент AMIN массива А (содержащего N элементов) и его порядковый номер К в массиве. Если минимальных элементов в мас- сиве несколько, требуется определить из них первый по порядку. Для решения поставленной задачи положим вначале AMIN = А (1), К = 1 Далее, просматривая все остальные элементы от второго до N-ro, будем сравнивать их с AMIN. Если очередной элемент А (I) окажется мень- шим AMIN, то присвоим его значение переменной AMIN, а значение его индекса I — переменной К; в результате получим искомые зна- чения: ' AMIN = А (1) К= 1 DO 20 I = 2, N IF (AMIN — A (I)) 20, 20, 10 10 AMIN = A (I) K= I 20 CONTINUE Пример 2. Дан массив L целых положительных чисел. Требуется найти сумму LS всех четных чисел, входящих в этот массив, и их коли- чество LK. Массив L содержит NB чисел. Для определения того, является ли данный элемент L (I) четным или нет, включим в программу следующий оператор присваивания: LI = L (I) — L (1)/2 *2+1 Учитывая особенность выполнения операции деления для целых чисел (см. порцию 23), легко заметить, что L1 = 2, если L (I) — нечет- ное число, LI = 1, если L (I) — четное число. Фрагмент программы для решения поставленной задачи может быть представлен в виде: LS = 0 LK = 0 100
DO 5 I = 1, NB LI = L (I) — L (I)/2 *2+1 GO TO (10, 5), LI 10 LS = L (I) + LS LK= LK+ 1 5 CONTINUE 7 {продолжение программы) Переставив местами в списке меток оператора GO ТО метки 5 и 10, получим фрагмент программы для вычисления суммы LS нечетных членов массива и их числа LK. Заменив в списке меток того же оператора GO ТО первую метку 5 на метку 7, получим программу для вычисления суммы первых четных членов массива L до первого нечетного члена и их числа LK. Заметим, что в последнем случае оператор CONTINUE может быть опущен при условии, что его метка 5 будет перенесена к предыдущему оператору присваивания. Задание. 1. Сформулируйте задачу, решаемую данным фрагментом программы: S1 = 0.0 DO 5 I = 1, N DO 5 J = I, N 5 SI = SI + A (I, J) 2. Ниже приведены фрагменты программы. Определите, какие из них эквивалентны фрагменту, приведенному в задании 1, какие со- держат ошибки и в чем эти ошибки заключаются. а) si = -е. е б) SI = 8. 8 DO 5 I = 1, N DO 5 I = 1, N DO 6 J = 1, N DO 6 J = I, N 5 SI = SI + А (К, J) 6 SI = SI + A (I, J) 6 CONTINUE 5 CONTINUE в) SI = 8. 8 г) si = e.0 DO 5 К = 1, N DO 5 К = 1, N DO 6 J = I, N DO 6 К = I, N SI = SI + A (K, J) SI = SI + А (К, I) 6 CONTINUE 5 CONTINUE 5 CONTINUE 6 CONTINUE Порция 39 Примеры использования оператора DO Пример 1. При рассмотрении этого фрагмента предполагается, что заданы два массива А (10), В (30). Задача состоит в вычислении в ука- занном порядке следующих величин: ю О s, = £ At • В. 1=1 101
2) S2 = S? 3) S3 = S2 + 1.5 4) S4 = S3+ 1.7 5) S8 = Ss + S42 io 6) S*+5 = £ A, • B,+*, k = 1, 2, ... , 19 z=i 9 7) S25 = (Ai + B30) • B21 + J] A, • B,+2o + (A10 — B30) • B30 i=2 Вычисление значений Se, S7, ...,S24 поформуле 6) осуществляется в цикле. Далее осуществляется выход в расширенную область, где про- изводится вычисление необходимого скалярного произведения (суммы попарных произведений). При этом в начале работы данного фраг- мента производится вычисление по формуле 1) с помощью тех же опера- торов, однако не рассматриваемых в качестве операторов, принадлежа- щих расширенной области оператора цикла. Пример имеет иллюстра- тивный характер и показывает, что понятие расширенной области оператора цикла является динамическим: тело цикла расширяется на время выполнения этого оператора при соблюдении указанных ранее условий 1 и 2 (см. порцию 37). DIMENSION А (19), В (39), С (4), S (25) ASSIGN 5 ТО М К= 9 8 G = 9.9 DO 1 I = 1, 10 12 = I + К 1 G = G + А (I) ♦ В (I 2) GO ТО М, (5, 9, 7) 5 S (1) = G ASSIGN 9 ТО М S (2) = G * G S (3) = S (2) + 1.5 S (4) = S (3) + 1.7 S (5) = S (3) + S (4) ** 2 DO 6 К = 1, 19 GO ТО 8 9 S (К + 5) = G 6 CONTINUE А (1) = А (1) + В (39) А (10) = А (19) - В (39) К = 29 ASSIGN 7 ТО М GOTO 8 7 S (25) = G 102
{продолжение программы) Пример 2. Для того, чтобы у Вас не сложилось впечатление, что оператор DO используется только для обработки данных, входящих в массивы (т. е. переменных с индексами), рассмотрим пример решения алгебраических или трансцендентных уравнений f (х) = 0 методом итераций. Метод итераций заключается в следующем. Исходное уравнение представляется в равносильной форме вида: х = ф (х) Затем выбирается некоторое значение х = х0 в качестве нулевого при- ближения; последующие приближения вычисляются по формулам: М = Ч> (х0). х2 = ф (хг), ... или в общем виде: хл+1 = ф(хл) (п = 0, 1, 2, . ..) Процесс продолжается до тех пор, пока не будет достигнута задан- ная точность: | хП4-1 — хп | < EPS (достаточным условием сходимости процесса является | ф' (х) | I < 1 для х в окрестности точки х0). При этом требуется подсчитать число итераций I и выдать его, на- ряду с найденным корнем х, на печать. Число итераций ограничено максимальным числом N = 500; если при выполнении N итераций условие | хп-1 — х| < ЕХР оказывается невыполненным, требуется выдать текст: МЕТОД НЕПРИМЕНИМ Поставленная задача может быть решена с помощью следующей про- граммы, в которой операторы ввода и вывода данных обозначены ус- ловно: {Ввод XI, EPS) (XI — начальное приближение) DO 6 L = 1,5-&-& Х& = XI XI = {арифметическое выражение, определяющее значение <Р (х0)> IF (ABS (XI — Х0). LT. EPS) GO ТО 2 6 CONTINUE (вывод МЕТОД НЕПРИМЕНИМ) STOP 2 {вывод XI, L) STOP END Обращаем Ваше внимание на то, что в приведенной программе зна- чение управляющей переменной L, если число итераций не превосходит 500, используется вне цикла в операторе с меткой 2. Программа вклю- чает два оператора STOP. Первый из них (считая в порядке записи в программе) будет выполняться в случае, когда процесс окажется расходящимся. При этом будет напечатана строка: МЕТОД НЕПРИ- МЕНИМ 103
Заметим также, что в промежутке программы между операторами CONTINUE и первым оператором STOP управляющая переменная опе- ратора цикла не определена и, следовательно, сюда не может быть вставлен никакой оператор, использующий эту переменную. Задание. Для решения систем алгебраических или трансцендент- ных уравнений [ х = фг (х, у, г); у = <р2 (х, /л *); . г = Ф3 (х, у, г) иногда применяется метод простой итерации, согласно которому Хл+1 = фх (х„, уп, Zn)\ Уп-и = ф2(хл, уп, zn\ Z/i+l = Фз(х„, У nt либо метод итерации типа Зейделя: хп+1 = Фх(хп, уп, zn); Уп+1 = <р2(Хл+1, Уп, znY, Zn+1 = Фз(хм-ь /М+ь гп). .Итерационный процесс продолжается до тех пор, пока не будет выполнено условие: IХ/2+1 — хп I < EPS л | ///2+1 — Уп I < EPS Д I Zn+\ — zn | < EPS, где EPS — заданная точность, х15 yv z1 — начальное приближение. 1. Составить фрагмент программы, реализующий метод простой итерации для решения системы линейных уравнений: %1 = а11х1 + а12х2 + а13х3 + Х2 — 4~ ^22^2 4“ #23X3 “Ь ^2» х3 = a3ixi + #32X2 + ^33X3 + Ь3. Если количество итераций N > 100, выдать текст ПРОЦЕСС РАСХО- ДИТСЯ. Требуется написать данный фрагмент в трех вариантах: а) рассматривая коэффициенты системы как отдельные простые пере- менные; б) полагая, что коэффициенты при неизвестных образуют дву- мерный массив А, а свободные члены — одномерный массив В; в) по- лагая, что все коэффициенты системы образуют общий массив. 2. Задание 1 (б) выполнить для системы п — линейных уравнений, где п произвольно. 3. Задание 1 (б) выполнить для метода итераций типа Зейделя. 4. Массив А содержит N элементов. Составьте фрагмент программы, определяющий М — число неотрицательных элементов в массиве А, расположенных с начала массива до первого отрицательного элемента. Искомое число равно 0, если первый же элемент массива окажется от- рицательным, и равно N, если все эти элементы неотрицательны. 104
Глава III ОПЕРАТОРЫ ВВОДА-ВЫВОДА Порция 40 Общая характеристика операторов ввода-вывода Операторы ввода-вывода предназначены для обеспечения обмена информацией между основной памятью и внешними йссителями. Данные на внешних носителях организуются в записи, которые, в свою очередь, объединяются в наборы данных, называемые файлами. Запись — это логически (содержательно) связанная группа данных, являющаяся минимальной порцией обмена. Допустимый размер запи- си, измеряемый числом составляющих ее литер, зависит от используе- мых устройств обмена — устройств ввода-вывода. Так, при исполь- зовании перфокарт последовательность литер, зафиксированная на одной перфокарте, может рассматриваться как запись, а последова- тельность таких перфокарт образует файл. При выводе на печать в ка- честве записи рассматривается строка печати. В стандарте ФОРТРАНа определены лишь так называемые после- довательные файлы, обращение (ввод или вывод) к отдельным записям которых возможно лишь в порядке расположения записей в файле (что соответствует таким носителям внешней памяти, как магнитные ленты, перфокарты, бумажная лента). В дополнение к этому в ФОРТ- РАН/ЕС определены файлы прямого доступа, порядок заполнения или выборки записей из которых может определяться пользователем. В стандарт ФОРТРАНа включены следующие операторы ввода-выво- да для последовательного запоминания и выборки записей: READ, WRITE, REWIND, BACKSPACE и объявления FOR- MAT, определяющие структуру записей последовательного файла и способ представления в нем данных. В ФОРТРАН/ЕС операторы READ и WRITE используются для обработки файлов как последовательного, так и прямого доступа. Кроме того, в этот же язык включены операторы ввода-вывода: DISPLAY, FIND, PRINT, PUNCH и объявления DEFINE FILE, NAMELIST. Для идентификации файлов последние снабжаются номерами, которые выбираются в соответствии с устройствами, обеспечивающими операции обмена. Для указания областей основной (внутренней) памяти, участвующих в операции обмена, используются списки ввода- вывода. 105
Списки ввода-вывода Области основной памяти, участвующие в операциях обмена, могут быть как смежными, так и раздельными и определяются списком ввода- вывода. Список может состоять из переменных (простых и индексиро- ванных), имен массивов или элементов формы неявного DO, использу- емой для передачи элементов массивов. Пример. При наличии объявления DIMENSION А (4), С (12), Е (1£) оператор WRITE (8) А, В, С (8), (С (К), К = 3,5), D, Е (3) предписывает вывод (занесение) в файл с номером 8 без преобразования формата всех элементов массива А (в порядке возрастания его индекса), затем зна- чения переменной В, затем восьмого элемента массива С, затем третьего, четвертого и пятого элементов того же массива С; затем переменной D и третьего элемента массива Е (здесь номер файла 8 указан в скобках после ключевого слова WRITE). Элементы списка включаются в операцию ввода-вывода в порядке их перечисления слева направо. В случае массива в операцию вклю- чаются все его элементы в порядке их расположения во внутренней памяти. При указании в списке отдельных элементов массивов в ка- честве индекса может быть задано некоторое допустимое арифмети- ческое выражение, однако содержащее лишь те переменные, значения которых к моменту выполнения оператора, содержащего данный спи- сок, уже определены. Форма неявного DO, используемая в качестве элемента списка ввода-вывода, заключается в круглые скобки. В этих скобках может быть указан список простых переменных, элементов массивов или имен массивов (разделенных запятыми). За последним из этих элементов после запятой записывается управляющая переменная, за которой после знака «=» указываются параметры, правила записи которых и смысл тот же, что и в случае оператора DO. Указанные в скобках неявного DO элементы перебираются при каждом значении управля- ющей переменной. Например, оператор READ(1)(A(I), В(1), 1 = 2, 8, 2), С предписывает ввести из файла с номером I значения переменных А (2), В (2), А (4), В (4), А (6), В (6), А (8), В (8) без преобразования их формата и затем значение переменной С (данные считываются из файла и присваиваются элементам списка в порядке их записи слева направо). В список ввода-вывода могут быть включены вложенные формы неявного DO, для каждой из которых должна быть определена своя управляющая переменная. Так, оператор WRITE (3) (АО (I), (А(1, К), К= 1,4), В (I), 1= 1,3) является предписанием ввести в файл последовательность значений сле- 106
дующих переменных: А0(1), А(1,1), А(1,2), А(1,3), А (1,4), В(1) АО (2), А (2,1), А (2,2), А (2,3), А (2,4), В (2) АО(3), А (3,1), А (3,2), А (3,3), А (3,4), В (3) Форма неявного DO удобна для ввода-вывода элементов массивов в порядке, отличном от порядка их размещения в памяти, для создания новых массивов из элементов нескольких других массивов (как это имело место в приведенном примере), а также отдельных элементов мас- сивов или их частей. В случае операторов ввода управляющая переменная и ее параметры могут встречаться внутри ее области только в индексах. В ФОРТРАН/ ЕС в качестве индексных выражений в списках ввода-вывода могут быть использованы, как и в других случаях, любые арифметические выра- жения с одним ограничением: не допускается включение указателей тех функций, алгоритм вычисления которых в свою очередь включает операции обмена. Задание. 1. Определите результат выполнения следующих опера- торов: a) WRITE (3) (A (I, I), В (I), I = 1, И) б) WRITE (3) (((А (К, I), К = 1, Ш), I = 2,И), (А (К, 1), К = 1,1#)) в) DATA LINE /'--7 WRITE (3) (LINE, I = 1, 3£) 2. Одинаков ли результат выполнения следующих операторов: a) READ (1) ((А (I, К), К = 1, 1Я), I = 1, Ш) б) READ (1) А П о р ц и я 41 Операторы ввода и вывода Операторы ввода-вывода могут выполняться без каких-либо пре- образований данных, в чем обычно возникает необходимость при запо- минании на внешнем носителе промежуточных данных (подлежащих в дальнейшем вводу в основную память машины для их обработки той же или другой программой). В подобных случаях между представлением данных в основной и во внешней памяти устанавливается однозначное соответствие — данные представляются в виде «образов оперативной памяти». Структура записей, называемых бесформатными, определя- ется непосредственно списком ввода-вывода. Рассмотренные в преды- дущей порции примеры операторов ввода (READ) и вывода (WRITE) являются примерами обмена бесформатными записями. Стандартом языка предусматривается связь с каждым отдельным устройством ввода-вывода только одного последовательного файла. 107
Поэтому номер устройства может отождествляться с номером файла. Оператор бесформатного ввода имеет формат READ (а) b или READ (а) Здесь b — список ввода; а — номер устройства (файла), который может быть задан целым без знака или именем простой переменной целого типа. Оператор бесформатного ввода предписывает ввести очередную запись из устройства а и, при наличии в нем списка ввода Ь, содержа- щиеся в этой записи значения последовательно присвоить элементам этого списка. Последовательность значений в бесформатной записи должна быть достаточной для определения значений всем элементам списка. При отсутствии списка запись пропускается. Оператор бесформатного вывода имеет формат WRITE (а) & Здесь амЬ имеют тот же смысл, что в предыдущем случае. Оператор бесформатного вывода предписывает создание очередной записи, состоящей из последовательности значений, определяемых списком 6, в файле с номером а. В том случае, когда информация подготавливается для обработки в машине (исходные данные) или выводится из машины для ее обозре- ния человеком, возникает необходимость в ее преобразовании к форме, удобной для человека. Для придания информации удобочитаемой формы при выводе и ее преобразования к внутреннему представлению при вводе в языке вве- дено понятие-форматных записей. Структура форматных записей на- ряду со списком ввода-вывода определяется специальным объявлением FORMAT. Связь между операторами ввода-вывода и соответствующими объявлениями FORMAT, определяющими структуру записи, устанав- ливается путем указания метки объявления в том или ином операторе ввода-вывода. Например, оператор READ (1,25) К, S при наличии в данном программном модуле объявления 25 FORMAT (13, F6.2) означает, что из файла с номером 1 должны быть введены значения пе- ременных К и S (в указанном порядке), которые перед присваивани- ем должны быть преобразованы согласно указанным в объявлении FORMAT форматам 13 и F6.2 (виды форматов и их смысл объясня- ются ниже). 108
Оператор форматного ввода READ Общий вид оператора форматного ввода следующий: READ (а, с)Ь или READ (а, с) Здесь b — список ввода, а — номер файла (целое без знака или прос- тая переменная целого типа), с — спецификация формата. Спецификация формата может быть задана одним из двух способов: 1) меткой объявления FORMAT (заданного в том же программном модуле); 2) именем массива; в начале используемого с данной целью массива должна располагаться правильная спецификация формата, которая, как и в случае объявления FORMAT, начинается открывающей и за- канчивается парной к ней закрывающей скобкой (пример спецификации формата, заданной именем массива, приведен в порции 102). Единственным ограничением на спецификацию формата, задавае- мую в массиве, является следующее: в ней не должен встречаться опи- сатель поля wH (см. далее, порц. 49). В ФОРТРАН/ЕС это ограничение снято, однако нельзя использо- вать формат, содержащий двойные апострофы. В результате выполнения форматного оператора ввода очередные записи файла с номером а вводятся и преобразуются в соответствии со спецификацией формата г, и присваиваются элементам списка Ь. Переменные в списке одного и того же оператора READ могут быть любого типа, в том числе различных типов. Например: READ(1,1)A, В, К, L(l), С, М(4) Пусть 1 — номер файла, заданного на устройстве ввода перфокарт. Значения переменных должны располагаться на перфокарте в той же последовательности, в какой их имена перечислены в операторе READ. Таким образом, процесс ввода происходит в следующем порядке: первое значение с перфокарты присваивается первой переменной, второе значение — второй и т. д., пока не будет исчерпан список пере- менных. Последовательный перебор идет слева направо, так что пер- вой переменной будет присвоено значение, отперфорированное в левом краю перфокарты с данными (вторая литера 1 в скобках после ключе- вого слова READ — метка объявления FORMAT). В одной записи (перфокарте) не могут находиться данные, предна- значенные для чтения двумя операторами READ, поскольку при выпол- нении оператора READ запись, с которой была прочитана хотя бы одна литера, считывается полностью. Для каждого оператора READ должны быть свои перфокарты либо перфокарта. Следовательно, при вводе данных с перфокарт оператор READ всегда означает чтение с новой перфокарты. Если, например, на одной перфокарте отперфорировано 109
шесть данных, то их нельзя ввести в машину с помощью двух операто- ров READ, перечислив переменные так, чтобы второй оператор начал ввод с того места, где первый остановился. Единственный способ ввести шесть данных с одной перфокарты — это написать один опера- тор READ и перечислить в нем все шесть переменных. Предположим, что за устройством ввода с перфокарт закреплен номер 1; тогда, если нам надо записать оператор считывания с одной перфокарты трех данных, значения которых необходимо присвоить переменным А, В, G, то запишем: READ (1,3) А, В, G (предполагается, что в объявлении FOPMAT с меткой 3 будет задана необходимая спецификация формата). Оператор форматного вывода WRITE Оператор WRITE выполняется аналогично оператору READ. Если использование оператора READ обеспечивает возможность ввода записей исходных данных в память ЭВМ, то применение опера- тора WRITE позволяет осуществлять вывод записей, включающих зна- чения переменных (результаты вычислений) или вспомогательную ин- формацию из памяти машины на устройство вывода — в файл, номер которого указан в данном операторе. Формат оператора WRITE следующий: WRITE (a, c)b или WRITE (а, с) Синтаксис и смысл элементов оператора а, Ь, с тот же, что и для формат- ного оператора READ. Рассмотрим пример записи оператора WRITE. Предположим, что за алфавитно-цифровым печатающим устройством (АЦПУ) закреплен номер 3. Тогда оператор выдачи на печать значений переменных А, В, С будет иметь вид: WRITE (3,5) А, В, С Форматные операторы READ и WRITE содержат следующую ин- формацию, связанную с процессом ввода и вывода: 1. Относится ли операция к вводу (READ) или выводу (WRITE). 2. Устройство, используемое при выполнении операторов ввода- вывода (это определяется номером устройства ввода-вывода). 3. Какие переменные должны получить новые значения или значе- ния каких переменных надо вывести (это определяется списком пере- менных в операторе READ или WRITE). 4. В каком порядке должны быть расположены значения в записи (перфокарте) или будут расположены при выводе (это определяется по- НО
рядком перечисления переменных в списке соответствующих опера- торов READ или WRITE). 5. Какому редактированию будут подвержены данные при передаче (эту информацию определяет спецификация формата). Оператор READ в ФОРТРАН/EC с параметрами ERR и END Необязательные параметры ERR и END могут использоваться только в операторе READ, причем END— только при чтении файлов последовательного доступа. Эти параметры предназначены для обра- ботки особых ситуаций, которые могут возникнуть при вводе. Параметр ERR задает обработку ситуации, возникающей при невозможности завершения операции ввода. Если параметр ERR не указан в операто- ре, то такая ситуация приведет к аварийному завершению программы. Параметр END задает обработку признака конца файла. Форматы параметров задаются в виде ERR =/ END = /, где I — метка оператора, содержащегося в том же программном модуле, в котором задан соответствующий оператор READ. При возникновении какой-либо из предусмотренных особых ситуа- ций управление передается по заданной метке, начиная с которой выполнение программы продолжается (в отличие от аварийного завер- шения). В отличие от других параметров оператора READ, необязательные параметры ERR и END являются ключевыми: их назначение определя- ется по ключевому слову (ERR или END), а не позицией параметра в их списке. Поэтому, например, можно записать оператор как в виде READ (1,1, END = 5, ERR = 6) так и в виде READ (1,1, ERR = 6, END = 5) Пример. Использование оператора READ с режимом END. Во входном потоке перфокарт содержится запись с признаком конца файла. Следующая программа вычисляет количество записей в файле 1, если известно, что их не более 1000. DO 1# I = 1, 1&&& 1& READ (1, Зе, END = 2&) KARD 2& WRITE (3, Зв) I Зв FORMAT (15) STOP END 111
Операторы ввода-вывода, обеспечивающие совместимость ФОРТРАН/ЕС с Базисным ФОРТРАНОМ (операторы READ, PRINT, PUNCH) В отличие от операторов READ и WRITE ФОРТРАНа, в которых номера устройств указываются с помощью константы целого типа или переменной, каждый из операторов ввода-вывода Базисного ФОРТРАНа связан с конкретным устройством: Оператор READ PUNCH PRINT Символическое имя устройства SYSIN SYSPCH SYSLST Назначение ввод с перфокарт вывод на перфокарты печать Общая форма операторов: READ /, s PUNCH A s PRINT A s где f — метка объявления FORMAT или имя массива, содержащего спецификации формата; s — список ввода-вывода. Для приведенных операторов не допускается бесформатный обмен, т. е. параметр f не может быть опущен. Ниже приведены примеры операторов Базисного ФОРТРАНа и их эквиваленты в ФОРТРАНе. Базисный ФОРТРАН ФОРТРАН READ 25, А, В, С PUNCH 20, ARR PRINT 7, X, R, D (6) PRINT 100 READ (1,15) А, В, С WRITE (2,2Я) ARR WRITE (3,7) X, R, D (6) WRITE (3, ItfBj Пример. В каком из вариантов языка ФОРТРАН определены операторы и что они обозначают: a) READ 1, А; б) READ (I) А; в) READ (1,1) А. Все операторы являются операторами ввода объекта А. Первый из них является оператором ввода по формату (объявление формата с мет- кой 1) и определен в Базисном ФОРТРАНе. Два других оператора определены в ФОРТАНе: б) — оператор бесформатного ввода, 1 — номер устройства; в) — оператор ввода по формату, первая из указан- ных в нем единиц обозначает номер устройства, вторая — метка объявления формата. 112
Порция 42 Объявление FORMAT Для выполнения форматных операторов ввода и вывода необходима информация о том, в каком формате отперфорированы или должны быть выведены, в частности отпечатаны, данные. Сколько колонок на перфо- карте занимает каждая вводимая величина? Сколько знаков займет каждая выводимая величина при выводе на перфокарты или при пе- чати? Каков тип вводимых или выводимых данных (целый, веществен- ный, комплексный, логический или текстовый)? Эти сведения о внешнем представлении данных содержатся в объяв- лениях FORMAT. Объявления FORMAT используются при выполне- нии тех операторов READ и WRITE, в скобках которых после запятой стоят их метки. Порядок использования объявления FORMAT следую- щий. Пусть, например, операторы READ и WRITE имеют вид: READ(1, 3)А, В, С WRITE (3, 5) А, В, С Первые константы в скобках являются символическими номерами файлов, а вторые— 3 в операторе READ и 5 в операторе WRITE — метками соответствующих объявлений FORMAT. В объявлениях FORMAT указываются форматы полей для каждого элемента списка оператора ввода или вывода, ссылающегося на это объявление. Ниже приведены примеры записи операторов READ и WRITE и связанных с ними объявлений FORMAT: READ (1, 3) А, К, С 3 FORMAT (F Ш. 3, 15, F6. -0) WRITE (3, 5) А, В, С 5 FORMAT (Е20. 8, Е 29. 8, Е 29. 8) В приведенных примерах форматов буквы I, F и Е определяют тип формата; при этом буква I используется для описания форматов це- лого типа, а буквы F и Е для вещественного в форме с фиксированной и плавающей запятой соответственно. Целое, стоящее после буквы I, обозначает общее число позиций в поле, предназначенном для разме- щения значения данного, включая позицию для знака. Целое, стоящее между буквами F и Е и точкой в форматах F и Е, как и в формате I, обозначает общее число позиций, отводимое для размещения числа, включая его знак, десятичную точку, символ Е, знак порядка и две цифры порядка, а целое, стоящее после точки, обозначает число пози- ций, отводимых для дробной части числа. Правила записи объявления FORMAT 1. Следующие за ключевым словом FORMAT форматы полей заклю- чаются в круглые скобки и отделяются друг от друга косой чертой или запятыми. 113
Пример 25 FORMAT (Fie. &, I5/E 20. 8) Здесь в объявлении FORMAT указано три формата полей. 2. Черта употребляется для указания перехода на новую запись: новую перфокарту (при вводе) или новую строку печати (при выводе). Пропуск п перфокарт при вводе или п строк при выводе на печать достигается простановкой (п + 1) символов «/» в соответствующих позициях в списке объявления FORMAT. Пример READ (1, 17) X, Y, L 17 FORMAT (R 10. 6/F 10. 6, 15) При выполнении данного оператора READ согласно приведенному объявлению FORMAT значение переменной X будет считано с 1-й перфокарты, а значения переменных Y и L — со 2-ой перфокарты (мы предполагаем, что при этом все используемые в примерах идентифика- торы являются именами простых переменных, а не массивов). Пример READ (1, 5) А, В, С, D, Е 5 FORMAT (F 12.3, F 12.3///F 10.0, F 8.0, F 10.2) При вводе информации с перфокарт значения переменных А и В будут считаны с 1-й перфокарты, 2-я и 3-я перфокарты будут пропущены и переменным С, D и Е будут присвоены значения, отперфорированные на 4-й перфокарте. Пример WRITE (3, 4) I, К, L 4 FORMAT (I 10/1 10/18) В этом примере каждое из значений переменных I, К и L будет на- печатано на новой строке. 3. Перед форматом поля в объявлении FORMAT может быть по- ставлена целая положительная константа, называемая коэффициентом повторения. Формат такого вида означает последовательность одина- ковых (указанных в нем) форматов, число которых равно коэффициенту повторения. В примере READ (1, 3) А, В, С 3 FORMAT (F 10. 3, F 10. 3, F 6. 0) объявление FORMAT можно записать так: 3 FORMAT (2F 10.3, F 6.0) 4. Объявления FORMAT можно помещать в любом месте того про- граммного модуля, в котором встречаются ссылающиеся на них опе- раторы ввода-вывода. 5. Метка объявления FORMAT может быть использована только в операторах ввода-вывода READ или WRITE. Одно и то же объяв- ление FORMAT может быть использовано несколькими операторами ввода-вывода. 114
Пример READ (1, 5) К, L, М, N 5 FORMAT (2 I I 15, 12 a) WRITE (3, 5) KAPPA, Li, L2, K2 В этом примере одно объявление FORMAT используется для чтения с перфокарт значений переменных К, L, М и N и для вывода значений переменных КАРРА, LI, L2, К2. 6. Форматы полей в объявлении FORMAT при выполнении опе- раторов ввода-вывода просматриваются слева направо и ставятся в соответствие переменным из списка операторов ввода-вывода. Пример WRITE (3, 3) А, К, С 3 FORMAT (Е 2-0. 8, 15, F 10.-&) В этом примере переменной А ставится в соответствие формат Е2-&.8, т. е. значение переменной А будет напечатано в формате Е2-&.8, переменной К — в формате 15, переменной С — в формате F 1&.&. 7. Если спецификации полей в объявлении FORMAT исчерпаны, а список переменных в операторе ввода-вывода еще не исчерпан, то автоматически происходит переход к новой записи (новой перфокарте или новой строке печати) и начинается повторное применение всех форматов, указанных в объявлении FORMAT, слева направо, начиная, при отсутствии внутренних скобок, с первого. Этот процесс будет про- должаться до тех пор, пока список переменных в операторе ввода-вы- вода не будет исчерпан. Пример READ (1, 1-0) А, В, L, С, D, М, Е, F, К, G, Н, N 10 FORMAT (F 10.0, F 15.3, I 10) При выполнении оператора READ переменной А будет присвоено первое значение, отперфорированное на первой перфокарте с данными в формате F 10.0, переменной В — второе значение, отперфорированное на первой перфокарте в формате F15.3, и переменной L — в формате ПО на той же первой перфокарте. Затем осуществляется переход на новую перфокарту и ввод продолжается так: переменной С присваива- ется первое значение, отперфорированное на второй перфокарте в в формате F10.0, переменной D — второе значение второй перфокарты, отперфорированное в формате F15.3, и т. д. Если в объявлении FORMAT окажется больше форматов, чем пе- ременных в списке оператора ввода-вывода, то часть форматов в конце остается неиспользованной. Пример READ (1, 11) А, В И FORMAT (F 10.-0, F15.3, 17) В этом примере используются только форматы F10.0 и F15.3 для переменных А и В соответственно. 115
Поскольку одно и то же объявление FORMAT может быть сопостав- лено нескольким операторам ввода-вывода, неиспользуемые одним та- ким оператором форматы могут быть использованы другими. 8. Для некоторых носителей размер записи фиксирован. В таких случаях суммарный размер полей форматов тех переменных, значения которых будут размещены в одной записи ввода-вывода, должны быть не больше размеров этой записи (т. е. не более 80 колонок на перфокарте при вводе; не более длины одной строки на АЦПУ при выводе). Напри- мер, следующая запись будет ошибочной: READ (1, 22) А, В, С, D, Е 22 FORMAT (5F 18.3) так как число колонок 5 • 18 = 90 превышает 80. 9. При написании объявления FORMAT на бланке в записи форма- тов полей и между ними, как и между литерами, из которых составлены другие предложения языка ФОРТРАН, можно оставлять пробелы для удобства чтения. Исключение составляют формат Н и текстовые константы, где пробелы воспринимаются как значащие литеры. 10. Литера 7" указывает на переход к очередной записи и, например, позволяет с помощью одного объявления FORMAT прочи- тать одну, первую карту, по одному формату и целую группу после- дующих — по другому. В этом случае второй формат должен быть взят в дополнительные скобки. Например, с помощью оператора: READ (1, 52) КАР, А, В, С, D, Е, F, Н, S, Т, U, V, W, X, Y, Z 52 FORMAT (I5/(4F15.3)) будет прочитано с первой карты одно число, занимающее пять колонок, а со второй, третьей, четвертой и т. д. — по четыре числа, занимающих по 15 колонок. Первый формат используется для одной карты, второй для всех остальных, до исчерпания списка всех читаемых оператором READ данных. Еще один пример: READ (1,3) Al, Bl, LONG, Cl, DI, Fl, Gl, Hl, SI, Tl, Ul, XI, Y1 3 FORMAT (2F6.a/I Ш/(2Е2е.8)) При выполнении этих операторов значения переменных Al, В1 будут прочитаны с первой карты по формату Еб.#, значение LONG со второй карты по формату I Ш и, наконец, значения остальных переменных будут прочитаны с третьей, четвертой и т. д. карт по два значения в фор- мате Е2£1'.8 с каждой карты. 11. Чтобы повторить не один формат, а целую группу, последняя заключается в скобки; перед скобками, если это нобходимо, может быть задан коэффициент повторения. Например, предложения WRITE (3, 5) К, LI, RS, RT, RU, RSI, RT1, RU1 5 FORMAT (214, 2 (F9.3, 2F1-&. #)) обеспечат печать переменных из списка оператора WRITE по следую- щим форматам: 116
Идентифи? Формат поля катор к 14 LI 14 RS F9.3 RT F10.0 RU Fie.-e RS1 F9.3 RT1 F10.-0- RU1 Fie.-a Если бы список оператора WRITE содержал еще три элемента, на- пример RS2, RT2, RU2: WRITE(3, 5) К, L I, RS, RT, RU, RSI, RT1, RU1, RS2, RT2, RU2 то повторение формата для вывода этих трех переменных RS2, RT2, RU2 начиналось бы с самой правой открывающей скобки, т. е. зна- чения переменных RS2, RT2, RU2 были бы выведены по форматам: Индгнтифи- Формат поля 'катор RS2 F9.3 RT2 РШ.£ RU2 F1M 12. В объявлениях FORMAT допускается еще один уровень скобок, используемый для ввода-вывода данных. Это позволяет задавать повторение блоков форматов. Общее правило последовательности ис- пользования форматов поля можно сформулировать так: сначала про- сматриваются все форматы слева направо до конца списка, затем, если список переменных в соответствующем операторе ввода-вывода не исчерпан, начинается повторение форматов с самой правой открываю- щей скобки, не считая скобок самого внутреннего уровня, если число уровней равно трем. Рассмотрим пример: 1 2 3 32 2 3 ЗЛ 17 FORMAT(I4/2(4F7.1,2(13, F10.3)), 3(213,2(F9.£,2F10.3)j) t Уровни скобок обозначены цифрами 1, 2, 3. В случае необходимости форматы повторяются с самой правой открывающей скобки уровня 2 (в записи эта скобка отмечена стрелкой). Задание. 1. Какую информацию несет объявление FORMAT? 2. Какие символы используются в качестве резделителей форматов полей в объявлении FORMAT? 3. Запишите в сокращенной форме объявление 3 FORMAT (16, 16, 16, F Ш.2, F Ш.2, F Ш.2, F Ш.2) 4. Найдите ошибки в записи следующих предложений: a) READ (1, 5) X, Y, К 5 FORMAT 2ЕШ.З, 16 117
6) READ (1, 7) К, LI, L2, SI, S2, T 7 FORMAT (3110, 3F 18.6) 5. Запишите предложения READ и FORMAT, необходимые для ввода значений переменных R, S, Т, I, J, К, L, М, N, IR, KR, LR, MR, NR Полагаем, что значения переменных R, S и Т отперфорированы на пер- вой перфокарте с первой позиции в формате F 15.3, а значения осталь- ных переменных х— по 3 на каждой перфокарте в формате 16. 6. Сколько уровней скобок допустимо в записи объявления FORMAT? 7. Пусть А, В, С, D, Е — идентификаторы простых переменных. Как должны быть отперфорированы данные для их ввода а) операто- ром READ (1,5) А, В, С, D, Е по объявлению 5 FORMAT (5F1-&.3) б) оператором READ (1,6) А, В, С, D, Е по объявлению 6 FORMAT (Fltf.3)? 8. Как будут напечатаны значения простых переменных А, В, С, D, Е при выполнении следующих пар предложений: a) WRITE (3, 5) А, В, С, D, Е 5 FORMAT (5F15.3) б) WRITE (3, 6) А, В, С, D, Е 6 FORMAT (F15.3) Порция 43 Представление данных на внешних носителях При подготовке данных на внешних носителях для ввода в ЭВМ необходимо соблюдать определенные правила, учитывающие свойства носителей. Так, весьма распространенным видом внешней памяти явля- ются перфокарты, удобства использования которых определяются лег- костью внесения исправлений в данные путем вставки, исключения или замены отдельных перфокарт. Учитывая это, рассмотрим правила под- готовки данных для ввода с перфокарт. Для кодирования информации на перфокартах выделены 80 пози- ций (колонок), в каждой из которых может быть отперфорирован один символ, в том числе любая литера языка ФОРТРАН. Для более плот- ного размещения информации на перфокартах на каждой из них может быть размещено одно или несколько данных в зависимости от размеров их значений, однако так, чтобы в последовательности данных никакое 118
из них не располагалось на двух перфокартах (т. е. без переносов с од- ной перфокарты на другую). В связи с этим некоторые позиции на пер- фокартах могут оставаться неиспользованными. Последовательности позиций на перфокартах, в которых кодиру- ются те или иные данные, называются полями данных. Распространенным видом внешнего носителя, используемым при выводе, является широкая бумажная лента АЦПУ, имеющая также фиксированное число позиций в строке (обычно 120 позиций). При подготовке данных для ввода могут быть использованы обычные или несколько модифицированные способы записи констант. Так, вещественные числа 3.703 • 10~3 и —2.62 • 102 могут быть представле- ны, соответственно, одной из следующих последовательностей: 3.70 ЗЕ — 3 + 3.7ш ЗЕ — 03 3.7Ш3 —3 3.7^ 3D —3 — 2.62 + 2 — 2.62D+02 — 2.62Е + 2 — 2.62Е02 Как видно из примера, десятичный порядок числа может быть задан с помощью одного из символов Е или D или путем указания не- посредственно за мантиссой показателя со знаком. Следует иметь в виду, что для удобства выполнения операций в па- мяти машины для данных выделяются поля памяти стандартных раз- меров (размер полей определяется для каждого типа данных). Однако нет необходимости в том, чтобы данные на внешних носителях имели также стандартные размеры. Это касается, например, вещественных и комплексных данных, которые могут быть заданы как меньшим чис- лом значащих цифр (что обычно имеет место, если этими данными явля- ются результаты некоторых наблюдений), так и большим (например, когда данные были получены и выведены на перфокарты в результате вычислений с повышенной точностью). Для учета особенностей внешнего представления данных исполь- зуются так называемые форматы данных. Использование форматов, кроме того, представляет возможность сокращать размеры необходи- мых полей, например, определять позицию десятичной точки без, яв- ного ее указания во вводимом значении. Последнее позволяет одну и ту же последовательность литер, представленную на внешнем носи- теле, интерпретировать по-разному, в зависимости от выбираемого фор- мата. Так, применение формата F6.2 (6 — общий размер поля, 2 — число символов после десятичной точки) к строке литер — 2405 дает значение—24.05, а формата F6.4 — значение—.2405. Порция 44 Описатели полей формата Форматы данных задаются посредством гак называемых описате- лей полей формата, которых в стандарте ФОРТРАНа имеется девять видов. Ниже приведены описатели полей форматов, типы данных, для
ввода-вывода которых используется указанный формат, и примеры описателей. Общий вид описателя поля формата Тип данных Пример описателя rlw целый 415 srFw.d вещее i венный — 2P3F8.2 srEw.d вещественный 2РЗЕ17.2 srGw.d вещественный 3P3G8.2 rGw * целый, логический 4G8 srDw.d вещественный, повышенной 3P3D12.5 точности rLw логический 4L4 rAw текстовый 4А4 wX строка пробелов 5Х . hw текстовый 5НЛЕВЫЙ • • • hn текстовый 'ПРАВЫЙ' r7.w * шестнадцатеричный 4Z1A5B Tn * задание позиции в записи Тб Звездочкой отмечены описатели полей формата, введенные дополни- тельно в ФОРТРАН/ЕС. Здесь буквы I, F, Е, D, G, L, А, Н, X, Z, Т (литеры ФОРТРАНа) используются в качестве кодов преобразования и редактирования при вводе-выводе записей (кодов формата). Соответственно, в зависимости от используемого кода формата описатели полей будем называть фор- матом F, форматом Е и т. д. Литера ' (языка ФОРТРАН/EC) использу- ется в качестве ограничителя. Параметры форматов w, d, г, s Параметр w — целое без знака (ш > Я); обозначает размер дан- ного — число занимаемых им позиций на внешнем носителе. Этот пара- метр является обязательным во всех тех форматах, где он указан. Параметр d — целое без знака (d Q\d < используется только с числовыми форматами F, Е, D, G для данных вещественного типа и указывает количество цифр в дробной части числа во внешнем пред- ставлении (за исключением формата G). Задание параметра d является обязательным для всех указанных форматов даже в том случае, когда d = Q. Параметр d при вводе данных используется лишь в том случае, когда в представлении данного десятичная точка явно не указана (при явном задании десятичной точки параметр d игнорируется). Параметр s также определен лишь для форматов F, Е, G, D, однако является необязательным. Этот параметр является предписателем мас- 120
штабного множителя и имеет вид иР или —пР где п — целое без знака — масштабный множитель, Р (литера ФОРТ- РАНа) — символ масштабного множителя. Действие масштабного множителя будет рассмотрено при описании соответствующих форма- тов. Отметим только, что масштабный множитель применяется ко всем следующим в объявлении формата описателям полей F, Е, G, D до тех пор, пока не встретится другой предписатель. Параметр г — целое без знака — является необязательным. Этот параметр задает число повторений следующего за ним описателя поля. Так, последовательность форматов 14, 14, 14 равносильна заданию, одного формата 314. Запись 113 равносильна записи 13. Описатели по- лей, в которых отсутствуют параметры s и г, называются основными. Порция 45 Управление печатью При составлении формата поля данных, выводимых на печать,, необходимо иметь в виду, что при выводе вначале формируется строка вывода (запись), первая литера которой не выводится, а используется лишь для управления печатью. Управление печатью состоит в задании вертикального смещения печатаемой строки. В языке ФОРТРАН выде- лены четыре литеры (табл. 21), за каждой из которых закреплена опре- деленная функция управления печатью; функция всех остальных ли- тер как символов управления одинакова. Таблица 21 Управление печатью Первая литера Действие перед печатью строки Пробел 0 1 + Любая другая литера Пропуск одной строки Пропуск двух строк Переход на новую страницу Смещение не выполняется (строка вывода накла- дывается на предыдущую) Переход к следующей строке Например, формат Ш FORMAT (5Н1ЦИКЛ) используемый для вывода текстовых данных, определяет следующую строку вывода: 1ЦИКЛ Первая литера этой строки указывает, что слово ЦИКЛ будет на- печатано с новой страницы; по формату 11 FORMAT (5Н—ЦИКЛ) это слово будет напечатано на следующей строке вывода. 121
Чтобы предотвратить потерю значащих литер при выводе или слу- чайное, не предусмотренное программистом, использование в первой позиции таких управляющих символов, как &, 1 или +, ведущее к ис- кажению результата, можно, например, использовать формат X (он будет описан далее), задающий при выводе печать пробелов. Напри- мер, при выводе массива по формату 12 FORMAT (13) старший (тре- тий) разряд в десятичном представлении чисел выводиться не будет и, кроме того, все числа, содержащие 1 в этом старшем разряде, будут напечатаны с новой страницы. Если же использовать для вывода этого массива формат 12 FORMAT (5Х, 13), то каждое число будет напеча- тано без искажения в очередной строке, причем, каждому числу будет предшествовать 4 пробела, указанные в формате 5Х (первый пробел будет использован для управления печатью). Тот же результат может быть достигнут путем использования в объявлении FORMAT первой спецификации формата или задания числового формата с числом позиций, заведомо большим требуемого для представления выводимого данного. Например, если известно, что значение пере- менной X может содержать не более трех цифр в целой- части и не более трех цифр в дробной, для вывода можно воспользоваться любой парой предложений: a) WRITE (3, 10) X W FORMAT (2Н^^, F8.3) б) WRITE (3, Ш) X Ш FORMAT (F Ш.З) в) WRITE (3, Ш) X 1© FORMAT (2Х, F8.3) Порция 46 Форматы ввода-вывода числовой информации Для спецификации при вводе-выводе числовых данных использу- ются форматы I, F, Е, G и D. Редактирование информации в соответ- ствии с этими форматами выполняется согласно следующим правилам: 1. Для всех числовых преобразований при вводе пробелы восприни- маются как нули. Знак числа плюс во внешнем представлении может быть опущен. Поле, состоящее только из пробелов, воспринимается как нуль. 2. Для форматов F, Е, G, D при вводе явная десятичная точка, стоя- щая в поле ввода, отменяет неявное определение позиции точки, зада- ваемое параметром d. 3. При всех способах преобразования чисел при выводе результат выравнивается по позиции десятичной точки; дробная часть числа при этом округляется или дополняется справа нулями; ведущие нули в целой части заполняются пробелами; если определенное форматом поле для целой части недостаточно, старшие разряды числа усекаются, 122
что приводит к искажению результата (поэтому нужно предусматривать достаточные размеры полей для вывода). 4. При выводе перед отрицательным числом всегда проставляется знак минус; перед положительным числом знак плюс может быть опу- щен (что определяется реализацией). Знак числа проставляется непо- средственно перед старшей значащей цифрой или десятичной точкой. 5. При подсчете числа позиций в формате поля для вывода необхо- димо предусматривать позиции для печати или перфорации знака числа, десятичной точки, а в форматах Е и D, кроме того,— для символа по- рядка (Е и D), его знака и двух цифр. 6. В ФОРТРАН/ЕС положительные числа при выводе представля- ются без знака. Если размер поля при выводе недостаточен для пред- ставления целой части числа, все поле заполняется литерами *. Формат I Iw Формат I используется для ввода и вывода значений переменных целого типа. Этот формат указывает, что во внешнем поле размера w размещена для ввода или будет размещена при выводе последова- тельность литер, представляющая целое со знаком или без знака. Пример 1. Пусть переменные целого типа имеют значения: I = 35; J = 107; К = 10250; L =—200050. Для ввода этих конкретных значений можно воспользоваться опера- тором READ (5, Ш) I, J, К, L ссылающимся на объявление Ш FORMAT (12, 13, 15, 17) В таком случае значения переменных на перфокарте должны быть от- перфорированы в виде 71и25мг2иии5и - Для тех же данных можно осуществить ввод по объявлению FORMAT с одним описателем формата I: Ш FORMAT (417) При этом значения переменных I, J, К, L должны быть отперфорирова- ны в виде: миииы35|ммим1м7|ми.1ы25мг2ыыи5м —— I----3—-I—К- 4—1— Пример 2. Для указанных в примере 1 значений переменных К J,‘K, L в результате выполнения оператора вывода WRITE (6, 15) I, J, К, L 123
15 FORMAT (417) будет выведена строка: U,uuuo35 uuuu,l/l7u,ull(25/-2W50 — I--------—3—-------К— —L— Пример 3. Представление данных при выводе по формату 1 в ФОРТРАН/ЕС: Значение, Формат Внешнее подлежащее выводу представление + 1234 15 1234 — 1234 15 — 1234 — 12345 15 ***** + 12345 15 12345 Описатели полей формата F, Е, G, D Здесь будут рассмотрены описатели полей Fw.d, Ew.d, Gw.d, Dw.d без учета предписателя масштабного множителя, рассмотрению ко- торого посвящена порция 48. Описатели числовых полей с кодами F, Е, G и D указывают, что, как и в случае формата I, для внешнего представления значения пере- менной вещественного типа или повышенной точности отводится поле размера w. Различие в использовании форматов F, Е, G и D сказыва- ется только при выводе; их действие при вводе одинаково. Однако, так как одно и то же объявление FORMAT, в котором задаются описа- тели полей формата, может быть использовано и для ввода, и для выво- да, иногда оказывается удобным тот или иной из указанных кодов при задании форматов для ввода. Ввод. Основная форма внешнего поля для ввода состоит из после- довательности цифр (нуль может быть изображен пробелом), которая может (не обязательно) содержать десятичную точку (отделяющую дробную часть числа от целой) и которой может (не обязательно) пред- шествовать знак + или —. За основной формой может (не обязательно) следовать экспонента в одной из следующих форм: целое число со знаком; Е, за которым следует целое (со знаком или без него); D, за которым следует целое (со знаком или без него). Экспоненты, отличающиеся лишь наличием литеры Е или D, эквивалентны. Так, приведенные изображения 250 45D — 5 25045Е — 5 25045 — 5 представляют собой одно и то же число, которое также может быть пред- ставлено в других формах, например, 2.5^45 — -01 .24^45 25^45 — 05 25^45Е — 5 25.045-02 25^ 450 — 5 124
Значения вещественных величин при вводе должны принадлежать интервалу допустимых значений констант вещественного типа. Пример. Действие описателей полей форматов F12.5, Е12.5, D12.5, G12.5 при вводе: Внешнее представление числового значения Вводимое значение Определение позиции десятичной точки 1 2 | 3 4 | 5 | 6 | 7 [ 8 9 10 11 | 12 .2 5 0 4 5 lj 0.25045 явное — 2 5 lj • 4 5 —250.45 явное — 2 5 i—i 4 5l_jl_jl_j u и —25045.0 параметром d 25l_j45l-JljE — 2 .25045 2 5i—i4 5i—ilj — 2 .25045 » 1 .1 » 1 1.0 явное 1 10000.0 параметром d 2 5 i—i 4 5 i—i D — 2 .025045 » Вывод по формату F. При выводе по формату F внешнее поле запол- няется пробелами, если это необходимо, за которыми проставляется знак минус для отрицательного и, возможно (не обязательно), плюс для положительного значения и последовательность цифр, содержа- щая десятичную точку и представляющая выводимое значение (быть может, измененное установленным масштабным множителем, см. порц. 48), округленное до d десятичных цифр после запятой. Пример. Действие описателя поля формата F7.3 при выводе в ФОРТРАН/ЕС: Значение, подлежащее выводу Внеш 1 2 нее г 3 |редс 4 тавле 5 :ние 6 7 Примечание 2.702881 । । । । 2 7 0 3 Округление 1358.8 * ♦ * * * * * Усечение целой части —233.135 * * * * ♦ * * » — 12.12023 — 1 2 1 2 0 Округление 5 • 10“5 1 । । । । । • 0 0 0 Округление 0 | | 1 1 । । 0 0 0 -5.0005 1—1 — 5 • 0 0 1 Округление Вывод по формату Е и D. Преобразования Ew.d и Dw.d применяются соответственно при выводе данных типа вещественного и повышенной точности. В ФОРТРАН/ЕС формат Е используется для данных типа REAL * 4, а формат D — для типа REAL*8 и DOUBLE PRECISION. Преобразованием Е удобно пользоваться в тех случаях, когда порядок выводимой величины заранее не известен. Значения величин 125
выводятся по коду формата Е и D с заранее заданным количеством зна- чащих цифр. Стандартная форма внешнего поля вывода при отсутствии масштаб- ного множителя имеет вид: g. ... xdE ± ntn2 g . %! ... xdD ± n1n2 Здесь | — отсутствие литеры либо знак минус в этой позиции; ... ... xd — старшие d десятичных значащих цифр округленного выводи- мого значения данного; пхии2— десятичные цифры. Размер поля w в описателях полей Ew.d и Dw.d, используемых при выводе, должен включать: одну позицию для знака числа d позиций для десятичных цифр числа одну позицию для десятичной точки одну позицию для буквы Е или D одну позицию для знака показателя степени две позиции для показателя степени, т. е. должно быть ш > d + 6 Пример. Действие описателя поля формата Е12.5 при выводе: Значение, подле- жащее выводу Внешнее представление Примечание 1 2 3 4 5 6 7 8 9 101 1" 12 —2.718281 — 2 7 1 8 3 Е + 0 1 Округление 1234.567 1 2 3 4 6 Е + 0 4 > —234.25 — 2 3 4 2 5 Е + 0 3 —0.25 — 2 5 0 0 0 Е + 0 0 0.5 5 0 0 0 0 Е + 0 0 —0.000125 — 1 2 5 0 0 Е 0 3 —22.5 • 106 — 2 2 5 0 0 Е + 0 7 123456.7 1 2 3 4 6 Е + 0 6 Округление Задание, 1, Заполните третью колонку таблицы. Действие описателей форматов полей при вводе № Внешнее представление данного Формат Значение, передаваемое во внутреннюю память 1 Ш437.83 F 8.3 2 —ljljlj43783 F 9.3 3 —43783 F 6.1 4 1.73Е + 03 F 8.1 5 1.73Е + 03 F 8.0 6 173Е + 3 F 8.0 7 173l_jE + 2 Е8.2 8 1735Е — 04 Е8.2 9 LJ1755 —04 Е8.2 10 LJL.JLJLJ1735 Е8.2 11 1234567891011D —02 D 17.6 126
Порция 47 Вывод по формату G При выводе по формату G внешнее представление числа зависит от величины его порядка. При выводе на печать вещественного числа А = В • 10р, где 0.1 В 1.0, формат G эквивалентен либо формату Ew.d, либо формату Fw.d в зависимости от величины порядка р; в последнем случае значение переменной выводится с постоянным числом значащих цифр d. В табл. 22 показана зависимость фактического формата от величины порядка числа при выводе по формату Gw.d. Из этой таблицы видно, что формат Gw.d в зависимости от величины р интерпретируется так: ' Ew.d Gw.d = \Fs.d — р, 4Х Ew.d при р < 0; при O^p^d; при р > d. s = w — 4; В первом и третьем случаях, когда фактически используется формат Е, для ширины поля w необходимо выполнять требова- ние: оу > d + 6. При этом выво- дится d значащих цифр после десятичной точки и порядок. Например, значение переменной А, равное—0.12345 • 10“2, при выдаче на печать в формате Gl 1.4 будет иметь вид: 1__1“.1234Е — Во втором случае само число имеет р цифр в целой части и (d — р) цифр после десятичной точки, поэтому общее число цифр равно: - > Таблица 22 Величина порядка нормализованного числа Фактический формат — 1 0 1 2 d — 1 d d+\ Ew.d Fs.d, 4Х Fs.d — 1, 4Х Fs.d — 2, 4Х Fs.l, 4Х Fs.£, 4Х Ew.d р + (d — p) = d Пример. После работы некоторой программы необходимо вывести на печать значения переменных А, В, С, D, Е, F, G, Н в формате G11.4. Предложения WRITE и FORMAT можно записать в виде: WRITE (3, 5) А, В, С, D, Е, F, G, Н 5 FORMAT (G 11.4) Так как в объявлении FORMAT в нашем примере задан только один формат поля, то при выводе значения каждой переменной объявление FORMAT будет просматриваться повторно, причем будет автомати- чески происходить переход на следующую строку печати. Таким обра- зом, приведенные выше значения переменных отпечатаются в столбец 127
(над последним для наглядности указаны номера позиций в строке вы- вода): , Имя Значение, Внешнее представление переменной подлежащее выводу №№ колонок А — 0.12343 • 10-2 1 2 3 4 5 6 7 8 9 0 — 0 1 23456 2 1 2 3 4 E В 0.12343 • 10-1 1 t 1 1 • 1 2 3 4 E — 0 1 С 0.12343 • 10° 1 j I J • 1 2 3 4 D — 0.12343 • 101 LJ - 1 • 2 3 4 Е 0.12343 • 102 LJ LJ 1 2 • 3 4 F 0.12343 • 103 LJ L_> 1 2 3 • 4 I 1 1 1 G 0.12343 • 104 LJ LJ 1 2 3 4 • Н 0.12343 • 105 1 J I 1 • 1 2 3 4 E1 б" JB отличие от стандарта в ФОРТРАН/ЕС формат G используется для преобразования данных не только вещественного, но и целого, повышенной точности и логического типа; при этом способ преобразо- вания определяется типом элемента списка ввода-Вывода. При передаче данных целого и логического типа параметр d в фор- мате Gw.d может быть опущен, так как для таких данных этот параметр игнорируется. Примеры представления данных целого типа и повышенной точности а) при вводе и б) при выводе по формату G: а) Внешне; представление Формат 12345 - 12345 1234567D4 G7.2 G7 G10.2 Вводимое значение + 12345 — 123450 + 0.1234567- 10е б) Значение, подлежащее выводу + 12 - 1234 + 0.9874321 • 105 + 0.987431 • 102 Формат Внешнее представление G4.1 G4.1 G14.3 G11.3 12 **** Jt_1.9874321E1_l05 j I_1 (_j ।_j 9 8.71_л_11 Ввод-вывод данных комплексного типа В языке ФОРТРАН нет специального описателя для преобразова- ния данных комплексного типа. Поскольку комплексное число пред- ставляется двумя вещественными константами, для его преобразования необходимо задавать два формата: один для действительной, другой для мнимой части. Преобразование каждой части может выполняться с по мощью одного из форматов: F, Е, D или G. 128
Пример. Имеется последовательность предложений: COMPLEX V, U READ (1, 5) V, U 5 FORMAT (2Е12.3, 2F7.3) На перфокарте с данными содержится следующая информация: 123456789 0 12345678901 2 345678901234567890 73412Е1_102 222Е+04 1.111 11222 В результате переменным V и U будут присвоены следующие значе- ния: U (1.111, 11 222) V (7341.2, 222&.) Задание. Двумерный массив А состоит из 100 элементов (10 X 10). Напишите предложения READ и FORMAT для ввода его элементов с перфокарт, предполагая, что каждому элементу массива отведено поле в 10 колонок, три из которых предназначены для дробной части; элементы массива закодированы а) в порядке их размещения по столбцам; б) в порядке их размещения по строкам. Выполните это же задание для вывода. 2. Покажите, какой вид будет иметь выводимая на печать в формате G15.4 информация, если требуется следующих переменных: 1-й столбец Q = 0.287365 • 105 Р= 0.117 • 104 R = 0.25253 • 104 напечатать в два столбца значения 2-й столбец S = — 0.32 • 10-5 Т = — 0.76 • 10-s U = -0.12345- 10~4 3. Запишите предложения WRITE и FORMAT, организующие пе- чать данных, указанных в задании 2. Порция 48 Масштабный множитель Предписатель масштабного множителя определен для использо- вания с кодами преобразования F, Е, G, D и имеет вид: иР Здесь Р— символ масштабного множителя, п— константа целого типа, называемая масштабным множителем. Масштабным множителем можно изменять значения вводимых й выводимых величин, а также положение десятичной точки в данном при выводе. 5 9—2712 129
Ввод. Масштабный множитель при вводе учитывается лишь в том случае, когда во внешнем представлении данного отсутствует экспо- нента (порядок). При наличии экспоненты масштабной множитель игнорируется. Действие масштабного множителя п при вводе для всех преобразо- ваний F, Е, G, D одинаково и состоит в сдвиге десятичной точки во вводимом значении на п позиций влево, если п > 0, и вправо, если п < <Z 0. Другими словами, число, представленное на внешнем носителе без экспоненты и вводимое по одному из форматов F, Е, G, D с масштаб- ным множителем и, в процессе ввода умножается на 10“'г. Рассмотрим на примерах влияние масштабного множителя при вводе значений по описателям полей F^. d, E^.d, Dw,d. Описатель поля Внешнее представление 1 2 3 4 5 6 7 8 9 10 11 12 13 Введенное значение Действие масштаб- ного множителя 5РЕ13.5 5РЕ13.5 5PF13.5 —5PF13.5 8PF13.4 1 РЕ 13.2 ЯРЕ 13.4 —3PF13.4 —2PD13.3 —2PD13.4 —2PD13.2 2 - 7 1 828 Е ЯЯ 2-71828 2 • 7 1 828 ЕЯЯ 271828 2 1234567 123-4567 23 • 456Е— Я 4 123-456 — 1 2345- 678 9 — 1 2345 • 678— 02 — 1 2345 - 678 D —2 2.71828 2.71828-10~6 2.71828 2.718282 1.234567 12.34567 23.456-10“4 123456-10° -1234567.89 — 123.45678 — 123.45678 Игнорируется Учитывается Игнорируется У читывается » » Игнорируется У читывается » Игнорируется » вывод Формат F. Действие масштабного множителя при выводе в случае преобразования F такое же, как и при вводе: число во внешнем пред- ставлении равно числу во внутреннем представлении, умноженному на 10". Формат Е и D. Для преобразований Е и D при выводе часть числа, образующая смешанную дробь, умножается на 10л, а значение экспо- ненты умножается на 10~л, при этом значение выводимой величины не изменяется; если п 0, то после десятичной точки будет выведено — п ведущих нулей и d + п значащих цифр. При п > 0 слева от десятич- ной точки будет выведено п значащих цифр nd — п + 1 цифр справа от нее. Формат G. Для преобразования G масштабный множитель игнорирует- ся, если выводимое число находится в области, допускающей использо- вание преобразования F; если преобразование G сводится к преобразова- нию Е, масштабный множитель действует так же, как и для Е при выводе. Примеры использования масштабного множителя при выводе дан- ных вещественного типа: 130
Выводимое значение Описатель формата поля Внешнее представление 123.454 9PF8.2 L-JL-J 123.45 123.454 1PF8.2 i—i 1234.54 123.454 2PF8.2 12345.49 123.454 — 1PF8.2 i—i i—i lj 12.34 123.454 —2PF8.2 L-ii—ii—ii—i 1.23 123.454 —3PF8.4 i—iljlj.1235 123.454 9РЕ8.2 L-1.12Е+93 123.454 1РЕ8.2 1.23Е4-92 123.454 2РЕ8.3 12.35Е4-91 123.454 ЗРЕ19.4 123.45Е+99 123.454 — 1РЕ8.2 l_J.91E+94 123.454 —2РЕ12.6 l_j.991234E+9'5 123.454 —ЗРЕ12.6 i_j.999123E4-96 В одном объявлении FORMAT действие масштабного множителя, указанного в одном из описателей полей, распространяется на все последующие форматы F, Е, G, D до тех пор, пока не встретится опи- сатель поля с другим масштабным множителем. Для устранения дей- ствия предыдущего масштабного множителя можно в описателе поля использовать масштабный множитель QP. Пример 1. 15 FORMAT (2PF Ш.4, F 7.2, Е Ш.4, — 1PF8.3) В данном объявлении масштабный множитель 2Р используется не только с описателем поля F 10.4, но и с описателями F 7.2 и Е 10.4. Пример 2. Ш FORMAT (2PF Ш.4, &PF 7.2, Е Ш.4, — 1PF8.3) Масштабный множитель 2Р в этом объявлении FORMAT используется только с описателем поля F Ш.4. Порция 49 Форматы ввода-вывода логических и текстовых значений Формат L Формат L применяется для ввода-вывода логических переменных. При вводе по формату Lw на перфокарте рассматривается очередное поле шириной w колонок. Если в этом поле первым слева отличным от пробела символом будет буква Т, то соответствующей логической пере- менной присваивается значение .TRUE., если первым символом, от- личным от пробела, будет буква F, то соответствующей логической переменной присваивается значение .FALSE.. За символами Т и F в рассматриваемом поле могут следовать символы, дополняющие до полных слов TRUE и FALSE соответственно. 5* 131
Пример. Значения трех логических дятся с перфокарт: READ (1, 31) LI, L2, L3 31 FORMAT (2L5, G7) Внешнее представление Ш О Т ш u U Ш ш F о F A L SE ы переменных LI, L2, L3 вво- Значение в памяти .TRUE. .FALSE. .FALSE. При выводе по формату L в поле w левые (w — 1) позиций заполня- ются пробелами. Правым символом будет Т, если значение логической переменной равно .TRUE., и F, если значение логической переменной равно .FALSE.. Пример. В результате работы некоторой программы значения логи- ческих переменных L1 и L2 равны соответственно .TRUE, и FALSE.. Предложения: WRITE (3, 50) LI, L2 50 FORMAT (L4, G6.1) обеспечат печать литеры Т в позиции 4 и F в позиции 10, как показано ниже: №№ позиций: 1234567890 Т F Формат Н В ФОРТРАНе имеются удобные средства для ввода и вывода текс- товой информации. Это прежде всего формат Н. Этот формат часто ис- пользуется для печати заголовков таблиц или другой необходимой ин- формации. Пусть требуется напечатать заголовок «ВЫЧИСЛЕНИЕ КОРНЕЙ УРАВНЕНИЯ». Необходимые для этого предложения ФОРТРАНа можно записать в виде: WRITE (3, 5) 5 FORMAT (28Н^ВЫЧИСЛЕНИЕ^КОРНЕЙ^УРАВНЕНИЯ) Запись 28Н в предложении FORMAT при выводе означает: «Следую- щие за Н 28 литер должны быть выведены в той последовательности, в которой они расположены в данном объявлении FORMAT (включая литеры пробела)». Поэтому машина отсчитает 27 позиций, непосредственно следую- щих за Н и пробелом, и отпечатает всю содержащуюся в них последова- тельность знаков, которая может состоять из любых литер, допустимых данным транслятором. Таким образом, для вывода текстовых данных можно использовать оператор WRITE, имеющий формат: WRITE (а, с) 132
Пример. Предложения WRITE (3, Id) Id FORMAT (ЗбН^РАСЧЕТ^ПОЛЕТА^РЕАКТИВНОГО^СА- МОЛЕТА) являются предписанием для печати текста РАСЧЕТ ПОЛЕ- ТА РЕАКТИВНОГО САМОЛЕТА Заметим, что спецификации поля Н не соответствуют никакие эле- менты списков ввода-вывода: при вводе передаваемая в память запись — текстовая константа — помещается непосредственно в поле, занимаемое этой спецификацией в объявлении FORMAT; при выводе запись извлекается непосредственно из полей объяв- ления FORMAT и передается во внешнюю среду. Пример READ (1, 7) 7 FORMAT (26НАААААААААААААААААААААААААА) При выполнении указанного оператора READ произойдет замена текстовой информации внутри объявления FORMAT: 26 литер, сле- дующих за символом типа формата Н, будут заменены на 26 очередных литер, считываемых из файла с номером 1. Если в файле содержалась запись ВВОД i_j ДВУМЕРНОГО LJ МАССИВА Р то после выполнения приведенного выше оператора READ текст объяв- ления FORMAT будет заменен введенным, т. е. получится: 26Н ВВОД ш ДВУМЕРНОГО МАССИВА Р Таким образом, если в объявлении FORMAT отсутствуют какие- либо другие описатели полей, кроме Н (а также X, см. следующую порцию), то ссылающиеся на него операторы ввода-вывода не должны содержать списка переменных; вся пересылаемая информация будет состоять только из текстовых данных. Формат Н может использоваться в списке объявления FORMAT вместе с любыми другими форматами. Например, результатом выпол- нения следующего оператора WRITE. WRITE (3, 28) X 28 FORMAT (3HljX = , lPEld.3) будет выдача на АЦПУ записи Х = ^ 1.374Е+#1 если к моменту его выполнения переменная X имела значение 13,74. Формат Н может находиться в списке форматов после любых других форматов, впереди них и между ними. Длина поля, задаваемого форма- том Н, не должна превышать длину строки внешнего носителя (напри- мер, длину строки на бумажной ленте при выводе на печать). Пример. В некоторой бригаде работает 25 рабочих, каждый из которых может выполнять любой из семи видов работ. За видами работ закреплены номера 1, 2, ..., 7. Стоимости единиц всех видов работ 133
постоянны и в памяти машины для их хранения отведен массив с име- нем СТ. Данные о выполненных работах каждым из рабочих подготов- лены в виде записей на отдельных перфокартах следующим образом: первая колонка — свободна (хранит пробел), следующие колонки со 2-й по 16-ю — фамилия и инициалы рабочего. Каждые следующие 8 колонок — объем выполненной работы в виде вещественного числа, при этом две колонки отведены для дробной части числа. Последние восемь колонок на перфокарте не используются. Предполагаем, что на устройстве ввода с перфокарт первой установлена перфокарта, на которой отперфорированы стоимости единиц работ (в порядке возрас- тания их номеров)., при этом: первая колонка свободна; каждые сле- дующие шесть колонок отведены для соответствующих стоимостей, представляемых в виде вещественных чисел с двумя знаками после де- сятичной точки. Остальные колонки свободны. Затем за перфокартой, хранящей стоимости, установлено 25 перфо- карт, содержащих фамилии рабочих и сведения об их выработке. Для хранения сведений о выработке одного рабочего (поступающих при чтении из вводного файла очередной записи) в памяти определен мас- сив Р. Приведенная ниже программа вводит вначале первую запись из входного файла — сведения о сто- имости работ; поочередно (в цикле) вводит записи данных о каждом из рабочих (фамилия поступает в спецификацию формата Н в объявлении FORMAT с меткой 14, а данные о выработке — в массив Р); вычисляет сумму заработка рабочего (скалярное произведение век- торов СТ и Р) — величину S; выводит в виде записи на устройство печати два элемента — фами- лию рабочего и сумму заработка, используя при этом то же объявле- ние FORMAT (фамилия извлекается из содержащейся в нем специфи- кации типа Н). DIMENSION СТ (7), Р (7) READ (1, 2) СТ 2 FORMAT (7F6.2) 14 FORMAT (IX, 15Н^ l_j l_j, 7F8.2) DO 15 L = 1,25 READ (1,14) P s = г. DO 5 К = 1, 7 5 S = S + СТ (К) * P (K) 15 WRITE (2, 14) S STOP END В ФОРТРАН/ЕС текстовая константа может быть записана в объяв- лении FORMAT в виде последовательности литер, заключенной в апост- рофы. При такой форме представления текстовой информации из объяв- ления FORMAT выводится или записывается в него столько литер, 134
сколько их заключено между апострофами. Например, объявления 25 FORMAT (29Н^ЗНАЧЕНИЯ^ЭЛЕМЕНТОВ^МАССИВА^К) и 25 FORMAT ('^ЗНАЧЕНИЯ^ЭЛЕМЕНТОВ^МАССИВА^К') эквивалентны. Формат X Формат X используется для пропуска заданного количества коло- нок перфокарты при вводе или вставке пробелов при выводе информа- ции. Если описатель поля шХ применяется при вводе, то w обозначает общее количество колонок, которые будут пропущены в соответству- ющих позициях перфокарты; при выводе между соответствующими поля- ми при печати будет вставлено w пробелов. Примеры. 1. Для ввода информации, отперфорированной на перфокарте в ко- лонках 11—20 и 31—40 в формате F10.3, следует написать предложе- ния: READ (1, 1) X, Y 1 format (iex, Fia.3, iex, Fie.3) 2. Чтобы отпечатать заголовок в середине строки в 120 символов, мы должны записать предложения: WRITE (3, 2) 2 FORMAT (4вХ, 36Н ТАБЛИЦА^КОРНЕЙ^ КВАДРАТ *НОГО^УРАВНЕНИЯ/ * 4 45Х, 2НХ1, 2-&Х, 2НХ2) WRITE (3, 4) X, Y FORMAT (42Х, Е2#.8. 8Х, Е2&.8) Результатом выполнения этого фрагмента программы будет выдача на устройство печати следующей таблицы: ТАБЛИЦА КОРНЕЙ КВАДРАТНОГО УРАВНЕНИЯ XI Х2 Формат А Формат А, как и формат Н, используется для ввода и вывода текс- товых данных. Однако, в отличие от формата Н, для размещения вводимых тек- стовых данных по формату А в памяти должны быть выделены надлежа- щие поля, определяемые простыми переменными, переменными с ин- дексами или именамц массивов одного из допустимых в языке типов. Переменные или массивы, к которым применяется формат А, указыва- ются в списке соответствующих операторов READ или WRITE. 135
Пример. WRITE (3, 1) А, В, С 1 FORMAT (2Х, ЗА4) Если значением переменной А является строка литер ВЫВО, пере- менной В— строка Д__|ТЕ, переменной С— строка КСТА, то при выполнении записанного выше оператора WRITE будет напечатано: ВЫВОД ТЕКСТА Если w, указанное в формате Aw, равно числу литер в поле соот- ветствующей переменной списка, то эта переменная будет прочитана или выведена без изменений. Если при выводе размер поля w недостаточен для размещения всех литер соответствующей переменной, то сохраняются левые литеры строки; если размер w больше необходимого, то строка литер выравни- вается к правому краю, а слева поле дополняется пробелами. Обозначим через п (п определяется реализацией) размер (в байтах) поля переменной, указанной в списке оператора ввода-вывода и свя- занной с форматом А. Если при вводе w < п, то строка будет введена в самые левые по- зиции поля переменной; остальные позиции этого поля будут заполнены пробелами. Если при вводе w > п, то в поле переменной будут пере- сланы крайние правые п позиций (а левые w — п позиций будут уте- ряны). Как было отмечено в порции 41, в форматах операторов READ и WRITE вместо метки соответствующего объявления FORMAT может быть указано имя массива. В этом случае начальная часть информации в указанном массиве, взятая в естественном порядке, должна представ- лять собой правильную спецификацию формата, однако не содержа- щую форматов типа Н. Как и в случае объявления FORMAT, специфи- кация формата должна быть заключена в скобки. Для размещения спецификации формата в массиве может быть ис- пользован оператор READ с форматом А или объявление начальных данных DATA. Примеры. 1. Предположим, что в программном модуле имеется по- следовательность предложений: DOUBLE PRECISION А, В, С READ (1, Ш) А, В, С Ш FORMAT (ЗА8) WRITE (3, 1ё) А, В, С и на перфокарте подготовлена для ввода следующая запись ТАБЛИЦА^ЗНАЧЕНИЙ^ФУНКЦИИ Результатом выполнения приведенных выше операторов ввода- вывода будет пересылка в память и затем вывод из памяти на печать приведенной строки без изменений. 136
Если же из этой последовательности предложений удалить объяв- ление DOUBLE PRECISION, то в поле переменных А, В, С операто- ром READ будет передана следующая информация: 2. В условиях примера, иллюстрирующего применение формата Н, составим программу для решения той же задачи, используя формат А. Для хранения фамилий рабочих (текстовых 15-символьных кон- стант) введем вещественный массив FIO, содержащий 4 элемента (осталь- ные обозначения используются те же, что и в упомянутом примере). DIMENSION FIO (4), СТ (7), Р (7) READ (1, 2) СТ 2 FORMAT (IX, 7F6.2) 14 FORMAT (IX, 4А4, 7F8.2) DO 15 L = 1, 25 READ (1,14) FIO, P S= Д. DO 5 K= 1,7 5 S = S + СТ (К) * P (K) 15 WRITE (3,14) FIO, S STOP END 3. На вводе задана тройка вещественных положительных чисел — значений переменных А, В, С. Составим программу на ФОРТРАН/ЕС, выдающую на печать характеристику этой тройки — одно из четырех слов: НЕЛЬЗЯ, ОСТРОУГОЛЬНЫЙ, ТУПОУГОЛЬНЫЙ, ПРЯМО- УГОЛЬНЫЙ в зависимости от того, можно ли построить треугольник из отрезков с длинами А, В, С и какого он будет вида. Программа может быть представлена в виде: COMPLEX * 16 AR (4) /'НЕЛЬЗЯ', 'ТУПОУГОЛЬНЫЙ', * 'ОСТРОУГОЛЬНЫЙ', 'ПРЯМОУГОЛЬНЫЙ'/ READ (1,5) А, В, С 5 FORMAT (3F6.2) IF (A. GE. В) GOTO2B U = А “ А = В В = U 137
С АБОЛЫПЕ В 25 Al = АМАХ1 (А, С) С= AMIN1 (А, С) С- А1БОЛБШЕ В, А1 БОЛЬШЕ С I = 4 IF (A1.GE.B + С) I = 1 С U=A1*A1 —В*В—С*С IF (U.GT.1E — 6) I = 2 IF (U.LT. — IE — 6) I = 3 WRITE (3, 45) AR (I) 45 FORMAT (15X, 2A8) STOP END Обращаем Ваше внимание на то, что в этой программе два раза про- исходит упорядочение двух значений из тройки А, В, С (А и В, А и С), причем это выполняется двумя различными способами: упорядочение значений А и В выполняется посредством условного логического опе- ратора с последующим обменом значениями переменных А и В (если значением истинности выражения A.GE.B является .FALSE.). Упо- рядочение значений А и С выполняется посредством основных внешних функций АМАХ1 и AMIN1. 4. На устройстве ввода дан логический массив Y(30). Составить программу для печати строки, содержащей четверки литер i_jY пт где п, т— цифры двузначных номеров элементов массива Y (если п = 0, печатать пробел), имеющих значение .TRUE.. Решение: LOGICAL * 1 Y (35) INTEGER *2 S/' о Y7, N (35) READ (1, 2) Y 2 FORMAT (35L1) К = 5 DO5 I = 1,35 IF (.NOT.Y (I)) GO TO 5 K= K+ 1 N (К) = I 5 CONTINUE WRITE (3, 3) (S, N (I), 1 = 1, K) 3 FORMAT (35 (A2, 12)) STOP END Задание. 1. В условиях рассмотренного примера 3, предполагая, что на вводе заданы 50 троек чисел, составить программу, выдающую на 138
печать таблицу, состоящую из последовательности 50 записей, каждая из которых содержит следующие элементы: 1) номер по порядку; 2)—4) — значения данных А, В, С; 5) характеристика тройки. Табли- ца должна быть снабжена заголовком вида N А В С ХАРАКТЕРИСТИКА 2. Прямоугольная матрица С имеет 10 строк и 8 столбцов. Запишите операторы вывода ее элементов: а) по столбцам, б) по строкам, исполь- зуя в обоих случаях формат F6.3. Вывод требуется организовать таким образом, чтобы каждый столбец (строка) матрицы был размещен в одной строке вывода и между элементами было проставлено по четыре про- бела. Перед выводом значений в середине строки в 120 позиций органи- зуйте печать заголовков ВЫВОД ЭЛЕМЕНТОВ МАТРИЦЫ С ПО СТОЛБЦАМ и ВЫВОД ЭЛЕМЕНТОВ МАТРИЦЫ С ПО СТРОКАМ соответственно. 3. Как будут размещены текстовые константы в строках печати в результате выполнения фрагмента программы: COMPLEX * 16 C16/'COMPLEX * IG^DATA') WRITE (3, 1) C16 WRITE (3, 2) C16 1 FORMAT (IX, A16) 2 FORMAT (1X,2A8) Порция 50 Дополнительные форматы в ФОРТРАН/EC Формат Z Формат Z используется для ввода-вывода шестнадцатеричных данных. Этим форматом обеспечивается вывод содержимого оператив- ной памяти во внутреннем представлении данных. В одном байте со- держатся две шестнадцатеричные цифры. При вводе в формате Zw данное во внешнем представлении занима- ет w позиций и представляется в виде шестнадцатеричных цифр. Пробел заменяется двумя шестнадцатеричными нулями. Данное при вводе выравнивается вправо; если w > 2п (п — размер поля переменной в байтах), избыточные цифры усекаются; если w < 2и, данное слева дополняется шестнадцатеричными нулями. При вводе нечетного числа цифр слева добавляются шестнадцатеричные нули для получения целого числа байтов. 139
При выводе, если ш < 2п, то избыточные левые цифры не выво- дятся; если w > 2л, то слева это данное дополняется пробелами. При- меры представления шестнадцатеричных данных при выводе: Внутреннее представление Длина пере- менной в байтах Формат FEDCBA98 4 Z8 56789АВС 4 Z10 123ABC4D 4 Z4 Внешнее представление FEDCBA98 56789АВС ВСЮ Пример использования формата Z: INTEGER*2J J =28 X = 28. WRITE (3,33) J, J, X, X 33 FORMAT(IX, 13, 4X, Z4, F6.1, Zl£) STOP END В результате выполнения данной программы будет напечатана строка: ^28^^^^ QQ 10^^28.9 ^^42100^ 13 4Х Z4 F6.1 гш J J X X Для наглядности под символами строки указаны форматы вывода и имена переменных (шестнадцатеричное представление целого числа 28 — 1С (16 + 12); вещественного числа 28.— 421О0‘0В'в (в.1С X X 162) (см. порцию 10). Формат Т (табуляция) Формат Т предназначен для указания позиции п в формируемой физической записи, начиная с которой выполняется пересылка под- строки данных из памяти по формату, непосредственно следующему за этим форматом Т. При выводе на печать (на системное устройство SYSLST) нужно учитывать, что первый символ — управляющий, т. е. r-й символ выходной записи всегда является (/ — 1)-м в строке печати. Формат Т может указываться перед любым описателем поля. При использовании нескольких форматов Тл в одном объявлении FORMAT их упорядочения по возрастанию не требуется. Из набора текстовых констант, заданных в спецификациях формата, используя формат Т, можно конструировать в виде записей и выда- вать на печать различные заголовки и придавать наглядную форму строкам вывода. 140
Пример 1. Пусть на вводе задана строка 01497. Рассмотрим выпол- нение следующей программы: READ (1,1) 17, 19, 10, 14, II 1 FORMAT (Т5, II, Т4, II, Tl, II, ТЗ, II, Т2, II) WRITE (3, 2) II, 19, 10, 14, II, 19, 17, 19 2 FORMAT (Т2О, 'МЕСЯЦ', Т1О, 'ЧИСЛО', ТЗО, ТОД7 * Til, 211, Т21, 211, ТЗО, 411) STOP END В результате выполнения оператора READ переменным 17, 19, 10, 14, II будут присвоены значения, взятые из строки ввода: переменной 17 будет присвоено по формату II значение, содержащееся в пятой по- зиции (согласно формату Т5) строки ввода, т. е. 7; соответственно, переменным 19, 10, 14, II будут присвоены значения 9, 0, 4, 1. При выполнении оператора WRITE будут сформированы две стро- ки вывода: начиная с 19 позиции первой строки (согласно форматам Т2О, 'МЕСЯЦ') будет размещено слово МЕСЯЦ; с девятой позиции будет размещено слово ЧИСЛО, с 29-ой — слово ГОД. Вторая строка вывода будет формироваться следующим образом: согласно паре форматов Til, 211 с десятой позиции вывода будут раз- мещены значения переменных II и 19 (без пробела между ними), т. е. число 19. Согласно следующей паре форматов с 20-ой позиции будут размещены значения переменных IO и 14, т. е. число-04, и далее с 29 позиции будет размещено число 1979. Таким образом, в результате будет напечатана табличка: ЧИСЛО МЕСЯЦ u-P-K-r-j’-u ГОД 19 1979 Пример 2. Используя спецификацию Т, можно одну и ту же физи- ческую запись прочитать повторно (точнее, поле перфокарты может считываться и пересылаться в несколько массивов). Программой LOGICAL * 1 POS (20) INTEGER DATA (5) READ (1, 2) POS, DATA 2 FORMAT (T21, 2OA1, T21, 5A4) литеры, содержащиеся в колонках 21—40, читаются как в массив POS, так и в массив DATA. Задание. 1. Выполняются ли какие-либо преобразования при вводе шестнадцатеричных данных? при выводе? 2. Какой символ является управляющим в выходной строке, за- данной форматом 10 FORMAT (Т20, 15, Т60, 15, Т1, '0') 3. Какой текст будет напечатан в результате выполнения следующей программы? (см. порцию 66). EQUIVALENCE (S, R) 141
INTEGER S (7) COMPLEX * 16 Е(2)/'ТОЛЬКО НЕ^ФОРМУЛ^', * 'ТРАНСЛЯТОРА^'/ 3 FORMAT (T2, 2A4, ТШ, А4, Tie, 2Х, Т15, А4, А2, Т32, * 2А4, Т22, 2А4, А2) PRINT 3, S (3), S (5), S (2), S STOP END Порция 51 Бланк записи исходных данных На рис. 26 изображен бланк записи исходных данных для ФОРТ- РАН-программы. Данные на бланке должны размещаться с первой позиции строки и точно в заданном формате. Напоминаем еще раз, что точку в числах, записываемых в форматах F, Е, G и D, можно не ставить. Она автоматически проставляется ма- шиной в том месте, которое указано в формате. Например, для пере- менных А, В и С, имеющих значения — 121.215, 17.213, —7.101 и ис- пользуемых в операторе READ (2,3) А, В, С 142
при наличии объявления 3 FORMAT (3F1 е.З) значения на бланке данных можно записать, как показано на рис. 27 (а, б или в). Задание. Запишите на бланке исходных данных в формате F9.3 значения переменных С, D, Е, равные соответственно 725,32; 8900,01 и 1,325. Порция 52 Вспомогательные операторы ввода-вывода В ФОРТРАНе определены три вспомогательных оператора, пред* назначенные для обслуживания последовательных файлов: оператор перемотки REWIND оператор обратного сдвига BACKSPACE оператор разметки ENDFILE Оператор REWIND Формат этого оператора следующий REWIND а Здесь а — целое без знака или идентификатор простой переменной це* лого типа, обозначающие номер файла. Оператор предписывает уста- новку указанного в нем файла в начальную позицию (т. е. в положение, в котором первая запись файла считается его очередной записью). Оператор REWIND может быть использован для повторной обработки одного и того же файла или для обработки новых файлов, установлен- ных, например, во время прерывания программы в результате выпол- нения оператора PAUSE на то же устройство ввода-вывода. Оператор BACKSPACE Оператор BACKSPACE используется для обработки записей файла в порядке, обратном их расположению в наборе. Оператор имеет формат BACKSPACE а где а—имеет тот же смысл, что и в операторе REWIND, т. е. определяет номер файла. Если файл, указанный в операторе, находится в начальной пози- ции, то выполнение этого оператора BACKSPACE не вызывает ника- ких последствий. В противном случае в результате выполнения данно- го оператора предыдущая запись указанного в нем файла становится очередной. 143
Оператор ENDFILE Оператор ENDFILE предназначен для определения конца после- довательного файла. Оператор имеет формат ENDFILE а Здесь а, как и в предыдущих операторах,— номер файла. В резуль- тате выполнения оператора ENDFILE в указанный в нем файл пере- дается специальная запись «конец файла», обозначающая границу последовательного файла. Действие оператора ввода, в результате ко- торого из файла считывается запись «конец файла», не определено. Задание. I. Перечислите вспомогательные операторы ввода-вывода. 2. Когда используются эти операторы? Порция 53 Объявление NAMELIST (ФОРТРАН/ЕС) Объявление NAMELIST (слово NAMELIST означает «список имен») предназначено для указания списков ввода-вывода, которым присва- иваются имена. Последние используются в операторах READ и WRITE вместо непосредственного задания в них списков ввода-вывода. Объявление NAMELIST имеет формат: NAMELIST/x^/aV^/ • • • IXkllk Здесь Xi — имя списка (идентификатор), lt — список (i = 1, 2, ..., k). Элементами списка в объявлении NAMELIST могут быть перемен- ные или имена массивов (но не формальные параметры). Формат операторов READ и WRITE, использующих списки NAMELIST, следующий: READ (а, х) WRITE (а, х) Здесь: а— номер набора данных (файла); х— имя списка NAMELIST. Ввод-вывод в этом случае производится в формате, соответствующем типу данных. Пример. NAMELIST/Х/ А, В, С /У/ В, А, С READ(1, X) WRITE (3,Y) По оператору READ (1, X) переменным (или элементам массива, если имена А, В или С встречаются в описателях массивов) из списка X присваиваются значения из файла 1. По оператору WRITE (3, Y) в файл 3 записываются значения переменных (или элементов массивов) из списка Y. 144
При использовании объявления NAMELIST необходимо придержи- ваться следующих правил: I. Объявление NAMELIST должно находиться в том же программ- ном модуле, что и операторы READ и WRITE, использующие данные, указанные в NAMELIST, и должно предшествовать этим операторам. 2. Имя списка NAMELIST в данном программном модуле не может быть использовано для идентификации других объектов; оно может быть указано только в объявлении NAMELIST, задающем этот список, и в операторах READ и WRITE, в которых используются данные из этого списка. 3. Имя списка NAMELIST может быть объявлено только в одном объявлении NAMELIST и только один раз. 4. В одном объявлении NAMELIST может быть задано несколько списков NAMELIST. 5. Имя переменной или массива может быть задано в нескольких списках одного или нескольких объявлений NAMELIST в одном про- граммном модуле. 6. Для файла, который читается или записывается с использованием объявления NAMELIST, оператор BACKSPACE не определен. Задание. I. Отличаются ли имена списков в NAMELIST от других имен, используемых в ФОРТРАНе? 2. Может ли использоваться имя списка, приведенное в NAMELIST, где-либо, кроме операторов ввода-вывода? 3. Может ли одно и то же имя списка использоваться в разных объявлениях NAMELIST? 4. Могут ли имена переменных (массивов) входить в разные име- нованные списки? 5. Может ли имя списка совпадать с именем, входящим в список? 6. Может ли список в NAMELIST содержать имена формальных параметров? 7. Должен ли NAMELIST предшествовать соответствующему опе- ратору ввода-вывода? Влияет ли на трансляцию операторов ввода- вывода наличие объявления NAMELIST? 8. Применим ли оператор BACKSPACE к файлу, содержащему список имен? 9. Может ли список объявления NAMELIST включать переменные с индексами? Порция 54 Подготовка данных для ввода-вывода по NAMELIST Ввод данных по объявлению NAMELIST Данные, вводимые оператором READ (а, х), где х— имя списка NAMELIST, должны быть подготовлены в следующем виде. 145
Первой литерой каждой записи должен быть пробел, второй лите- рой первой записи — литера &, за которой следует имя списка NAMELIST с последующим пробелом. ' Например, если Q12— имя списка NAMELIST, то первая запись должна начинаться литерами | первая колонка (_i&Q 12|_k Далее размещаются данные, разделенные запятыми. Конец группы данных, относящихся к одному списку, указывается литерами &END. Данные в записи ввода должны быть подготовлены в одной из сле- дующих форм: (переменная} = (константа} или (имя-массива} = (список-констант} где (переменная} — простая переменная или переменная с индексами (индексами могут быть только константы целого типа); (константа} — константа любого допустимого типа, причем кон- станты логического типа могут быть представлены в виде Т или .TRUE., F или .FALSE.; (список-констант} имеет ту же форму, что и в объявлении DATA. Перечисленные во входной записи имена переменных и массивов должны быть указаны в соответствующем списке NAMELIST, причем порядок их следования не существенен. Замена имен данных, указан- ных во входной записи, эквивалентными им именами (см. порц. 66) не допускается. Данные для одного списка NAMELIST могут размещаться в не- скольких записях. В таком случае имя элемента может быть располо- жено в одной записи, а присваиваемое значение— в другой; перенос части одного имени или одной константы из одной записи в другую не- допустим. Пример. Пусть в программе содержатся предложения: DIMENSION А (7) NAMELIST/RQS/A, С, L, М READ (5, RQS) Пусть переменным из списка NAMELIST должны быть присвоены следующие значения: А = {5.2; 3.7; 4.5; 9.8; 9.8; 9.8; 9.8}; С = 7.48; L = 125; М = 15. Вводимые данные могут быть представлены на одной перфокарте в в виде: 146
{колонка 1 l^&RQS М = 15, С = 7.48, L = 125, А = 5.2, 3.7, 4.5, 4 * * 9.8 & END на двух перфокартах: 1-ая перфокарта (_□& RQS^L = 125, А = 5.2, 3.7, 4.5, 2-ая перфо- карта ^4 * 9.8, С = 7.48, М = 15 & END или 1-ая перфокарта ^«Зс RQS^, А = 5.2, 3.7, 4.5, 4 * 9.8, 2-ая пер- фокарта ,-jC = 7.48, М = 15, L = 125 & END Действие оператора READ (5, RQS) заключается в следующем: читается первая запись данных и проверяется, согласуется ли имя списка, указанное в ней, с именем списка, указанным в операторе READ. При несовпадении имен читается следующая запись и т. д. до тех пор, пока не будет прочитана запись с требуемым именем списка. Далее читаются и помещаются в соответствующие поля памяти эле- менты данных, входящих в список. Вывод данных по объявлению NAMELIST При выводе по объявлению NAMELIST данные представляются в виде, пригодном для последующего ввода по тому же списку NAME- LIST: за именами переменных и массивов, указанными в списке NA- MELIST, выводятся их значения. Вывод производится в формате, соответствующем типу каждого данного. Массивы выводятся поэле- ментно в порядке расположения их в памяти. Пример вывода по NAMELIST Программа: NAMELIST/NL1/I1, I1/NL2/IШ, I4/NL3/I1, 19, 17, 17 II = 1 14 = 4 17= 7 19 = 9 1Ш = & W RITE (3, NL1) W RITE (3, NL2) W RITE (3, NL3) STOP END Результат: 1-ая строка l_j& NL1(_j 2-ая строка ^11 = uuuuuol^uuu 1, П = шииииии »!—11 3-я строка END 4-ая строка l-i&NL?^ 5-ая строка ^ПЯ = l_il_^,14 = l__ 6-ая строка ^&END 147
7-ая строка lj&NL 3^ 8-ая строка <_□!! = l_jl_h_ii_ii_ii_jl_h_»_)i_i 1,19 = i_iL_ji_it_ii_it_ji_j ।__ii_ii_|9, 17 = ।ii,i u » u||n ii ii। 7, 17 = ।_и_и_и_||__||_,|_и и । - u_>7 9-ая строка END Для целых чисел в соответствии с допустимым в ЕС максимальным диапазоном при выводе используется 11 позиций (десять для цифр и одна для знака). Задание. Переменные, которым должны быть присвоены значения: СВА = 23.5; В = {1.2; 1.2; 1.2; 1.2; 1.2); J = 23; К = 5; L (2,5) = = 10, вводятся в соответствии с объявлением NAMELIST/STR/A, В, J, К, L оператором READ (5, STR) Из приведенных вариантов представления данных на перфокартах выбрать правильные: 1) 1-ая перфокарта l_j& STRi_, 2-ая перфокарта i_jL (2, 5) = 10, К = 5, СВА = 23.5, J = 23, В = 5 * 1.2 3-я перфокарта l_i& END 2) 1-ая перфокарта ,_>& STRi_jK = 5, В = 5 * 1.2, L (2, 5) = = 10, СВА = 23.5, J = 23& END 3) 1-ая перфокарта !_□& STRl_,K = 5, В = 5 * 1.2, L (2, 2-ая перфокарта с_|5) = 10, J = 23, СВ 3-я перфокарта ljA = 23.5, J = 23& END
Глава IV ФУНКЦИИ И ПОДПРОГРАММЫ Порция 55 Классы функций и подпрограмм Экономии труда при написании программы на ФОРТРАНе можно достичь, используя определенные в этом языке средства задания функций и подпрограмм. Можно предварительно написать один раз некоторый оператор или их последовательность — тело процедуры, а затем по мере необходимости обращаться к их выполнению. Для такой цели ФОРТРАН включает развитый аппарат средств, которые в языках Рис. 28 программирования принято подраз- делять на два класса: 1. Процедуры для вычисления функций (другие названия: про- цедуры-функции, функции); 2. Процедуры-подпрограммы (иначе: подпрограммы SUBROUTI- NE, подпрограммы). Основное различие между фун- кциями и подпрограммами состоит в способе обращения к этим про- цедурам. В случае функций обращение к соответствующей процедуре, пред- назначенной для вычисления, как правило, одного значения — зна- чения функции — осуществляется посредством так называемого ука- зателя функции, который не является оператором, а лишь использу- ется в качестве первичного выражения. В отличие от этого подпрограммы могут предназначаться для вы- числения как одного, так и ряда значений (в том числе значений раз- ных типов, а также всех или части элементов массивов и пр.) и опре- деляются как законченные единицы действия, в связи с чем обращение к ним в языках программирования (например, в ФОРТРАНе, АЛГОЛ-60, ПЛ/1 и многих других) определяется посредством операторов вызова подпрограмм, называемых также операторами обращения к подпро- граммам. Подпрограммы на языке ФОРТРАН оформляются в виде отдельных программных модулей, заголовком которых служит объявление SUBROUTINE, в связи с чем их называют иногда подпрограммами SUBROUTINE или процедурами SUBROUTINE. 149
В ФОРТРАНе по способу определения различается три класса «функций: 1. Внутренние. ' 2. Встроенные. 3. Внешние, называемые также процедурами FUNCTION (рис. 28). Тип основных внешних и встроенных функций определяется в 4ЮРТРАН/ЕС по начальным буквам имени (см. табл. 35, 36): I I INTEGER* 2 I, М INTEGER* 4 D DOUBLE PRECISION (REAL* 8) C COMPLEX* 8 CD COMPLEX* 16 Остальные REAL * 4 Задание. 1. Назовите классы вычислительных процедур, использу- емых в языке ФОРТРАН. 2. Назовите классы функций, используемых в ФОРТРАНе. Порция 56 Имена функций и подпрограмм С каждой из вычислительных процедур — функцией или подпро- граммой — связывается некоторое имя, называемое соответственно име- нем (идентификатором) данной функции или подпрограммы. Посред- ством имен функций и подпрограмм осуществляется обращение к про- цедурам их выполнения (вычисления). Что касается встроенных функций, то процедуры их выполнения со- держатся в реализации языка, и аппарат их выполнения предусматри- вает включение (встраивание) соответствующих команд (число таких команд для каждой из этих функций весьма невелико) во все те точки объектной программы, где данная функция используется. Заметим также, что имена для встроенных функций заранее опре- делены. Список встроенных функций, предусматриваемых стандартом языка и реализованных в ФОРТРАН/ЕС, приведен в табл. 36 (стр. 346). Точно так же за некоторыми внешними функциями, оформляемыми реа- лизацией языка в виде отдельных программных модулей и называе- мыми основными внешними функциями, закреплены определенные имена. Список основных внешних функций стандарта и ФОРТРАН/ЕС приведен в табл. 35 (стр. 343). Во всех остальных случаях идентификаторы для функций и под- программ выбираются составителем программы согласно общим пра- вилам построения имен. В некоторых случаях на использование имен тех или иных классов функций и подпрограмм накладываются до- полнительные ограничения. Задание. 1. Для какой цели вводятся имена функций и подпрограмм? 2. Для каких классов функций закреплены имена? 150
3. Какие из приведенных имен являются именами встроенных функ- ций? основных внешних функций? МАХО, MAXI, DMIN1, IFIX, REAL, EXP, СЕХР, ALOGIO, DCOS, CCOS, ATAN Какой тип имеют аргументы этих функций и сами функции? Порция 57 Фактические и формальные параметры Каждая вычислительная процедура, помимо имени, используемого для ее обозначения и обращения к ней, характеризуется перечнем ар- гументов, которые в языках программирования принято называть па- раметрами. Понятие параметров в языках программирования является одним из основополагающих. При записи вычислительных процедур их параметры обозначаются идентификаторами и называются формальными параметрами. При этом разные формальные параметры обозначаются различными иден- тификаторами. Существенно заметить, что в качестве формальных параметров про- цедур могут быть использованы не только идентификаторы переменных, принимающие в момент вызова процедуры значения тех или иных выра- жений — фактических параметров, но и идентификаторы других объек- тов — массивов, внешних процедур, а также идентификаторы, име- нующие результат. В АЛГОЛ-60 определены (явно) два способа вызова формальных параметров: значением (по значению) и по имени. Параметрам, вызы- ваемым значением, на время выполнения процедуры отводится локаль- ная память (именуемая их идентификаторами) и в момент вызова в. эту память помещаются предварительно вычисленные значения аргу- ментов — фактических параметров. При выходе из процедуры содер- жащиеся в этой локальной памяти значения становятся недоступными (теряются). Таким образом, параметр, вызываемый значением, не может служить именем результата. Формальный параметр, вызываемый по имени, служит лишь обозна- чением позиции, которая должна быть замещена соответствующим, фактическим параметром. Так, если таким параметром будет иденти- фикатор простой переменной, которой присваивается в процессе вы- полнения процедуры некоторое значение, то получаемый результат будет пересылаться в поле, обозначаемое соответствующим фактиче- ским параметром. Таким образом, фактический параметр, соответст- вующий вызываемому по имени, может быть использован в качестве имени результата. Способ вызова формальных параметров в ФОРТРАНе определяется прежде всего их принадлежностью к тому или иному классу объектов. 151
Если формальным параметром процедуры является имя массива или внешней процедуры, вызов осуществляется по имени. Если формальным параметром процедуры является имя перемен- ной, то: если формальный параметр определяется или переопределяется в теле этой процедуры, вызов осуществляется по имени; в других случаях вызов осуществляется значением. Следующий пример иллюстрирует использование формальных па- раметров, вызываемых по значению и по наименованию: Вызывающий программный Вызываемый программный модуль модуль READ (2,5) A, F, Е С = А * F/(2. * F ** 4) CALL Р1 (А, В, С) S(I)-А + В*А**3 SUBROUTINE Pl (X, Y, Z) Y = X * Z** I 4- X ** I *Z RETURN END 5 FORMAT (3F 10.1) STOP END Разберем подробно этот пример. Вызываемый программный модуль является подпрограммой и вызывается с помощью специального оператора CALL. Подпрограмма обозначена идентификатором Р1 и имеет формальные параметры X, Y, Z. Давайте теперь посмотрим, как взаимодействуют формальные параметры X, Y и Z с фактическими параметрами (А, В, С), указанными в операторе CALL в вызывающем программном модуле. Предполагаем, что формальные параметры X и Z в подпрограмме Р1 не определяются и, следовательно, вызываются зна- чением. Значение переменной А определяется при выполнении операто- ра ввода; переменная С получает определенное значение при выполне- нии оператора присваивания; в память, отведенную переменным X и Z, будут помещены соответственно значения А и С. Значение третьего формального параметра Y вычисляется в процессе выполнения под- программы и будет помещено в поле, отведенное фактическому пара- метру В. Этот формальный параметр вызывается по имени. Таким образом, в языке ФОРТРАН принято некоторое ограниче- ние на использование формальных параметров, вызываемых по наиме- нованию. В том случае, когда фактический параметр является выра- жением, отличным от переменной (простой или с индексами), соответст- . вующий ему формальный параметр вызывается значением. Последнее означает, что в момент вызова вычисляются значения выражений, 152
являющихся фактическими параметрами, при текущих значениях вхо- дящих в них величин; последние должны быть определены к моменту вызова. Эти значения присваиваются формальным параметрам (т. е. эти значения засылаются в поля памяти, обозначаемые формальными параметрами). С другой стороны, если фактический параметр соответствует фор- мальному параметру и значение последнего в процедуре определяется или переопределяется, то этот формальный параметр вызывается по наименованию, а фактический параметр может быть только идентифи- катором простой переменной, переменной с индексами или идентифи- катором массива. Для обращения к процедуре необходимо указать, какие объекты должны быть использованы вместо формальных параметров, т. е. задать в вызывающем программном модуле фактические параметры. Естественно, формальные параметры и фактические должны быть между собой согласованы в количестве, и каждому формальному параметру должен быть сопоставлен определенный фактический параметр, что достигается заданием в вызываемой процедуре списка формальных, а в вызывающей — списка фактических параметров; в каждом из списков параметры разделяются запятыми, а сами списки заключаются в скобки; формальные и фактические параметры должны быть согла- сованы в порядке их перечисления в соответствующих списках. Кроме того, требуется согласование между типами формальных и фактических, параметров. Формальному параметру, являющемуся идентификатором массива, может соответствовать фактический параметр, являющийся только идентификатором массива или элементом массива того же типа. Формальному параметру процедуры, являющемуся именем проце- дуры, может соответствовать фактический параметр, являющийся идентификатором процедуры того же класса — подпрограммы или функции и, в случае функции, того же типа. Единственное исключение из правила согласования типов формаль- ных и фактических параметров составляет следующее: фактическим, параметром в обращении к процедуре-подпрограмме (но не к проце- дуре-функции) может быть текстовая константа. Списки формальных и фактических параметров указываются соот- ветственно в вызывающей и вызываемой процедурах после идентифи- катора данной процедуры. Задание. 1. Какие (формальные или фактические) параметры необ- ходимо задать при обращении к процедуре? 2. Какие способы вызова формальных параметров допускаются в в языке ФОРТРАН (стандарт) и в каких случаях они используются? 3. Как вызывается формальный параметр процедуры, обозначаю- щий результат ее выполнения? 4. Чем может быть фактический параметр, обозначающий результат выполнения процедуры? 153
' 5. В чем должны согласовываться списки формальных и фактиче- ских параметров процедур? 6. Требуется ли согласование списков формальных параметров двух разных процедур? Порция 58 Связь между фактическими и формальными параметрами Выполнение обращения к процедуре приводит к связи фактических параметров со всеми употреблениями формальных параметров в теле этой процедуры. При этом, если фактический параметр является пере- менной с индексами и выражения, составляющие индексы, содержат переменные, то такой фактический параметр автоматически заменяется тем же параметром со списком постоянных индексов, равных их те- кущим значениям, полученным непосредственно в момент установления связи между параметрами (такая замена осуществляется транслято- ром). Пример. Допустим, в вызываемой процедуре Р переменные X и Y являются формальными параметрами, причем X вызывается значением, a Y — наименованием (Y встречается в левой части оператора при- сваивания). Среди выполняемых операторов в этой процедуре имеется оператор Y = X + Y + X*Y Пусть в качестве фактических параметров для X и Y в вызывающей процедуре соответственно используются выражения АВ (N + 1), AD (К — 2) и в момент обращения к вызываемой процедуре N = 2, К = = 4. Тогда в момент вызова значение переменной АВ (3) (так как N + 1 = 3), которое должно быть определенным в вызывающем мо- дуле, будет присвоено формальному параметру X, а формальный пара- метр Y в процедуре всюду будет заменен фактическим AD (2) (так как К — 2 = 2), т. е. в процедуре Р будет выполняться оператор AD (2) = X + AD (2) + X * AD (2) причем значение X равно значению АВ (3). Обратим Ваше внимание еще на одно обстоятельство. Как было отмечено в порции 57, формальные параметры любой про- цедуры должны быть отличными друг от друга идентификаторами (и только идентификаторами). Что касается фактических параметров, то такого ограничения на них не накладывается. Так, процедура, предназначенная, например, для вычисления суммы квадратов двух величин и оформленная посредством использования двух формальных параметров — идентификаторов соответствующих переменных (на- пример, SUBROUTINE А (С, D)), естественно, может быть применена для вычисления суммы квадратов двух равных величин. Таким обра- 154
зом, фактические параметры могут оказаться совпадающими и тем самым связывать различные формальные параметры. Правила языка ФОРТРАН допускают задание фактических пара- метров при вызове процедур, совпадающих между собой, только для таких формальных параметров, из которых в процессе выполнения процедуры определяется (или переопределяется) не более чем один. Такое же ограничение накладывается на связывание формальных параметров с величинами в общем блоке. Понятие общего блока вели- чин будет объяснено позднее. Задание. 1. Какой фактический параметр может соответствовать, формальному параметру, являющемуся идентификатором массива? 2. Могут ли формальные параметры быть одинаковыми идентифика- торами? А фактические параметры? Порция 59 Вызов параметров в ФОРТРАН/ЕС Стандарт ФОРТРАНа не располагает средствами явного задания способа вызова формальных параметров процедур. Как было показано в предыдущей порции, способ вызова параметров определяется тем, как используется параметр в теле процедуры. Реализация вызова параметров внешних процедур в ФОРТРАН/ЕС не контролирует запрещенного стандартом языка обращения к пара- метрам, используемым в теле процедуры в качестве простых перемен- ных и вызываемых по имени (т. е. определяемых или переопределяемых в этом теле), с фактическими параметрами, являющимися выражения- ми, отличными от переменных (простых или с индексами). Подобные нарушения могут служить причиной появления «побочных эффектов», вообще говоря, труднообнаруживаемых ошибок. Возникновение побочного эффекта является следствием принятого способа установления связи между фактическими и формальными параметрами, играющими роль простых переменных в теле процедуры. Суть этого способа сводится к выполнению следующих трех действий: 1) при обращении к процедуре каждому из параметров выделяется внутреннее по отношению к вызываемому модулю (локальное) поле; 2) вычисляется значение соответствующего фактического параметра и пересылается в это локальное поле; если значение фактического пара- метра не определено, то и содержимое локального поля не определено; 3) при выходе из процедуры текущее значение локального поля пе- ресылается по адресу, соответствующему фактическому параметру. Приведенный способ вызова параметров, называемый вызовом по значению-результату, отличается от принятого в АЛГОЛ-60 вызова параметров по значению наличием дополнительного пункта 3. Бла- годаря этому, используя в качестве фактического параметра иден- тификатор, можно в вызываемой внешней процедуре ФОРТРАНа 155
присвоить новое значение фактическому параметру (что можно сделать в АЛГОЛ-60 только вызовом по имени). Каковы же возможные послед- ствия того, что вместо переменной в качестве фактического параметра используется константа? При трансляции константы предварительно размещаются в некото- рые поля памяти и в операторах программы заменяются адресами этих полей. Таким образом, если в ФОРТРАН-программе некоторая кон- станта была (вопреки запрету) использована в качестве фактического параметра для параметра, переопределяемого в теле процедуры, при выходе из процедуры по адресу этой константы (т. е. в его поле) будет послано новое значение (согласно п. 3 описанной процедуры установле- ния связи между параметрами), что в общем случае приведет к иска- жению этой константы. В том случае, когда формальному параметру, переопределяемому в теле процедуры, будет поставлено в соответствие в качестве факти- ческого параметра некоторое выражение, отличное от константы и пе- ременной, побочный эффект не возникает; в этом случае предваритель- но будет вычислено значение выражения и сохранено в некотором про- межуточном поле памяти, адрес которого будет переслан в процедуру. Особый случай представляет использование в качестве формальных параметров имен массивов и внешних процедур: 1. Формальному параметру идентификатору массива может сопос- тавляться фактический параметр, являющийся именем массива или переменной с индексами. В первом случае формальному параметру- массиву в качестве начального адреса передается адрес первого эле- мента фактического массива. В этом случае размер массива, использу- емого в вызванной процедуре, может быть равным размеру массива, определенного фактическим параметром или не превышать его. Во втором случае в качестве начального адреса формальному массиву сообщается адрес элемента массива, являющегося фактическим пара- метром. В этом случае размер используемого в вызываемой процедуре массива не должен превосходить числа элементов, содержащихся в ос- татке массива, определяемого фактическим параметром и получаемого при отбрасывании всех его элементов, приведенный индекс которых меньше индекса фактического параметра. Формальный массив не лока- лизуется: выборка и запись осуществляется непосредственно в памяти, выделенной массиву в вызывающей процедуре. Напомним, что в. каж- дом программном модуле, в котором используется какой-либо массив или какие-либо его элементы, должен быть объявлен описатель этого массива (независимо от того, является ли имя этого массива формаль- ным параметром), который имеет силу в данном модуле. Таким образом, на что следует обратить внимание, хотя вызываемая процедура опери- рует с элементами массивов, память для которых определена вызыва- ющей процедурой, в случае, когда имена этих массивов являются формальными параметрами, приведенный индекс этих элементов вы- числяется по граничным значениям индексов, задаваемым описателем 156
в вызываемой процедуре. Другими словами, если имя массива явля- ется формальным параметром, начальный адрес массива и объем выде- ляемой ему памяти определяются в вызывающем модуле, а структура этой памяти — в вызываемом. Пусть, например, в некотором программном модуле А описан мас- сив DIMENSION Ml (3, 4) элементы которого соответственно равны а & & & iiii 2 2 2 2 и в этом модуле имеется обращение к внешней процедуре В, в которой в качестве формального параметра используется имя массива М2, для которого дано объявление DIMENSION М2 (2, 2) Обращаясь из процедуры А к процедуре В и ставя в соответствие фор- мальному параметру М2 фактический Ml, мы вырезаем часть массива Ml — его первые (в порядке пересчета по столбцам) четыре элемента &, 1, 2, -©и делаем их доступными в процедуре В посредством пар ин- дексов, т. е. имеем: М2(1, 1) = 0, М(2, 1)=1, М(1, 2) = 2, М (2, 2) = 0. Пусть в этом же программном модуле А имеется обращение с фак- тическим параметром Ml к формальному параметру М3 внешней про- цедуры С, в которой дано объявление DIMENSION М3 (5). В резуль- тате вызова имеем МЗ(1) = 0, М3(2) = 1, М3(3) = 2, МЗ(4) = 0, М3(5) = 1 Если теперь обратиться из процедуры А к процедуре С, поставив в соответствие формальному параметру М3 фактический Ml (3, 1), то в результате будем иметь М3(1) = 2, М3 (2) = 0, М3(3)=1, М3 (4) = 2, МЗ(5) = 0 2. В случае имени внешней процедуры через формальный параметр в вызываемую процедуру передается адрес загрузки соответствующего модуля. Использование в теле процедуры адреса фактического параметра вместо соответствующего формального параметра получило название вызова по ссылке (адресу). При таком вызове значение фактического параметра в вызываемой-процедуре не локализуется. Если фактическим параметром является выражение, то его значение вычисляется перед обращением и помещается по адресу, передаваемому в подпрограмму. Важно отметить, что при вызове по ссылке адрес фактического пара- метра вычисляется только один раз, перед обращением. В этом состоит 157
отличие вызова по ссылке от вызова по имени в АЛГОЛе. Действитель- но, при вызове по имени формальный параметр заменяется выражени- ем, которым представлен фактический параметр, в результате чего гГри обращении к формальному параметру всякий раз внутри вызывае- мой процедуры вычисляется адрес фактического параметра. В отличие от стандарта, в ФОРТРАН/ЕС имеются средства для задания вызова по ссылке: формальные параметры, вызываемые по ссылке, в заголовке вызываемой процедуры заключаются в наклонные черточки. Например, заголовок процедуры SUBROUTINE SUM (/А/, Р, /Q/, /В/) указывает, что первый, третий и четвертый ее параметры вызываются по ссылке. Для параметров, представляющих собой идентификаторы массивов и внешних процедур, такой вызов не влечет никаких дополнительных последствий. Для всех других объектов, используемых в качестве фак- тических параметров, вызов по ссылке дает более эффективный объект- ный код: объектная программа получается короче и выполняется быст- рее, что может оказаться ощутимым при большом количестве парамет- ров, для каждого из которых при вызове по значению-результату в про- цедуре формируются дополнительные локальные поля и команды для пересылки в них исходных и извлечения из них результирующих зна- чений. Отметим в заключение, что перечисленные ниже способы вызова формальных параметров: 1) по ссылке (адресу) — ФОРТРАН/ЕС; 2) по значению — АЛГОЛ-60; 3) по значению-результату — ФОРТРАН; 4) по имени — АЛГОЛ-60—различны (и в результате трансляции дают различные объектные коды). В принципе возможен также способ вызова 5) по результату, который задается пунктами 1 и 3 описания, при- веденного в начале порции. В этом случае формальный параметр лока- лизуется, но не определяется при входе в процедуру. Все пять спосо- бов иллюстрируются следующим ниже примером подпрограммы, вы- полнение которой дает при всех пяти способах вызова различные ре- зультаты. Пример. Рассмотрим фрагмент емой — процедуры-подпрограммы Вызывающая: COMMON В, I DIMENSION В (2) В(1)= 1 в (2) = 1 вызывающей процедуры и вызыва- ем. порцию 63). Вызываемая: SUBROUTINE Q (X) COMMON В, I DIMENSION В (2) INTEGER X I = 1 158
CALL Q (В (I)) END В (I) = 10 1 = 2 X = X +2 RETURN END В зависимости от способа вызова параметра подпрограммы Q эквива- лентами объектных кодов этой подпрограммы будут: 1. При вызове по ссылке (ref): I = 1 В (1) = В (1)+ 2 В (1) = 10 I = 2 В (1)= В (1)+ 2 2. При вызове по значению (value): X = 1 I = 1 X = X + 2 В (1) = 10 I = 2 X = X + 2 Результат: В (1) = 12 В (2) = 1 3. При вызове по результату (result): I = 1 I = 1 X = X + 2 В (1) = 10 I = 2 X = X + 2 В (1) = X Результат: В (1) неопределено в (2) = 1 Результат: В (1) = 10 В (2) = 1 4. При вызове по значе- н и ю-р езультату (value-re- sult): X = 1 I = 1 X = X + 2 В (1) = 10 1 = 2 X = X + 2 В (1) = X Результат: В (1) = 5 В (2) = 1 5. При вызове по имени (пате): I = 1 В (1) = В (1) + 2 (В (I) = В (I) + 2) В(1)= 10 I = 2 В (2) = В (2) + 2 (В (I) = В (I) + 2) Результат; В(1) = 10 В (2) = 3 Задание. 1. Каков максимальный размер массива А, имя которого используется в качестве формального параметра в процедуре, если соответствующий фактический массив В имеет описатель В (6, 15), 159
а фактическим параметром являются: а) имя массива В: б) переменная В (2, 10)? 2. Какие способы вызова параметров определены в языке ФОРТРАН/ЕС? Чем они отличаются от способов вызова параметров, определенных в стандарте ФОРТРАНа? Порция 60 Типы функций Как было отмечено в порции 55, в процедуре, предназначенной для вычисления функций, выделяется одно значение, принимаемое в ка- честве результата, присваиваемого ее идентификатору и возвращаемого в точку вызова через указатель этой функции. ФОРТРАНОМ* устанав- ливается возможность получения такого результата при вычислении каждой конкретной функции (при любых допустимых для этой функции значениях параметров) только одного, установленного для нее типа, называемого типом функции. ФОРТРАН допускает функции целого, вещественного, повы- шенной точности, комплексного и логического типов. Целый и вещественный тип функций может быть определен, как и тип переменных этих двух типов, неявно. Для функций целого типа при неявном определении типа требуется выбирать идентификатор, начинающийся одной из букв I, J, К, L, М, N; для вещественного типа — одной из остальных букв латинского алфавита. В прочих слу- чаях тип должен быть объявлен для идентификатора функции явно. Существенно отметить, что идентификатором определяется (явно или неявно) не только тип функции. Этому идентификатору присваи- вается и результат выполнения соответствующей процедуры. Типы встроенных функций определены табл. 36 (стр. 346) и специального описания их типов в программах на ФОРТРАНе не требуется. То же самое касается типов основных внешних функций. Внутренние функции могут быть использованы только в том про- граммном модуле, в котором приведено их объявление, поэтому опи- сание их типа в случае его явного задания должно быть дано в этом же модуле. Такое описание типа задается объявлением спецификации, как и при задании типа переменных, с помощью соответствующего описателя типа или (в ФОРТРАН/ЕС) объявлением IMPLICIT. Фор- мальные параметры внутренней функции могут быть использованы в качестве идентификаторов других объектов, используемых в данном программном модуле, например, формальных параметров других внут- ренних функций, идентификаторов внешних функций или простых переменных. Для внешних функций в случае необходимости явного задания их типа это задание должно быть приведено как в вызывающем, так и в вызываемом программных модулях. В вызывающем программном 160
модуле (им может быть как головной модуль, так и некоторый проце- дурный модуль) такое описание типа внешней функции должно быть задано так же, как и в случае внутренней функции. Например, REAL L, М, КВ В вызываемой внешней процедуре-функции описание ее типа осущест- вляется посредством задания перед служебным словом FUNCTION соответствующего описателя. В случае языка ФОРТРАН/ЕС описание типа функции в ее теле может быть также задано в объявлении типа или определено объявлением IMPLICIT. Задание. 1. Какие типы функций допустимы в языке ФОРТРАН? 2. Как задается тип внутренней функции? 3. Как и в каком случае может быть задан неявно тип внешней функции? 4. Допустимо ли описание типа функции Z следующим образом: FUNCTlOxN Z(X) LOGICAL Z Порция 61 Встроенные функции Большинство реализаций ФОРТРАНа предусматривает несколько десятков встроенных функций. От описания процедуры вычисления встроенных функций составитель программы на ФОРТРАНе полностью освобожден, и вместе с тем эти функции могут быть использованы в лю- бых программных модулях — в головном, внешних функциях и под- программах. Каждый программист должен иметь полный список функ- ций, предусмотренных реализацией языка на данной ЭВМ в качестве встроенных, вместе с подробными к ним пояснениями, такими как указание точности вычисления значений функций, формы представле- ния аргументов и т. д. В табл. 36 на стр. 346 приведен список встро- енных функций, предусмотренных стандартом языка и ФОРТРАН/ЕС. За каждой из встроенных функций закреплен идентификатор, но это не запрещает его использование в некотором программном модуле в других целях, например, для обозначения некоторой переменной. Однако в последнем случае необходимо иметь в виду следующее: если идентификатор некоторой встроенной функции в данном программном модуле используется для обозначения именно этой функции, то он в этом программном модуле не может быть использован ни в каких других целях и нет необходимости в его специальном описании (в объявлениях спецификации). Исключение составляет возможное использование этого идентификатора в качестве наименования общего блока данных в объявлениях COMMON. Идентификатор встроенной функции может быть использован в не- котором программном модуле в качестве простой переменной или имени 6 9-2712 161
массива по умолчанию. В любом таком случае в данном программном модуле соответствующая встроенная функция становится недоступ- ной для обозначения любого другого объекта посредством соответству- ющего объявления. Заметим при этом, что данное правило не запрещает использование идентификатора встроенной функции в качестве имени общего блока при сохранении за этим идентификатором его роли имени встроенной функции (поскольку для имени блоков в языке не введены никакие специальные объявления). Назовем еще два дополнительных требования, которым должны удовлетворять идентификаторы встроенных функций (в том случае, когда они не используются для обозначения некоторых других объек- тов программы): 1) Идентификатор встроенной функции не может встречаться в объ- явлении EXTERNAL (об этом объявлении Вы узнаете в дальнейшем). 2) Идентификатор встроенной функции всегда предшествует непо- средственно заключенному в скобки списку фактических параметров (т. е. встречается только в конструкции, представляющей собой ука- затель функции). Обращение к встроенной функции, как и ко всякой другой, осу- ществляется посредством употребления ее указателя в качестве пер- вичного в арифметическом или логическом выражении. При этом в ка- честве фактических параметров могут быть использованы любые вы- ражения, тип, количество и порядок которых определяются таблицей <36. Заметим, что встроенные функции AMOD, MOD, ISIGN, DSIGN, SIGN не определены, если их второй аргумент равен нулю. Пример обращения к встроенной функции ABS: IF (R —ABS (S —4.)) 12, 10, 30 Задание. 1. Какие из приведенных ниже конструкций языка явля- ются допустимыми записями операторов присваивания в стандарте ФОРТРАНа? 1) А = ABS + ABS (X + Y) 5) А = FLOAT (К) + 1 2) А = AINT +1 6) А = AMOD (С) + 2.1 3) А = MAX# + 1.2 7) А = IFIX (С) + 2 4) А = AINT + ABS (X + Y) 8) Какие из приведенных выше операторов допустимы в ФОРТРАН/ЕС? 2. Ниже приведена программа, вычисляющая интеграл ERR О х 3.75 с точностью EPS = IE — би шагом 0.25. DIMENSION ERR (15) EPS = IE___6 P = SQRT (ATAN (1.)) x = 0.0- 162
DO 7 I = 1, 15 X = X + e.25 s = &. В = X к = e y = x * x 2-0 A = B/(2 * К + 1) IF (ABS (A). LT. EPS) GO TO 7 S = S + A К = K+ 1 В = — В * Y/K GO TO 20 7 ERR (I) = S/P WRITE (3, 1) ERR 1 FORMAT (5X, 5E 15.7) STOP END Составьте программу для вычисления ERR с помощью основной внешней функции ERF. Выполните обе программы на ЕС ЭВМ и сравните полученные значения. 2 Обратите внимание, для задания константы в приведенной про- У л грамме вычисляется обратная ей величина V^arctg 1 Порция 62 Внутренние функции Часто случается, что в программе необходимо многократно выпол- нять вычисления по одной и той же формуле, заданной арифметическим или логическим выражением, но над различными аргументами или вы- ражениями (или над теми же самыми выражениями, содержащими пере- менные, которые могли изменить свои значения). Предположим, например, что в программе имеется последователь- ность операторов: R = А * А + В * В 4 С * С 4 0.5 — F D = (Х2 — X 1) ** 2 + (Y2 - Y1) ** 2 + (Z2 — Z1) ** 2 - F S = SQRT (ALPHA ** 2 + ВЕТА ** 2 + SKAP ** 2 — F) V = (X (I) * X (I) + Y (I) * Y (I) + W (I) * W (I) - F)/(X X (J) ** 2 + UU (J) ** 2 + WW (J) ** 2 — F) 6 163
Все эти операторы содержат выражения вида ARG 1*ARG 1 + ARG2*ARG2 + ARG3*ARG3 — F, хотя операции производятся в них над разными переменными или вы- ражениями, за исключением переменной F, используемой в каждом из них. Если одно и то же арифметическое или логическое выражение или сходные выражения, как это имело место в нашем примере, встречаются в одном и том же программном модуле несколько раз, то это выражение можно определить в виде особого объявления, которое в ФОРТРАНе носит название внутренней функции. Такое определение имеет вид равенства, напоминающего оператор присваивания. Формат внутрен- ней функции следующий: v (а) = е. Здесь v — идентификатор внутренней функции; а — список ее формальных параметров; е — арифметическое или логическое выражение. Число формальных параметров внутренней функции может быть произвольным. Идентификаторы функций выбираются составителем программы по его усмотрению и должны быть описаны в данном модуле явно или неявно, а их тип должен быть согласован, как и в операторе присваи- вания, с типом выражения, составляющего правую часть объявления функции. Другими словами, идентификатор внутренней функции может быть целого, вещественного типа или типа повышенной точности, если указанное выражение является выражением арифметического типа, отличного от комплексного; он может быть комплексного или логиче- ского типа, если это выражение комплексного или логического типа, соответственно. Формальными параметрами, число которых для каждой функции фиксируется (и, как и для всех прочих классов функций, не может быть равным нулю), являются различные между собой идентификаторы; они перечисляются в объявлении функции в скобках после ее иденти- фикатора слева от знака равенства и отделяются друг от друга запя- тыми. Идентификаторы формальных параметров выбираются про- извольно, но должны быть различными и по типу должны соответ- ствовать способу их использования в выражении, составляющем правую часть объявления. Так, для сокращения записи приведенных выше операторов можно определить функцию DIS, вводя в программу объявление внутренней функции DIS (X, Y, Z) = X * X + Y* Y + Z*Z —F Заметим, что так как переменная F неизменно входит во все выражения указанного вида, включать ее в число формальных параметров нет необходимости. 164
Фактическими параметрами, в отличие от формальных, могут быть не только идентификаторы, но и переменные с индексами, константы, а также выражения соответствующего типа. (При этом, в отличие от формальных параметров, фактические могут быть и одинаковыми). При наличии в программном модуле объявления функции DIS рас- смотренные выше операторы могут быть переписаны в виде: R = DIS (А, В, С) + #.5 S = SQRT (DIS (ALPHA, BETA, SKAP)) V = DIS (X (I), Y (I), W (I))/DIS (XX (J), UU (J), WW(J)) При выполнении этих операторов с идентификатором функции DIS, как с идентификатором любой переменной, связывается значение (в данном примере числовое), получаемое в результате подстановки фактических параметров в позиции формальных и вычисления зна- чения выражения, стоящего в правой части данного объявления внут- ренней функции. Список фактических параметров в указателе функции должен быть согласован со списком формальных параметров, заданным в объявлении функции, в том смысле, что переменные должны быть в нем указаны в том же количестве, в том же порядке и должны соответствовать им по типу. Так, при использовании неявного объявления типа перемен- ных в рассматриваемом примере запись оператора вида RES = DIS (1, Е, Q, D(1)) + Q*D(2) недопустима, поскольку фактические параметры здесь не согласованы ни по количеству, ни по типу (I — переменная целого типа) с объяв- лением функции DIS (X, Y, Z). На рис. 29 схематически показано вза- имодействие внутренней функции с вызывающими ее операторами. Объявления задают лишь форму вычислительной процедуры (алго- ритм), но не содержат значений аргументов, к которым она должна быть применена. Эти значения поступают в момент обращения к функ- ции через ее указатель посредством фактических параметров. Указатель функции при этом является не только носителем исходной информации, необходимой для вычисления значения данной функции, но и носителем результата этого вычисления. Некоторые особенности объявления внутренних функций состоят в следующем: 1. Формальные параметры в списке — это различные между собой идентификаторы (они не могут иметь индексов, а также не могут быть выражениями, содержащими знаки операций или константы). 165
2. Правая часть объявления может содержать помимо формальных параметров нетекстовые константы, переменные простые или с индек- сами, указатели встроенных и внешних функций. 3. Правая часть объявления может содержать указатели других внутренних функций, объявления которых находятся в записи того же программного модуля и предшествуют объявлению данной внут- ренней функции. 4. Идентификаторы формальных параметров (но не идентификатор этой внутренней функции) могут быть использованы для обозначения некоторых других объектов программы тех же типов (в том числе объектов данного программного модуля). 5. Вызов внутренней функ- ции допустим только опера- торами, содержащимися с ней в одном и том же программном модуле. Результатом вызова внутренней функции (посред- ством ее указателя) является передача вычисленного при заданных значениях факти- ческих параметров значения ее правой части и присвоение его этому указателю. Таким образом, указатель внутрен- ней функции может быть ис- Подстановка фактических параметров Рис. 29 пользован в данном програм- мном модуле как первичное выражение, в частности, может быть ис- пользован в качестве фактического параметра некоторой встроенной функции или процедуры-функции. Например, допустима запись: IF (SIN (DIS (R, T, S))) 3, 2, 1 3 A = С * BX + SIN (DIS (С, В, B)) 6. Тип возвращаемого значения может определяться неявно, если он целый или вещественный; для всех других типов возвращаемых значений, а также в случае, когда первая буква идентификатора не со- ответствует типу функции, ее идентификатор должен быть описан в данном программном модуле. 7. Внутренние функции могут быть заданы в любом программном модуле; соответствующие объявления должны быть расположены ранее всех операторов и следовать за спецификациями (при их наличии). Пример 1. Применение метода Рунге-Кутта для решения дифферен- циального уравнения вида -%L = F (х, у) dx \ ’ л 166
при заданном начальном условии у (х0) = yQ сводится к последователь- ному вычислению цепочки равенств h = Л • F (Xlt у() ki = h-F(xl + ^-, yi + ^] k3 = h + , уi + A-) k4 = h- F + Л, yt + k3) yt+\ = У( H—g- (^i + 2fe2 + 2£3 + #4), i = 0. 1, ...» n x/+i = xt + h, где h — шаг интегрирования. Пусть требуется проинтегрировать диф- ференциальное уравнение = х2 + 1 + sin у ах ‘ на отрезке [0, 2] и выдать на печать значение функции в каждой два- дцатой точке. В качестве шага интегрирования взять h — 0,005, в ка- честве начальных условий у (0) — 1. Определив по длине интервала и шагу интегрирования число точек", 2 выдаваемых на печать п = 0 ~ 20, мы можем написать сле- дующую программу, в которой после каждого завершения внутреннего цикла выводится на печать строка, содержащая: номер строки, значение X и значение Y. F (U, V) = U ** 2 + SIN (V) + 1. DATA X, Y, Н, N/О., 1., -В.-0-&5, 20/ DO 2 I = 1, 400 IF (MOD (I, N). EQ.0) WRITE (3, 3) I, X, Y FK1 = H * F (X, Y) FK2 = H * F (X + H/2., Y + FK1/2.) FK3 = H * F (X + H/2., Y + FK2/2.) FK4 = H * F (X + H, Y 4- FK3) X = X + H 2 Y = Y + (FK1 + 2.* FK2 + 2.* FK3 + FK4)/6. 3 FORMAT (15, 2 (5X, F10.4)) STOP END В приведенной программе нами введена внутренняя функция (пер- вое предложение программы), заменяя которую мы можем реализовать интегрирование любого другого уравнения данного вида, правая часть которого может быть задана в виде выражения на языке ФОРТРАН. Заменяя при необходимости список значений в объявлении DATA, 167
мы можем изменить начальные данные, шаг интегрирования и число точек, выдаваемых на печать. Встроенная функция MOD дает остаток от деления I на 20. Если он равен нулю, то I кратно 20, и, согласно условию, в этом случае печа- таются I, X и Y. Пример 2. Пусть функция Р определяется как сложная функция от параметров С и Т посредством промежуточных аргументов X, Y, и Z равенствами: X (С, Т) = С + Т2; Y (С, Т) = С2 + Т; Z (А, В) = А2 • В2 + COS (А2 + В2) + 1; Р (С, Т) = 5 + Z (Х(С, Т), Y (С, Т)) + X (С, Т) /Y (С, Т). Требуется составить программу вычисления значений этой функции для всевозможных сочетаний рядов значений параметров С и Т, представ- ленных в виде массивов (соответственно размеров 12 и 8), которые должны быть введены с устройства с номером 1. Результатом выполне- ния программы должна быть таблица значений функции Р, состоящая из четырех колонок: 1. Номер строки. 2. Значение С. 3. Значение Т. 4. Значение Р. В начале таблицы должна быть напечатана строка, представляющая собой заголовок выдаваемой таблицы вида: НОМЕР ЗНАЧЕНИЕ С ЗНАЧЕНИЕ Т ЗНАЧЕНИЕ Р Полученная таблица должна быть выдана на устройство с номе- ром 3. Помимо вводимых наборов данных значения функции должны быть вычислены еще для двух пар значений параметров С и Т: С Т 1.7 —2.41 —2.41 1.7 и помещены в ту же таблицу после всех остальных. Необходимая программа может быть представлена в виде: REAL С (12), Т (8) X (С, Т) = С + Т * Т Y (С, Т) = С * С + Т Z (А, В) = А * А * В ** 2 4- COS (А ♦ А +В »В) + 1.0 Р (С, Т) = 5.+ Z (X (С, Т), Y (С, Т)) + X (С ,Т) * SQRT (Y (С.Т)) WRITE (3, 4) 4 FORMAT (5Х, 5ННОМЕР, 5Х, ШНЗНАЧЕНИЕ^С, 5Х, * ШНЗНАЧЕНИЕ^Т, 5Х, ШНЗНАЧЕНИЕ^Р' READ (1, 2) С, Т 2 FORMAT (6F12. 2) к = а DO3 1 = 1, 12 DO 3 J = 1, 8 К = К + 1 Pl = Р (С (I), Т (J)) 3 WRITE (3, 5) К, с (1), Т (J), Р1 168
5 FORMAT (6X, 13, 3 (ЗХ, E12.6)) K = K+ 1 A = 1.7 В = —2.41 Pl = P (A, B) WRITE (3, 5) К, A, B, Pl К = К + 1 Pl = P (B, A) WRITE (3, 5) К, B, A, Pl STOP END Пример 3. Если в программном модуле на ФОРТРАН/ЕС выпол- няются арифметические вычисления только обычной точности, т. е. данные, подлежащие преобразованию, имеют стандартный размер, то не представляет труда такую программу преобразовать в программу, выполняющую тот же алгоритм, но с повышенной точностью. Если в исходной программе не использовались никакие из основных внешних и встроенных функций, то такое преобразование сводится лишь к вве- дению объявления IMPLICIT, в котором должен быть указан соответ- ствующий размер данных. Что касается основных внешних и встроенных функций, то их имена считаются явно объявленными и соглашение, определяемое объяв- лением IMPLICIT, их не касается. Однако вместо замены всех имен таких функций именами соответ- ствующих функций повышенной точности можно в начале раздела операторов задать внутренние функции вида а (х) = Da (х) где а—имя соответствующей функции, например, SQRT (X) = = DSQRT (X). Задание. 1. Какую роль в программе (пример 2) играет переменная К? Чему равно последнее присвоенное ей значение? 2. Учитывая, что в качестве фактических параметров могут быть использованы константы, запишите обращения к внутренней функции Р (пример 2), используя заданные в примере пары значений парамет- ров С и Т. 3. Функция W задана как сложная функция от переменных х и у посредством промежуточных функций a, v и F равенствами: н (х, у) = х + у v (х, у) = х2 + sin у F (w, г) = ewz + w + 3 (х, у) = In (F (и (х, у), v (х, у))) + Га (х, у) • v (х, у) 169
Составьте программу для вычисления таблицы значений функции W (х, у) для всех пар значений к и у, заданных соотношениями: х=0,2 + 0,1 -k k = 1, 2, ..., 11 //- — 0,28 +Л L = 1, 2, 3, 4 и // —6,1 +0,2 • М М - I, 2, . . 11 Таблицу значений выдать на устройство с номером 3. 4. Напишите внутреннюю функцию NATS (N) для вычисления суммы всех натуральных чисел от единицы до N. 5. Напишите внутреннюю функцию INTS (М, N) для вычисления суммы целых чисел 6. Введите надлежащую внутреннюю функцию и, используя ее, запишите операторы присваивания: z = х + ]/ 1 + х + 2х2 + Зх3 ; и ________7,83х + 3,75 , х2 + /1+ X2 + 2л4 + Зх6 ’ v ЗЛ^ + ^/Сх + У 1+х + 2х2 + ЗхЗ) . у — (X + /1 + X + 2х2 + Зх3 ) w =_______________1,25х —8,55у______________ sin г + У I + sin z + 2 sin2 z + 3 sin3 z 7. Определите значение переменной R в следующем фрагменте программы: F (U, V) = U * U - V * V X = 2. Y = 3. R = F (F (X + 1., Y - 1.), F (5, 3)) + 2&&. Порция 63 Объявление COMMON В языке ФОРТРАН имеются средства, позволяющие использовать одну и ту же область памяти для хранения данных, общих для двух или более программных модулей выполняемой программы,— общий блок, или общую область памяти. Для определения общих областей и указания идентификаторов переменных и массивов, располагаемых в этих областях, используется объявление COMMON, имеющее следую- щий формат: COMMON [xjalx^lbl ... [xn!w 170
Здесь а, by ..., w—непустые списки, элементами которых могут быть идентификаторы простых переменных, идентификаторы массивов и описатели массивов, размеры которых могут быть заданы только кон- стантами; элементы списка разделяются запятыми; Xi (i = 1, 2, ..., п) — идентификаторы, используемые в качестве наименований общих блоков, или пусто. В последнем случае принято считать, что речь идет об общем непомеченном блоке; если х, — не пусто, соответствующий блок памяти называется помеченным (име- нованным). Первые две косые черты в записи непомеченного общего блока необязательны. Например, записи COMMON //А, В, С и COMMON А, В, С эквивалентны. Наименования общих блоков составляются по общим правилам записи идентификаторов. Идентификатор, именующий общий блок, может быть использован в том же программном модуле для идентификации массива, простой переменной или внутренней функции. Переменные и массивы, описанные как объекты некоторого общего блока в одном программном модуле, будут занимать соответствующие поля в той же области памяти, что и переменные и массивы, описанные как объекты общего блока с тем же наименованием в другом програм- мном модуле выполняемой программы. При этом, если несколько про- граммных модулей используют одну и ту же общую область памяти, то каждое поле памяти с одним и тем же порядковым номером в области определяет одно и то же значение для всех программных модулей, несмотря на то, что оно может иметь в них различные обозначения. Пример. Пусть в каждом из трех программных модулей одной вы- полняемой программы заданы соответственно объявления COMMON /Р/ Al, А2, АЗ COMMON /Р/ HP, PH, РТ COMMON /Р/ ТО, ТЕ, ТА Эти объявления обозначают следующее: для всех трех программных модулей в процессе сборки программы будет отведен общий блок памя- ти Р, в который будут помещаться значения трех переменных, причем к первому полю общего блока можно обращаться в каждом из про- граммных модулей соответственно посредством идентификаторов А1, HP и ТО, так как вычисляемые в разных программных модулях зна- чения переменных Al, HP и ТО будут помещаться в одну и ту же еди- ницу памяти. Это же относится к переменным А2, PH, ТЕ и АЗ, РТ, ТА. При этом не только экономятся единицы памяти, но (что более важно!) также устанавливается связь между программными модуля- ми: определяемые значения переменных в одном из них становятся 171
доступными для использования непосредственно в других, если они отнесены к общему блоку памяти. В общем блоке переменные и массивы располагаются в порядке, определяемом последовательностью их записи в объявлении COMMON. Списки в COMMON, относящиеся к общему блоку с одним и тем же наименованием, рассматриваются как один список. Например, объяв- ление: COMMON /А/ К, М, I /В/ С, Н, Р /А/ КА, МВ, КВ эквивалентно объявлению: COMMON /А/ К, М, I, КА, МВ, КВ /В/ С, Н, Р Это замечание относится также к общему непомеченному блоку. Если некоторый программный модуль содержит несколько объяв- лений COMMON, то все они, начиная с первого, рассматриваются как одно объявление, список элементов которого составлен из списков всех этих объявлений, записанных в порядке их появления в программе, т. е. каждое очередное объявление COMMON в данном программном модуле считается продолжением предыдущего. Если имя массива или описатель массива появляется в списке объявления COMMON, то все элементы этого массива, начиная с пер- вого элемента, помещаются в соответствующий общий блок. Обращаем Ваше внимание на то, что в списки COMMON нельзя помещать пере- менные с индексами; если какой-либо элемент массива требуется по- местить в общую область, то в нее должен быть помещен весь этот мас- сив. Такое требование связано с принятой концепцией размещения мас- сивов и элементов общей области в последовательности следующих друг за другом единиц памяти. Следующий пример иллюстрирует порядок размещения объектов общих блоков в памяти машины. Пусть в первом программном модуле имеется объявление: COMMON /В/ Р, Т, Н (3) (Р и Т — простые переменные). Память в помеченном общем блоке В будет распределена следующим образом: Элементы общего блока Р Т Н(1) Н(2) Н(3) Единицы памяти i <4-1 < + 2 <' + з <4-4 Если теперь во втором программном модуле будет задано объяв- ление COMMON /В/ А (3), В, С то значением переменной А (1) будет содержимое Лй единицы памяти, 172
значением А (2) — содержимое i + 1-й и значением А (3) — содер- жимое i + 2-й единицы памяти; содержимое i + 3-й и i + 4-й единиц соответственно будут отведены под переменные В и С. Если в списке COMMON указан только идентификатор массива, то размеры этого массива должны быть описаны в объявлении DIMEN- SION или типа в этом же программном модуле. Задание. 1. Какие элементы могут быть в списках объявления COMMON? 2. Может ли использоваться идентификатор помеченного блока для наименования других элементов программного модуля? 3. Напишите объявление для размещения в общем блоке памяти двумерных массивов А и В, содержащих по 4 столбца и 3 строки. Дайте этому блоку наименование /Т/. Порция 64 Соответствие общих блоков Размер общего блока — это сумма единиц памяти, необходимой для размещения объектов, указанных в объявлениях COMMON и EQUIVALENCE (это объявление будет рассмотрено далее). Размеры помеченных общих блоков с одним и тем же наименованием в разных программных модулях, которые включаются в один выполняемый мо- дуль, должны быть одинаковыми. Размеры непомеченного общего блока в различных программных модулях выполняемой программы могут быть различными, однако эти размеры во внешних процедурах не должны превосходить размер непомеченного общего блока в головном модуле. Пример. Предположим, что выполняемая программа состоит из четырех программных модулей, которые содержат следующие объяв- ления COMMON: 1-й модуль: COMMON /Т/ К, М, N //RS, RT, RU/K/A, С 2-й модуль: COMMON // А2, АЗ/ К/ SR, TR 3-й модуль: COMMON /Т/I, J, Л // AR, BR, CR, DR 4-й модуль: COMMON /Т/ И, 12, 13 /К/ Р, U Ниже показаны порядок и соответствие элементов в общих блоках: Общий блок Т Общий блок К 1-й модуль К М N 2-й модуль 3-й модуль I J Л 4-й модуль 11 12 13 Единицы памяти i >4-1 1 + 2 1-й модуль А С 2-й модуль SR TR 3-й модуль 4-й модуль Р и Единицы памяти ’ i /+1 173
Непомеченный общий блок . 1 -й модуль RS RT RU 2-й модуль А2 АЗ 3-й модуль AR BR CR DR 4-й модуль Единицы памяти k *+ 1 k+ 2 *4-3 Значения переменных повышенной точности и комплексных пере- менных считаются расположенными в двух последовательных еди- ницах памяти. Пример 1-й модуль: COMMON /С/ А, В, С, D, Е, F, G 2-й модуль: COMPLEX R, S, Т COMMON /С/ R, S, Т, U Соответствие элементов в блоке С: 1-й модуль А В с D Е F G 2-й модуль R S Т и Единицы памяти i <4-1 <+2 <4-з < + 4 <4*5 <4-6 В этом примере значение переменной А является значением вещест- венной части комплексного числа, обозначенного идентификатором R, а значение переменной В — значением его мнимой части. В списках COMMON запрещается употреблять формальные пара- метры функций и подпрограмм. Пример. Пусть четыре программных модуля используют общий блок В1, при этом первый использует первые десять единиц этого блока; второй — первые три и последние три из указанных десяти; третий — со второй по восьмую, а четвертый — с пятой по двенадцатую. В таком случае: во-первых, общий блок будет содержать 12 единиц памяти; во-вторых, в каждый из названных четырех модулей должно быть включено объявление COMMON, содержащее (помимо наименования блока В1) двенадцать единиц памяти (на что особо обращаем Ваше вни- мание!), независимо от того, что в каждом из модулей используются лишь те или иные из них; в-третьих, необходимые (используемые в каждом модуле) объекты должны указываться в соответствующих позициях в списках COMMON, а в неиспользуемые позиции должны быть поставлены некоторые 174
«фиктивные» идентификаторы, т. е. идентификаторы, не используемые этим модулем. Обозначим в приведенном примере с четырьмя модулями идентифи- каторы используемых в них объектов через Al, А2, AIS'; Bl, В2, ..., В6; С1, С7; El, Е2, ..., Е8. Фиктивные переменные обозна- чим Fl, F2, ... . Тогда в каждом из четырех модулей в нашем примере должны быть указаны, соответственно, следующие объявления: 1-й модуль: COMMON/B1/ Al, А2, АЗ, А4, А5, А6, А7, А8, А9, AIS, Fl, F2 2-й модуль: COMMON/B1/ Bl, В2, ВЗ, Fl, F2, F3, F4, В4, В5, В6, F5, F6 3-й модуль: COMMON/B1/ Fl, Cl, С2, СЗ, С4, С5, С6, С7, F2, F3, F4, F5 4-й модуль: COMMON/B1/ Fl, F2, F3, F4, El, Е2, ЕЗ, Е4, Е5, Е6, Е7, Е8 Задание. 1. Как определяется размер общего блока? 2. Могут ли одинаково помеченные общие блоки в разных модулях одной выполняемой программы иметь разные размеры? А непоме- ченный? Порция 65 Помеченные и непомеченные общие блоки Рассмотрим вопрос о том, чем отличаются помеченные общие блоки от непомеченного и когда возникает необходимость в использовании помеченных общих блоков. Переменным из помеченных общих блоков можно присваивать на- чальные значения объявлениями DATA, заданными только в модуле- блоке данных (см. порцию 89). Переменным из непомеченного общего блока присваивать начальные значения объявлением DATA нельзя. На первый взгляд может показаться, что проще было бы определить в выполняемой программе один общий блок и поместить в него все переменные и массивы, значения которых мы хотим использовать в разных модулях. Но посмотрим, во что выливается эта кажущаяся простота. Пред- положим, что некоторая выполняемая программа состоит из головного модуля, трех подпрограмм и двух внешних: функций. Все указанные программные модули используют некоторые переменные из общего блока, причем: головная программа и подпрограмма Р1 используют переменные А, В, С, D, головная программа и подпрограмма Р2 — переменные Е, F, G, Н, головная программа, внешняя функция F1 и подпрограмма РЗ — переменные I, J, К, L, М, N, 175
головная программа, подпрограммы Р1 и Р2 и внешняя функция F2 — переменные О, Р, Q, R, подпрограмма Р2 и подпрограмма РЗ — переменные S, Т, U, V, подпрограмма Р1 и подпрограмма РЗ — переменные W, X, Y, Z. Полный список переменных в общем блоке был бы таким: А, В, С, D, Е, F, G, Н, I, J, К, L, М, N, О, Р, Q, R, S, Т, U, V, W, X, Y, Z. Поскольку отдельное значение в общем блоке памяти определя- ется порядковым номером поля, который соответствует порядковому номеру идентификатора переменной в списке COMMON, нам пришлось бы в каждом из модулей повторять весь список объявления COMMON, чтобы нужные переменные оказались в соответствующих позициях. Однако это неудобно, так как длинный список оставляет больше воз- можностей для ошибок. Разбив описанный выше непомеченный общий блок на несколько помеченных блоков, мы в каждом из модулей за- пишем: головная программа: COMMON /А/ А, В, С, D, /В/ Е, F, G, Н /С/ I, J, К, L, М, N /D/О, Р, Q, R, подпрограмма Pl: COMMON /А/ А, В, С, D /D/ О, Р, Q, R,/F/ W, X, Y, Z, подпрограмма Р2: COMMON /В/ Е, F, G, Н /D/ О, Р, Q, ~R /Е/ S, Т, U, V, подпрограмма РЗ: COMMON /F/ W, X, Y, Z /Е/ S, Т, U, V/C/I, J,K, L, М, N, внешняя функция Fl: COMMON /С/ I, J, К, L, М, N, внешняя функция F2: COMMON /С/ I, J, К, L, М, N /D/ О, Р, Q, R. Для наглядности мы обозначили переменные в помеченных общих блоках, используемых в разных модулях, одинаковыми идентификато- рами, что делать не обязательно. Порядок следования наименований общих блоков в каждом из приведенных объявлений COMMON (с соответствующими списками) произвольный. Как видно из приведенного примера, кроме тех преимуществ, о которых говорилось выше, использование помеченных общих блоков придает компактность записи объявления COMMON. Задание. Когда возникает необходимость использовать помеченные общие блоки? Порция 66 Объявление EQUIVALENCE Объявление EQUIVALENCE используется для совмещения памяти двух или более объектов одного модуля (в отличие от COMMON, по- средством которого в одной и той же единице памяти размещаются зна- 176
чения объектов из разных программных модулей). Формат записи объявления EQUIVALENCE следующий: EQUIVALENCE (AJ, .... (kn) Здесь ki — списки, содержащие не менее двух элементов, значения которых помещаются в одну и ту же единицу памяти. Элементом списка может быть: 1. Идентификатор простой переменной. 2. Идентификатор переменной с индексами, причем список индек- сов может состоять только из констант и их количество должно соот- ветствовать размерности массива, указанной в его описателе, или быть равным единице (в последнем случае индекс рассматривается в качест- ве приведенного). Так как элементы массивов размещаются в памяти упорядоченно, то эквивалентность двух элементов разных массивов приводит к совмещению в памяти остальных элементов этих массивов. Пример DIMENSION PI (2,2), SI (3), Т1 (3,^) EQUIVALENCE (С, D, Е), (Т1 (1,1), А, В), (Р1 (2), SI (1), К) В этом примере массив Р1 описан как двумерный, а его элемент в операторе EQUIVALENCE записан с одним индексом. Это значит, что этот индекс является приведенным. Распределение памяти для пере- менных К, А, В, С, D, Е и массивов Pl, S1 и Т1 приводится ниже. Первый список объявления EQUIVALENCE (С, D, Е) Переменные и элементы массивов С 1 D 1 Е 1 Единицы памяти 1 k 1 k+1 Второй список объявления EQUIVALENCE (Т1 (1,1) А, В) Переменные и эле- менты массивов Т1 (1,1) I Т1 (2,1) | Т1 (3,1) | Т1 (1 2) | Т1 (2,2) | ' Т1 (3,2) *11111 В 1 1 1 1 1 Единицы памяти | / 1 /+ 1 | / + 2 | / + 3 | / + 4 | / + 5 Третий список объявления EQUIVALENCE (Pl (2), SI (1), К) Переменные и элементы мас- сивов Р1 (1,1) Pl (2,1) Pl (1,2) Pl (2,2) SI (1) SI (2) SI (3) к Единицы памяти i « +1 i + 2 «’ + 3 177
Типы объектов одного и того же списка могут быть различными, т. е.‘допускается совмещение памяти для объектов, занимающих по две единицы памяти (комплексные и повышенной точности), и объектов, занимающих по одной единице памяти (целые, вещественные, логиче- ские). Если объявляется эквивалентность между объектами, занима- ющими одну единицу памяти, и объектами, занимающими две единицы, то совмещение выполняется по первой из двух единиц памяти. Пример DOUBLE PRECISION D (3), D2 COMPLEX Rl (4) DIMENSION A (2, 4), C (6) EQUIVALENCE (A (3), D (1)), (D2, C (3), Rl (3)) Память для переменных, перечисленных в объявлении EQUIVA- LENCE, будет распределена следующим образом: Первый список объявления EQUIVALENCE (А (3), D (1)) Переменные и элементы мас- сивов А (1,1) А (2,1) А (1,2) А (2,2) А (1,3) А (2,3) А (1,4) А (2,4) D(l) D(2) D(3) Единицы памяти i »+ 1 г+ 2 / -Н 3 * 4* 4 < + 5 <+6 / + 7 Второй список объявления EQUIVALENCE (D2, С (3), R1 (3)) Переменные и элементы массивов D2 С(1) С (2) С(3) С (4) С (5) С (6) Rl (I) R1 (2) Rl(3) R1 (4) Единицы памяти / /4-1 / + 2 /4-3 /4-4 /4-5 /4-6 /4-7 Если в списке EQUIVALENCE содержится объект из блока COM- MON, то все объекты этого списка будут расположены в этом общем блоке (поскольку при распределении памяти раньше выделяются поля для общих блоков). Объявление EQUIVALENCE не влияет на распределение памяти внутри общего блока, оно может привести лишь к его удлинению, которое допускается лишь в том случае, когда общий блок расширяет- ся за пределы последней единицы памяти. Объявление EQUIVALENCE не должно расширять общий блок в сторону его начала (так как это потребовало бы перераспределения памяти, отводимой под общие блоки). Пример DIMENSION ST (4), TS (6) 178
COMMON /BR/ ST, SR, SV EQUIVALENCE (ST (3), TS (2)) По объявлению COMMON память в блоке BR будет распределена следующим образом: Элементы общего блока ST (1) ST (2) ST (3) ST (4) SR SV Единицы памяти k 1 *4-2 k + 3 k-\-4 fc + 5 Объявление EQUIVALENCE расширяет общую область в сторону конца и распределение памяти будет таким: Элементы общего ST (1) ST (2) ST (3)* ST (4) SR SV блока TS (1) TS (2) TS (3) TS (4) TS (5) TS (6) Единицы памяти k *4-1 *4-2 *4-3 k + 4 fc + 5 k + 6 Еще один пример DIMENSION ST (4), TS (6) COMMON /BR/ ST, SR, SV EQUIVALENCE (ST (2), TS (4)) Эквивалентность ST (2) и TS (4) требовала бы такого распределе- ния памяти: ST (1) ST (2) ST (3) ST (4) SR SV TS (1) TS (2) TS (3) TS (4) TS (5) TS (6) Массив TS в общем блоке разместить нельзя, его пришлось бы рас- ширить в сторону начала, поэтому подобная эквивалентность стандар- том языка недопустима. Объявление EQUIVALENCE может установить косвенную экви- валентность между объектами программного модуля. Например: EQUIVALENCE (R, S, Т), (S, V) В этом примере переменная V косвенно эквивалентна переменным R и Т. Объекты, входящие в общий блок, не могут быть объявлены экви- валентными между собой, поэтому установление косвенной эквивалент- ности между переменными общего блока А и D, как это имеет место в следующем примере, недопустимо: COMMON А, В, С, D EQUIVALENCE (X, Y, А), (X, D) 179
Естественно, объявление EQUIVALENCE не может устанавливать эквивалентность двух элементов одного и того же массива. Точно так же в списке EQUIVALENCE может содержаться не бо- лее одной переменной, которая ранее была определена как эквива- лентная. Причина этого ясна из приведенного ниже примера: EQUIVALENCE (D, Е, F) EQUIVALENCE (Н, S, Т) EQUIVALENCE (D, Н) Первое из перечисленных объявлений ставит в соответствие трем пере- менным D, Е и F одну единицу памяти, скажем, поле i. Второе — по- мещает в поле памяти i + 1 переменные Н, S и Т. Третье пытается поставить в соответствие переменным Н и D одну и ту же единицу памя- ти. Но это невозможно, поскольку переменной D уже соответствует поле г, а переменной Н — поле i + I. Поэтому третье объявление EQUIVALENCE, которое содержит две переменные, определенные ранее как эквивалентные, недопустимо. Интересным применением объявления EQUIVALENCE является следующее. Так как элементы массива любой размерности размеща- ются в машине в упорядоченные последовательности полей памяти, объявление EQUIVALENCE позволяет многомерные массивы интер- претировать как одномерные. Например, объявления DIMENSION А (Ш, 5, 4), В (200) EQUIVALENCE (А (1, 1, 1), В (1)) позволяют одну и ту же последовательность данных рассматривать как трехмерный или одномерный массив. Этим можно воспользоваться в некоторых случаях для составления более эффективных программ. Так, если элементы трехмерного массива подлежат одинаковой обра- ботке (например, суммирование, поиск максимального или минималь- ного элемента и др.), для ее выполнения можно избежать вложенных циклов. Так, при помощи указанных объявлений следующие две про- граммы, вычисляющие сумму элементов массива, равнозначны, одна- ко вторая из них короче и выполняется быстрее: DIMENSION А (10, 5, 4) S = &.& do 1 I = 1, DO 1 J = 1,5 DO 1 К - 1,4 1 1 S = S + A (I, J, К) DIMENSION А (10, 5, 4), В (200) EQUIVALENCE (A (1, 1, 1), В (1)) S - &.& DO 1 I = 1, 200 S = S + B (I) Задание. 1. В каждом из приведенных ниже объявлений или группе объявлений EQUIVALENCE допущена ошибка. Найдите ее. a) EQUIVALENCE (А, В, С) (D, Е) б) EQUIVALENCE (А, В, С), (F, D), (A, F, Е) в) COMMON /С/ В (2, 2), А (3, 4) 180
DIMENSION R (3, 2) EQUIVALENCE (B (2, 1), R (4)), (A (1), C) 2. В ФОРТРАН/EC имеется основная внешняя функция CABS (отсутствующая в стандарте). Пользуясь этой функцией и посредством объявления EQUIVALENCE интерпретируя пару вещественных чи- сел как одно комплексное число, записать следующий фрагмент про- граммы, вычисляющий длину незамкнутой ломаной, заданной коор- динатами своих вершин на плоскости. SUM = &. DO 3# 1 = 2, N DELX = X (I) — X (I — 1) DELY = Y (I) — Y (I — 1) DELS = SQRT (DELX * DELX + DELY * DELY) Зв SUM = SUM + DELS 3. Многоугольник на плоскости задан последовательностью коор- динат своих вершин: Mj (хъ у^, М2 (х2, у2), ..., Mn (xn, уи)- Считая последовательности х2,..., хц и уъ у2,..., уn элементами одномерных массивов, составить программу для вычисления периметра заданного многоугольника. Ниже приведены три программы. Определите, какая из них решает поставленную задачу. Положите N = 10. Программа 1 DIMENSION X (10), Y (10) READ (5, 10) X, Y 10 FORMAT (10 F 6.2) P = SQRT ((X (10) — X (1)) ** 2 + (Y (10) — Y (1)) **2) DO 30 I = 2, 10 30 P = P + SQRT ((X (1) — X (I — 1)) ** 2 + (Y (I) - Y (I — * 1)) ** 2) WRITE (6,40) P 40 FORMAT (5X, E12.6) STOP END Программа 2 DIMENSION X (10), Y (10), XA (11), YA (11) EQUIVALENCE (X (1)-, XA (1)), (Y (1), YA (1)) READ (5, 10) X, Y 10 FORMAT (10 F6.2) XA (11) = X (1) YA (11) = Y (1) P = 0.0 181
do зф i = 1,10 30 P = P + SQRT ((ХА (I + 1) - ХА (I)) ♦* 2 + (YA (I + ♦ 1) — YA (I)) *♦ 2) WRITE (6, 40) P 40 FORMAT (5X, E12.6) STOP END Программа 3 DIMENSION X (10), Y (10) READ (5, 10) X, Y 10 FORMAT (10F6.2) P = &.& j = 10 DO 30 I = 1, 10 P = P + SQRT ((X (J) - X (I)) ** 2 + (Y (J) - Y (I)) ** 2) 30 J = I WRITE (6, 40) P 40 FORMAT (5X, E15.6) STOP END Порция 67 Внешние функции При всей очевидной полезности для написания программ внутрен- ние фУНК1Хии имеют три серьезных ограничения: их определяющая процедура состоит из одного предложения языка; с их помощью можно вычислять только одно значение; ими можно пользоваться только в том программном модуле, в котором они определены. Этих ограничений не имеют внешние функции, к рассмотрению которых мы переходим. По своему действию внешние функции аналогичны внутренним. Обращение к внешней функции, как и для других классов функций (внутренних, встроенных), производится с помощью ее указателя, который может быть использован в качестве первичного выражения в соответствующих выражениях в программе. Так же, как и для других классов функций, с указателем внешней функции связывается единственное значение, вырабатываемое про- цедурой ее вычисления при заданных этим указателем значениях фак- тических параметров. Вычисленное значение передается через ука- затель функции в точку ее вызова. Однако, в отличие от внутренних функций, определяемых в телах соответствующих модулей и компили- руемых вместе с ними, внешние функции оформляются в виде отдельных 182
(«внешних») программных модулей, компилируются независимо и бла- годаря этому могут быть использованы различными программными мо- дулями и в разных выполняемых программах. Еще одно важное отличие внешних функций от внутренних состоит в том, что процедура выполнения внешней функции может состоять из любого необходимого количества предложений ФОРТРАНа. Вслед- ствие этого внешняя функция может вычисляться по сколь угодно сложному алгоритму и может присваивать значения некоторым другим переменным, кроме той, которая определяется ее указателем, или даже целым массивам (что может оказаться полезным для ускорения вычис- лений), а также в процессе выполнения определяющей ее процедуры может осуществляться вывод во внешнюю среду тех или иных данных посредством выполнения соответствующих операторов вывода. Существенную особенность внешних функций составляет то, что пре- емником результата вырабатываемого ею значения и передаваемого че- рез указатель в вызываемую точку программы является идентификатор этой функции; поэтому процедура вычисления функции в числе своих операторов должна содержать по меньшей мере один оператор, опре- деляющий ее значение, например оператор присваивания, левая часть которого является ее идентификатором. При этом, каковы бы ни были исходные данные, при каждом выполнении процедуры вычисления внешней функции должно иметь место определение (возможно с по- следующим переопределением) значения ее идентификатора. Программный модуль, предназначенный для реализации процеду- ры ( внешней функции, должен иметь заголовок, имеющий следующий формат: t FUNCTION s (г) или FUNCTION s (г) Здесь s — идентификатор данной функции; г — список ее формальных параметров. Если количество параметров больше одного, то парамет- ры в списке отделяются друг от друга запятыми; t — один из описате- лей типа: REAL, INTEGER, LOGICAL, DOUBLE PRECISION, COMPLEX. В ФОРТРАН/EC в заголовке внешней функции после ее имени мо- жет указываться описатель размера (допустимого для данного типа): t FUNCTION s*l (г) Например, мы можем использовать объявление INTEGER FUNC- TION L * 2 (X, Y) (в то же время объявление INTEGER * 2 FUNC- TION L (X, Y) является ошибочным). В качестве формальных параметров внешних функций допускают я идентификаторы (различные между собой) переменных, массивов и/ и 183
внешних процедур. Тип возвращаемого в вызывающую точку программы значения, вырабатываемого внешней функцией, определяется описа- телем, указываемым в объявлении FUNCTION в случае первого из приведенных видов формата, или определяется по первой букве иден- тификатора данной функции в случае формата второго вида, что воз- можно лишь для вещественного и целого типов. В ФОРТРАН/ЕС тип функции может быть определен кроме того любым из способов, применяемых при определении типа переменной, т. е. неявно, явно в объявлении типа или в соответствии с объявлением IMPLICIT. Идентификаторы формальных параметров не могут быть указаны в списках объявлений EQUIVALENCE, COMMON и DATA. Что каса- ется идентификаторов внешних функций, то они не могут появляться ни в одном из объявлений в теле определяющих их процедур, за исклю- чением объявления FUNCTION, где этот идентификатор обязательно записывается непосредственно после ключевого слова FUNCTION. В ФОРТРАН/ЕС идентификатор внешней функции может появить- ся в определяющей ее процедуре также в объявлении типа. В конце записи вычислительной процедуры., определяющей внеш- нюю функцию, проставляется заключительная строка END. В теле процедуры-функции FUNCTION не могут содержаться объявления BLOCK DATA, SUBROUTINE, FUNCTION, а также не могут содер- жаться операторы, которые прямо или косвенно ссылаются на опре- деляемую функцию (поскольку рекурсивные обращения к процеду- рам в языке ФОРТРАН запрещены). Среди всех предложений, размещенных в теле процедуры-функции, должен быть по крайней мере один оператор RETURN (и хотя бы еще один оператор, определяющий значение идентификатора функции). Выполнением оператора RETURN завершается выполнение проце- дуры. Присвоенное в процедуре к этому моменту значение идентифика- тора функции является вычисленным ее значением. Пример 1. Пусть в программе имеются операторы: IF (А * А —- Y * Z) 1,2, 3 1 К1 = —1 GO ТО 4 2 К1 - & GO ТО 4 3 К1 = 1 4 IF (R * R — S * Т) 5, 6, 7 5 К2 = — I GO ТО 8 6 К2 - Q GO ТО 8 7 К2 = 1 8 IF (Ki +К2) 9, 1В, 11 184
9 10.................... ii ................... В приведенном участке программы дважды вычисляются выражения по одной и той же формуле и выполняются одинаковые присваивания значений переменным К1 и К2 целого типа в зависимости от знака вы- ражения или равенства его нулю. Чтобы не повторять запись одних и тех же действий в программе несколько раз, повторяющуюся последо- вательность действий можно описать в виде внешней функции 1, если X > 0; sign (х) = 0, если X = 0; . — 1, если X <0. INTEGER FUNCTION SIGN (X) IF (X) 1, 2, 3 1 SIGN = —1 RETURN 2 SIGN = 0 RETURN 3 SIGN = 1 RETURN END Используя внешнюю функцию с именем SIGN, первоначальный участок программы перепишем в виде одного оператора INTEGER SIGN IF (SIGN ((А * А — Y* Z) + SIGN (R * R — S *Т))) 9, 10, 11 9 ............................................ 10 ................................................ 11 ................................................. В ФОРТРАН/ЕС правильность согласования формального и факти- ческого параметра по типу контролируется лишь для встроенных и основных внешних функций. Это позволяет проверять знак как це- лого, так и вещественного X, интерпретируемого как целое, включив в процедуру SIGN описание INTEGER X. Напомним, что такая интер- претация в данном случае возможна, так как внутреннее представление 185
нуля одинаково в обеих формах, а знак числа определяется по знаковому биту (Q для +, 1 для —). Пример 2. Рассмотрим внешнюю функцию комплексного типа (обо- значим ее идентификатором AM), определяющую тот элемент двумер- ного массива комплексных чисел АК (15, 15), модуль которого явля- ется максимальным: COMPLEX FUNCTION AM (АК, N) COMPLEX АК DIMENSION AK(N) A = Q.Q M = 1 DO 1 К = 1, N IF (CABS (АК (K)) — A) 1, 1, 2 2 A = CABS (АК (K)) M = К 1 CONTINUE AM = АК (M) RETURN END В данной процедуре нами посредством объявления DIMENSION определен одномерный комплексный массив АК, имеющий то же число членов N, задаваемое при обращении к функции AM, которое имеет исходный массив, определяемый формальным параметром АК. Это позволило реализовать поиск элемента с максимальным модулем по- средством одинарного (а не двойного) циклического процесса. В области оператора DO для определения модуля элемента комплек- сной матрицы АК (К) мы использовали указатель основной внешней функции CAB S (см. табл. 35, стр. 343). Пример 3. Использование основных внешних функций комплекс- ного типа. С ВНУТРИ КРУГА CAB S (W). LT. 1.-0 С ВЫЧИСЛИТЬ CONJG (R) = CCOS (1. + CSQRT (W) + С W 2) COMPLEX R, W W = (—.9, —.9) 44 IF (CABS (W). GE. 1.0) GOTO 33 R = CONJG (CCOS (1. + CSQRT (W) + W * W)) WRITE (3, 1) W, R 1 FORMAT (5X, 4E 18.8) 33 W = CMPLX (REAL (W) + 0.25, AIMAG (W)) IF (REAL (W). LE.. 9) GO TO 44 W = CMPLX (—.9, AIMAG (W) + -0.25) IF (AIMAG (W). LE.. 9) GO TO 44 STOP END 186
Результаты: W — 0.39999998Е 00 — .89999998E 00 — 0.14999998E 00 — #.89999998Е 00 ОЛ0000002Е 00 — 0.89999998E 00 R J0*.63276297E 00 — 0.87371826Е-0\ И.74723858Е 00 — tf.35#57247E 00 0Я2^\ЗЬ0Е00 -О6175Я2Е 00 — Я.39999998Е 00 — J0.14999998E 00 0Л0000002Е00 0.3Ь00Ъ002Е00 0&000002E00 0Я5000002Е00 0&000002E00 0A5000002E00 -0’,5816344-0'E-O'# 0.69006217Е#£ #.7388196#Е#а #.6239993-0'Е<0'# 0.11344945Е 00 0.36949772Е 00 0.720\6969Е00 -0’.1288ОО49Е6'1 Задание. 1. Составьте внешнюю функцию для определения номера последнего из максимальных по модулю элементов массива комплекс- ных чисел АК (100). 2. Составьте описание внешней функции для определения мини- мального по модулю элемента массива комплексных чисел АК (20). 3. Составьте описание внешней функции F для вычисления разности между величиной максимального и минимального из модулей элементов матрицы В (20, 30), состоящей из вещественных элементов. 4. Какие изменения необходимо внести в программу, составленную в задании 3, для решения той же задачи в случае, когда элементы ма- трицы являются комплексными числами? Порция 68 Связь внешней функции с вызывающим программным модулем Для того чтобы в вызывающей процедуре использовать процедуру вычисления внешней функции, необходимо написать ее идентификатор с последующими за ним в скобках фактическими параметрами там, где требуется получить ее значение, т. е. записать ее указатель. Естественно, в одной выполняемой программе во избежание неопреде- ленности, идентификаторы для различных внешних функций должны быть различными. Когда при выполнении оператора встречается указатель какой- либо внешней функции, производится передача управления к началу процедуры ее вычисления (т. е. к соответствующему заголовку FUNC- TION). После завершения процедуры, что соответствует выполнению в ней оператора RETURN, управление передается вызываемому моду- лю в точку его прерывания, т. е. в точку вызова данной функции. На рис. 30 схематически изображено взаимодействие внешних функций с вызывающим модулем. Следует заметить, что стандарт языка разрешает обращение из од- ного модуля к некоторым другим (быть может, нескольким) в процессе выполнения тела вызванного модуля — процедурам вычисления 187
функций или подпрограммам (о подпрограммах речь идет несколько далее). Глубина вызывов подобного рода ничем не ограничивается. Одна- ко цепочка вызова должна быть в любом случае незамкнутой: никакой программный модуль непосредственно или посредством других не может обращаться к самому себе (рекурсивный вызов процедур языком ФОРТРАН не допускается; однако см. порцию 108). Фактические параметры функции должны согласовываться с фор- мальными в порядке следования, типе и числе. Этими параметрами, в отличие от формальных, могут быть: константы; идентификаторы простых переменных; идентификаторы элементов массивов (перемен- ные с индексами); указатели функций; любые другие выражения; идентификаторы массивов; идентификаторы процедур — внешних функций и подпрограмм. В ФОРТРАН/ЕС фактическими параметрами функции могут быть также текстовые константы и метки. Требования, касающиеся размеров массивов, идентификаторы которых являются формальными парамет- рами, следующие: 1. Размеры массивов, идентифицируемых формальными параметра- ми, не должны превышать размеры массивов, определяемых соответ- ствующими фактическими параметрами. Если формальному параметру- имени массива ставится в соответствие фактический параметр-элемент массива, то размер формального массива не должен превосходить числа тех элементов фактического массива, которые в порядке возрастания 188
приведенного индекса следуют в фактическом массиве, начиная с этого элемента. 2. Размерность таких массивов должна быть определена в теле дан- ной функции. 3. Описание массивов, идентифицируемых формальными парамет- рами, может быть задано только объявлениями DIMENSION или типа (и не может быть задано объявлениями COMMON, как это может быть сделано для других, возможно, используемых в теле данной внешней функции массивов). 4. Имена всех используемых в теле процедуры-функции массивов, у которых хотя бы один из размеров задается переменной (их принято называть массивами с регулируемыми размерами), должны быть вклю- чены в список формальных параметров, в который также должны быть включены идентификаторы всех переменных, определяющих регули- руемые размеры массивов. В ФОРТРАН/EC имена переменных, определяющих регулируе- мые размеры, должны быть включены либо в список формальных пара- метров, либо в область COMMON. Пример. Сравнение текстовых констант (ФОРТРАН/ЕС). В некоторых случаях сравнение двух текстовых значений одина- кового размера можно выполнить одной операцией. Если, например, переменным А и В повышенной точности присвоены текстовые зна- чения, то оператором IF (A. EQ. В) PRINT 5 5 FORMAT (’^А = В’) можно проверить их идентичность; если условие A.EQ.В истинно, опе- ратор PRINT (см. порц. 41) напечатает текстовую константу А = В. Однако часто возникает необходимость в посимвольном сравнении текстовых значений. Рассмотрим функцию PALY (TEXT, L), распоз- нающую, является ли текстовая константа TEXT длины L палиндро- мом, т. е. словом, которое читается одинаково в обоих направлениях: FUNCTION PALY (TEXT, L) C PALY = TRUE ЕСЛИ TEXT — ПАЛИНДРОМ C PALY - FALSE В ПРОТИВНОМ СЛУЧАЕ С LOGICAL PALY, LI, L2, TEXT ♦ 1 (1) EQUIVALENCE (LI, Nl), (L2, N2) PALY = .FALSE. IF(L.LE.e) RETURN IF (L.GT.l) GO TO 2 PALY = .TRUE. RETURN 2 К = L/2 J = L DO 1 I = 1, К LI = TEXT (I) 189
L2 = TEXT (J) IF (N1.NE.N2) RETURN 1 J = J — 1 PALY = .TRUE. RETURN END Если к этой логической функции обратиться из программы LOGICAL PALY, LI, L2 LI = PALY (7 XX + XX/', 7) L2 = PALY (' ПАЛИНДРОМ', 9) PRINT 1, LI, L2 I FORMAT (L1-07L1-0) STOP END то на печать будут выданы результаты Т F Независимо от способа задания текстовой константы, являющейся фактическим параметром, в теле функции она интерпретируется как логический массив типа LOGICAL*!. Последнее позволяет выделять символы TEXT (I) и TEXT (J), предназначенные для сравнения. Од- нако операции отношения, в том числе .EQ. и .NE., не применимы к логическим значениям. Действительно, сравнение логических ве- личин с помощью подходящего логического выражения, например X. AND. Y. OR. NOT. X. AND. NOT. Y выполняется только для одного бита, тогда как наша задача — сравнить значение всех восьми битов, представляющих код символа, храня- щегося в логической переменной. С этой целью коды литер присваива- ются переменным L1 и L2 типа LOGICAL * 4. (NI) 11 |/0 ,00 ,00 , Ч-Код 1'г0 самВш (N2) L2 \00,00 ,0Ъ , Ч--Kodj-го симбма В соответствии с эквивалентностью имен значения N1 и N2 интер- претируются как целые числа и в итоге сравнение литер сводится к сравнению целых чисел. Заметим, что оператор К = L/2 присваивает переменной К значение, равное целой части от деления L на 2; таким образом, если проверяемое слово состоит из нечетного числа цифр, проверке на совпадение подвергаются лишь буквы, расположенные симметрично от середины слова. Задание. 1. Можно ли в одной выполняемой программе обозначить одним и тем же идентификатором две разные внешние функции? 190
2. Можно ли обозначить внешнюю функцию одним из имен, закреп- ленных за одной из встроенных функций? основных внешних? внут- ренних? 3. Выполнение какого оператора определяет момент завершения процедуры? 4. Обозначим буквами а, р, у, 6 внешние функции, а символом -> будем указывать обращение внещней функции к другой внешней функции. Допустимы ли следующие цепочки обращений? а) а->~Р->у->р->6 I 6->р б) а р —у I 6 + Р в) а р -> а I Р->у 5. Внешняя функция F имеет в качестве своих формальных пара- метров X, Y, Z. Что можно сказать об этих параметрах, если в теле этой функции встречаются конструкции Y (Z + 1.2), X (1, 2, Z, 4)? Порция 69 Правила использования внешних функций В заключение приведем правила, которых следует придерживаться при написании внешних функций. 1. Имя внешней функции должно быть использовано в ее заголов- ке; употребление этого имени в других объявлениях тела этой функции недопустимо (в ФОРТРАН/EC оно еще может быть использовано в объявлении типа или IMPLICIT). 2. Имя внешней функции должно определяться в ее теле (например, посредством его использования в левой части операторов присваива- ния). Например: FUNCTION Y (X) IF (X — 2.5) 4&, 4&t За 49 Y = .5* X + .95*SIN (X + 1.1) RETURN за y = .7 * х + .53ai * cos (X) RETURN END 3. Каждая внешняя функция должна иметь по меньшей мере один формальный параметр. Заголовок внешней функции вида FUNCTION А без формальных параметров недопустим. 191
4. Никакой из формальных параметров внешней функции не может появиться в объявлениях EQUIVALENCE, COMMON, DATA. 5. Внешняя функция может обращаться к другим функциям и под- программам, но не может обращаться сама к себе ни непосредственно, ни посредством других программных модулей; в частности, две про- цедуры не могут взаимно обращаться друг к другу. 6. Тип функции должен определяться ее заголовком (явно или неяв- но). В ФОРТРАН/ЕС тип функции может определяться в ее теле объяв- лением типа или IMPLICIT. Вместе с тем, тип внешней функции дол- жен быть также определен (явно или неявно) во всех вызывающих ее модулях. 7. Если фактический параметр функции является именем внешней функции (или подпрограммы), то соответствующий ему формальный параметр должен употребляться в теле процедуры также в качестве имени внешней функции или подпрограммы. 8. Если фактический параметр соответствует формальному, ко- торый определяется (или переопределяется) в теле процедуры-функ- ции, то он в этом случае может быть только переменной, переменной с индексами или идентификатором массива. 9. Если формальный параметр внешней функции является иденти- фикатором массива, то соответствующий ему фактический параметр должен быть идентификатором массива или элементом массива. 10. Если формальным параметром является идентификатор внешней процедуры, то в вызывающем программном модуле соответствующий ему фактический параметр должен быть указан в списке объявления EXTERNAL. 11. Допускается в теле функции определение или переопределение некоторых формальных параметров или переменных из общих облас- тей, а также вывод во внешнюю среду значений переменных и массивов. 12. В теле процедуры-функции не может быть более одного объяв- ления FUNCTION (этим объявлением является ее заголовок), более одной заключительной строки (она является последней в записи про- цедуры), в нем обязательно использование по меньшей мере одного оператора RETURN (такой оператор завершает выполнение процеду- ры вычисления внешней функции); в теле процедуры не допускается использование объявлений SUBROUTINE, BLOCK DATA. Задание. I. С помощью внешней функции предполагается произ- вести сравнение значений трех переменных X, Y, Z. В случае X = — Y в основную программу должно быть возвращено значение 3. Если X Y и X = Z, то должно быть возвращено значение 4. Если же X у= Y и X у= Z, то возвращается значение 6. Для выполнения указанных операций составьте описание соответствующей процедуры FUNCTION. 2. Напишите описание внешней функции для нахождения наимень- шего элемента в одномерном массиве вещественного типа, состоящем не более чем из 1000 элементов. Дайте функции наименование SMALL. 192
SMALL должна иметь два формальных параметра: наименование мас- сива и переменную целого типа, обозначающую количество элементов в массиве. 3. Опишите процедуру-функцию S1, определяющую возможность построения треугольника по трем его сторонам а. Ь, с и вычисляющую площадь S, как значение переменной из общего непомеченного блока, в случае утвердительного ответа. Порция 70 Пример использования внешних функций Для решения систем линейных алгебраических уравнений приме- нимы некоторые усовершенствованные методы, если матрица А = = \ац{} i, j = 1, 2, ..., /i, составленная из коэффициентов этих уравнений, является симметричной. В связи с этим представляется целесообразным иметь в наборе процедур внешнюю логическую функ- цию, назовем ее идентификатором SIM, имеющую в качестве формаль- ных параметров идентификатор вещественной квадратной матрицы (массива) А и ее размер N. В качестве своего значения функция SIM выдает .TRUE., если матрица А симметрична, и .FALSE, в противном случае. Описание такой функции может быть представлено в виде: LOGICAL FUNCTION SIM (A, N) DIMENSION A (N, N) N1 = N — 1 DO 2 I = 1, N1 11 = 1 + 1 DO 2 J = II, N IF (A (I, J) - A (J, I)) 3, 2, 3 2 CONTINUE SIM = .TRUE. RETURN 3 SIM = .FALSE. RETURN END Задание, 1. Является ли обязательным в приведенном примере включение второго параметра в список формальных параметров? 2. Обязательно ли включение в тело описанной функции объявле- ния DIMENSION? 3. Замените в процедуре SIM арифметический оператор IF логиче- ским оператором IF. 7 9-2712 193
4. Опишите процедуры-функции для вычисления: п / п \ п/п . п/п ' a) ps = П I У а(/); б) sp = X I П си, ; в) р$1 = П I £ az/ Z=1 \/=1 / t = l \/=1 / /=1 п / п \ Г) Spl = П Л// • /=1 \/ = 1 / Порция 71 Подпрограммы Допустимые языком ФОРТРАН подпрограммы всегда оформляются в виде независимых («внешних») по отношению к головной програм- ме и друг к другу программных модулей, которые могут транслиро- ваться раздельно и использоваться другими программами. Заголовком каждой подпрограммы на ФОРТРАНе должно быть объявление SUBROUTINE, общий формат которого имеет вид: SUBROUTINE $ (а) или SUBROUTINE s Здесь s — имя подпрограммы, a — список ее формальных параметров. В отличие от функций, где список формальных (а следовательно, и фактических) параметров всегда должен содержать хотя бы один параметр, в языке допускаются подпрограммы без параметров. В этом случае связь вырабатываемых значений и передача их в вызывающий программный модуль может быть осуществлена посредством исполь- зования переменных из общих блоков (посредством объявления COMMON). Второй из приведенных форматов объявления SUBROUTINE ис- пользуется в том случае, если подпрограмма не имеет параметров. Что касается остальных предложений тела подпрограммы, то ими могут быть любые предложения, которые допускаются при записи внешних функций; в конце записи подпрограммы также должна быть проставлена заключительная строка END. Как и в записи внешних функций, в теле каждой подпрограммы необходим хотя бы один опе- ратор RETURN. Пример. Предположим, что необходимо находить номер первого равного нулю элемента одномерного массива (число элементов в мас- сиве равно 200). В этом случае можно написать подпрограмму, парамет- рами которой будут имя массива и индекс искомого элемента в нем: SUBROUTINE ZERO (АМАС, К) DIMENSION АМАС (2##) 194
do in - i,2-&e if (amac (L)) ш, 2a, 1a 2a к = l RETURN ia CONTINUE к = a RETURN END Если нуль в массиве не встретится, то переменной К присваивается значение 0, в противном случае — значение индекса первого элемента, равного нулю. Обращение к подпрограмме может иметь вид: CALL ZERO (В2, I) 4 А Рассмотрим некоторую подпрограмму и вызывающий ее програм- мный модуль (которым может быть головная программа, другая под- программа или внешняя функция). Для установления связи между этими двумя программными моду- лями идентификатор вызываемой подпрограммы должен быть указан в каждой из них. В вызываемой подпрограмме он должен быть упо- треблен единственный раз — в ее заголовке. Иное использование данно- го идентификатора в этом программном модуле (в том числе для обо- значения каких-либо других объектов) языком запрещено. В вызываю- щем модуле использование идентификатора вызываемой подпрограммы является обязательным, и оно возможно только в операторах вызова подпрограмм — операторах CALL и в объявлениях EXTERNAL (см. порцию 83). В операторах CALL указываются фактические параметры, исполь- зуемые при выполнении вызываемой подпрограммы. В отличие от функций, которые обычно предназначены для опре- деления одного значения — значения функции, подпрограммы, как правило, предназначаются для определения нескольких значений (а также массивов). В связи с этим никакое из определяемых в под- программе значений не связывается с идентификатором подпрограммы; как было указано, идентификатор подпрограммы используется лишь для связи с вызываемыми модулями, чем и объясняется запрет его использования в каких-либо других предложениях в теле этой про- цедуры. Таким образом, в теле данной подпрограммы ее идентификатор не связывается с типом данного, не может быть специфицирован, и первая буква не играет никакой роли в выборе идентификатора под- программы. Задание. 1. Использование каких предложений запрещено в теле подпрограммы между заголовком и заключительной строкой? 2. Каковы различия в использовании идентификаторов подпро- грамм и функций, в частности, внешних? 7* 195
Порция 72 Идентификатор подпрограммы Если подпрограмма построена с учетом взаимодействия формаль- ных и фактических параметров, то в заголовке SUBROUTINE за идентификатором подпрограммы следуют скобки, в которых указыва- ются ее формальные параметры, а в вызывающей процедуре в опера- торе CALL за этим идентификатором в скобках записываются фак- тические параметры. Помимо этих двух употреблений идентификаторов подпрограмм (а также внешних функций) допустимо еще одно — в объявлениях EXTERNAL. Указание идентификаторов внешних процедур в теле некоторого программного модуля в объявлении EXTERNAL необхо- димо в том случае, когда эти идентификаторы в теле данной процеду- ры встречаются в качестве фактических параметров в обращениях к другим процедурам, иначе говоря, если в данном модуле имеются косвенные (через другие процедуры) обращения к этим процедурам. Поскольку язык запрещает рекурсивные процедуры, очевидно, идентификатор процедуры не может быть указан в объявлении EXTERNAL, содержащемся в ее же теле. Заметим, что в одном и том же модуле могут быть как непосредст- венные, так и косвенные обращения к одной и той же процедуре. И в этом случае идентификаторы этих процедур должны быть указаны в объявлении EXTERNAL в данном модуле. Если в программном модуле имеет место лишь косвенное обраще- ние к некоторой внешней процедуре, т. е. идентификатор процедуры в операторах встречается только в качестве фактического параметра, то в таком случае информации, содержащейся в данном модуле, не- достаточно для определения вида этого идентификатора внешней про- цедуры. Принадлежность его к идентификаторам внешних функций или подпрограмм может быть определена лишь при рассмотрении ее тела или других программных модулей (обращающихся непосредст- венно к данной процедуре). В этом случае говорят, что идентификатор в данном программном модуле относится к идентификаторам «внешних процедур, которые не могут в данном программном модуле быть клас- сифицированы как внешние функции или как подпрограммы». Рассмотрим вопрос о том, могут ли идентификаторы подпрограмм быть использованы для обозначения каких-либо других объектов в программе и в каком случае? Такое использование не допускается языком в модулях, вызываю- щих данную процедуру, а также в теле самой этой подпрограммы (исключение составляет допускаемое их использование в качестве наименований общих блоков). Что касается всех других модулей, то в них допускается использование идентификаторов подпрограмм для обозначения каких-либо других объектов: простых переменных. 196
массивов, внутренних функций, формальных параметров, названий общих блоков, но не внешних функций и подпрограмм, так как выпол- няемая программа не должна содержать двух внешних функций или подпрограмм, имеющих одинаковые идентификаторы. Примеры. 1. Рассмотрим подпрограмму, определяющую возмож- ность построения треугольника из трех заданных отрезков. Если тре- угольник можно построить, то вычисляется его периметр Р и площадь S. В противном случае выдается на печать строка: ТРЕУГОЛЬНИК ПОСТРОИТЬ НЕЛЬЗЯ. SUBROUTINE HERON (А, В, С, S, Р) IF (А + В .LE. С. OR. А — В. GT. С) GO ТО 15 Р = А + В + С Р1 = Р/2.-0 S = SQRT (Pl * (Pl — А) * (Pl — В) * (Pl — С)) RETURN 15 WRITE (6, 20) 23 FORMAT (5X, 28H ТРЕУГОЛЬНИК^ПОСТРОИТЬ^НЕЛЬ- * ЗЯ) RETURN END 2. Ниже приведена подпрограмма, вычисляющая полином Чебы- шева для заданных х и п по рекуррентной формуле: Тй (х) = 1; 7\ (х) = х; T„+2 (х) = 2х • Тп+\ (х) — Тп (х). SUBROUTINE СНЕВ (X, N, Т) IF (N. EQ. 0) Т = 1. IF (N. EQ. 1) Т = X IF (N. GT. 1) GO TO 23 RETURN 23 ТВ = 1. T1 = X DO 25 К = 2, N т = 2.* x ♦ ti — те те = Ti Tl = т 25 CONTINUE RETURN END Задание. 1. В каких модулях используются идентификаторы про- цедур (внешних функций и подпрограмм), в каких операторах? 2. Наличие какого объявления в программном модуле обязательно в связи с косвенным обращением в ней к некоторым процедурам? 3. Идентификаторы каких объектов должны быть включены в спи- сок идентификаторов объявления EXTERNAL? 4. О чем говорит наличие объявления EXTERNAL в программном модуле? 5. Одномерный массив Е1 содержит сто элементов. Напишите 197
подпрограмму нахождения среднего арифметического всех значений элементов массива. Полученное значение присвоить переменной А2. 6. Напишите процедуру типа SUBROUTINE для инверсии одно- мерного массива; иначе говоря, требуется поместить первый элемент исходного массива на последнее место результирующего массива, втсрэй элемент исходного массива — на предпоследнее место резуль- тирующего массива и т. д. Массивы могут содержать не более 150 элементов. Дайте подпрограмме наименование INV. Подпрограмма INV долж- на иметь три формальных параметра: X — идентификатор исходного массива, Y — идентификатор результирующего массива и К — иден- тификатор целой переменной, определяющей длину массивов. 7. Опишите подпрограмму с формальными параметрами A, N, S, К, L, реализующую алгоритм поиска минимального элемента S и его индексов К и L того столбца квадратной матрицы А, для которого сумма абсолютных величин элементов максимальна (если таких столб- цов несколько, взять первый из них; если минимальных элементов в столбце несколько, взять последний из них); N — порядок матрицы. Порция 73 Вызов подпрограмм. Оператор CALL Вызов подпрограмм осуществляется посредством специального опе- ратора CALL который имеет формат: CALL s (с) или CALL s, где s — идентификатор подпрограммы, с — список фактических пара- метров. Напоминаем, что список фактических параметров, заклю- ченных в скобки и разделенных между собой запятыми, в операторе CALL должен быть согласован в числе элементов, порядке их следова- ния и типе со списком формальных параметров, указанным в заголов- ке соответствующей подпрограммы. Что касается согласования параметров по их типу, то из общего правила имеется исключение. Оно касается использования текстовых констант в качестве фактических параметров модулей-подпрограмм, которое допускается языком. Фактическими параметрами в операторах обращения к подпро- граммам (операторах CALL) могут быть: 1) идентификаторы массивов; 2) выражения; 3) идентификаторы внешних процедур; 4) текстовые константы. 198
После вызова подпрограммы посредством оператора CALL управ- ление передается первому оператору подпрограммы. При этом фор- мальные параметры в вызываемой подпрограмме примут значения фак- тических параметров или будут заменены фактическими параметрами, указанными в операторе CALL, в соответствии с правилами, изло- женными в порции 69. Далее подпрограмма будет выполняться, как и любой программный модуль вплоть до выполнения оператора RETURN, посредством которого управление вновь будет передано в вызывающую программу оператору, следующему за оператором CALL, вызывавшим эту подпрограмму. Задание. 1. Одномерный массив А содержит не более 50 элемен- тов. Напишите подпрограмму SUBROUTINE, с помощью которой мож- но было бы подсчитать среднее арифметическое первых N элементов массива A (N 50), а также количество К тех элементов, которые ока- зались равными нулю среди N элементов. Назовите эту подпрограмму СР. Используйте в качестве формальных параметров идентификаторы А и К для идентификатора исходного массива и числа его элементов, равных нулю. 2. Затем составьте фрагмент программы, вызывающей эту под- программу и использующий ее для нахождения квадрата среднего ариф- метического первых 40 элементов массива В, причем значению квад- рата среднего арифметического присвойте идентификатор VCP, а ко- личеству нулевых элементов — KN. Порция 74 Результаты выполнения подпрограммы Как было описано в порции 67, результат выполнения внешней функции присваивается ее идентификатору и посредством указателя функции передается в вызывающий оператор (в точку вызова этой функции). В отличие от функций с идентификатором подпрограммы не связывается никакое значение. Каким же образом передаются ре- зультаты выполнения подпрограмм в точку их вызова? Вырабатываемые подпрограммами значения могут быть использо- ваны тремя способами: 1. Они могут быть переданы в другие программные модули факти- ческими параметрами посредством формальных, вызываемых по на- именованию. 2. Эти значения могут быть переданы в другие модули посредством идентификаторов простых переменных или массивов, определенных в данном модуле в объявлении COMMON. 3. Результаты, получаемые в подпрограмме, могут быть выданы во внешнюю среду (например, на печать) посредством выполняемых в них соответствующих операторов вывода, для 'чего могут быть 199
Посылка и бозбрат значений переменных через общий блок Рис. 31
использованы любые переменные или массивы, значения которых опре- делены внутри этих подпрограмм. Очевидно, что в случае подпрограмм без параметров единственной возможностью передачи результатов из вызываемой подпрограммы в вызывающую является использование объявлений COMMON (т. е. использование идентификаторов, именующих элементы из общих бло- ков данных). На рис. 31 схематически изображены способы передачи резуль- татов выполнения вызываемой подпрограммы в точку ее вызова. На рисунке показан обмен значениями между головным модулем и тремя подпрограммами (Al, А2, АЗ). Причем значения, выработанные в подпрограмме А1, могут быть возвращены в головной модуль только через фактические параметры посредством формальных, вызываемых по наименованию. Значения из подпрограммы А2 могут быть переданы как через параметры, так и через идентификаторы переменных, опре- деленных в общем блоке (BL). Поскольку подпрограмма АЗ не имеет параметров, то результаты ее работы можно передать в вызывающий модуль только через переменные из общего блока (ВК). В порции 77 мы ответим на вопрос о том, является ли аппарат формальных-фактических параметров и объявлений COMMON взаи- мозаменяемым, а также рассмотрим особенности каждого из них. Задание. 1. Какими средствами могут быть переданы исходные данные в подпрограмму? 2. Каким образом могут быть использованы результаты выполне- ния подпрограмм? 3. Может ли подпрограмма без параметров выдавать в разные мо- менты обращения к ней различные результаты? 4. Как могут быть использованы результаты выполнения проце- дур без параметров? Порция 75 Некоторые ограничения на формальные параметры внешних функций и подпрограмм Как это было показано ранее, существует три способа установления связей между идентификаторами, используемыми в программе: 1. Связь фактических с формальными параметрами. 2. Связь идентификаторов посредством объявлений EQUIVA- LENCE. 3. Связь идентификаторов посредством использования общих бло- ков памяти (устанавливаемая с помощью объявления COMMON). Наличие последних двух видов связи является причиной установ- ления некоторых дополнительных ограничений 'на формальные 201
параметры процедур и возможности использования формальных пара- метров в объявлениях DATA. А именно: формальные параметры данной процедуры не могут быть включены в ней в списки объявлений EQUI- VALENCE, COMMON и DATA. Для разъяснения этого ограничения вспомним, что среди фор- мальных параметров следует выделять параметры, вызываемые зна- чением и вызываемые по наименованию. Если формальный параметр вызывается значением, то, как это ясно из предыдущего, начальное значение этого идентификатора опре- деляется текущим значением соответствующего фактического пара- метра. Таким образом, определение значения формального параметра посредством трех указанных объявлений противоречило бы самой идее использования аппарата формальных-фактических параметров. Если формальный параметр является параметром, вызываемым по наименованию, то, как было указано ранее, значения этих парамет- ров, определяемые в теле данной процедуры, пересылаются в поля па- мяти, отводимые соответствующим фактическим параметрам, в свя- зи с чем, очевидно, нет смысла говорить об эквивалентности их зна- чений, как значений их полей, определяемых объявлениями EQUI- VALENCE или COMMON, так же, как нет смысла говорить о началь- ных значениях этих идентификаторов, так как в качестве последних (если в этом появляется необходимость) должны быть взяты значения из полей памяти, отведенных соответствующим фактическим пара- метрам. Задание. Какие ограничения накладываются на использование формальных параметров? Порция 76 Интерпретация в ФОРТРАН/ЕС объектов, заданных формальными параметрами В момент трансляции модуля выделяется память всем объявлен ным в нем объектам, за исключением формальных параметров. Этим и объясняется запрет использования имен формальных параметров в объявлении EQUIVALENCE. Поэтому, когда в теле процедуры воз- никает необходимость в различных интерпретациях объекта, задан- ного формальным параметром, необходимо записать оператор присва- ивания, снимающий копию с этого формального параметра, которому будет выделена память, допускающая различные интерпретации. Для иллюстрации подобного обстоятельства рассмотрим пример. Пример. Печать в двоичном коде. SUBROUTINE BINARY (WORD) INTEGER WORD, STRING, LOC (8) LOGICAL * 1 X (4), Y (4) INTEGER HEX (16)/WW, W#!', 'Ы11', 202
♦ 'гиг, * '!&&&', 'i&&r, чгш', чги', * 'игг', 'liar, чиг', чпг/ EQUIVALENCE (STRING, X), (NUM, Y) DATA NUM/г/, LIST/3/ STRING = WORD J = 1 DO 5 I = 1, 4 Y (4) = X (I) LOC (J) = NUM/16 + 1 LOC (J + 1) = MOD (NUM, 16) + 1 5 J = J + 2 WRITE (LIST, 1) (HEX (LOC (I)), 1 = 1,8) 1 FORMAT (IX, 8A4) RETURN END Подпрограмма BINARY осуществляет печать слова, заданного параметром WORD, в двоичном коде, т. е. в виде строки из 32 двоичных цифр. В массиве HEX задана таблица четырехразрядных двоичных кодов (представленных текстовыми константами), соответствующих шестнадцатеричным цифрам. Алгоритм основан на просмотре всех восьми шестнадцатеричных цифр исходного слова и формировании последовательности индексов, определяющих порядок печати соответствующих элементов массива HEX. Таким образом, индекс элемента массива HEX определяется значением шестнадцатеричной цифры, выделяемой в исходном слове. Вначале выделяется старший байт слова. Обращение к байту осущест- вляется с помощью объявления LOGICAL * 1 X (4), Y (4): STRINC ( Х(1) Х(2) J Х(3) J Х(4) □ 1 1 && 1 е& t 1-1 1 NUM Y(l) Y(2) Y(3) Y(4) Y(4)« Х(1) Выделенный байт рассматривается (при помощи эквивалентных имен) как целое число NUM. Тогда NUM/16 дает значение первой шест- надцатеричной цифры этого байта, a MOD (NUM, 16) — второй цифры, так как деление на 16 (24) равносильно сдвигу вправо на 1 шестнад- цатеричный разряд (четыре двоичных). Увеличенные на 1, эти зна- чения представляют индексы таблицы HEX. Аналогичные операции выполняются для каждого байта исход- ного слова. В результате формируется последовательность из восьми индексов. Выдавая на печать запись, состоящую из элементов HEX с этими индексами (не разделяя их пробелами), получим искомое дво- ичное представление исходного слова. 203
Пусть необходимо отпечатать в двоичном коде внутреннее пред- ставление вещественного числа 67345.'&. Для этого достаточно запи- сать оператор CALL BYNARY (67345.) Шестнадцатеричный код внутреннего представления этого числа имеет вид: 45 1Ф711-0 Поэтому значением массива LOC будет следующая последователь- ность индексов: 5, 6, 2, 1, 8, 2, 2, 1 Циклический список, приведенный к линейному, будет иметь вид: HEX (5), HEX (6), HEX (2), HEX (1), HEX (8), HEX (2), HEX (2), HEX (1). В результате будет отпечатана строка: 010101 QQ&l QQQQ 0111 Ж1 0001 QQQQ Порция 77 Формальные параметры и элементы общих блоков Сопоставим возможности, предоставляемые аппаратом формальных- фактических параметров и использованием переменных из общего блока. 1. Допустим, что в некотором программном модуле, назовем его А, имеется два обращения к подпрограмме, назовем ее В. При этом в качестве результатов подпрограмма В вырабатывает значения не- которого массива. Здесь возможны две различные ситуации: резуль- таты, вырабатываемые при каждом из обращений, используются по- следовательно, т. е. выработанные при первом обращении результаты используются некоторым образом и к моменту второго обращения к подпрограмме они уже не нужны. Другими словами, результаты, получаемые из подпрограммы,— массивы данных, могут быть разме- щены в одни и те же поля памяти, чем достигается определенная эко- номия памяти. В этом случае передача получаемых результатов из подпрограммы может быть реализована посредством использования элементов общего блока памяти, т. е. заданием в вызывающей и вызываемой процедурах объявлений COMMON, в каждом из которых среди элементов списков на одних и тех же позициях указываются, например, имена первых элементов общего поля памяти, отводимой для вырабатываемого про- цедурой массива данных. Тот же эффект будет достигнут и при вклю- чении в список формальных параметров параметра, идентифицирую- щего вырабатываемый массив: при этом для размещения этого мас- сива-результата в одно и то же поле памяти потребуется в качестве соответствующего фактического параметра в каждом из названных двух обращений указать один и тот же идентификатор. Однако возможна и другая ситуация, при которой выработанный в результате первого обращения к подпрограмме массив впослед- ствии используется и должен быть сохранен после второго обращения к той же подпрограмме. Например, после второго обращения полу- ченные в указанных массивах матрицы должны быть перемножены. Здесь для каждой из матриц должно быть выделено свое поле памяти. 204
Таблица 23 Таблица основных характеристик функций и подпрограмм Тип процедуры Формирование Трансляция Объединение с вызывающим модулем Использование другими модулями Встроенная функция Обеспечивается реализацией Хранятся в виде рабочих программ Встраивается при трансля- ции в каждой точке обра- щения Может использоваться любым программным модулем Внутренняя функция Формируется программистом Совместно с вы- зывающим мо- дулем Встраивается при трансля- ции в одном экземпляре в тело вызывающего модуля Может использоваться только в том модуле, в котором определена Основная внешняя функция Обеспечивается реализацией Хранятся в виде рабочих программ Присоединяются после трансляции с помощью программы-загрузчика Может использоваться любым модулем Внешняя функция типа FUNCTION и подпрограмма типа SUBROUTINE Формируется программистом Т ранслируется независимо Присоединяются после трансляции с помощью программы-загрузчика Могут использоваться любым модулем
ьэ (аблица формирования и использования процедур Таблица 24 Тип процедуры Имя Параметры Способ определения Способ обращения Количество опреде- ляемых значений Встроенная функция Определено языком Фиксированное количество оп- ределенного типа Предусмотрен в транс- ляторе Запись идентификатора с заключенными в скоб- ки фактическими пара- метрами Одно, соответст- вующее иденти- фикатору функции Внутренняя функция 1—6 буквенно- цифровых литер, первой должна быть буква Один или более Тело функции,состоя- щее из одного предло- жения, записывается перед первым операто- ром в вызывающем модуле Основная внешняя функция Определено языком Фиксированное количество Обеспечен реализа- цией Написать идентификатор с заключенными в скоб- ки фактическими пара- метрами там, где необ- ходимо значение функции Одно, соответст- вующее иденти- фикатору функ- ции Внешняя функ- ция типа FUNCTION или подпро- грамма типа SUBROUTINE 1—6 буквенно- цифровых литер, первой должна быть буква. Тип функции должен быть задан яв- но или (для це- лого и вещест- венного типов) неявно Для функций один или более, для подпро- грамм — любое количество (в том числе, рав- ное нулю) Любое количество операторов, вклю- чающих по меньшей мере один оператор RETURN. Внешняя функция — указатель функции там, где необходимо значе- ние функции. Подпрог- рамма — оператор CALL. Любое количест- во, присваиваемое фактическим па- раметрам и пере- менным общего блока. Для функ- ции одно из зна- чений присваива- ется ее иденти- фикатору
Если использовать аппарат, предоставляемый объявлениями COMMON, то в вызывающем модуле в промежутке между первым и вторым обращением к подпрограмме потребуется осуществить пере- сылку первого массива в некоторое другое поле (для чего необходимо в любом случае ввести соответствующий идентификатор). Если же воспользоваться аппаратом формальных-фактических параметров, то в такой пересылке массива никакой необходимости не возникает, достаточно будет в каждом из обращений к подпрограм- ме указать в качестве соответствующих фактических параметров раз- ные идентификаторы. Отсюда следует, что аппарат формальных-факти- ческих параметров является более гибким. Однако реализация аппарата формальных-фактических пара- метров, вообще говоря, является более сложной. В связи с этим, если во всех операторах обращения к некоторой подпрограмме в качестве фактического параметра используется один и тот же массив, следует исключить соответствующий параметр из числа формальных пара- метров и использовать возможности объявления COMMON. Обрати- тесь еще раз к рис. 32, иллюстрирующему различные способы пере- сылки значений — результатов работы вызываемой процедуры. 2. Другой важный способ связи между вызывающим и вызы- ваемым программными модулями, обеспечиваемый аппаратом фор- мальных-фактических параметров, состоит в передаче в качестве фактического параметра имени той внешней процедуры, которая долж- на быть вызвана, в свою очередь, при выполнении вызываемой процедуры. (Как будет разъяснено в порц. 83, в подобных случаях имя указанной процедуры—фактического параметра должно быть включено в список объявления EXTERNAL, задаваемый в вызыва- ющей процедуре). Такого рода связь аппаратом общих блоков реа- лизована быть не может, поскольку посредством списка COMMON могут быть переданы лишь значения переменных или массивов или присвоенные им значения текстовых констант, но не имена процедур. Примеры программ, в которых имена процедур используются в качестве фактических параметров, приведены в порц. 95. 3. В отличие от головного модуля, в котором границы массивов должны быть заданы константами (целого типа), в процедурах они могут быть представлены в виде простых переменных (целого типа). Такие массивы принято называть массивами с регулируемыми раз- мерами. При наличии в процедуре массивов с регулируемыми раз- мерами их имена и переменные, определяющие регулируемые раз- меры, должны быть включены в список формальных параметров. Это еще один случай, когда средства, предоставляемые аппаратом формальных-фактических параметров, не могут быть реализованы средствами аппарата объявлений COMMON (см. также порц. 85). Задание. В каком случае использование аппарата формальных- фактических параметров является необходимым? Когда вместо него можно воспользоваться общим блоком данных? 207
Порция 78 Побочный эффект при вычислении внешних функций Вычисление с помощью указателя внешней процедуры-функции значения, связанного с ее именем, может оказатьсй не единствен- ным результатом обращения к этой функции. В теле процедуры могут быть осуществлены присваивания переменным из общих блоков, а также некоторым параметрам, вызываемым по имени. Такого рода эффекты принято называть побочными в отличие от «главного» эф- фекта, передаваемого через указатель функции в точку вызова. Побочный эффект может быть использован для попутного вычис- ления каких-либо других значений. Однако наличие процедур-функ- ций с побочным эффектом может служить источником сложных и трудноучитываемых взаимосвязей между программными модулями, и поэтому использование таких функций требует особого внимания. Проиллюстрируем влияние побочного эффекта на простом примере. Пример. В приведенной ниже программе на ФОРТРАН/ЕС ис- точником побочного эффекта является наличие в теле процедуры- функции оператора К = К + 4, изменяющего значение ее параметра К (вызываемого в связи с наличием этого оператора присваивания по имени). К = 2 L = К + 1 + М (К) WRITE (3,Ш) L 1-0 FORMAT (14) К = 2 L = М (К) + К + 1 WRITE (3,10) L STOP END INTEGER FUNCTION M (K) К = К + 4 M = К ** 2 RETURN END Результаты 39 43 Результат несколько неожиданный: К - 1 + М (К) ф М (К) + К 4- 1 Задание. Устраните побочный эффект функции М (К), исполь- зованной в приведенном выше примере. 208
Порция 79 Передача меток через параметры в ФОРТРАН/ЕС Оператор RETURN i Переменные типа метка являются особым видом данных в языке ФОРТРАН, значением которых являются метки операторов. Значе- ние метки можно хранить только в переменных типа INTEGER; при- сваивание этого значения осуществляется оператором ASSIGN. На- помним, что переменная целого типа, которой присвоено значение метки, используется только в операторе GO ТО по предписанию и не может использоваться в другом контексте до тех пор, пока ей не будет присвоено числовое значение. Никаких других операций над метками, кроме присвоения метки переменной, в стандарте ФОРТРАНа не предусмотрено. В некоторых языках программирования метки могут быть организованы в масси- вы и введено понятие выражения типа метка. В АЛГОЛ-60, напри- мер, одномерному массиву меток соответствует понятие переключа- теля, г обращение к элементу массива меток осуществляется посред- ством указателя переключателя. Значением указателя является метка. Подобием переключательных списков АЛГОЛа являются списки меток в операторах GO ТО языка ФОРТРАН. В АЛГОЛе метка может быть фактическим параметром операторов процедур или указателей функций. Формальным параметром, соот- ветствующим метке, должна быть переменная, объявленная специ- фикатором label. Посредством параметра-метки можно обеспечить в АЛГОЛе передачу управления из тела вызываемой процедуры во внешний блок в точку, не совпадающую с точкой вызова. Аналогич- ной возможности нет в стандарте ФОРТРАНа, но она имеется в ФОРТРАН/ЕС. Если в ФОРТРАН/ЕС необходимо передать метку в качестве факти- ческого параметра в подпрограмму, то в списке параметров оператора CALL записывается конструкция & ххххх.гдеххххх — мет- ка. В списке фактических параметров может быть любое количество меток, причем подразумевается, что они пронумерованы слева на- право от 1 до К =#= 0, где К — количество меток в списке. Таким об- разом, метки в списке параметров организованы в структуру, подоб- ную одномерному массиву, например: CALL LABEL (А, &13, В, & 23, С, & 33, & 43, & 55) 1 2 3 4 5 Можно сказать, что в этом примере задан массив меток размер- ности 5, причем меткам приписываются индексы без учета параметров другого вида. Формальным параметром, соответствующим фактическому пара- мегру-метке, должен быть символ «*». Это единственный случай, когда 209
формальный параметр не является идентификатором. Таким способом в ФОРТРАН/EC фактически задается спецификация label, исполь- зуемая в АЛГОЛе. Между последовательностью символов * в списке формальных парахметров и последовательностью меток в списке фак- тических параметров должно быть установлено взаимно однозначное соответствие. Значение фактического параметра-метки должно быть определено; иначе говоря, метки, передаваемые через параметр, должны быть явно указаны в вызывающем программном модуле в операторе CALL. Например: .................. SUBROUTINE Q (А, *,*,*, В) CALL Q (R,&21,&12,&3,RES) ............ з: Фактические параметры-метки указывают возможные точки воз- врата в вызывающий модуль, отличные от стандартной точки, опре- деляемой правилами использования оператора RETURN. Поэтому важно, чтобы в подпрограмму передавалась метка оператора, а не метка объявления FORMAT (употребление которой в данном случае вызовет программное прерывание). Возврат в особую точку, определенную меткой, осуществляется в ФОРТРАН/EC оператором RETURN особой формы: RETURN L где i — целое без знака или простая переменная целого типа, значе- ние которой играет роль порядкового номера метки в списке парамет- ров соответствующего оператора CALL. При выполнении оператора RETURN i управление будет передано оператору вызывающей программы с меткой, номер которой в списке фактических параметров-меток равен значению L Пример. Программу на ФОРТРАН-стандарте, имеющую следую- щую структуру Головной модуль Подпрограмма ...................... SUBROUTINE SUBR (X, Y, I) CALL SUBR (X, Y, I) IF (X) И, 22, 33 GO ТО (Ш, 4, 33), I 11 Y = X + SQRT (Y) ..............................................1 = 1 ..............................................RETURN 33 ... ................... 210
le...................... 22..................... ................... 1 = 2 4 ........................ RETURN END 33........................ I = 3 RETURN END используя параметры-метки, можно написать на языке ФОРТРАН/ЕС в более компактном виде: Головной модуль CALL SUBR (X, Y, & 10, *&4, &33) 33 ’ ’ ’ ’ ’ ’ 4 ............. END................ Подпрограмма SUBROUTINE SUBR (X, * Y * * *) IF (X) 11, 22, 33 11 Y - X + SQRT (Y) RETURN 1 22 RETURN * 2 33 RETURN 3......... END Оператор RETURN i может быть использован только в подпро- граммах. Действительно, вычисление функции состоит в определении ее указателя (и, быть может, в создании некоторого побочного эф- фекта), а не в передаче управления. Задание. 1. Можно ли передать метку в качестве фактического параметра через несколько уровней вызова подпрограмм? 2. Допустимо ли следующее обращение к процедуре Р? ASSIGN 5 ТО К CALL Р (К, R) если заголовок Р имеет вид: SUBROUTINE Р(*, А) 3. Может ли в операторе RETURN i использоваться индексиро- ванная переменная? Выражение, содержащее знаки операций? 4. Проверьте, какова будет реакция системы, если в RETURN i i t IR К]. где К — количество «*» в списке формальных параметров. 5. Если в списке формальных параметров нет «*», допускается ли в подпрограмме оператор RETURN i? 211
6. Допускается ли запись 1 CALL S (&1, X, Y)? Всегда ли она при- водит к зацикливанию? 7. Напишите на стандарте ФОРТРАНа эквивалент подпрограммы SWITCH и обращения к ней: SUBROUTINE SWITCH (I, *, *, *, *) RETURN I END CALL SWITCH (I, &1, &2£, &3£, &4QQ) Порция 80 Выполнение подпрограмм в неявном цикле (ФОРТРАН/ЕС) Пусть с помощью подпрограммы с именем OUTPUT требуется отпечатать N раз некоторый текст (например, бланк). Один из спосо- бов организации циклического выполнения подпрограмм в ФОРТРАН/ ЕС состоит в использовании меток в качестве фактических парамет- ров и оператора RETURN L Подпрограмма OUTPUT и обращение к ней для печати 20 копий текста при такой организации цикла могут быть представлены в виде: N = SUBROUTINE OUTPUT (К, *) 1 CALL OUTPUT (N, &1) К = К — 1 ....................... IF (К. EQ.£) RETURN END (операторы, обеспечивающие печать) RETURN 1 END Как видно из примера, при использовании такого «неявного» цикла изменение его параметра (К = К — 1) осуществляется в вызы- ваемом модуле. В вызывающем модуле нужно задать количество выполнений цикла (фактический параметр N) и метку (фактический па- раметр &1), которой помечен оператор вызова данной подпрограммы OUTPUT. Замечание. Обращаем Ваше внимание, что фактический пара- метр N в подобном случае не может быть задан в виде константы (2в), так как соответствующий формальный параметр переопределяется и константа будет искажена. Задание. Объясните особенности рассмотренного выше цикла: 1. Укажите, как реализован счетчик количества выполнений мо- дуля OUTPUT. 2. Укажите точки входа в цикл и выхода из цикла; условие вы- хода. 3. Как организованы повторные входы в процедуру? Можно ли назвать подобное обращение рекурсивным? 212
Порция 81 Источники неопределенности при вызове параметров в ФОРТРАН/ЕС Стандарт языка запрещает связывание формальных параметров процедур, вызываемых по имени (т. е. определяемых или переопреде- ляемых в теле процедуры), между собою или с объектами общих бло- ков. Однако, поскольку реализацией языка ФОРТРАН/ЕС подобное связывание не контролируется, последнее может служить источником неопределенностей. Проанализируем подобные случаи связывания формальных пара- метров в ФОРТРАН/ЕС через фактические параметры. Рассмотрение случаев связывания через объекты общих блоков можно провести аналогично. 1. Пусть обращением CALL PGM(X, Y, X) к подпрограмме с заголовком SUBROUTINE PGM (А, В, С) А и С связываются между собой фактическим параметром X (т. е. один и тот же фактический параметр ставится в соответствие нескольким формальным) и в теле PGM имеются операторы, присваивающие зна- чения обоим параметрам А и С (т. е. А и С вызываются по имени-ре- зультату). Пусть, в конечном счете, им присвоены значения А = 5. с = ibb1. Каждому из этих параметров в модуле PGM будет отведена локаль- ная память. В момент выполнения оператора RETURN возникает неопределенность, поскольку нельзя предсказать, значение какой из переменных А или С будет передано переменной X. Рассмотрим следующую структуру вызовов: .................. SUBROUTINE PGM (А, В, С) CALL PGM (X, Y, X) STOP END A = 5. C= IBB. CALL MODULE (A) CALL PROG(C) RETURN 213
SUBROUTINE MODULE (Z) END SUBROUTINE PROG(W) RETURN RETURN END END В подпрограмму MODULE будет в качестве фактического парамет- ра передано значение А (равное 5.), а в PROG — значение С (равное ШФ), так как в PGM имеются два соответствующих локальных зна- чения. Таким образом, если вызов связываемых параметров осуществля- ется по значению-результату, то эта связь проявляется только в момент возврата из данной процедуры. 2. Если, однако, «связанные» формальные параметры вызываются по адресу, т. е. заголовок PGM имеет вид SUBROUTINE PGM (/А/, В, /С/) то связанными оказываются и параметры следующего уровня подпро- грамм, т. е. Z и W. 3. Пусть заголовок некоторой процедуры имеет вид SUBROUTINE QR (/А/, /В/, /С/) и в ее теле имеется последовательность операторов: А = 2. В-3. D-А + В При вызове этой процедуры оператором CALL QR (X, X, Р) установится связь между формальными параметрами А и В и фак- тическим параметром X, в результате которой все эти имена будут обозначать одно и то же поле памяти. Эффект такой связи оказывается весьма неожиданным. Так, в данном случае при выполнении последо- вательности приведенных трех операторов значение^м переменной D будет 6. (а не 5.!). (Напомним, что подобный эффект возникает при установлении эквивалентности имен объявлением EQUIVALENCE). Хотя при возврате из процедуры, последующем после ее вызова, связывающего формальные параметры, результат в этом случае од- нозначен (переменной X будет присвоено то значение, которое было присвоено последним из выполняющихся операторов присваивания любому из эквивалентных имен А или В), однако подобное связывание параметров является источником труднообнаруживаехмых ошибок. 214
4. Рассмотрим случай связывания параметров, один из которых вызывается именем, а второй — значением. Пусть список формальных параметров включает параметры /А/, В и в результате вызова они связываются фактическим параметром Z. Если в теле процедуры имело место присваивание обоим пара- метрам А и В, то, независимо от того, какое из присваиваний было последним, переменная Z при возврате из процедуры получит значе- ние, равное последнему присвоенному параметру В. В то же время, если в теле не выполнялись присваивания переменной В, то, независи- мо от того, что имело место присваивание переменной А, параметр Z сохранит свое исходное значение: это значение при вызове процедуры было присвоено В, а при возврате — из В переслано в Z. Из изложенного следует интересный практический вывод. Если значение какого-либо фактического параметра должно быть сохранено, а соответствующий ему формальный параметр может из- меняться в теле процедуры, то следует в число формальных параметров включить дополнительно параметр, вызываемый по значению-резуль- тату (которому в теле процедуры не будут производиться никакие при- сваивания). В этом случае при обращении к процедуре для сохране- ния значения какого-либо из параметров последний следует связать с дополнительным параметром. Заметим при этом, что посредством од- ного дополнительного параметра можно по мере необходимости со- хранить значение одного (любого) из нескольких фактических пара- метров. Следует заметить, что тот же результат может быть достигнут посредством «запоминания» значения соответствующего фактического параметра перед вызовом процедуры и «восстановления» после воз- врата. Например, последовательность операторов X = Z CALL PQ (Z, U) Z = X даст тот же эффект, что и вызов CALL PQ(Z, U, Z) если в описание процедуры PQ ввести дополнительно третий параметр SUBROUTINE PQ (/А/, В, С) А= . . . . 215
END Как видно из примера, использование дополнительного параметра в подобных ситуациях придает программе более изящную форму. 5. Связывание формального параметра с элементом общего блока аналогично связыванию двух формальных параметров, например, ситуация, определяемая предложениями: COMMON A SUBROUTINE Р(Х) CALL Р (A) COMMON В END X - 5 В= END аналогична рассмотренной в п. 1. Задание. Даны головной модуль и подпрограмма DOUBLE. Какое значение будет напечатано в результате выполнения про- граммы? N = 5 SUBROUTINE DOUBLE (/I/, J) CALL DOUBLE (N, N) I - 10 PRINT 1, N STOP RETURN 1 FORMAT (15) END END Порция 82 Примеры использования подпрограмм Пример 1. Рассмотрим в деталях подпрограмму PROC, считыва- ющую с перфокарт (номер устройства ввода — 1) массив FR, содержа- щий текстовую информацию, и помещающую его в блок А. Затем этот массив печатается в виде 50 строк так, что в первую строку помещают- ся его первые 15 элементов, во вторую — следующие 15 элементов и т. д. В начале каждой строки формируется по девять пробелов. Вывод массива указанным образом осуществляется некоторой подпрограммой Р без параметров, вызываемой подпрограммой PROC» 216
Подпрограмма Комментарии SUBROUTINE PROC COMMON/A/FR (75В) READ (1, 100) FR 100 FORMAT (14A5) В общий блок помещается мас- сив, содержащий 750 элементов. Коэффициент повторения 14 ука- зывает на то, что с каждой оче- редной перфокарты считывает- ся по 14 значений элементов массива FR. CALL P RETURN END Вызов подпрограммы Р, не имею- щей формальных параметров Подпрограмма Р может быть представлена в виде: Подпрограмма Комментарии SUBROUTINE Р COMMON /А/FR Содержащийся в общем блоке А массив именуется тем же иденти- фикатором FR (что делать не обязательно). DIMENSION FROUT * (15,5-0) EQUIVALENCE (FR (1), FROUT (1)) Определяется двумерный массив FROUT. Устанавливается эквивалент- ность двумерного массива FROUT и массива FR (из об- щего блока), что означает, что идентификаторы FROUT и FR именуют один и тот же массив данных. DO 10 I = 1, 50 10 WRITE (3,200) (FROUT * (J, I), J = 1, 15) Вывод текста осуществляется посредством оператора цикла. В операторе WRITE, содержащем- ся в теле оператора DO, ис- пользуется список типа цикл. 200 FORMAT (10X, 15A5) Формат 1ФХ означает печать девяти пробелов в начале каж- дой строки вывода (формиро- вание полей на странице пе- чати). Коэффициент повторения 15 за- дает вывод на каждую строку 75- RETURN END ти символов (среди которых в вы- водимом тексте возможны пробе- лы) В объявлении DIMENSION определен двумерный,массив FROUT, содержащий 50 подмассивов по 15 элементов: I меняется от I до 50; 217
J меняется от 1 до 15. Объявление EQUIVALENCE устанавливает следующее соответствие между элементами массивов FR и FROUT: FR (1) FROUT (1, 1) FR(2) FROUT (2, 1) FR (16) FROUT (1, 2) FR (736) <-> FROUT (1, 5£) FR(75£) ~ FROUT (15, 5£) Порция 83 Объявление EXTERNAL Объявление EXTERNAL определяет в данном модуле те иден- тификаторы внешних процедур (процедур-функций и процедур-под- программ), которые в нем используются в качестве фактических пара- метров. Этот оператор необходим для того, чтобы отличить идентифи- катор процедуры от других имен в списке фактических параметров и обеспечить вызов соответствующей процедуры косвенно, посредством другой процедуры или ряда процедур. Формат объявления EXTERNAL следующий: EXTERNAL v Здесь v — список имен внешних процедур. Появление идентификатора в списке EXTERNAL объявляет, что данный идентификатор является именем внешней процедуры. Все иден- тификаторы внешних процедур, используемые в качестве фактических параметров в данном модуле, должны быть приведены в списке EXTERNAL. Например, появление в некотором модуле объявления: EXTERNAL G, А12, К1£ говорит о том, что идентификаторы G, А12, K1# являются идентифи- каторами внешних процедур и что они могут быть использованы в качестве фактических параметров при обращении к другим процедурам выполняемой программы. В ФОРТРАН/EC, если из контекста следует, что некоторый иденти- фикатор является именем подпрограммы, нет необходимости в допол- нительном объявлении EXTERNAL. Например, если в модуле име- ются операторы CALL X CALL Р(Х) то X обозначает имя подпрограммы независимо от наличия объяв- ления EXTERNAL. 218
Отметим, что язык не допускает использования встроенных функ- ций посредством обращения к ним через формальные параметры. Дру- гими словами, если в списке EXTERNAL приведен идентификатор встроенной функции, то этот идентификатор тем самым объявляется идентификатором внешней процедуры, а не встроенной функции. Это значит, что при обращении к этой функции (т. е. при использовании ее идентификатора в качестве фактического параметра) тело встроенной функции с этим идентификатором не встраивается в рабочую программу, а осуществляется обращение к внешней процедуре с данным идентифи- катором, которая должна быть в этом случае составлена програм- мистом. Разберем примеры, иллюстрирующие ситуации, когда исполь- зование объявления EXTERNAL оказывается необходимым. Предположим, что некоторая выполняемая программа состоит из нескольких модулей, среди которых нам понадобится рассмотреть головной модуль и некоторые процедуры. Головной модуль Процедуры EXTERNAL R, ABS, SIN, COS SUBROUTINE RES (X, Y, Z) ; ‘ ' ’ ' ' ' ’ ' ' ' ’ ’ ’ ’ z = y (X) + i. e........ CALL RES (A, SIN, D) CALL RES (2.7*S, COS, C) RETURN ............................ END CALL XI (ABS, Y, А, В, C) CALL XI (R, Y2, Al, Bl, Cl) END................. SUBROUTINE X1 (А, В, C, D, E) В = A (C, D, E) * 7.3/2.*S RETURN ............ END FUNCTION ABS (А, В, C) RETURN............... END.................. FUNCTION R (Al, Bl, Cl) RETURN............... END 219
Здесь предполагается, что посредством формального параметра Y в подпрограмму RES и параметра А в подпрограмму XI будут переда- ваться фактические параметры, являющиеся идентификаторами некото- .рых внешних функций. Заметим, что все те внешние функции, обраще- ние к которым осуществляется одним и тем же указателем в теле ка- ждой из подпрограмм, должны иметь в своих списках одинаковое число формальных параметров, согласуемых по типам и порядку следования, что следует из правила согласования списков фактических и формаль- ных параметров. Обратите внимание на идентификатор ABS; он яв- ляется идентификатором встроенной функции, но, как отмечалось выше, здесь он будет выполнять функцию идентификатора внешней функции, которая должна быть составлена дополнительно; заголовок этой функции может иметь вид: FUNCTION ABS (А, В, С) При выполнении оператора присваивания Z = Y (X) + 1.0 в подпрограмме RES в результате ее вызова первым из указанных в головной программе операторов CALL будет выполнен оператор D = = SIN (А) + 1.-0 и второго — оператор С = COS (2.7* S) + 1.0. При выполнении оператора В = А (С, D, Е) * 7.3/2.*S в подпрограмме XI при первом обращении к ней выполнится оператор Y = ABS (А, В, С) * 7.3/2. *S, при втором — Y2 = R (Al, Bl, С1) * 7.3/2.*S. Рассмотрим еще пример: Вызывающий модуль Внешние процедуры SUBROUTINE RES1 (А, В, C) CALL RES1 (X, Re (Y), Z) • • • • • • • RETURN END END FUNCTION R£(X) R0 =....... RETURN END В этом примере объявление EXTERNAL в вызывающем модуле не нужно, так как фактическим параметром в операторе CALL яв- ляется не идентификатор внешней процедуры, а указатель функции, т. е. при обращении к подпрограмме RES1 в качестве второго факти- 220
ческого параметра будет передан результат выполнения внешней функции с фактическим параметром Y. Задание. 1. В каком случае в программном модуле необходимо объяв- ление EXTERNAL? 2. Может ли в программном модуле в списке объявления EXTERNAL быть указанным его идентификатор? 3. О чем свидетельствует наличие идентификатора встроенной функции в списке EXTERNAL? Что в этом случае означает наличие указателя этой встроенной функции в правой части оператора при- своения в данном модуле? Порция 84 Косвенное обращение Проиллюстрируем на примерах использование объявления EXTERNAL. Пример 1. Пусть в некотором модуле требуется вычислить значение следующего выражения: п 2 п4 пв пд _________ ____________ \ 4~ S cos 2i 4~ S *3 4~ %c + Ус 4" ^^50 4- Уьо 4~ i=/7( С=*пл i=ns C=n, 4" ^ioo 4- f/100 Здесь пределы суммирования в общем случае различны и заданы пе- ременными целого типа. Обратив внимание на то, что первые четыре слагаемых, являющие- ся суммами, могут быть вычислены посредством надлежаще заданного циклического процесса, мы вместе с тем замечаем, что их общие члены различны. Для вычисления общих членов заданных сумм определим внешние процедуры-функции, которые обозначим соответственно идентифика- торами Pl, Р2, РЗ, Р4. Поскольку во всех указанных суммах общие члены являются функциями одного параметра, переменной целого типа I, определим их как процедуры-функции с одним параметром це- лого тцпа (сохранив за ним идентификатор I). Кроме того, определим внешнюю процедуру-функцию Т, пред- назначенную для суммирования некоторых членов, задаваемых в этой процедуре с помощью указателя, идентификатор которого является ее формальным параметром F. Поскольку нам понадобится использовать данную процедуру Т для вычисления сумм с разными пределами сум- мирования, определим ее как процедуру с тремя параметрами: два из них являются нижним и верхним пределами суммирования (перемен- ные целого типа N и М) и один — идентификатор процедуры F (внеш- ней функции). При обращении к процедуре Т в качестве фактических параметров для параметра F будут использованы идентификаторы Р1, 221
Р2, РЗ или Р4 для вычисления первой, второй, третьей или четвертой сумм соответственно. Заметив также, что последние два слагаемые имеют тот же вид, что и общий член четвертой суммы, мы выясняем, что для их вычисле- ния мы сможем обратиться к процедуре Р4. Прежде чем привести описания фрагмента модуля, в котором производится вычисление заданного выражения, и перечисленных процедур, обратим Ваше внимание еще на одно обстоятельство. По- скольку в четвертой сумме используются элементы массивов X и Y, а функцию Р4 мы определили как функцию от одного параметра, возникает необходимость в использовании общего блока для вызываю- щей процедуры (ниже мы приводим фрагмент этой процедуры) и про- цедуры Р4, в котором используются элементы этих массивов. Передача информации о массивах в данном случае посредством аппарата формаль- ных-фактических параметров не представляется возможной, посколь- ку помимо процедуры Р4 из вызывающей процедуры мы обращаемся к процедурам Pl, Р2, РЗ, у которых используется только по одному формальному параметру (используемому в качестве простой перемен- ной целого типа). Заметим при этом, что правилами языка ФОРТРАН допускается косвенное обращение посредством одного и того же фор- мального параметра (в нашем случае он обозначен через F) только к тем процедурам, которые идентичны по типу (в нашем случае они все — внешние функции вещественного типа), имеют равное число формаль- ных параметров (у нас — по одному) соответственно одного и того же типа (у нас — целого типа). Обращаем также внимание на обязательность использования в вызывающем программном модуле объявления EXTERNAL и пере- числение в нем идентификаторов Pl, Р2, РЗ, Р4 (но не идентификатора процедуры Т, к которой вызывающий программный модуль обращается непосредственно). Фрагмент программы: EXTERNAL Pl, Р2, РЗ, Р4 common Xi (iaa), yi (i <&&) R = T (NI, N2, Pl) + T (N3, N4, P2) + T (N5, N6, РЗ) +T * (N7, N8, P4) + P4 (5Bj + P4 (Ш£) END FUNCTION T (N, M, F) T - &.& DO II = N, M 1 T == T + F (I) RETURN END 222
FUNCTION Pl (I) Pl = I * I RETURN END FUNCTION' P2 (I) A = I P2 = COS (2.Д * A) RETURN END FUNCTION P3 (I) P3 = I ** 3 RETURN END FUNCTION P4 (I) common x (iee), y (ieej P4 = SQRT (X (I) ** 2 + Y (I) ** 2) RETURN END Пример 2, Для сравнения методики использования внешних функ- ций и подпрограмм приведем фрагмент программы, решающей ту же задачу, что и в первом примере, однако использующую вместо внешней функции Т подпрограмму, которую мы обозначим идентификатором РТ. В отличие от использованной в предыдущем примере внешней функции Т, помимо тех же формальных параметров N, М, F, нам по- надобится включить еще один формальный параметр S, предназначае- мый в качестве носителя результата выполнения этой подпрограммы РТ, т. е. результата выполненного в ней суммирования. Фрагмент вызывающего модуля: EXTERNAL Pl, Р2, РЗ, Р4 COMMON XI (1ДД), Y1 (1ДД) CALL РТ (Nl, N2, Pl, SI) CALL PT (N3, N4, P2, S2) CALL PT (N5, N6, P3, S3) CALL PT (N7, N8, P4, S4) P = SI + S2 + S3 + S4 + P4 (5Д) + P4 (1ЯЯ) END Подпрограмма PT: SUBROUTINE PT (N, M, F, S) S = Q.e 223
DO 1 I = N, М 1 s = S + F (I) RETURN END Описание внешних функций Pl, P2, РЗ, P4, используемых в дан- ном фрагменте, при этом не претерпевает никаких изменений. Задание. 1. В каком случае можно упростить программу, восполь- зовавшись вместо внешней функции внутренней функцией? 2. Учитывая ответ на предыдущий вопрос, по возможности мак- симально упростите приведенный в примере 1 в этой порции фрагмент программы, полагая, что NI = N3 = N5 = N7; N2 = N4 = N6 = - N8. 3. Замените в первом из приведенных в этой порции примеров внешние функции Pl, Р2, РЗ, Р4 подпрограммами. 4. Допустимы ли следующие последовательности предложений в одном и том же программном модуле? 1).................... 2) EXTERNAL Т COMMONA(5€), В(5«) А - Т (М, N) EXTERNAL Т ................... Т1 (К) = А (К) + В (К) **2 CALL F(A, Т, Т (MS, MS)) Р = Т1 (1) + Т (2) 3) EXTERNAL Т CALL F (1.1, Т) Т (А) = А * В + С 4) FUNCTION F (А, М) COMMON А (1££), М, С 5. Можно ли в примере 2 во всех операторах CALL в качестве четвертого параметра указать один и тот же идентификатор? Порция 85 Массивы с регулируемыми размерами Как было указано в порции 13 (при рассмотрении описателей массивов), для указания размеров массивов могут быть использованы, помимо положительных целых констант, идентификаторы переменных целого типа. Однако размеры массивов с помощью идентификаторов не могут указываться в головном модуле; их разрешено употреблять только в подпрограммах и внешних функциях. Массив, в описателе которого размер задан идентификатором, называется массивом с регулируемыми размерами. Если в некоторой процедуре используются массивы с регулируе- мыми размерами, то в список формальных параметров этой процедуры должны быть включены: 1. Все идентификаторы массивов с регулируемыми размерами. 224
2. Все идентификаторы переменных целого типа, задающие разме- ры регулируемых массивов (в ФОРТРАН/ЕС они могут быть включены не в список формальных параметров, а в общую область). Если среди регулируемых массивов имеются такие массивы, гра- ничные значения индексов которых совпадают, эти значения могут быть обозначены одним и тем же идентификатором, что позволит умень- шить число формальных параметров процедуры. Обратим внимание на ограничение, накладываемое языком на использование формальных параметров, задающих регулируемые размеры используемых в процедурах массивов: 1. Значения фактических параметров, задающих регулируемые размеры массивов, должны быть определены до обращения к проце- дуре. 2. Эти значения не могут переопределяться в процедуре. 3. Эти значения не могут становиться неопределенными. Таким образом, например, формальный параметр в процедуре не может быть использован в качестве параметра оператора цикла, а также не может быть использован в операторе GO ТО по предписанию и, соответственно, в операторе ASSIGN (поскольку при этом соответ- ствующая переменная целого типа становится неопределенной). Таким образом, каждому массиву с регулируемыми размерами ставится в соответствие массив (или переменная с индексами) из вы- зывающей процедуры. Последний, в свою очередь, если вызывающая процедура сама была вызвана другой процедурой или головным мо- дулем, может оказаться массивом с регулируемыми размерами. Од- нако в любом случае для каждого массива с регулируемыми размерами должно существовать по меньшей мере одно описание с постоянными размерами. Пример. В массив Т вводится набор записей, содержащийся на перфокартах. Последняя перфокарта в первых двух позициях содер- жит признак конца /♦. Предшествующие ей записи рассматриваются как непрерывная текстовая строка из п символов (и < 800). Строка состоит из слов, разделенных точками (16-ричный код 4В = 75i0). Конец строки задан символом Q (16-ричный код 5В = 9110). Напечатать таблицу из двух колонок, содержащую в первой ко- лонке номера слов, а во второй — их длины. Решение: LOGICAL *1 Т (8ЭД) READ (1, 12, END = 13) Т 13 N = 1 I = 1 1 J = LOC (Т (I)) IF (J. EQ. Q) STOP L = J - 1 8 9-2712 225
PRINT 5, N, L I = I + J N = N + 1 GO TO 1 12 FORMAT (SB Al) 5 FORMAT (2110) END FUNCTION LOC (PNT) LOGICAL *1 PNT (1) LOGICAL S INTEGER I EQUIVALENCE (S, I) LOC = & DO 1 N = 1, 800 S = PNT (N) IF (I.EQ. 91) RETURN IF (I. EQ. 75) GO TO 2 1 CONTINUE STOP 777 2 LOC = N RETURN END Задание. 1. С какой целью в теле функции LOC введено объявление EQUIVALENCE? 2. Выполните приведенную программу для какого-либо исходного набора данных. Порция 86 Примеры использования массивов с регулируемыми размерами Пример 1. Рассмотрим процедуру (обозначим ее идентификатором W) умножения двух квадратных матриц фиксированного порядка К = = 10. Оформим ее в виде подпрограммы с тремя параметрами А, В, С, используемыми в ее теле в качестве идентификаторов двух исходных массивов (А и В) и результирующего массива (С). По определению элемент матрицы-произведения С (L, М) вычисляется по формуле: ю C(L, М) = У} A (L, I) • В (I, М). 1=1 Для вычисления одного элемента С (L, М) можно обратиться к оператору цикла DO. Для вычисления строки матрицы-произведения нам понадобится выполнить двойной цикл, для получения всей искомой 226
матрицы — тройной цикл. SUBROUTINE W (А, В, С) DIMENSION А (10, 10), В (10, 10), С (10, 10) do 1 м = 1, 10 DO 1 L= 1, 10 c(L, М) = 0. & DO 1 I = 1, 10 1 C(L, M) = C(L, M) + A (LЛ) * В (I, M) RETURN END Напомним, что описание размеров и размерностей любых массивов (что осуществлено в нашем примере с помощью объявления DIMEN- SION), используемых в каждом программном модуле, обязательно. Оператор вызова данной подпрограммы может иметь, например, следующий вид: CALL W(X1, Х2, ХЗ) При этом размерности массивов XI, Х2, представляющих собой исходные матрицы, должны быть равными 10 X 10. Число формальных параметров может быть уменьшено при дости- жении того же результата (поскольку в данном случае массивы имеют фиксированные размеры). Например, мы можем отказаться от фор- мального параметра С, воспользовавшись общим для вызывающего и вызываемого программных модулей блоком памяти. Так, если в вы- зывающем программном модуле будет задано объявление: COMMON Х3(10, 10) и оператор обращения к подпрограмме, которой мы теперь присвоим идентификатор W1: CALL W1 (XI, Х2) то подпрограмму W1 можно будет записать в виде: SUBROUTINE W1 (А, В) COMMON С (1-0, 10) END Остальную часть программы, не претерпевшую изменений, мы обо- значили многоточием. Однако имеется некоторое различие в подпрограммах W и W1. Если первой из них мы можем воспользоваться, исходя из любого программного модуля (в котором определены соответствующие масси- вы, имеющие необходимые размеры 10 X 10), то вторая может быть применима только теми, которые используют массивы, определенные 8* 227
в них соответственно объявлением COMMON, то есть для всех обраще- ний используются одни и те же поля памяти, обозначенные, быть мо- жет, другими идентификаторами. Таким образом, аппарат формальных-фактических параметров является более гибким, что уже было нами отмечено ранее. Пример 2. Продолжим рассмотрение предыдущего примера, по- ставив вопрос о расширении возможностей приведенной в нем под- программы вычисления произведения квадратных матриц. Для решения той же задачи составим подпрограмму, но такую, которая позволяла бы наводить произведение квадратных матриц любого порядка. В таком случае нам понадобится воспользоваться формальными параметрами, идентифицирующими регулируемые массивы, что означает необходимость включения в число формальных параметров также идентификатора, определяющего размеры массивов (в данном случае, так как матрицы квадратные, понадобится ввести только один дополнительный параметр). Присвоим подпрограмме идентификатор W2. SUBROUTINE W2 (А, В, С, К) DIMENSION А (К, К), В (К, К), С (К, К) DO 1 М = 1, К DO 1 L= 1, К С(м, L) = a. е DO 1 1= 1, К 1 С(М, L) = C(M, L) + A(M, I) *B(I, L) RETURN END Теперь к приведенной подпрограмме можно обратиться, например, с помощью оператора CALL W2(X1, Х2, ХЗ, 12) или CALL W2(X1, Х2, ХЗ, N + I) При этом значение переменной N (как и значение всех элементов массивов XI и Х2 в обоих случаях) должно быть определено к моменту вызова процедуры W2. Следует обратить внимание на то, что в подпрограмме W2 мы не можем освободиться от формальных параметров, прибегнув к объяв- лению COMMON; другими средствами передачи данных в вызывае- мую подпрограмму или возврата из нее результатов в случае массивов с регулируемыми размерами, кроме аппарата формальных-фактиче- ских параметров, язык ФОРТРАН не располагает. 228
Порция 87 Объявление ENTRY в ФОРТРАН/ЕС (дополнительные точки входа во внешнюю процедуру) В стандарте ФОРТРАНа заголовок внешней процедуры является единственной точкой входа в эту процедуру — при любом вызове с него начинается выполнение процедуры. В некоторых случаях это ограничение оказывается обременительным. Пусть необходимо вычислить длину отрезка строки до определенного символа, слу- жащего признаком конца. В то же время нужна процедура измерения длины отрезка строки до произвольного символа. В первом случае можно построить внешнюю функцию с одним параметром, задающим адрес массива, содержащего строку. Во втором случае необходимы два параметра: адрес строки и ограничивающий ее символ. В стандарте ФОРТРАНа для решений этой задачи можно применить один из двух способов: 1) составить две отдельные процедуры-функции; 2) написать одну процедуру с двумя параметрами и, таким образом, всегда указы- вать ограничивающий символ. Первый способ ведет к неоправданному расходу памяти, так как получаемые процедуры почти совпадают. Вто- рой способ неудобен, если в некоторой задаче для исходных строк используется один и тот же признак конца. ФОРТРАН/EC предоставляет дополнительную возможность ре- шения подобных (и более сложных) задач путем использования введен- ного в этот язык объявления ENTRY (ВХОД). По своей структуре это объявление подобно объявлениям FUNCTION или SUBROUTINE. Каждое из объявлений ENTRY, записанных в теле внешней про- цедуры, определяет дополнительную точку входа в процедуру (т. е. внешняя процедура, но не головной модуль, может иметь несколько дополнительных входов). Вид входа — функция или подпрограмма — определяется видом главного входа. Поэтому обращение к дополни- тельному входу, содержащемуся в подпрограмме, возможно лишь посредством оператора CALL {имя входа) а содержащемуся в функции — указателя имени этого входа. Пример 1. Опишем процедуру LENGTH (с одним параметром), определяющую длину отрезка строки, заканчивающегося литерой Q, и имеющую дополнительный вход LIMIT (с двумя параметрами); обращение к дополнительному входу обеспечивает вычисление длины строки, завершающейся любым символом, задаваемым вторым формаль- ным параметром. В процедуре используется некоторая функция GETSY, выделяющая очередной символ в строке: первый параметр этой функции определяет имя строки, второй — порядковый номер в строке выделяемого символа. FUNCTION LENGTH (STR) DATA Q/'Q'/ 229
DIMENSION STR (1) CHAR = a ENTRY LIMIT (STR, CHAR) S = GETSY (CHAR, 1) I = 1 1 IF (GETSY (STR, I). EQ.S) GO TO 2 1=1 + 1 GO TO 1 2 LENGTH = 1 — 1 LIMIT = LENGTH RETURN END Независимо от вида первого фактического параметра в обращениях к GETSY (переменная или массив), в теле процедуры GETSY он ин- терпретируется как начальный адрес строки символов (см. порцию 96). При обращении к дополнительному входу выполнение процедуры начинается с оператора, следующего за объявлением ENTRY. Объяв- ление ENTRY при обращении по другому (например, по главному) входу, игнорируется. Если дополнительный вход содержится в теле внешней функции, то его тип можно объявить непосредственно после ключевого слова ENTRY перед именем входа, например: ENTRY COMPLEX * 16 А(Х, Y) Следует учитывать, что для значений имен функций, определяемых различными входами, отводится одно и то же поле памяти, что равно- сильно объявлению EQUIVALENCE для всех этих имен. Входы в функциях могут иметь различные типы. При этом, неза- висимо от того, какому из эквивалентных имен входов имело место последнее перед возвратом из тела функции присваивание, результат будет интерпретироваться в зависимости от типа имевшего место вхо- да. Таким образом, эта ситуация является еще одним случаем, когда один и тот же код (в данном случае значение функции, обладающее различными именами) можно интерпретировать как данное разных типов. Как видно из примера, имеет важное значение также и тот факт, что формальные параметры различных входов в процедуру могут не совпадать как по их числу, так и по типу (и порядку следования в спис- ке параметров). Однако имена всех формальных параметров (во всех входах), равно как и имена локальных переменных, имеют силу во всей процедуре (считаются в ней объявленными). Аналогично, объяв- ления DIMENSION имеют силу во всем теле процедуры. Обратите внимание, что в приведенной выше программе имя CHAR обозначает как локальную переменную (при обращении по главному входу), так и формальный параметр. Здесь нет противоречия, посколь- ку при вызове по значению-результату фактический параметр локали- 230
зуется. Противоречие возникло бы, если бы CHAR вызывался по адресу; поэтому такой вызов CHAR недопустим. Пример 2. Рассмотрим фрагмент программы: Вызывающий модуль Вызываемый модуль I = 15 J = 2# CALL А (1, J) DO 1 I = 1,2# J = I + 5 Z = J CALL В (Z, R) 1 PRINT 2,R SUBROUTINE A (I, J) RETURN ENTRY В (X, Y) K = i +J Y = X +K RETURN END В данном примере обращение по главному входу приводит к един- ственному действию: вызову параметров. При вызове по значению- результату это означает, что значения фактических параметров лока- лизуются и становятся доступными всей вызываемой процедуре, т. е. происходит начальная установка параметров. В дальнейшем исполь- зуется только дополнительный вход, в котором параметры I, J не ис- пользуются. Это означает, что их вызов не осуществляется, и, несмот- ря на то, что в вызывающей процедуре значения соответствующих фактических параметров I, J изменяются, подпрограмма В будет работать все время с их начальными значениями. Таким образом, локальные поля (адреса которых скрыты от составителя программы) используются для хранения этих начальных значений. Парамет- ры I, J в теле процедуры не переопределяются, поэтому их вызов яв- ляется вызовом по значению (в терминологии АЛГОЛ-60). Поскольку формальные параметры I и J главного входа А не являются формальными параметрами входа В и используются непо- средственно после входа В, вызов процедуры по входу В возможен лишь после того, как имел место вызов по главному входу. При этом при обращении к А вызов параметров по ссылке недопустим, посколь- ку он не обеспечивал бы передачу в процедуру значений фактических параметров, которые используются при вызове по входу В. Использование объявления ENTRY позволяет, таким образом, экономить память путем совмещения идентичных последовательностей предложений различных процедур и использовать локальные ячейки, выделяемые трансляторами, для хранения значений. Объединение про- цедур за счет использования дополнительных входов обеспечивает создание более эффективных программ. Задание. 1. Может ли в указателе функции использоваться имя функции, отличное от того имени, которому в ее теле присваивается значение? 2. Может ли объявление ENTRY находиться в области действия оператора DO? 231
3. Можно ли использовать объявление ENTRY в головной про- грамме? 4. Допустима ли следующая последовательность предложений -в программном модуле? Если нет, то почему? SUBROUTINE А (X, Y) RETURN ENTRY В (Z) CALL А (X, Y) END 5. Допустима ли следующая структура программы: DIMENSION Q (100) SUBROUTINE X CALL y'(Q)........... DIMENSION Z (100) END................. ENTRY Y (Z)........... END 6. Определите результат работы программы: М = 1 N = 1 CALL Pl (М) CALL Р2 (N) WRITE (3,3) M, N 3 FORMAT (2110) STOP END SUBROUTINE Pl (I) RETURN ENTRY P2 (J) 1 = 1 + 2 J = J + 2 RETURN END 7. Можно ли в предыдущем задании в заголовке процедуры Р1 задать вызов параметра I по ссылке: SUBROUTINE Pl (/I/) 8. Какие значения будут напечатаны в результате выполнения следующей программы? CALL S1 (3) 3 CALL S3(&1, &2, J, &2) 232
PRINT 5, J 2 CALL S2(J, &2, &3) 1 STOP 5 FORMAT (110) END SUBROUTINE SI (I) RETURN ENTRY S2 (K, *, *) I = K-1 ENTRY S3(*, *, L, *) PRINT 5, I L = I RETURN I 5 FORMAT (II#) END 9. С какой целью в примере 1 данной порции в программе введена переменная S? Порция 88 Примеры использования процедур Пример 1. Пусть требуется составить описание внешней функции, принимающей значение скалярного произведения двух любых столб- цов произвольной заданной матрицы. Примем следующий план решения поставленной задачи: 1) Выбор идентификатора функции. 2) Определение формальных параметров. 3) Составление тела внешней функции. 4) Анализ полученного описания. 1. Для определяемой нами функции выберем идентификатор SP (неявно определяя ее тип). 2. Считая, что размеры заданных матриц могут быть различными, приходим к выводу, что в описании функции следует воспользоваться массивом с регулируемыми размерами. В соответствии с правилами, изложенными в порции 85, в число формальных параметров данной внешней функции в таком случае должны быть включены как иденти- фикатор массива (пусть это будет идентификатор вещественного мас- сива А), так и идентификаторы переменных, значения которых опре- деляют размеры данного массива А (пусть это будут идентификаторы 233
переменных целого типа: N — число строк, М — число столбцов). Поскольку составляемая процедура-функция должна быть рассчитана на вычисление скалярного произведения двух произвольно выбранных столбцов любой заданной матрицы, в число ее формальных параметров следует включить идентификаторы переменных целого типа, явля- ющихся номерами этих столбцов. Пусть это будут идентификаторы I и J соответственно. 3. В принятых обозначениях перейдем к составлению необходимо- го описания. Заголовком процедуры-функции должно быть объявле- ние FUNCTION SP (A, N, М, 1, J) Заметим, что формальные параметры в описании функции могут быть перечислены в произвольном порядке, однако раз и навсегда фик- сированном. Следующим в искомом описании должно быть, очевидно, объяв- ление DIMENSION или REAL, в котором будет описан массив А: DIMENSION A(N, М) или REAL A(N, М) Вычисление скалярного произведения двух столбцов матрицы мо- жет быть выполнено посредством следующих операторов: DO 5 К = 1, N 5 SP = SP + А (К, I)* А (К, J) которым должен предшествовать, например, оператор sp = e. е присваивающий переменной SP начальное значение, равное или соответствующее объявление DATA. Таким образом, описание интересующей нас процедуры-функции можно представить в виде: FUNCTION SP (A, N, М, I, J) DIMENSION A (N, М) sp = £. е DO 5 К = 1, N 5 SP = SP + А (К, I) * А (К, J) RETURN END 4. Давайте посмотрим, не может ли быть уменьшено число формаль- ных параметров внешней функции SP? Если бы все матрицы, для столбцов которых будут вычисляться скалярные произведения, имели размер 15 X 10, то вместо приведен- ного выше описания процедуры-функции SP можно было бы написать такую процедуру (присвоим ей идентификатор SP1): 234
FUNCTION SP1 (I, J) COMMON A (15, 10) SP1 = 0.0 DO 15 К = 1, 15 15 SP1 = SP1 + А (К, I) * A (K, J) RETURN END Таким образом, включение в список формальных параметров иден- тификатора массива А и идентификаторов N и М, определяющих его размеры в случае регулируемых размеров, является обязательным. Что касается параметров I и J, то эти параметры могут быть исключе- ны из списка формальных параметров, а передача им значений может быть осуществлена посредством идентификаторов переменных из общего блока. Однако синтаксис языка ФОРТРАН требует наличия по меньшей мере одного формального параметра в записи объявления FUNCTION. Таким образом, описание требуемой функции может быть представле- но, например, в виде: FUNCTION SP2 (А) COMMON/S/I, J DIMENSION А (15, 10) SP2 = 0.0 DO 6 К = 1, 15 6 SP 2 = SP2 + А (К, I) * А (К, J) RETURN END или FUNCTION SP3 (I) COMMON A (15, 10), J SP3 = 0.0 DO6 К = 1, 15 6 SP3 = SP3 + А (К, 1) * A (K, J) RETURN END Пример 2. Составить описание внешней функции, определяющей скалярное произведений 1-й строки матрицы А, имеющей размер 15 х х 10, на J-й столбец матрицы В, имеющей размер 10 X 12. В отличие от описания процедуры, приведенного в предыдущем примере, в теле этой функции встречаются обращения к элементам двух матриц: А и В. Ниже приведено описание требуемой функции с учетом возможно- сти использования массивов с регулируемыми размерами. FUNCTION SPS (А, В, М, N, L, I, J) DIMENSION А (М, N), В (N, L) SPS =0.0 DO 7 К = 1, N 235
7 SPS = SPS + A (I, К) * В (К, J) RETURN END Подпрограмма SPP, описание которой приведено далее, предна- значена для вычисления произведения матриц А и В, имеющих, соот- ветственно, размеры 15 X 10 и 10 X 12. В теле этой подпрограммы име- ется обращение к внешней функции SPS, описанной выше. SUBROUTINE SPP (А, В, С) DIMENSION А (15, 10), В (10, 12), С (15, 12) DO 10 I = 1, 15 DO 10 J = 1, 12 10 С (I, J) = SPS (A, B, 15, 10, 12, I, J) RETURN END Пример 3. Опишем процедуру LOG, содержащую в качестве фор- мального параметра идентификатор двумерного массива А и выдаю- щую в качестве результата логический вектор В, £-ая компонента ко- торого В (К) равна .TRUE., если хотя бы один элемент £-го столбца матрицы А отличен от нуля, и .FALSE, в противном случае. Описание данной процедуры может быть представлено в виде: SUBROUTINE LOG (А, М, N, В) LOGICAL В DIMENSION А (М, N), В (N) DO 4 I = 1, N DO 2 J = 1, М IF (A (J, I) .NE. 0.) GO TO 3 2 CONTINUE В (I) = .FALSE. GO TO 4 3 В (I) = .TRUE. 4 CONTINUE RETURN END Задание. 1. Какими средствами могут описываться размеры масси- вов и в каких случаях? 2. Какие массивы называются массивами с регулируемыми раз- мерами? 3. Каковы требования к спискам формальных параметров проце- дур, использующих массивы с регулируемыми размерами? 4. Процедура использует три массива с регулируемыми разме- рами. Какое минимальное число формальных параметров должно быть использовано в ней в связи с этим? максимальное? 5. Процедура использует массив с регулируемыми размерами. Может ли эта процедура быть задана как процедура без параметров? Б. В процедуре осуществляется умножение квадратных матриц, имеющих регулируемые размеры. Можно ли в качестве параметров 236
циклов при этом воспользоваться ляющим размеры массивов? 7. Допустимы ли следующие в одном программном модуле? 1) FUNCTION F (А, М) DIMENSION А (М) ASSIGN 5 ТО М 2) SUBROUTINE F (А, М) DIMENSION А (М, 5, 3) DO 5 М = ’1,М1’ 5 CONTINUE 3) SUBROUTINE F (А, В, С) EXTERNAL В CALL А (В) формальным параметром, опреде- последовательности предложений 4) SUBROUTINE F (А, М) DIMENSION А <10, М) GO ТОМ, (3,4) 5) FUNCTION F (А, М) . DIMENSION А (М) DO 5 М1'= Г, М ’ 6) FUNCTION F (А, М) DIMENSION А (М) М = 5................ DO 5 К = 1, 100, М 8. В некотором программном модуле требуется вычислить S — сумму произведений второго столбца матрицы А на третий, и S1 — тре- тьего на пятый, а также S2 — сумму квадратов элементов второго и третьего столбцов. Запишите операторы присваивания для вычисления этих значений, используя описанную в примере 1 функцию SP. 9. Может ли быть уменьшено число формальных параметров в под- программе, приведенной в примере 3? 10. Замените в примере 3 логический оператор IF арифметическим. 11. Обязательно ли наличие в теле процедуры (пример 3) объяв- ления DIMENSION А (М, N), В (N)? 12. Сохранив содержание программы, в примере 3 постарайтесь уменьшить число составляющих ее операторов. Порция 89 Модуль-блок данных Модуль-блок данных используется для присвоения начальных значений переменным из помеченных общих блоков. Заголовком это- го модуля должно быть объявление, формат которого имеет вид: BLOCK DATA За заголовком следуют объявления спецификаций, начальных данных DATA и заключительная строка END. Кроме перечисленных объявлений модуль-блок данных не может со- держать никаких других предложений. Этот модуль должен содержать 237
хотя бы одно объявление COMMON и хотя бы одно объявление DATA. Пример BLOCK DATA COMMON/BLOCK 1/ONE, TWO, THREE, FOUR REAL ONE, TWO, THREE INTEGER FOUR DATA ONE, TWO, THREE/5.-B, 2*6.5/, FOUR/92/ END Для.данного примера модуля-блока данных ниже приведен порядок следования элементов в помеченном общем блоке BLOCK 1, их тип и значения, присвоенные им этим модулем. Идентификатор элемента блока COMMON ONE TWO THREE FOUR Тип REAL REAL REAL INTEGER Начальное значение 5.0 6.5 6.5 92 Если какой-нибудь переменной помеченного блока COMMON присваивается начальное значение в модуле-блоке данных, то в этом модуле должны быть полностью описаны (в объявлениях типа, DIMENSION ит. д.) все элементы данного блока COMMON, даже если некоторые из них не появляются в объявлении DATA. Пример. BLOCK DATA INTEGER Al REAL IA2 (4) LOGICAL BOOL 1, BOOL 2 DIMENSION A3 (3) COMMON/BLOCK/A1, IA2 (4), BOOL1, BOOL2, A3 DATA Al, IA2 (2), BOOL1, BOOL2/-0,1A .TRUE.,.FALSE./, * A3 (1), АЗ (3)/4.21, 2.-S7 END Порядок следования элементов в помеченном общем блоке, их тип и значения, присвоенные им в модуле-блоке данных: Иденти- фикаторы элементов блока А1 1Л2 (1) IA2 (2) 1А2 (3) IA2 (4) BOOL1 BOOL2 A3 (1) A3 (2) A3 (3) Тип INTEGER REAL REAL REAL REAL LOGICAL LOGICAL REAL REAL REAL Началь- ное значе- ние 0 1,0 .TRUE. .FALSE. 4.21 2.0 238
С помощью одного модуля-блока данных можно присвоить началь- ные значения переменным из нескольких помеченных блоков COMMON. Пример BLOCK DATA INTEGER R (5) REAL M, C COMPLEX Z DIMENSION C (3) COMMON/BLOCK/R, C/BLOCK4/M, Z DATA R (1), R (2), R (3)/3*5/, C (1), C (2)/l., 2./, Z/(2.3, 1.5)/ END Размещение элементов общего блока BLOCK Идентификаторы элементов блока COMMON R (1) R (2) Q R (3) R (4) R (5) c (1) c (2) C(3) Тип INTEGER INTEGER INTEGER INTEGER INTEGER REAL REAL REAL Начальное значе- ние 5 5 5 1. 2. Размещение элементов общего блока BLOCK4 Идентификаторы элементов блока COMMON М Z Тип REAL COMPLEX Начальное значение 2.3 1.5 Модуль-блок данных является независимым модулем и трансли- руется отдельно. Результатом трансляции будет размещение в соот- ветствующих ячейках памяти начальных значений в помеченных об- щих блоках. Программа может включать несколько модулей BLOCK DATA. Задание. Присвоить следующим переменным общего блока BLOCK 5 начальные значения, используя модуль-блок данных.В блок COMMON входит два двумерных массива данных целого типа (А и В), состоящие из четырех элементов каждый (2x2), две вещественные переменные 239
С0НМ0Ы/А5/ CAIL SAMI(RK) • •••••••••••• CALL SAM2(5,A,F03) CALL 5AM2(K.R,7.2) sr=A»»2+FI(5,R,lj Тело голобного мобуля С и Р и переменная логического типа BOOL 3. Перечисленные переменные должны получить следующие значения: А (1, 1) = 2; А (2, 1) = 3; В (1, 1) = = 4; С = 77,7; BOOL 3 = .FALSE.. STOP END Порция 90 SUBROUTINE SAMlfF) NK-RL+50RT(F2(i,K)j • • • • •••••• • • • Тело > подпрограммы Структура ФОРТРАН-программы RETURN END SAMt Как мы уже говорили в пор- ции 1, ФОРТРАН-программа может состоять из нескольких SUBROUTINE $AM2(l,5.R) программных модулей, среди Teno которых обязательно должен CALL 5AM3 ► подпрограммы 5АМ2 быть один, называемый голов- ным. Выполнение ФОРТРАН-про- граммы всегда начинается с RETURN END FUNCTION F1(A,B,l) первого оператора головного Тело модуля. H =A»*I/F2(A,Jj ‘RETURN END > функции F1 На рис. 32 приведена типич- ная структура выполняемой программы. Выполнение каждого проце- дурного модуля, как и головно- го, также начинается с его пер- вого оператора (или, в случае ФОРТРАН/ЕС, с первого опера- тора, следующего за соответ- FUNCTION F2(B, I) CALL‘sAM^RR^^S’f) r'eturn END Тело . функции F2 SUBROUTINE 5AM3 . Тело ствующим дополнительным вхо- дом). > подпрограммы Вызов любого модуля—внеш- RETURN END SAM3 ней функции или подпрограм- мы — всегда связан с обраще- Рис. 32 нием из головного модуля, непосредственным или посред- ством других модулей. Задание. 1. Запишите внутреннюю функцию для вычисления ее значения по каждой из перечисленных ниже формул (тип идентифика- торов задан неявно): 240
Идентификатор функции a) F б) F в) М Формула Р + sin (i 4- 1) + k Vk+fyk+z+t & + (l + 2kf Параметры i k, t s, k 2. Напишите функцию с идентификатором G и двумя формальны- ми параметрами: X и А. Значением G должно быть ах2, если х меньше нуля, и ах3, если х больше либо равно нулю. 3. Составьте программу, использующую внешнюю функцию из предыдущего задания и подпрограмму умножения матриц десятого порядка. Программа должна выполнять следующие действия: а) чтение с перфокарт массива В размером 10 X 10. Чтение долж- но производиться по столбцам в предположении, что исходные данные отперфорированы в формате F 14.4; б) чтение с перфокарт массива ВМ размером 10 X 10. Чтение должно производиться по строкам. Используйте то же самое объяв- ление FORMAT; в) умножение матрицы В (множимое) на матрицу ВМ (множитель) с помощью подпрограммы М. Результат необходимо поместить в мас- сив А; г) вычислить, используя функцию G, значение G (A (I, J), D) при D = 5.0 для каждого элемента массива А. Присвоить значения функции соответствующим элементам А, заменив прежние значения; д) отпечатать на АЦПУ массив А (по строкам) по пять чисел в стро- ке в формате F 10.4.
Глава V МЕТОДИКА КОНСТРУИРОВАНИЯ ПРОГРАММ Порция 91 Головной модуль и вызываемая им внешняя процедура Для усвоения методики конструирования ФОРТРАН-программ из программных модулей рассмотрим ряд примеров. Пример 1. Для приближенного вычисления определенных инте- гралов ь J = f f (х) dx а часто используют метод Симпсона (парабол) численного интегрирова- ния, согласно которому + Ш + 4/ (д —Л) 4- £ [4f(a + (2£-l)ft)-|- + 2/ (а 2kh)lj, где h = — , 2/п — число точек деления интервала интегрирования. Приведем программу на ФОРТРАНе, предназначенную для интегри- рования функции У = f (*) по методу Симпсона на интервале (а, Ь). Данные а, Ь, т (обозначим их идентификаторами А, В, М) отперфорированы и вводятся с устрой- ства с номером 1. Результат в виде «J = (значение интеграла)» дол- жен быть выдан на устройство с номером 3. В программе будет использована внешняя процедура-функция, предназначенная для вычисления значений подынтегральной функции f (х) (обозначим ее идентификатором F, а ее аргумент — формальный параметр — идентификатором X). Программа численного интегрирования по методу Симпсона: REAL J READ(1, 4) А, В, М 4 FORMAT (2F10. 3, 16) 242
AM = М Н = (В — А)/2./АМ J = F(A) + F(B) + 4.*F(B — Н) Ml = М— 1 DO 5 К = 1, Ml АК = К 5 J == J + 4. * F (А + (2. * АК — 1.) * Н) 4- 2. * F (А + 2. * АК*Н) J = J/3. ♦ Н WRITE (3, 7)J 7 FORMAT (5Х, 4HJ _=_, Е15.6) STOP END FUNCTION F (X) END Приведенный программный модуль (головной) рассчитан на ис- пользование совместно с внешней вещественной функцией F с одним вещественным параметром, определяющей значение подынтегральной функции. Так, например, для интегрирования функции f (х) = -1 - V1 + *3 (на интервале а < х < b с заданным числом делений этого интервала 2m) необходимо в выполняемую программу, помимо головного модуля, включить следующую внешнюю функцию: FUNCTION F (X) F= l./SQRT(l. + X**3) RETURN END Задание. 1. Объясните, почему в вышеприведенной программе в операторе с меткой 5 используется не целая константа, а вещественная (2.). Можно ли заменить эту константу целой константой в стандарте языка ФОРТРАН? в языке ФОРТРАН/ЕС? 2. Объясните, для какой цели в программу введена переменная Ml, переменная АК? Какую из этих переменных можно исключить из программы в языке ФОРТРАН/ЕС? 243
3. Назовите допустимые перестановки операторов в программе, не нарушающие ее смысла. 4. Чем является в данном программном модуле конструкция В—Н, конструкции F(A), F(B), F(B-H), F(A + 2.*AK*H) 5. Какие изменения должны быть внесены в приведенный выше головной модуль, если процедура вычисления значений функции F (X) будет задана в виде подпрограммы, описанной посредством двух формальных параметров: X и Y; X — аргумент, Y — значение функ- ции? Порция 92 Методика использования внутренних функций Из изложенного ясна методика использования готовых программ- ных модулей: согласуй фактические и формальные параметры (как это сделано в приведенном примере), а также переменные общих бло- ков, мы можем подключать в выполняемую программу те или иные процедуры, заменять одни из них другими. Если программный модуль не рассчитан на использование в выпол- няемых программах наряду с другими подлежащими замене программ- ными модулями, то более экономным в сравнении с внешними функ- циями в смысле затраты времени на трансляцию, а также выполнение рабочих программ является использование в тех случаях, где это возможно, внутренних функций. Так, в рассмотренном нами примере интегрирования функций по методу Симпсона можно ограничиться использованием лишь головного модуля, вставив в него внутреннюю функцию F (X) = 1./SQRT (1. + Х**3) и тем самым освободившись от обращений к внешней функции для вы- числения значений подынтегральной функции. Иногда описанный прием удается использовать и в случае более сложного задания функций. Пример 2. Составить программу для интегрирования функции —т--1-' — для 0 х < 2; У для 2<х<4; на интервале 0 < х < 4, используя аппарат: а) внешних функций, б) внутренних функций. 244
Решение, а) используем головной модуль, приведенный в приме- ре 1. С этой целью необходимо в выполняемую программу, помимо дан- ного головного модуля, включить описание внешней функции, кото- рое может быть представлено в виде: FUNCTION F(X) К = X/2. + 1. GOTO(3, 12, 12), К 3 F = l./SQRT (1. + X ** 3) RETURN 12 F = SQRT((1. + X * X)/(X * X — 1.)) RETURN END б) обратив внимание на то, что интервалы, на которых задана функция разными аналитическими выражениями, равны между собой, и учитывая свойство аддитивности определенных интегралов Ь с b § f(x)dx = J f(x)dx + j f (x) dx, a a c представим искомый интеграл в виде: 4 2 4 ______ \f (х) dx = ( - + ^ ]/” ~~2~^Х1 dx. J J /1 + *3 J г х2-1 Сделав замену переменной интегрирования во втором из полученных интегралов х = t + 2, получим: 4 2 2 С 1/..'+*2 1/ !+« + 2)г di-{у /2 + 4< + 5 dt^ J V хг - 1 аХ J V (t -ь 2)2 - 1 al J г /2 + 4/ + 3 1 2 0 0 2 __________ = с у *;+4*+5 dx J V х2 + 4х + 3 о (последнее преобразование произведено на основании независимости определенного интеграла от переменной интегрирования). Таким об- разом, задача сведена к вычислению интеграла: , С I 1 I 1/ х2 + 4х + 5 Л J = J I /т5 ' X2 + 4а. + з I dx. 245
Для завершения поставленной задачи остается включить в ранее приведенную программу (головной модуль) интегрирования функций по методу Симпсона внутреннюю функцию: F (X) = 1./SQRT (1. + Х**3) + + SQRT ((X * X + 4. * X + 5.)/(X * X + 4. * X + 3.)) Пример 3. Рассмотрим в качестве примера алгоритм решения ал- гебраического или трансцендентного уравнения методом половинного деления. Если функция у = F (х) непрерывна на отрезке [а, Ь] и на его концах имеет противоположные знаки, то на [а, Ь] она имеет по меньшей мере один вещественный корень. Если при этом F (х) имеет знакопо- стоянную производную, то этот корень — единственный. Составим программу нахождения корня уравнения F (х) = О на интервале [а, Ь] в предположении наличия на нем единственного корня. Примем следующую схему работы алгоритма. Пусть F (х) имеет разные знаки на концах интервала а и Ь. 1. Полагаем х0 = a, Xj = b. 2. Вычисляем х = Х° + Х1., 3. Проверяем условие | F (х) | < EPS. При выполнении этого условия принимаем х в качестве искомого корня и печатаем его, на чем программа завершает свою работу. Если указанное условие не выполнено, переходим к п. 4. 4. Проверяем условие F(x) • F(x0) > 0. При выполнении последнего условия полагаем х0 = х и перехо- дим к п. 2, в противном случае полагаем хг = х и также переходим к п. 2. Нетрудно заметить, что описанный рекуррентный процесс при ука- занных условиях является сходящимся. В предположении, что процедура вычисления значения заданной функции F (х) может быть задана в виде внутренней функции, инте- ресующий нас алгоритм можно представить в виде: F (X) = (выражение для вычисления функции от х) К - & READ (1, 1) Х^, XI, EPS 1 FORMAT (2F1&.4, F8.6) 5 X = (хе + Х1)/2. IF (ABS (F (X)).LT.EPS) GO TO 6 IF (F (X)*F (X#)) 2, 2, 4 2 XI = X 246
z GO TO 1& 4 X& = X i© к = к + i GO TO 5 6 WRITE (3, 7) X, К 7 FORMAT (5X, E12.5, 14) STOP END Задание. 1. Составьте программу вычисления изолированного корня уравнения функции F (х) = 0 на отрезке [a, fe] методом пропорцио- нальных частей (хорд). Схема этого метода отличается от схемы метода половинного деления лишь пунктом 2, вычислительная формула для которого в данном случае имеет вид: г = Хр Р М — • F (х0) F(xx)-F(x.) ’ 2. Какие значения принимает переменная К, определяемая опера- тором присвоения К = X/2. + 1. (см. описание внешней функции F (X), приведенное в данной порции), когда X изменяется в промежутке 0 X 4? 3. Нельзя ли заменить в приведенном в задании 2 операторе кон- станты соответствующими константами целого типа? 4. С какой целью в теле функции F (X) в операторе GO ТО указа- ны две одинаковые метки? 5. Нельзя ли в описании функции F (X) воспользоваться одним оператором RETURN? 6. Укажите место в головном модуле, куда должна быть помещена внутренняя функция F (X). Порция 93 Внешняя процедура, вызывающая другую внешнюю процедуру Пример 4. Составим описание процедуры-функции SIMP, пред- назначенной для интегрирования функций по методу Симпсона и опи- санной с помощью трех формальных параметров: А — нижний предел интегрирования (вещественная переменная), В — верхний предел интегрирования (вещественная переменная), М — переменная целого типа, 2 * М — число делений интервала интегрирования. Обращение к вычислению значений интегрируемой функциивтеле процедуры SIMP будет осуществляться посредством использования указателя внешней функции F (вещественного типа), описанной 247
посредством одного формального параметра X — переменной интегри- рования (вещественного типа). Таким образом, в головном модуле будут определяться пределы интегрирования и число делений интер- вала интегрирования, замена же функции интегрирования при необ- ходимости интегрирования другой функции будет осуществляться посредством замены внешней функции, за которой будет сохраняться идентификатор F. Описание процедуры-функции SIMP FUNCTION SIMP (А, В, М) AM = М Н = (В — А)/2./АМ SIMP = F (А) + F (В) + 4. *F (В — Н) КМ = М — 1 DO5K = 1, КМ АК= К 5 SIMP = SIMP + 4. *F(A + (2. *АК— l.)*H) + 2. *F (A + * 2. *AK*H) SIMP = SIMP/3.*H RETURN END Пример 5. Воспользуемся приведенной в предыдущем примере процедурой для составления программы вычисления объема тела вра- щения, получаемого при вращении вокруг оси ОХ отрезка кривой У — f (•*)> а х Ь, где f (х) — некоторая функция, алгоритм вы- числения значений которой предполагается заданным в виде вещест- венной процедуры-функции с идентификатором F1 и одним формаль- ным параметром вещественного типа (обозначим его через X). Объем тела вращения выражается формулой: ь J = л\ [/(x)]2dx В предположении наличия описаний двух внешних функций SIMP и F1 необходимая программа может быть представлена в виде: REAL J READ (1, 4) А, В, М 4 FORMAT (2Fie.3, 16) J = SIMP (А, В, M) * 3. 1416 WRITE (3, 7) J 7 FORMAT (5X, 4HJl_j = E15.6) STOP END FUNCTION SIMP (А, В, M) END................ 248
FUNCTION F (X) F = Fl (X) ** 2 RETURN END FUNCTION Fl (X) (вычисление значения Fl (x)) END..................... Таким образом, головной модуль обращается к процедуре SIMP за вычислением интеграла, умножает его значение на л и выдает полу- ченный результат на печать. Процедура SIMP обращается к процедуре F за значением подынтегрального выражения [f (х)]2, а процедура F, в свою очередь, обращается за значением заданной функции f (х) к соответствующей процедуре F1. Замена пределов интегрирования требует замены соответствующей перфокарты на вводе; то же касается замены числа делений интервала интегрирования. Замена функции f (х) требует замены соответствую- щей процедуры F1. I Задание. 1. Укажите допустимые перестановки операторов и мо- дулей в приведенной программе, не искажающие ее смысла. к 2. Опишите приведенную процедуру SIMP в виде внешней функ- ции с одним параметром А, полагая, что: а) В и М определяются как идентификаторы переменных, принад- лежащих общему блоку; б) В и М — фиксированные константы: В — 10.0; М = 200. Порция 94 Элемент массива в качестве фактического параметра Пример 6. Воспользуемся процедурами, рассмотренными в преды- дущем примере, для построения программы, в которой вычисляются объемы тел вращения, получаемые при вращении одной и той же кри- вой, но ограниченной несколькими разными нижними и верхними пре- делами значений переменной X. Допустим, что таких объемов требует- ся вычислить 20. Предположим, что на первой перфокарте отперфорировано число М, на каждой из следующих двадцати перфокарт — пары чисел А£ и Bt (i = 1, 2, ..., 20). Получаемые значения объемов разместим в массиве Ml, который в конце головного модуля выдадим на печать. Приведем лишь описание головного модуля; описания же всех используемых в данной выполняемой программе программных моду- лей укажем лишь схематически. 249
REAL Ml DIMENSION Ml (20), A (20), В (20) READ (1, 4) M, (A (I), В (I), I = 1, 20) 4 FORMAT (I5/(2F10.3)) DO 1 I = 1, 20 1 Ml (I) = 3.1416 * SIMP (A (I), В (I), M) WRITE (3, 7) Ml 7 FORMAT (5X, 5E15.6) STOP END FUNCTION SIMP (А, В, M) END FUNCTION F (X) F = Fl (X) ** 2 RETURN END FUNCTION Fl (X) (вычисление значения Fl (x)) RETURN END Замечание. Легко видеть, что, заменив процедуру вычисления функ- ции F1 (х) процедурой вычисления ее квадрата, можно вместо двух последних функций ограничиться одной: FUNCTION F (X) (вычисление [F (х)]2) RETURN END Задание. 1. Предполагая, что данные на вводе представлены так, как это было указано при описании рассмотренного в данной порции примера, запишите оператор READ без списка типа цикл. 2. Назовите синтаксические типы конструкций, использованных в упомянутой программе: a) Ml (I) = 3.1416 * SIMP (А (I), В (I), М) б) Ml (I) в) 3.1416 г) SIMP (А (I), В (I), М) д) (А (1), В (I), М) е) М ж) I з) FUNCTION SIMP (А, В, М) и) (А, В, М) к) END 250
Порция 95 Идентификатор процедуры в качестве формального (фактического) параметра Пример 7. Недостатком предыдущей программы является невоз- можность ее использования в одной и той же программе для вычисле- ния объемов нескольких тел вращения, получаемых при вращении различных кривых, заданных разными функциями. Действительно, при переходе от одной к другой такой функции необходимо осуществить замену описания соответствующей внешней функции F1, т. е. изменить компоновку выполняемой программы из программных модулей. Недостаток подобного рода может быть устранен посредством включения в список формальных параметров процедуры SIMP ин- тегрирования функций, обозначим ее теперь идентификатором SIMP 2, еще одного параметра, соответствующего используемой в ее теле внеш- ней функции F. Пополняя выполняемую программу всем набором не- обходимых внешних функций и указывая при обращении к процедуре интегрирования не только пределы интегрирования (и число делений интервала интегрирования), но и соответствующий идентификатор той или иной из этих функций, мы получаем возможность вычисления в ос- новной программе объемов тел вращения кривых, заданных разными функциями. Ограничимся рассмотрением лишь схемы выполняемой программы для случая, когда в головном модуле вычисляются объемы двух тел вращения, описанных соответственно графиками кривых Y = Fl (X) и Y = F2 (X). Пределами для переменной X для этих кривых являются величины А1 и А2, В1 и В2 соответственно. В обоих случаях полагаем заданными соответственно целые значения Ml и М2, определяющие чис- ло точек деления интервалов интегрирования. При составлении настоящей программы описания FI и F2 даны схе- матически. EXTERNAL Fl, F2 READ (1, 4) Ml, Al, Bl, М2, A2, B2 4 FORMAT (15, 2F10.3) AMI = 3.1416 * SIMP 2 (Al, Bl, Ml, Fl) AM2 = 3.1416* SIMP 2 (A2, B2, М2, F2) WRITE (3, 7) AMI, AM2 7 FORMAT (5X, SHVl^ = F9.4, 5X, 5HV2 Ш,Р9.4) STOP END FUNCTION SIMP2 (А, В, M, F) AM - M H = (B — A)/2./AM 251
SIMP2 = F (A) + F (B) + 4.* F (В - H) IM = M — 1 DO 5K = 1, IM АК = К 5 SIMP 2 = SIMP2 + 4. * F (A + (2. * AK — 1.) * H) + 2. * F ♦ (A + 2. * АК * H) SIMP2 = SIMP2/3. ♦ H RETURN END FUNCTION Fl (X) {вычисление значения Fl (x)) RETURN END FUNCTION F2 (X) (вычисление значения F2 (x)) RETURN END Пример 8. Используя процедуру SIMP2, составленную в приме- ре 7, составим программу для вычисления координат центра тяжести криволинейной трапеции, ограниченной осью ОХ, прямыми х — А, х = В и графиком кривой у = F (х). Искомые координаты центра тяжести вычисляются по формулам: в в J xF (х) dx J [f (х)]а dx А А Описание внешней функции F, предназначенной для вычисления функции у = F (х), предполагается заданным. Как и в предыдущих примерах, значения А, В, М задаются операто- ром ввода; результаты вычислений выдаются на печать. Рассмотрим два варианта программы: а) при вычислении подынтегральных функций интегралов, входя- щих в числители выражений координат центра тяжести, осуществля- ется обращение к процедуре вычисления значения функции F (X); б) задаются три процедуры-функции соответственно для вычисле- ния значений функций F (X), X-F(x), LF(X)]2. Вариант а) Для возможности передачи процедуре SIMP2 информации о спо- собе вычисления подынтегральной функции в число ее параметров 252
включен формальный параметр F. Фактическими параметрами, которые будут ставиться в соответствие этому параметру, будут идентификато- ры внешних функций (обозначим их соответственно Tl, Т2, ТЗ): Т1 = F (X); Т2 = X • F (X); ТЗ = [F (Х)Р Последние две из них будут включать обращения к первой. REAL KSI, ETA EXTERNAL Tl, T2, ТЗ READ (1, 4) М, А, В 4 FORMAT (15, 2F18.3) KSI = SIMP2 (А, В, М, T2)/SIMP2 (А, В, М, Т1) ETA = SIMP2 (А, В, М, T3)/SIMP2 (А, В, М, Т1) WRITE (3,7) KSI, ETA 7 FORMAT (5X, 4HKSI = , F9.4, 5X, 4HETA = , F9.4) STOP END FUNCTION SIMP2 (А, В, M, F) END FUNCTION Tl (X) Tl = (вычисление значения F (x)) RETURN END FUNCTION T2 (X) T2 = Tl (X) « X RETURN END FUNCTION ТЗ (X) T3 = Tl (X) ** 2 RETURN END Вариант 6) Этот вариант программы будет отличаться от предыдущего лишь описаниями внешних функций Т2 и ТЗ, приведением которых мы здесь и ограничимся: FUNCTION Т2 (X) Т2 = (выражение для вычисления произведения к • F (х)) RETURN END FUNCTION ТЗ (X) ТЗ == (выражение для вычисления (F (х))2) 253
RETURN END Чтобы подчеркнуть различие описаний функций Т2, ТЗ в вариан- тах а) и б), запишем их конкретные выражения в случае, когда F(x) = —J=- V1 -I- X3 Вариант а) FUNCTION Т1 (X) Т1 = 1./SQRT (1. + X **3) RETURN END FUNCTION Т2 (X) Т2 = Т1 (X) * X RETURN END FUNCTION ТЗ (X) ТЗ = Т1 (X) ** 2 RETURN END Вариант б) Выражение для Т1 (X) то же, что и в варианте а). FUNCTION Т2(Х) FUNCTION ТЗ(Х) Т2 = X/SQRT(1.X **3) Т3= 1./(1.+ Х**3) RETURN RETURN END END Задание. 1. Воспользуйтесь процедурой SIMP2 и составьте програм- му для вычисления длины четверти дуги эллипса, заданного уравне- нием у2 /у2 —_____L JL- = 1 а2 Ь2 ь Длина дуги L кривой у = f (х), ограниченной прямыми х = а, у = Ь, вычисляется по формуле: ь L = \ V\ + (f (x))*dx. а 2. Воспользуйтесь процедурой-функцией SIMP2 и составьте про- грамму для вычисления объема тела вращения, получаемого при вра- щении вокруг оси ОХ отрезка кривой у = f (х), 0 х л, где f (х) = = sin2 х. 3. Является ли обязательным в приведенной программе объявле- ние EXTERNAL Tl, Т2, ТЗ? Чем вызвано отсутствие этого объявле- 254
ния в аналогичных программах, рассмотренных в предыдущих пор- циях? 4. Воспользуйтесь процедурой SIMP2 и составьте программу для вычисления площади поверхности вращения линии у = F (х), огра- ниченной ординатами х = а, х = Ь, вокруг оси ОХ; площадь поверх- ности вращения вычисляется по формуле: ь Q = 2л j F (х) /1 + (F' (х))2 dx, а П о р ц и я 96 Интерпретация объектов памяти Рассматривая объект памяти, мы отличаем его представление от его значения. Получение значения объекта из его представления на- зывается интерпретацией. Например, строка 333 может интерпретиро- ваться как число 219 в восьмеричной системе и число 819 в шестнад- цатеричной системе. В ФОРТРАНе способ интерпретации слов задается объявлением переменной, связанной с этим объектом. Наличие объявлений EQUIVALENCE и COMMON позволяет интерпретировать один и тот же объект разными способами, поставив ему в соответствие несколько переменных различных типов. При этом объявлением EQUIALENCE может декларироваться новая интерпре- тация соответствующего объекта в рамках одного и того же программ- ного модуля, а объявлением COMMON — при установлении межмо- дульных связей. ФОРТРАН/ЕС допускает еще одну возможность различной интер- претации объектов в разных модулях путем задания фактических параметров, тип которых не соответствует типу формальных парамет- ров (стандартом допускается лишь один случай несоответствия типов формальных и фактических параметров: в процедурах-подпрограммах в качестве фактического параметра может быть указана текстовая кон- станта). В общем случае различная интерпретация слов может служить источником ошибок, однако умелое ее использование зачастую оказы- вается полезным. Пример 9. Укрупнение элементов с целью уменьшения числа опе- раций. Головной модуль LOGICAL * 1 STR (16) С ВЫРАВНИВАНИЕ НА ГРАНИЦУ: REAL *8 BOUND EQUIVALENCE (BOUND, STR) READ (1, 1) STR 255
1 FORMAT (16L1) CALL CHECK (STR) STOP END Подпрограмма SUBROUTINE CHECK (NUM) REAL * 8 NUM (2), FALSE/Z00000B00/ IF (NUM (1). EQ. FALSE. AND. NUM (2). EQ. FALSE) GO TO 7 PRINT 11 RETURN 7 PRINT 22 RETURN 11 FORMAT ('ЕСТЬ ЭЛЕМЕНТЫ ИСТИНЫ') 22 FORMAT ('СПЛОШНАЯ ЛОЖЬ') RETURN END |B головном модуле определен логический вектор STR из 16 элемен- тов, каждому из которых отведен один байт. Подпрограмма CHECK проверяет наличие в нем истинных элементов и выдает на печать в за- висимости от наличия хоть одного отличного от .FALSE, элемента в массиве STR текст ЕСТЬ ЭЛЕМЕНТЫ ИСТИНЫ или СПЛОШНАЯ ЛОЖЬ. Интерпретация вектора STR (16) как числового NUM (2) сокращает число проверок с 16 до 2. В программе используется то об- стоятельство, что однобайтовая логическая константа .FALSE, пред- ставляется в памяти кодом #0. Так как величина NUM в подпрограмме выровнена на границу двойного слова, то и исходный вектор также дол- жен быть распределен в памяти с адреса, кратного восьми. Такое рас- пределение памяти будет обеспечено объявлением EQUIVALENCE в головном модуле. Пример 10. Обработка символов. Байтовая адресация. Головной модуль REAL * 8 ТЕХТ/'ЕС 1-0207 С CALL MOVE ('12345', 3, TEXT, 7) PRINT 1, TEXT 1 FORMAT (IX, A8) STOP END Подпрограмма SUBROUTINE MOVE (FROM, I, TO, J) LOGICAL * 1 FROM (1), TO (1) TO (J) = FROM (I) С ПЕРЕСЫЛКА I-ГО СИМВОЛА СТРОКИ FROM 256
С В ПОЗИЦИЮ J-ГО СИМВОЛА СТРОКИ то с RETURN END Результат: ЕС 1-023 В головном модуле текстовая константа присвоена переменной вещественного типа TEXT. В подпрограмме к ней применено описание LOGICAL * 1, благодаря чему становится возможной обработка бай- тов (символов). При этом следует учесть, что текстовая константа всегда выравнивается на границу двойного слова. Подпрограмма MOVE пересылает I-й символ строки FROM в J-ую позицию стро- ки ТО: Пример 11. Хранение информации с перекрытием. Головной модуль: REAL * 8 NUMS (8)/1., В., 1., —1., 1., .5, —.5, —.5/ DO II = 1,7 1 CALL OVERL (NUMS (I)) C STOP END Подпрограмма: SUBROUTINE OVERL (COMPL) COMPLEX * 16 COMPL R = CDABS (COMPL) PRINT 1, R 1 FORMAT (IX, F2B.1B) C RETURN END Результаты: i.bbbbbbbbbb l.BBBBBBBBBB 1.41421318B5 1.41421318B5 1.118B334B91 B.7B71B67691 B.7B71B67691 Благодаря тому, что комплексные числа размером 16 байтов вырав- ниваются на границу двойного слова, первые семь элементов массива NUMS рассматриваются как действительные части комплексных чисел. Таким образом, восемь чисел типа REAL * 8 представляют семь чисел типа COMPLEX * 16. При этом имеет место перекрытие информации: действительная часть всех элементов, начиная со второго, является одновременно мнимой частью предыдущего элемента. 9 9-2712 257
Порция 97 Подпрограммы без параметров Пример 12 В этой порции мы разберем пример использования подпрограммы без параметров. Для этого рассмотрим фрагмент программы, в котором используется процедура вычисления очередного члена ряда Фибо- наччи. (Рядом Фибоначчи называется последовательность чисел 1, 1, 2, 3, 5, 8, 13 и т. д., в которой каждый член, кроме первых двух, яв- ляется суммой двух предыдущих). Пусть подпрограмма, которую обозначим идентификатором FIB, вычисляет по двум предыдущим членам ряда Фибоначчи очередной член этого ряда, который используется в вызывающем программном модуле. Поскольку получаемый член и непосредственно предшествующий ему нужны для вычисления следующего очередного члена, эти две величи- ны должны сохраняться от одного обращения к подпрограмме FIB к следующему. Это может быть достигнуто посредством использования общего блока памяти для вызывающего программного модуля и данной подпрограммы FIB. Для обозначения двух последних членов ряда выберем идентифи- каторы II и 12. Присвоение начальных значений этим переменным II = 12 = 1 может быть осуществлено посредством оператора DATA II, 12/1, 1/ в модуле-блоке данных BLOCK DATA (напоминаем, что присвоить начальные данные переменным 11 и 12 оператором DATA в головном модуле или подпрограмме FIB нельзя, так как эти переменные нами включены в блок COMMON). Модуль BLOCK DATA может быть запи- сан в виде BLOCK DATA COMMON /В/П, 12 DATA II, 12/1,1/ END Здесь общий блок данных обозначен идентификатором В. Таким об- разом, помимо программного модуля, вызывающего подпрограмму FIB, и самой этой подпрограммы FIB, в выполняемую программу дол- жен быть включен приведенный модуль-блок данных. Вызываемая процедура, в которой в объявлении COMMON долж- ны быть указаны идентификаторы последних членов ряда Фибоначчи, может быть записана в виде: SUBROUTINE FIB COMMON /В/П, 12 L = 12 12 - Il + 12 Il = L RETURN END 258
Задание. 1. Можно ли, отказавшись от модуля BLOCK DATA в при- веденном в данной порции примере, получить тот же результат, вклю- чив в подпрограмму FIB соответствующие операторы присваивания? 2. Используя приведенную в данной порции подпрограмму FIB, составьте программу для вычисления и выдачи на печать в виде таб- лицы следующей последовательности величин: ‘+2 (1= 1, 2, .... 20), S ^/+2 /=1 где через обозначен i-й член ряда Фибоначчи. 3. Предположим, что программный модуль, вызывающий под- программу FIB, содержит объявления: INTEGER U, V COMMON/В/U, V Может ли этот программный модуль при каждом очередном обращении к подпрограмме FIB получать от нее очередной член ряда Фибоначчи, если она содержит также оператор V = V — 2*U Порция 98 Подпрограммы и внешние функции Пример 13 Поставим вопрос о том, каким изменениям должна быть подвергну- та приведенная в предыдущей порции подпрограмма FIB для превра- щения ее во внешнюю функцию (которую мы обозначим идентификато- ром FIBO). Прежде всего заметим, что определяемая нами функция будет выдавать результат целого типа, поэтому ее заголовок должен содер- жать описатель типа INTEGER для явного указания типа идентифика- тора FIBO. Согласно определению понятия внешней функции, результат об- ращения к ней должен быть присвоен ее идентификатору. Поэтому вместо идентификатора 12 нами будет использован идентификатор FIBO. Поскольку синтаксис языка требует наличия по крайней мере од- ного формального параметра в определении любой функции, в каче- стве последних естественно взять два предыдущих члена ряда Фибо- наччи, обозначаемые, как и в подпрограмме FIB, идентификаторами И и 12, так как процедура Фибоначчи для получения очередного члена по существу использует два параметра — два предыдущих члена ряда. При этом процедура FIBO не только должна получать через свои пара- метры 11,12 предыдущие члены ряда, но и выдавать через них же (поми- мо выдачи результата через идентификатор FIBO) последующие члены 9* 259
для обеспечения рекуррентности процесса. Таким образом, получаем следующее описание внешней функции FIBO, в котором, как это легко заметить, 12 и FIBO дублируют друг друга. INTEGER FUNCTION FIBO (II, 12) L = 12 12 = Il + 12 FIBO = 12 Il = L RETURN END Заметим, что для обеспечения рекуррентности процесса получения членов ряда Фибоначчи посредством приведенной процедуры необ- ходимо также, чтобы вызывающая процедура сохраняла значения пере- менных II и 12, начальные значения которых должны быть также обес- печены извне процедуры FIBO. Задание. Выполните задание 2, приведенное в предыдущей порции, воспользовавшись при этом описанной в настоящей порции внешней функцией FIBO. П о р ц и я 99 Фиксация числа обрабатываемых массивов Обладая обширным запасом тех или иных изобразительных средств, каждый язык программирования требует представления описываемых в нем алгоритмов в терминах именно этого набора средств. Другими словами, в любом языке как классы форм представления обрабатывае- мых объектов, так и средства обработки ограничены определенными рамками. Примером подобного рода ограничений в языке ФОРТРАН явля- ется недопустимость обработки сложных объектов — массивов разно- типных элементов, древовидных структур и др., а также процедур, обрабатывающих массивы, число которых является переменным, опре- деляемым в момент обращения к этим процедурам, т. е. невозможность задания массива с регулируемыми размерами, компонентами которого были бы в свою очередь массивы (в случае, когда размеры массива, компонентами которого являются массивы, являются фиксированными, можно задачу свести к рассмотрению последовательности массивов). Необходимость же в рассмотрении подобного рода процедур проиллю- стрируем на примере. Предположим, что в результате выполнения определенной програм- мы составляется некоторая фраза, подлежащая выводу и состоящая из заданного числа N слов фиксированной длины. Каждое 1-е (1 = 1, 2, ..., N) слово формируемой строки извлекается из некоторого 1-го словаря, содержащего слов. Набор индексов слов, образующих фразу вывода, определяется некоторым программным модулем. Та- 260
ким образом, в результате выполнения программы образуется массив L (целого типа) L (I), 1 = 1,2, N; каждое L (I) лежит в пределах 1 < L (1)< kt Допустим, требуется составить подпрограмму СТР, формирующую по массиву L строку вывода. При этом, предполагая число N компонент (слов), составляющих фразу, переменным, мы встаем перед проблемой составления подпрограммы, обрабатывающей переменное число мас- сивов, что, как было замечено, языком не допускается. Однако, поскольку объектом обработки составляемой подпрограм- мы в нашем случае является массив L (размера N), можно составить процедуру, рассчитанную на максимальное число Nmax (и соответствен- но использующую массивов-словарей для соответствующих слов формируемых фраз). Считая, например, что N = 5, а также для определенности положив, что словари имеют размеры, указанные в объявлении COMMON (где им присвоены соответственно идентифика- торы Cl, С2, СЗ, С4, С5), необходимую процедуру представим в виде: SUBROUTINE СТР (L) COMMON /А/Cl (Ш), С2 (2в), СЗ (15), С4 (Ш), С5 (2Й) DOUBLE PRECISION Cl, С2, СЗ, С4, С5 DIMENSION L (5) Il = L (1) 12 = L (2) 13 = L (3) 14 = L (4) 15 = L (5) WRITE (3,3) Cl (II), C2 (12), C3 (13), C4 (14), C5 (15) 3 FORMAT (4X, 5A9) RETURN END Заметим, что для хранения пяти массивов, содержащих указанное в программе число элементов, требуется 10 + 20 + 15 + 10 + 20 = = 75 ячеек памяти. Если предположить, что формируемые строки могут содержать любые сочетания содержащихся в этих массивах слов, мож- но получить на выводе 10 • 20 • 15 • 10 • 20 = 600 000 различных фраз. Подобного рода процедура может быть использована при диагнос- тике ошибок, осуществляемой трансляторами. При этом, например, первым словом в выдаваемой фразе может служить глагол, определя- ющий тип оператора, содержащего ошибку (WRITE, READ, ASSIGN, GO TO и т. д.), вторым — код типа ошибки, третьим — номер пози- ции недопустимой литеры в предложении и др. 261
Порция 100 Вывод графиков На следующем примере будут проиллюстрированы возможности, предоставляемые языком ФОРТРАН для вывода данных, в частности, для вывода на печать графиков функций. Предположим, что в программе вычисляются значения некоторой вещественной функции Y (X) с фиксированным по X шагом и требу- ется выдать график этой функции на печать. Допустим, что число позиций в строке вывода равно 120, а вы- водимые значения функции Y принадлежат диапазону Nmin Y Ymax. Тогда цена Н одного деления (позиции) в строке вывода бу- дет определяться соотношением: Y — У тд max 1 min Н “ 120 График функции будет представлен в виде последовательности строк вывода, в каждой из которых размещена в позиции, соответствующей значению функции, литера *. Последняя определяется значением пере- менной целого типа К по следующей формуле: K = (Y-Y^)/H. Предположим, что в одну машинную ячейку помещается 4 литеры, тогда строка вывода должна быть сформирована из содержимого 30 ячеек (120 : 4). Чтобы поместить литеру * в надлежащую позицию строки вывода, введем массив текстовых констант: А(1) = 4Н*ыыи А(3) = 4Н А (2) = 4HL_J*L_|L__I А(4) = 4Hl_jl_jl__i* т. е. А (I) содержит в I-й позиции литеру *, а в остальных — пробел (I = 1, 2, 3, 4). Для формирования строки вывода введем массив В, состоящий из 30 элементов, каждый из которых представляет собой текстовую кон- станту, состоящую из четырех литер. Начальное значение массиву В присвоим посредством объявления DATA B/3# * 4Н lj lj/ обеспечивающего засылку пробелов во все позиции строки вывода. Чтобы поместить литеру * в соответствующую позицию выводи- мой строки, необходимо определить индекс М элемента массива В, который покрывает К-ю позицию строки вывода, и индекс N позиции помещаемой в нем литеры *. Указанные индексы, как нетрудно убедить- ся, определяются равенствами: М = К/4 + 1 N = MOD (К, 4) + 1 262
где MOD — встроенная функция, определяющая остаток от деления числа К на число 4. Пользуясь массивом констант А и определенными значениями пе- ременных М и N, для формирования строки вывода остается восполь- зоваться операторами: В (М) = A (N) WRITE (3,3) В 3 FORMAT (ЗХ, 3£А4) В (М) = С Здесь последний оператор введен для восстановления исходного зна- чения массива В; С — переменная, имеющая своим значением кон- станту 4H(_1L_jl_j1_j. Таким образом, поставленная задача может быть решена путем выполнения следующей последовательности предложений (много- точием в ней обозначены не интересующие нас участки програм- мы): DIMENSION В (Зв), А (4) DATA В/3€'*4Н|_р_и___(/, А/4Н*(_н_ц_|, 4Н|_|*|_ц_н 4Н|_ц_н {определение очередного значения X) {вычисление Y при заданном X) К = (Y — Y MIN)/H М = К/4 + 1 N = MOD (К, 4) + 1 В (М) - A (N) WRITE (3,3) В 3 FORMAT (ЗХ, 3£А4) 5 В (М) = С END Задание. 1. Замените определение массива А посредством объявле- ния DATA его определением посредством оператора ввода. Какой фор- мат должен быть при этом выбран? Обращаем Ваше внимание на то, что, варьируя литеру для изобра- жения графика, мы получим возможность выводить графики, отмечая на них точки кривой разными литерами. 2. Составить подпрограмму построения графика функции; заголо- вок подпрограммы имеет вид: SUBROUTINE GRAPH (YMAX, YMIN, F, Xtf, XN, S) где YMAX, YMIN — наибольшее и наименьшее значение функции на отрезке; Хв, XN — начальное и конечное значение аргумента 263
функции f (х); S — шаг по аргументу; F — идентификатор внешней функции. Используя подпрограмму GRAPH и внешнюю функцию F (X), Составить программу для построения графика функции f (х) = х2 на отрезке [—4; 4] с шагом 0.25 по х. Порция 101 Анализ прямоугольной структуры (ФОРТРАН/ЕС) Рис. 33 Дана квадратная решетка, заданная точками плоскости с коор- динатами X, Y = 1, 2, ..., К, связанными между собой горизонтальны- ми и вертикальными линиями. Связи между точками зададим с по- мощью двух логических массивов. Элемент массива HOR (I, J) устанавливается в. TRUE., если в 1-й строке J-я точка связана с J + 1 точкой, и в .FALSE, в противном слу- чае. В частности, для структуры, приведенной на рисунке 33, HOR (2,1) равно .FALSE. HOR (2,2) равно .TRUE. Аналогично с помощью массива VER зададим связи пар соседних точек по вертикали. Составим программу, печатающую по логи- ческим массивам связей соответствующую решет- ку и вычисляющую количество содержащихся в ней квадратов каждого допустимого размера. Например, структура, приведенная на рис. 33, включает три квадрата со стороной, равной 1, и один квадрат со стороной, равной 2. В программе используются подпрограмма PRINTS и внешняя функ- ция COGNIS. Подпрограмма PRINTS печатает изображение исходной решетки. Логическая функция COGNIS определяет принадлежность к решетке квадрата со стороной, равной L, и заданной верхней левой вершиной. Подпрограмма PRINTS: SUBROUTINE PRINTS (HOR, VER, N) LOGICAL * 1 HOR (N, N), VER (N, N), LOG * 4, X INTEGER LINE (2)/'*', '*---7, I (2)/'^', '17 С ПРЕОБРАЗОВАНИЕ LOGICAL * 1 В LOGICAL: LOG (X) = X С ИНТЕРПРЕТАЦИЯ LOGICAL КАК INTEGER: INDEX (К) = К + 1 DO 1 J = 1, N PRINT 11, (LINE (INDEX (LOG (HOR (J, L)))), L = 1, N) DO 1, M = 1, 2 1 PRINT 11, (I (INDEX (LOG (VER (J, L)))), L = 1, N) 264
11 FORMAT (IX, 30A4) RETURN END На каждом из N = DIM шагов печатается строка решетки, со- стоящая из N специально подобранных элементов и N вертикальных отрезков, соединяющих связанные точки i-й строки с точками i + 1 строки. Текстовые константы, которые используются как элементы для печати горизонтальных линий, хранятся в массиве LINE. LINE (2) содержит константу '*-', изображающую /-ю точку строки и отрезок, соединяющий ее с / + 1 точкой; LINE (1) содержит константу изображающую точку, не связанную с соседней по горизон- тали. Текстовые константы, которые используются как элементы печати отрезков вертикальных линий, хранятся в массиве I. I (1) содержит константу (четыре пробела) и используется в том случае, когда вертикальный отрезок не формируется; I (2) содержит константу 'I^jl^^j' и используется, когда строится вертикальный отрезок. Строка с элементами массива I строится дважды после печати строки с элемен- тами LINE. Например, на первом шаге печати структуры, изображенной на рис. 33, будут выведены следующие три строки печати: * — — — * ,____( । . * — — — * 1 ( 1 I L—I L—j l__. 1 . I l_u 1 _ _ _ Если HOR (J, L) равно .TRUE., печатается LINE (2); иначе — LINE (1). Индекс LINE формируется при помощи следующей цепочки пре- образований. Внутренняя функция LOG преобразует значение HOR (J, L) к типу LOGICAL * 4. Так как внутреннее представление .TRUE, совпадает с представлением целого числа 1, a .FALSE.— с представле- нием числа значение внутренней функции INDEX равно 2 при HOR (J, L), равной .TRUE., и 1 при HOR (J, L), равном .FALSE.. Анало- гично формируется индекс в списке вывода вертикальных отрезков. Функция COGNIS: LOGICAL FUNCTION COGNIS (X, Y, L, N) LOGICAL * 1 X (N, N), Y (N, N) COGNIS = = X (1, 1). AND. Y(l, 1). AND. X (L + 1, L). AND. Y (L, L 1) IF (.NOT. COGNIS. OR. L. EQ. 1) RETURN COGNIS = = X (1, L). AND. Y (L, 1). AND. X (L + 1, 1). AND. Y (1, L + 1) IF (.NOT. COGNIS. OR. L. EQ. 2) RETURN LL = L — 1 DO 1 J = 2, LL 265
COGNIS = X (1, J). AND. Y (J, 1) * . AND. X (L, J). AND. Y (J, L) IF. (.NOT. COGNIS) RETURN 1 CONTINUE END Проверка, существует ли в структуре N X N квадрат со стороной длины L с левым верхним углом, заданным точкой с координатами X и Y, выполняется в три этапа. 1. Для L = 1 достаточно проверки двух узлов: 2. Если L = 2 и результат первого этапа равен .TRUE., допол- нительно проверяются еще два узла: 3. При L = 3, если результат предыдущего этапа равен .TRUE., дополнительно проверяется наличие промежуточных звеньев, соеди- няющих внутренние узлы: На любом шаге, если значение логического выражения равно .FALSE., осуществляется выход из процедуры. Ниже следует пример решения задачи для решетки 5 X 5 (DIM = = 5). В логическом массиве X (горизонтальные связи) элементы по- следнего столбца, а в массиве Y (вертикальные связи) элементы по- следней строки равны .FALSE, (так как точки последней строки и последнего столбца не связаны с последующими точками). Сначала программа печатает изображение решетки с помощью подпрограммы PRINTS. Затем на каждом из DIM — 1 шагов просма- триваются К2 точек (К = 4,3,2,1) и для каждой точки с помощью функции COGNIS проверяется существование квадрата со стороной длины L = DIM — К, в котором эта точка задает левый верхний угол. Количество квадратов подсчитывается и печатается в виде таблицы. LOGICAL * 1 X (5,5), Y (5,5), COGNIS * 4 INTEGER DIM 15 FORMAT (5L1) READ 10, X, Y DIM = 5 266
L = 1 К = 4 CALL PRINTS (X, Y, DIM) PRINT 2 7 NUM = & DO 51 = 1, К DO5J = 1, К 5 IF (COGNIS (X (I, J), Y (I, J), L, DIM)) NUM = NUM + 1 PRINT 1, L, L, NUM L = L + 1 К = K- 1 IF (L.LE.4) GO TO 7 STOP 1 FORMAT (IX, 13, II, 8X, 12) 2 FORMAT (//IX, 'РАЗМЕР', ЗХ, 'КОЛИЧЕСТВО') END Пример вывода: РАЗМЕР КОЛИЧЕСТВО 1*1 9 2*2 2 3*3 1 4*4 Q Порция 102 Обработка матриц в ФОРТРАН/ЕС (регулируемые размеры массивов; спецификация формата, задаваемая в массиве) Рассмотрим пример, иллюстрирующий использование в процеду- рах массивов с регулируемыми размерами. Кроме того, на данном примере демонстрируются возможности задания спецификаций фор- мата, изменяемых в процессе выполнения программы. С этой целью спецификация формата задается в массиве, а ее изменение достига- ется путем изменения значений соответствующих его элементов. Дана квадратная .матрица N х N, представленная в программе двумерным массивом X. 267
Требуется построить подпрограмму вывода на печать всех матриц размером п X п, где 1 п 4^ N, с главной диагональю Хц (i = 1,... п) При решении этой и подобных задач часто пользуются перемен- ной размерностью. Иногда это приводит к ошибкам, вызванным не- правильным использованием формулы приведенного индекса. Рас- смотрим вначале причины возможных ошибок. В головном модуле сформирован массив целого типа X, в котором для наглядности Хи — ij(= Ю • i + j; например, Xo.s = 25) Существенно, что значение размерности изменяется именно в го- ловном модуле, а затем, через общий блок, передается в подпрограм- му VARD для печати очередной матрицы. На первый взгляд, правильным может показаться следующее решение: INTEGER X (8, 8) COMMON N N = 8 DO II = 1,8 DO U = 1,8 i x (j, i) = j * ia+ I DO 21 = 1,8 CALL VARD (X) 2 N = N — 1 STOP END SUBROUTINE VARD (I) COMMON N DIMENSION I (N, N) EQUIVALENCE (INSERT, LOG (2)), (LOG, ARR) LOGICAL * 1 DIG (8)/’Г, ’2’, ’3’, ’4’, ’5’, ’6’, 7’, ’87, * INSERT, LOG * 4 (2) REAL * 8 ARR (1) DATA ARR (1)/’ (IX, 14)7 INSERT = DIG (N) PRINT ARR, ((I (L, J), J = 1, N), L = 1, N) RETURN END 268
Напомним, что значение переменной размерности может быть передано в подпрограмму либо через параметр (как это опреде- лено стандартом языка), либо через общий блок (ЕС-расшире- ние). Как известно, при обработке массивов, являющихся формаль- ными параметрами, используется память фактического массива, а размерность — формального, причем именно последняя учитывается при вычислении приведенного индекса. В приведенном выше примере значения элемента общего блока N и локальной переменной, содержащей размерность, совпадают в те- чение всего времени выполнения программы. Формула приведенного индекса меняется на каждом шаге цикла, а распределение памяти остается неизменным. В результате при выполнении программы будут получены вместо искомых следующие матрицы 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27 28 81 82 83 84 85 86 87 88 11 81 72 63 54 45 36 21 12 82 73 64 55 46 71 62 53 44 35 26 17 11 41 71 21 51 81 31 61 12 11 31 21 41 11 Для получения правильного результата необходимо «разделить» переменные, введя дополнительную переменную в качестве парамет- ра. Тогда обращение к VARD будет иметь вид INTEGER X (8,8) COMMON N N = 8 DO II = 1,8 DO 1J = 1,8 DO 21 = 1,8 2 CALL VARD (X, I) STOP END 269
При этом начало подпрограммы VARD должно иметь вид SUBROUTINE VARD (I, К) COMMON N DIMENSION I (N, N) а в остальной ее части необходимо заменить N на К. Мы, однако, покажем, что в ФОРТРАН/ЕС подобное разделение переменных можно осуществить без введения дополнительных пара- метров (обозначений). Правильным будет следующее решение: INTEGER X (8, 8) COMMON N N = 8 DO II = 1,8 DO 1J = 1,8 i x(j, i) = j »ia + i c CALL VARD (X) STOP END SUBROUTINE VARD (I) COMMON N DIMENSION I (N, N) EQUIVALENCE (INSERT, LOG (2)), (LOG, ARR) LOGICAL ♦ 1 DIG (8)/’Г, ’2’, ’3’, ’4’, ’5’, ’6’, 7’, ’87, * INSERT, LOG*4(2) REAL * 8 ARR (1) DATA ARR (1)/’(IX, ^14)7 C 1 INSERT = DIG (N) PRINT ARR, ((I (L, J), J = 1, N), L = 1, N) N = N — 1 IF (N. EQ.d) RETURN GO TO 1 RETURN END Результаты: 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27 28 81 82 83 84 85 86 87 88 11 12 13 21 22 23 31 32 33 270
11 12 21 22 11 Подпрограмма VARD вызывается единственный раз. При обра- щении к VARD в память (которая не имеет имени) заносится число 8; последнее сохраняется и используется в формуле приведенного индек- са в течение всего периода выполнения программы. Оператор N = = N — 1 изменяет только содержимое общего блока, но не значение размерности. В программе используется переменный формат. Спецификации заданы в массиве ARR (использование простой переменной для этой цели, даже если ее размеры достаточны, не допускается). Переменным в тексте спецификаций является пятый символ, указывающий коэф- фициент повторения спецификации 14 в зависимости от количества элементов в строке матрицы X. Формирование этого коэффициента осуществляется логическим оператором присваивания INSERT = = DIG (N) в соответствии со следующей схемой эквивалентности имен ARR (1) LOG (1) INSERT I 4 ) LOG (2) Порция 103 Особенности использования и преобразования объектов в ФОРТРАН/ЕС Использование, интерпретация и преобразование объектов имеют в ФОРТРАН/ЕС некоторые особенности, вызванные введением в этот язык новых типов данных и правилами внутреннего представления. В частности, введение шестнадцатеричных данных позволяет фор- мировать число непосредственно во внутреннем представлении. От- сюда вытекает, что в ФОРТРАН/ЕС можно задать вещественное число в ненормализованном виде, например, следующим образом: REAL R /Z43O5531/ т. е. 0.0055311в • 163 Так как использование ненормализованных чисел ведет к потере точности, все операции над вещественными числами выполняются в ФОРТРАН/ЕС с нормализацией. Поэтому при вычислении значения арифметических выражений можно выделить дополнительный этап — нормализацию. Так, при вычислении R + X величина R будет пред- ставлена перед выполнением сложения как 41553100 = 0.55311б • 161. 271
Следует заметить, что при выполнении операции присваивания веще- ственное число не нормализуется. Так, при выполнении оператора Y = X значение Y будет ненормализованным, если X ненормализо- вано. Еще одна особенность вызвана введением данных типа INTEGER ♦ 2. Так как для целой константы всегда отводится память типа INTEGER *4, во многих случаях в выражениях целого типа возника- ют дополнительные преобразования. Например, в операторе 5 INTEGER * 2 HALF HALF = 255 5 HALF = HALF + 1 вначале значение HALF будет преобразовано к типу INTEGER * 4: HALF t&Q , FF, TEMP , Off , ffff , ffff , FF, затем будет выполнено сложение TEMP = TEMP + 1 и, наконец, при пересылке значения TEMP в HALF будет выполнено преобразова- ние INTEGER *4 в INTEGER *2: temp , ея , , ei, ее, half ,ffi , &&, Заметим, что преобразование INTEGER * 2 в INTEGER *4 не сводится к простой пересылке двухбайтового значения в четырехбай- товое поле. Одновременно с этим первые два байта принимающего четырехбайтового поля заполняются двоичной цифрой, соответствую- щей знаку числа (О соответствует плюсу, а 1 — минусу). Эта операция сохраняет представление отрицательных целых чисел в виде допол- нительного кода, а положительных целых — в виде прямого кода. Например, во фрагменте INTEGER *2 II/— 15/ l = ii...... значение II представляется дополнительным шестнадцатеричным ко- дом FFF1, а значение L соответствующим дополнительным кодом FFFFFFF1. Десятичное представление L равно — (FFFFFFFF — FFFFFFF1 + 1)16 = — 1510 Обратите внимание, что при делении целых знаковый разряд иг- рает аналогичную роль. Так, при вычислении выражения 1/16, где пе- ременная I имеет тип INTEGER *4, деление реализуется сдвигом впра- во на один шестнадцатеричный разряд. Двоичные разряды, освобо- ждающиеся при сдвиге, заполняются двоичной цифрой, соответству- ющей знаку. При I = —64, например, r FF FF FF Cf I L--1---1--1---) 272
значение 1/16 равно —4; код этой константы имеет вид FF FF FF FC I——I--1----1___I Освободившийся шестнадцатеричный разряд заполнен цифрой F с двоичным кодом 1111. Переменными типа INTEGER * 2 нельзя пользоваться в операторах ASSIGN и GO ТО по предписанию. Это объясняется тем, что метке соответствует адрес памяти, для хранения и представления которого в ЕС ЭВМ отводится 3 байта. В связи с введением новых типов данных набор встроенных функ- ций, используемых для преобразования типа, в ФОРТРАН/ЕС расши- рен (см. табл. 36). С одной стороны, расширены имеющиеся семейства функций. Так, к функции FLOAT добавлена DFLOAT, к IFIX добав- лена HFIX, к INT и AINT добавлены DINT и IDINT. С другой сторо- ны, введены новые функции усечения младших разрядов мантиссы SNGL (X) и увеличения точности DBLE (X). Выполнение функции SNGL (X), где X — переменная типа REAL ♦ 8 сводится к взятию первого слова из двух, содержащего порядок, и 6 шестнадцатеричных из 14-ти цифр мантиссы X: Л т X ‘ REAL * 8Х R ; Л R=SNGL(X) Выполнение DBLE, где X — переменная типа REAL *4, сводится к созданию двойного слова, причем значением первого из них является значение X, а второго — шестнадцатеричные нули, представляющие 8 младших разрядов мантиссы. Функция используется при вычислении выражений для перевода REAL *4 в REAL *8. В следующем ниже примере иллюстрируется действие функции DBLE: DOUBLE PRECISION DP, EX DP = 1.3D# EX - DBLE (1.3) R _ J 3 PRINT 3, R, DP, EX 3 FORMAT (IX, Z8/1X, Z16/1X, Z16) STOP END В результате выполнения приведенной программы в шестнадца- теричном виде печатаются значения константы 1.3, представленные в памяти способами: 1. С обычной точностью: 4114СССС 2. С повышенной точностью: 4114СССС СССССССС 3. С увеличенным размером: 4114СССС &&&&&&&& 273
При выполнении некоторых преобразований могут возникать ситуации, связанные с искажением исходного значения. Рассмотрим, например, следующий фрагмент программы: INTEGER *4 MAX/Z7FFFFFFF/ 2 R = МАХ CALL OVERFL (R) в котором в операторе 2 используется функция FLOAT для преобра- зования INTEGER*4 в REAL*4 Произведя это преобразование вручную, получим 0.7FFFFFFF16 • 168 или, в соответствии с правилами внутреннего представления веще- ственных чисел, код: 487FFFFFFF Как видно, эквивалент значения МАХ в форме REAL занимает 5 байтов памяти, т. е. имеет место переполнение мантиссы. При этом R присваивается усеченный справа до слова код 48 7FFFFF. Таким об- разом, фактически мы получили число 487FFFFFO = 7FFFFFW = 2147483392.-0 Имеющаяся в ФОРТРАН/ЕС подпрограмма OVERFL (см. порц. 120) фиксирует переполнение порядка, а не мантиссы, поэтому возникшая ситуация не обнаруживается программными средствами. Задание. 1. Равны ли значения, присваиваемые переменной SUM следующими ниже операторами: a) DOUBLE PRECISION SUM SUM = SUM + A (I, J)*X (J) 6) DOUBLE PRECISION SUM, AX, XX AX = A (I, J) XX = X (J) SUM = SUM + AX * XX 2. Какое преобразование типа выполняется функцией X? FUNCTION X (Y) INTEGER * 2Y DATA CONST /Z461-&-eoee/ EQUIVALENCE (IR, R) R = CONST IR = IR + Y R = R — CONST X = R RETURN END 274
Порция 104 Умножение целых чисел с повышенной точностью Требуется написать подпрограмму, печатающую целое число i = х • у, где х и у не более чем шестиразрядные целые десятичные числа. В об- щем случае i — двенадцатиразрядное число, т. е. выходит за допус- тимый в ЕС ЭВМ диапазон целых чисел. Тем не менее, результат можно получить на печатающем устройстве, если представить х и у в виде х = рх • 103 + qx У — РУ • 103 + ЧУ где рх, qx, ру, qy — трехразрядные числа, и использовать формулу i = ху = (рх • ру) • 10б + (qx • ру + рх • qy) • 103 + + (qx, qy) = I • 106 + m • 103 + г Дальнейший ход действий проиллюстрируем на примере. Пусть х = 123 456, у = 654 321. Тогда i равно сумме 080442 000000 + } 000000 146376 + Г 000337 707000 Теперь, независимо от исходных х и у, нетрудно получить два числа, одно из которых представляет первые шесть разрядов резуль- тата, а второе — последние шесть разрядов. Для нашего примера сле- дует выполнить действия: LEFT = 080442 + 337707/1000 = 080779 (первые шесть раз- рядов) RIGHT - 146376 + mod (337707, 1000) X 1000 = 146376 + + 707000 = 853376 (последние 6 разрядов) LEFT - LEFT + (RIGHT/1000000) Последнее из указанных действий обеспечивает возможный перенос в 7-ой разряд. Далее остается напечатать одно за другим (в виде непрерывной строки) значения LEFT и RIGHT в формате I. Однако, если ведущими цифрами RIGHT окажутся нули, при выводе по формату I вместо них будут напечатаны пробелы. Во избежание этого эффекта, перед выводом на печать к значению RIGHT прибавляется число 1000000, т. е. в седь- мом разряде (в строке вывода это восьмая позиция) формируется 275
дополнительно единица. Строка вывода формируется затем с помощью формата Т таким образом, что значение LEFT перекрывает этот раз- ряд. Сначала формируется знак числа и младшие разряды: Т8 затем в строку печати вставляются старшие разряды. Необходимая подпрограмма может быть представлена в виде: SUBROUTINE MULTEX (А, В) INTEGER X, Y, РХ, PY, QX, QY, А, В, RIGHT, T/13W LOGICAL* 1 SIGN (2)/'^', '—'I I = 1 RIGHT = Q IF (A.EQ.-&.OR.B.EQ.#) GO TO 3 X = IABS (A) Y = IABS (B) PX = X/T QX = MOD (X, T) PY = Y/T QY = MOD (Y, T) LEFT = PX * PY RIGHT = QX*QY MID = QX ♦ PY + PX * QY LEFT = LEFT + MID/T RIGHT = RIGHT + MOD (MID, T) * T LEFT = LEFT + (RIGHT/1W0-000) IF (ISIGN (1, A). NE. ISIGN (1, В)) I = 2 IF (LEFT. EQ.e) GO TO 3 RIGHT = RIGHT + PRINT 2, SIGN (I), RIGHT, LEFT 2 FORMAT (IX, Al, T8, 17, T3, 16) RETURN 3 PRINT 33, SIGN (I), RIGHT 33 FORMAT (IX, Al, 16) RETURN END Обращаясь к этой подпрограмме оператором CALL MULTEX (253^30, 55757S), получим результат: 141-&819371-8-0 276
Порция 105 Особенности использования текстовых констант в ФОРТРАН/ЕС Если текстовая константа указана в некотором объявлении, т. е. присвоена переменной, то все атрибуты этой переменной распростра- няются на текстовую константу. Так, в результате объявления INTEGER R (2)/'ABCD', 'EFGH'/ текстовая константа будет представлена двумя элементами массива размером по 4 символа. Объявление LOGICAL * 1 R(8)/8*'L7 задает текстовую константу 'LLLLLLLL', которая присваивается массиву R; при этом исполь- зование переменной R с индексами обеспечивает обращение к отдель- ным элементам (символам) текста. Текстовая константа, используемая в качестве фактического па- раметра внешних процедур, интерпретируется в соответствии с ат- рибутами соответствующего формального параметра. При распре- делении памяти для таких констант транслятор отводит поле с ад- ресом, выровненным на границу двойного слова, чем обеспечивается возможность применения любой (определяемой формальным пара- метром) интерпретации. Пример. Опишем подпрограмму LET, присваивающую текстовую константу «текстовым переменным». Под текстовой переменной будем понимать поле памяти, задан- ное некоторым начальным адресом. Этот начальный адрес может быть представлен простой или индексированной переменной или именем массива. Процедура LET имеет три параметра: текстовая переменная, текс- товая константа, размер константы в символах. Например, дано объявление REAL *8 FIELD (Ш) Требуется присвоить переменной FIELD (2) текстовую константу 'CONSTANT'. Для этого достаточно написать CALL LET (FIELD (2), 'CONSTANT', 8) Подпрограмму LET можно представить в виде: SUBROUTINE LET (VAR, С, N) LOGICAL* 1 VAR (1), C (1) DO 51 = 1, N 5 VAR (I) = С (I) RETURN END 277
Обратите внимание, что в подпрограмме LET простые переменные интерпретируются как массивы в соответствии с объявлением LOGICAL* 1 VAR (1), С (1) и, следовательно, вызываются по адресу. - Задание. Определите, какое значение будет присвоено переменной L в результате выполнения следующего фрагмента программы: LOGICAL L INTEGER A/'ABCD7 REAL B/'ABCD7 L = A.EQ.B Порция 106 Поразрядная сортировка Ниже приводится программа упорядочения по возрастанию по- следовательности из 40 двузначных десятичных целых неотрицатель- ных чисел методом поразрядной сортировки. В общем случае можно рассмотреть NN чисел с разрядностью К. Предполагается, что исход- ный массив чисел, подлежащих сортировке, не содержит повторяю- щихся элементов. Для реализации метода используется двумерный массив POCKET, состоящий из 10 столбцов (по количеству десятичных цифр). Каж- дый столбец предназначен для размещения чисел с одной и той же цифрой в рассматриваемом разряде. Так как исходный массив не содержит повторяющихся элементов, для К = 2 достаточно 10 строк. В общем случае в массиве POCKET должно быть 10Л~* строк. Индекс столбца 12 3 45 678 9 10 Цифра 01 2345678 9 12 62 72 02 22 32 42 52 92 82 Сортировка осуществляется за К шагов. На каждом шаге вы- полняются следующие действия: 1. Начальная установка указателей позиций в столбцах массива POCKET (POS (Т) = 1, Т = 1, 2, ..., 10). 2. Просмотр сортируемого массива и размещение его элементов в 278
столбцы POCKET в соответствии со значением рассматриваемого разряда. Если в N-м разряде стоит цифра J, то число помещается в J + 1-й столбец в первую свободную позицию. 3. Выборка чисел из POCKET и формирование текущего массива NUM, пересортированного по текущему разряду. Числа выбираются, начиная с первого столбца. Из J-ro столбца выбирается POS (J) — 1 чисел. В массив NUM числа заносятся столбцами подряд, начиная с первой позиции. г DO IB N = 1, к [1. Очистка массива POCKET. [2. Формирование POCKET. . [3. Выборка из POCKET. IB CONTINUE Пример Исходный массив 65 21 01 55 33 32 Шаг 1. 0 1 1 2 3 5 1 6 21 01 32 33 65 55 21 01 - 32 33 65 55 Ш а г 2. .------------------------------------------------------------- 01 21 32 33 55 65 01 21 32 33 55 65 С ПОРАЗРЯДНАЯ СОРТИРОВКА INTEGER NUM (4В) INTEGER POS (IB), POCKET (IB, IB) INTEGER R, T READ 2, NUM 2 FORMAT (2BI2) С К - КОЛИЧЕСТВО РАЗРЯДОВ, NN — КОЛИЧЕСТВО ЧИ- СЕЛ К = 2 NN = 4В DO 1BN = 1, К DO 2ВТ = 1, IB 2B POS (T) = 1 R = IB ** N СОРТИРОВКА: DO 3BT = 1, NN J = MOD (NUM (T), R)/(R/1B) + 1 POCKET (POS (J), J) = NUM (T) 3B POS (J) = POS (J) + 1 279
С ФОРМИРОВАНИЕ МАССИВА, ПЕРЕСОРТИРОВАННОГО С ПО ТЕКУЩЕМУ РАЗРЯДУ J = Q Т = 1 3 J = J + 1 I = 1 4 IF (Т. GT. NN) GO ТО 10 IF (I. GE. POS (J)) GO TO 3 NUM = POCKET (I, J) 1 = 1 + 1 T = T + 1 GO TO 4 1-0 CONTINUE PRINT 22, NUM 22 FORMAT (IX, 4013) STOP END Порция 107 Использование списковых структур Дан массив ARR из N элементов типа COMPLEX * 16, содержащий последовательность текстовых констант. Последние составлены из латинских букв, десятичных цифр и пробелов. Необходимо задать алфавитный порядок элементов в массиве без перемещения их в памяти, сформировав массив LINK «связей» элементов исходного массива ARR, I-й элемент которого имеет струк- туру LINK (I) = PREV NEXT где PREV — номер предыдущего, NEXT — номер следующего эле- ментов массива ARR в алфавитном порядке (I = 1, 2, ..., N). Для пер- вого по алфавиту элемента полагаем PREV = 0; для последнего, ана- логично, NEXT = 0. Коды, используемые в ЕС ЭВМ для внутреннего представления латинских букв и десятичных цифр, рассматриваемые как целые положительные числа, в шестнадцатеричной системе упорядочены по возрастанию. Например, букве А соответствует шестнадцатеричный код С1, букве В — код С2 и т. д. Пробел представляется кодом 40, поэтому он предшествует всем буквам алфавита. 280
Литера Шестнадцатеричный код Двоичный код Пробел А 40 С1 01000000 11000001 Z Е9 11101001 И F0 11110000 9 F9 11111001 Учитывая это обстоятельство, отношение предшествования для рассматриваемых литер можно заменить отношением «меньше». Рассматривая действительную и мнимую часть элемента массива ARR как числа типа REAL*8 (фактически это строки литер), заме- тим, что какая бы из указанных литер не была записана в первом бай- те числа, число окажется отрицательным, так как первый бит любого из них равен единице, а порядок — положительный, так как второй бит равен единице. Если в первом байте числа записан пробел, то число положительно, и его порядок равен нулю (см. порцию 10). В связи с этим для строк литер, рассматриваемых в целом, отно- шение предшествования можно заменить отношением «больше» (от- рицательное число больше, если порядок — первая буква — меньше). Если при совпадающих знаках действительной части совпадают по- рядки (первые буквы),то при сравнении сыграет роль различие ман- тисс. Если мантисса меньше (число больше), то слово предшествует по алфавиту. При совпадении действительных частей анализируются мнимые части. Для описания в языке структуры элементов LINK используем массив NODE, задаваемый объявлением EQUIVALENCE так, что NODE (1*2—1) содержит соответствующее значение PREV элемен- та LINK (I), a NODE (1*2) — значение NEXT. »NTE6£R , Unko , , , • • • , , , LINK i-f | INTEGER • • •__. ...... 2 1-2 1-1 1 node2i.f\ode2i node2n С помощью эквивалентности в массив LINK включен специаль- ный элемент с нулевым индексом. Значение NEXT этого элемента рав- но номеру первого по алфавиту слова в ARR, a NEXT — последнего. 281
Аналогичным образом расширен влево на один элемент массив ARR. ARR С&) содержит комплексное число, действительная и мнимая части которого равны наибольшему по модулю отрицательному веществен- ному числу, допустимому в ЕС ЭВМ. Этот элемент используется при сортировке как строка, предшествующая по алфавиту всем возмож- ным строкам. Список связей LINK, задающий лексикографический порядок, создается подпрограммой ORDABC. Например, для последовательно- сти строк ARR (1) АВА ARR (2) ААС ARR (3) АВВ ARR (4) ААА Массив связей будет иметь вид: 432341 1002 0 12 3 4 На каждом шаге цикла, который начинается меткой 1: 1. Находится NEXT, т. е. индекс следующего по порядку элемента, причем элементы, для которых связи уже построены, не просматрива- ются. « j 2. Формируется величина PREV в LINK (NEXT), т. е. устанавли- вается связь текущего элемента с предшествующим. 3. Формируется величина NEXT в LINK (PREV), т. е. в предыду- щем элементе устанавливается связь с данным. Благодаря введению элемента LINK (-&) все эти действия возможны уже на первом шаге цикла. После завершения цикла формируется величина NEXT в LINKC&) и величина NEXT = 0 в последнем по порядку элементе. Несмотря на то, что ARR (I) и LINK (I) находятся в несмежных по- лях памяти, они связаны взаимнооднозначным соответствием. Поэтому можно считать, что в программе моделируется единый структурный эле- мент вида ARR PREV NEXT содержащий объект и его связи с другими объектами набора. Струк- туры, аналогичные набору элементов массива LIST, называют списками. Используя информацию, содержащуюся в списке, подпрограмма DIROUT печатает содержимое ARR в алфавитном порядке. Подпро- грамма REVOUT печатает строки в обратном порядке. Эти подпрограм- мы реализованы в виде единого модуля с двумя входами. Индекс на- чального элемента для каждой подпрограммы берется в LINK (#)• 282
Подпрограмма упорядочения: SUBROUTINE ORDABC (ARR, NUM, LINK) INTEGER * 2 LINK (1), PREV * 4 COMPLEX * 16 ARR (1), X, Y REAL * 8 P (2), Q (2) EQUIVALENCE (X, P), (Y, Q) C NR = NUM PREV = e 1 NEXT = •& C DO 41 = 1, NUM IF (LINK (I * 2 — 1). GE.-&) GO TO 4 X = ARR (I) Y = ARR (NEXT) IF (P (1) — Q (1)) 4, 2,3 2 IF (P (2) — Q (2)) 4, 3, 3 3 NEXT = I 4 CONTINUE LINK (NEXT * 2 - 1) = PREV LINK (PREV * 2) = NEXT NR = NR — 1 PREV = NEXT IF (NR. NE. S) GO TO 1 LINK (1 — 2) = NEXT LINK (NEXT * 2) = •& RETURN END Подпрограмма вывода: SUBROUTINE REVOUT (ARR, NUM, LINK) COMPLEX * 16 ARR (1) INTEGER LINK (1) INTEGER * 2 R (2) EQUIVALENCE (R, K) L = 1 GO TO 11 ENTRY DIROUT (ARR, NUM, LINK) L = 2 11 J = 0 PRINT 12 DO ie I = 1, NUM К = LINK (J) PRINT 12, I, ARR (R (L)) 1# J = R (L) 283
12 FORMAT (13, ЗХ, 2A8) RETURN END Головной модуль: COMPLEX * 16 ARR (25), Q (2) EQUIVALENCE (ARR, Q (2)), (Q (1), LOG) LOGICAL * 1 LOG (16)/16 * ZFF/ EQUIVALENCE (LINK, S (2), NODE) INTEGER LINK (25), NODE * 2 (50), S (2) N = 25 DO 55 NUM = 1, N READ (1,5, END = 555) ARR (NUM) PRINT 15, NUM, ARR (NUM) 55 LINK (NUM) = —1 555 CALL ORDABC (ARR, NUM — 1, LINK) К = —1 NUM = NUM — 1 L = NUM + NUM PRINT 10, (NODE (I), NODE (I + 1), I = K, L, 2) CALL DIROUT (ARR, NUM, LINK) CALL REVOUT (ARR, NUM, LINK) STOP 5 FORMAT (2A8) 10 FORMAT (///217// (217)) 15 FORMAT (13, ЗХ, 2A8) END Замечание. Хотя в головном модуле описан массив ARR, как мас- сив, содержащий 25 элементов, использование параметра END в опера- торе READ позволяет завершить ввод при чтении карты, содержащей код /* — признак конца файла. При этом параметр цикла NUM будет равен числу введенных элементов, увеличенному на единицу. Пусть исходная последовательность элементов массива ARR имеет вид: FORTRAN 2.0 FORTRAN 2.2 EDITION PRIMER ARTIST ARTICLE COMMUNICATIONS ZERODIVIDE OVERFLOW THIS BOOK AUTHORITY 284
CODIAL MALGOR ES /♦ Головная программа выдает на печать этот же массив, снабжая каждую строку печати номером. Подпрограмма ORDABC выдает на печать индексы конечного и на- чального по алфавиту элементов и массив, задающий отношения пред- шествования LINK для всех элементов. LINK (^) 8 6 LINK 3 2 1 13 7 1 9 10 6 11 0 5 12 3 10 0 13 4 4 8 5 12 11 7 2 9 В результате вызова подпрограммы DIROUT на печать выдаются элементы массива в алфавитном порядке: 1 ARTICLE 2 ARTIST 3 AUTHORITY 4 CODIAL 5 COMMUNICATIONS 6 EDITION 7 FORTRAN 2.0 8 FORTRAN 2.2 9 MALGOR EC 10 OVERFLOW 11 PRIMER 12 THIS BOOK 13 ZERO DIVIDE Подпрограмма REVOUT выдает тот же массив в обратном порядке. Порция 108 О реализации рекурсивных процедур в ФОРТРАН/ЕС Реализация рекурсивных процедур сопряжена с определенными затруднениями, связанными с необходимостью хранения нескольких поколений значений параметров. ФОРТРАН/ЕС, как и стандарт язы- ка, не допускает рекурсивных процедур. 285
Если в нарушение этого ограничения в некоторой процедуре будет задано непосредственное обращение к самой себе, то такая рекурсия обнаруживается транслятором с ФОРТРАН/ЕС как синтаксическая ошибка. На косвенную рекурсию транслятор (в силу раздельной транс- ляции модулей) не реагирует; однако ее использование приводит к неправильному выполнению операторов CALL и RETURN. Прибегая к некоторой «транзитной» процедуре и осуществляя че- рез нее рекурсивные обращения, а также используя магазинную па- мять, можно реализовать некоторые рекурсивные процедуры на ФОРТРАН/ЕС. Особенность подобной реализации состоит в такой орга- низации управления в процедурах, при которой выполнение опера- торов RETURN избегается. Программа завершает свое выполнение пе- редачей управления оператору STOP (содержащемуся не в головной программе, а в рекурсивно выполняемой процедуре). Для иллюстрации описанного приема рассмотрим задачу о ханой- ских башнях. Рекурсивное решение задачи о ханойских башнях. Задача о ханойских башнях формулируется следующим образом. Имеются три вертикальных стержня, на одном из которых установ- лена пирамида, состоящая из п дисков. Чем выше расположен диск, тем меньше его диаметр. I I 1 2 3 Требуется переместить башню на один из свободных стержней, расположив их в том же порядке и соблюдая следующие правила: 1. Каждый раз можно перекладывать только один диск. 2. Нельзя класть диск на диск меньшего размера. Обозначим процедуру решения этой задачи HANOI (FROM, ТО, N) где FROM — номер исходного стержня; ТО — номер целевого стержня; N — количество дисков, образующих пирамиду. Выполнение процедуры для N дисков сводится к выполнению этой же процедуры для N — 1 дисков. Действительно, для N = 2 схема решения задачи имеет вид HANOI (1, 2, 2) = HANOI (1, 3, 1) HANOI (1, 2, 1) HANOI (3, 2, 1) Для N = 3 схема имеет вид (для краткости указаны только тройки 286
параметров); (1,3, 2) = ' (1, 2, 1) (1,3, 1) 1 (2, 3, 1) HANOI (1, 2, 3) = ( (3, 1,2)^< 1, 2, 1) (3, 2, 1) (3, 1, 1) [(2, 1, 1) причем последний столбец в каждой такой рекурсивной схеме задает требуемую последовательность элементарных операций, необходимых для переноса башни в целом. Легко видеть, что для N = 2 необходимо выполнить 22 — 1 = 3 элементарных операции, а для N = 3 таких операций 23 — 1 = 7. По индукции можно доказать, что в общем случае требуется 2П — 1 операций, а процедура решения задается следующей рекурсией: HANOI (FROM, ТО, N) = HANOI (FROM, 6 — FROM — TO, N — 1) HANOI (FROM, TO, 1) HANOI (6 — FROM — TO, TO, N— 1) Выражение 6 — FROM — TO задает номер стержня, который для лю- бых FROM и ТО является резервным: FROM ТО 6 — FROM — ТО 1 2 3 1 3 2 2 3 1 Рекурсивную схему решения задачи удобно задавать в виде дерева, которое может быть получено зеркальным отображением схемы и по- следующим ее поворотом на 90° против часовой стрелки. Для HANOI (1, 2, 3) дерево имеет вид: 287
Узлам дерева (они обозначены на дереве точками) соответствуют рекурсивные вызовы процедуры HANOI. Корневой узел (1, 2, 3) соот- ветствует начальному вызову процедуры, концевые (листья) — соот- ветствуют элементарным операциям. Порядок обход#дерева (рекурсивных обращений) указан стрелками. Очередная тройка параметров формируется в момент рекурсивного об- ращения. При обращении к элементарной операции печатается пара Рис. 34 Рис. 35 дыдущие моменты времени, а также задача обработки троек в требуе- мой последовательности. Для решения этой задачи используем так называемую магазин- ную память. Магазин — это вектор, в котором в каждый момент вре- мени доступен единственный элемент, называемый вершиной мага- зина. Номер элемента, который в данный момент является вершиной, указывается текущим значением специальной переменной — указа- теля. Основные операции над магазином — это чтение и запись. При записи данное помещается в вершину, а значение указателя увеличива- ется на 1. При чтении данное выбирается из вершины, а значение ука- зателя уменьшается на 1. 288
После вызова процедуры с начальной тройкой параметров начина- ется порождение левой ветви дерева, в ходе которого формируются и переносятся в магазин порождаемые узлы, кроме концевого. При по- рождении концевого узла дерева на его левой ветв^выполняется соот- ветствующая элементарная операция. Затем читаетсФтройка, находяща- яся в вершине магазина. Так как данное, записанное в магазин послед- ним, читается первым, то мы получим тройку, соответствующую преды- дущему обращению к процедуре. После чтения из магазина всегда выполняется элементарная опера- ция средней ветви и формируется тройка, принадлежащая правой вет- ви. Если последняя задает элементарную операцию, то после ее выпол- нения снова осуществляется чтение из магазина, выполняется опера- ция средней ветви и формируется тройка правой ветви. В общем слу- чае эта тройка задает поддерево, к которому применяется тот же алго- ритм (рис. 34). Так как тройки, задающие элементарные операции, в магазин не записываются, размер магазина должен быть не меньшим чем N/2 — 1. Действительно, величина N/2 — 1 задает наибольшую длину пути от корня дерева к его листьям. Для реализации магазина в программе используются три массива (для каждого параметра). Указатель вершины задан индексной пере- менной LOC. В начальном состоянии магазин пуст, значение LOC рав- но 1. FROM ТО N LOC = 1-> Ниже приводится последовательность состояний магазина и после- довательность выполнения операций при N = 3. ЗАПИСЬ 1,2,3 ЗАПИСЬ 1,3,2 Печать 1,2 ЧТЕНИЕ 1, 2, 3 - 1,3,2 Печать 1,3 Печать 2,3 _ ЧТЕНИЕ— 1,2,3 Щ. -------- Печать 1,2 Печать 3,2 Печать 3,1 LOC= Я Печать 2,1 Если включить в программу оператор DEBUG INIT (LOC) (см. пори. 111), то в процессе обработки магазина будут печататься текущие значения указателя LOC. 10 9-2712 289
Хранение нескольких поколений значений параметров в магазин- ной памяти в нашем примере является одним из условий реализации рекурсии. Другим условием является использование специальной тран- зитной программы RECALL, через которую осуществляется рекурсив- ный вызов подпрограммы HANOI и передача параметров (без каких- либо их изменений). Кроме того, подпрограммы HANOI и RECALL построены так, что содержащиеся в них операторы RETURN никогда не выполняются. Схема взаимодействия модулей при рекурсивном вызове процеду- ры представлена на рис. 35. Ниже приводятся исходные тексты этих модулей. Головной модуль CALL HANOI (1, 2, 6) STOP 777 END Транзитный модуль SUBROUTINE RECALL (X, Y, Z) CALL HANOI (X. Y, Z) RETURN END Модуль, выполняемый рекурсивно SUBROUTINE HANOI (FROM, TO, N) INTEGER FROM, TO, TEMP, LOC/1/, P (16), S (16), К (16) IF (N. EQ. 1) GO TO 5 С ЗАПИСЬ: P (LOC) = FROM S (LOC) = TO К (LOC) = N LOC = LOC + 1 С РЕКУРСИЯ CALL RECALL (FROM, 6—FROM—TO, N — 1) 5 PRINT 1, FROM, TO 1 FORMAT (216) С ЧТЕНИЕ: LOC = LOC — 1 IF (LOC. EQ. 0) STOP 111 FROM = P (LOC) TO = S (LOC) N = К (LOC) PRINT 1, FROM, TO С РЕКУРСИЯ CALL RECALL (6 — FROM — TO, TO, N — 1) 11 RETURN C DEBUG INIT (LOC) END В результате выполнения приведенной программы будет напеча- тана последовательность из 63 пар чисел, которые (для экономии места) 290
мы расположили в 4 колонки; вторая колонка является продолжением первой, третья — второй, четвертая — третьей. 1 3 1 2 3 2 1 3 2 1 2 3 1 3 1 2 3 2 3 1 3 1 3 2 1 3 1 2 3 2 1 3 2 13 2 13 2 3 3 1 12 13 2 13 2 2 13 2 13 3 2 1 3 2 1 3 1 12 2 3 2 13 2 13 2 3 3 112 13 2 13 2 1 2 2 3 3 1 3 2 1 3 2 1 13 2 13 2 2 13 2 13 2 3 3 1 1 2 13 2 13 2 12 3 2 10*
Глава VI СРЕДСТВА ОТЛАДКИ ПРОГРАММ В ФОРТРАН/ЕС Порция 109 Предложения отладки Среди многих средств, которые могут использоваться на различных этапах отладки ФОРТРАН-программ, особое место занимают специаль- ные предложения отладки, вставляемые непосредственно в исходный текст. В отличие от транслятора, который обнаруживает ошибки в исходном тексте, и супервизора, который контролирует особые ситуации, приво- дящие к прерываниям, предложения отладки позволяют в ходе выпол- нения программы проследить, как изменяются значения переменных; установить последовательность выполнения операторов и вызовов про- граммных модулей; определить правильность использования индек- сов; напечатать имена и значения просматриваемых объектов. Подоб- ный анализ динамической структуры программы часто называют про- круткой или трассировкой. В ФОРТРАН/ЕС имеется пять предложений отладки: 1. Объявление DEBUG 2. Объявление АТ Оператор TRACE ON (ОТЛАДИТЬ) (НАЧИНАЯ С) (ВКЛЮЧИТЬ ПРОКРУТКУ опера- торов) (ВЫКЛЮЧИТЬ ПРОКРУТКУ опера- торов) (ВЫВЕСТИ) 3. 4. Оператор TRACE OFF 5. Оператор DISPLAY Действие этих предложений ограничено одним программным моду- лем. Предложения отладки включаются в исходный текст по специаль- ным правилам. Объявление DEBUG, которое должно быть единствен- ным в программном модуле, записывается внутри операторной части модуля. После этого объявления из других отладочных предложе- ний формируется последовательность так называемых пакетов от- ладки х. Каждый пакет отладки (табл. 25) начинается объявлением АТ и должен включать по крайней мере один оператор отладки. Пакет от- 1 В данном случае значение слова «пакет» никак не связано с другими зна- чениями этого термина, используемого в программировании. 292
ладки может содержать любые предложения ФОРТРАНа, кроме объяв- лений IMPLICIT, SUBROUTINE, FUNCTION, ENTRY, BLOCK, DATA и внутренних функций. Если пакет отладки содержит оператор DO, то область действия DO должна полностью принадлежать этому пакету. Заключительная строка END данного программного модуля одновременно является концом последовательности определенных в нем пакетов отладки. Таблица 25 Структура программного модуля, содержащего предложения отладки Предложения ФОРТРАНа, составляющие отлаживаемую программу Объявление DEBUG Объявление АТ Операторы Последовательность пакетов отладки Объявление АТ Операторы END Задание. 1. Заполните указанный пробел одним из приведенных от- ветов. Предложения отладки позволяют проследить за ситуациями, возникающими в ходе: а) трансляции; б) редактирования; в) выполне- ния программы. 2. Какое предложение должно непосредственно предшествовать первому пакету отладки? 3. Очевидно, что синтаксис предложений отладки проверяется транс- лятором. Контролируется ли транслятором правильность размещения отладочных предложений в программном модуле и структура пакетов отладки. Для ответа обратитесь к таблице сообщений транслятора (стр. 348). 293
Порция НО Взаимодействие пакета отладки с программным модулем В отличие от объявления DEBUG, который включает в действие режимы, распространяющиеся на весь программный модуль, предло- жения пакета задают отладочные операции на определенных его участ- ках. При этом оператор DISPLAY выполняется один раз при входе в отлаживаемый участок как обычный оператор вывода. Участки трас- сировки задаются операторами TRACE ON и TRACE OFF. Трассиров- ка выполняется, в отличие от операции DISPLAY, на протяжении всего участка. Пакет отладки выполняется непосредственно перед выполнением отлаживаемого участка, то есть перед тем оператором программного модуля, метка которого указана в соответствующем объявлении АТ. Таким образом, в исходном тексте пакеты отладки отделены от места их выполнения, что облегчает чтение отлаживаемой программы и по- зволяет легко удалять отладочные предложения из программного модуля. Порядок записи отладочных пакетов в последовательности не влияет на порядок их выполнения и может быть произвольным. Как было отмечено, в пакеты отладки разрешается включать опера- торы ФОРТРАНа, что позволяет организовывать пакеты как угодно сложной логической структуры. Все операторы пакета могут иметь метки, но так как пакет отладки не является независимым элементом программного модуля, эти метки не должны совпадать с его другими метками (в том числе, с метками других его пакетов). Правилами исполь- зования пакетов отладки допускается передача управления из пакета в данный программный модуль, однако передача управления в пакет из области, находящейся вне его, запрещена. Задание. 1. Возможна ли передача управления из одного пакета отладки в другой? 2. Какой из операторов STOP в приведенном фрагменте будет выпол- нен при I = 125? Какие тексты и на каких устройствах будут напечатаны? 1 ..................................... IF (I. GT. 100) GO ТО 19 I = I + К GO ТО 1 19 STOP 19 20 STOP 20 DEBUG UNIT (3) AT 19 DISPLAY I GO TO 20 END 294
Порция 1 1 1 Объявление DEBUG Объявление DEBUG задает подавляющее большинство отладочных действий и часто используется вообще без пакетов отладки. Общий вид объявления следующий: DEBUG (список-режимов) Язык допускает пять режимов отладки, которые указывают вид от- ладочных действий и используемый при этом файл для вывода имен и значений просматриваемых объектов. Действие режимов, активизи- Режимы отладки Таблица 26 Форма режима Назначение 1. UNIT ({номер-файла)) 2. TRACE 3. SUBTRACE 4. INIT ({список-имен)) 5. SUBCHK ({список-имен)) Определяет выходной файл отладки Прокрутка операторов Прокрутка вызовов программных модулей Контроль присвоения значений Контроль значений индексов руемых объявлением DEBUG, распространяется на весь программный модуль. Режимы отладки перечислены в табл. 26. Если в DEBUG указывается несколько режимов, то они отделяются друг от друга запятыми, например: DEBUG UNIT (3), SUBCHK (ARRAY), INIT (А, В, C) Режимы могут перечисляться в произвольном порядке. Порция 112 Режимы отладки Режим UNIT Общий вид записи режима: UNIT ((/г)) где (и) — номер допустимого в ФОРТРАНе файла. Режим предназначен для задания файла отладки, т. е. фай- ла, в который будут помещены все сообщения о состоянии просмат- риваемых объектов программы. Если в качестве файла отладки 295
используется SYSLST, то режим UNIT можно не указывать. Например, следующие объявления эквивалентны: DEBUG UNIT (3), TRACE, SUBTRACE DEBUG SUBTRACE, TRACE Режим TRACE Режим TRACE (в сочетании с оператором TRACE ON) предназна- чен для вывода в файл отладки меток тех операторов, которые выполня- лись в процессе работы некоторого участка программы. Границы этого участка определяются в соответствующих пакетах отладки. Режим TRACE предоставляет только принципиальную возможность фиксирования трассы программы. Фактическое включение трассиров- ки выполняется оператором TRACE ON. Можно представить это так, что режим TRACE подключает программу, реализующую трассировку, а оператор TRACE ON запускает ее. Таким образом, если режим TRACE в объявлении DEBUG не указан, то операторы TRACE ON в пакетах отладки будут игнорироваться. Режим SUBTRACE Если в некотором программном модуле в объявлении DEBUG указан режим SUBTRACE, то каждый раз при входе в этот модуль в файл будет помещаться сообщение SUBTRACE (р) где (р) — имя данного модуля. При выходе из модуля в файл отладки заносится сообщение SUBTRACE RETURN Режим INIT Формат режима: INIT ((s)) где (s) — список, элементами которого могут быть имена переменных или массивов. Например: REAL А, В, С (L0), X, Y, Z (Ш£) DEBUG INIT (А, В, С, X, Y, Z) Указание этого режима приводит к тому, что всякий раз, когда в данном программном модуле выполняется присваивание значения пере- менной или элементу массива из списка $, в файл отладки выводится сообщение (0 = (С) где (v) — имя переменной, (с) — присвоенное ей значение (конс- танта). Список имен может быть пустым. В этом случае выводятся сообще- ния для всех присваиваний. 296
Режим SUBCHK Формат режима: SUBCHK ((список-имен)) Элементами списка должны быть имена массивов. Например: DIMENSION К (2-0), L (50, 50) DEBUG SUBCHK (К, L) END Указание этого режима приводит к тому, что значения индексов эле- ментов массивов, перечисленных в списке, подвергаются проверке: если значение индекса выходит за верхнюю границу, то в файл отладки заносится сообщение вида SUBCHK (е) где (е) — элемент массива. Например: REAL S (100, 100) К = 55 L = К * 2 WRITE (3,1) S (К, L) DEBUG SUBCHK (S) Если список пуст, контроль индекса осуществляется для элементов всех массивов. Задание. 1. Какой файл используется в качестве отладочного по умолчанию? 2. В каком случае может быть использовано объявление DEBUG, в котором не указаны никакие режимы? Порция 113 Оператор DISPLAY Оператор DISPLAY может использоваться только в пакете отладки. Формат оператора: DISPLAY (список) Элементами списка могут быть имена простых переменных и мас- сивов. Оператор DISPLAY осуществляет вывод в файл отладки значений элементов списка в соответствии с их типом. Для простой переменной выводится имя, знак равенства и значение в формате, соответствующем 297
типу переменной. Для массива выводится имя, знак равенства и список разделенных запятыми констант, являющихся значениями элементов массива. - Оператор DISPLAY дополняет режим INIT объявления DEBUG, позволяя осуществить разовый вывод значений некоторых переменных в определенной точке программы. Как и остальные операторы отладки, DISPLAY запрещено включать в логический оператор IF. Кроме этого, в список DISPLAY не могут быть включены формальные параметры. Задание. Чем отличается список оператора DISPLAY от списка ввода-вывода? Порция 114 Объявление АТ Объявление АТ имеет следующий формат: АТ (метка) Метка, указанная в АТ, должна содержаться в отлаживаемом про- граммном модуле и должна быть меткой некоторого оператора (а не объявления FORMAT). Объявление АТ является, с одной стороны, разделителем в последо- вательности пакетов отладки, а с другой—АТ расчленяет с помощью ме- ток отлаживаемую процедуру на участки, к которым применяются соот- ветствующие пакеты. 30 Участок, пакет 3 к которому применяется 15 ' Участок, пакет 2 к которому применяется 20 ' DEBUG АТ 20 1 АТ 15 1 АТ 30 1 END Участок, пакет 1 Пакет 1 Пакет 2 Пакет 3 к которому применяется Применение пакета заключается в выполнении перед оператором с меткой, указанной в АТ, операторов этого пакета. 298
Порция 115 Операторы TRACE ON и TRACE OFF Эти операторы не имеют параметров и могут использоваться только в пакетах отладки. Оператор TRACE ON включает прокрутку того участка, определя- емого пакетом отладки, в котором этот оператор записан, т. е. выпол- няется перед оператором с меткой, указанной в АТ. Прокрутка операторов заключается в занесении в файл отладки сообщений вида TRACE (метка) (печатаются метки операторов отлаживаемого участка программы). Оператор TRACE OFF выключает прокрутку, если к моменту его выполнения она была включена оператором TRACE ON. Таким обра- зом, TRACE OFF через метку в АТ отмечает концы участков. TRACE ON и TRACE OFF выполняются тогда, когда в DEBUG указан ре- жим TRACE. Эти операторы запрещено использовать в логическом опе- раторе IF. Следует заметить, что, в принципе, все действия, выполняемые опе- раторами отладки, можно реализовать с помощью оператора WRITE, записывая его в соответствующих местах программы. Однако большое количество таких операторов и, соответственно, объявлений FORMAT загромождает программу и обычно служит источником дополнительных ошибок. Использование операторов отладки имеет следующие преи- мущества: ,1) при выводе не используются объявления формата; 2) отладочные операторы записываются отдельной группой; 3) операторы отладки более компактны и лаконичны, чем операторы ввода-вывода. Задание. Как определяются начало и конец участка прокрутки операторов? Порция 116 Подпрограммы DUMP и PDUMP Подпрограммы DUMP и PDUMP содержатся в библиотеке объект- ных модулей и могут быть вызваны ФОРТРАН-программой оператором CALL. Чаще всего эти подпрограммы используются для отладки про- грамм. Назначение этих программ — вывод содержимого основной па- мяти (дампа) на устройство SYSLST. В отличие от системного дампа, результатом которого является вывод содержимого всего раздела ос- новной памяти и регистров в шестнадцатеричном коде, DUMP и PDUMP выводят содержимое только некоторых участков памяти, заданных программистом, и при этом в любом из допустимых форматов. 299
При использовании подпрограммы DUMP после выдачи дампа вы- полнение программы продолжается. В отличие от этого, PDUMP при- водит к тому, что после печати выполнение программы прекращается. Действие оператора CALL PDUMP «р» эквивалентно последовательности двух операторов CALL DUMP «р» STOP где (р) — список параметров. Вызов рассматриваемых подпрограмм в общем случае имеет вид: CALL DUMP (av bv fv ... , an, bn, fn) CALL PDUMP (av bv fv ... , an, bn, fn) где — имя левой границы участка основной памяти; bi — имя правой границы участка основной памяти; fi — код формата. at и Ь^ — это индексированные или простые переменные. Адрес, соответствующий ah должен быть не больше адреса Ь^, если адрес сц равен адресу bi, то выводится единственная скалярная величина. При необходимости вывода части массива требуется, чтобы приведенный индекс левой границы не превышал приведенный индекс правой. В остальных случаях необходимо проана- лизировать протокол распределения па- мяти для выяснения правильности за- дания границ участков памяти. Так как область памяти, распределя- емая под общие блоки, не является смеж- ной с локальными участками памяти, то cii и bi одновременно должны принадле- жать либо одной и той же области COMMON (глобальной памяти), либо локальной памяти. fi — это целые без знака, принимающие значения от 0 до 9 и опре- деляющие формат вывода согласно табл. 27. В принципе не запрещается выводить содержимое памяти в формате, не соответствующем типу данного. В частности, данные любого типа час- то полезно выводить в шестнадцатеричном формате. Иногда, однако, несовпадение формата с типом данного может вызвать программный сбой. Например, вызов PDUMP: INTEGER I (5) Таблица 27 Формат^^чати Q 1 2 3 4 5 6 7 8 9 Шестнадцатеричный LOGICAL * 1 LOGICAL * 4 INTEGER * 2 INTEGER ♦ 4 REAL ♦ 4 REAL * 8 COMPLEX ♦ 8 COMPLEX* 16 Текстовый CALL PDUMP* (I (1), I (3), 6) 300
может привести к ошибке, если адрес I не выравнен на границу двойного слова. Вывод, осуществляемый подпрограммами DUMP и PDUMP, оформ- ляется на SYSLST следующим образом. Содержимое участков, опреде- ленное границами ait bit может занимать несколько строк печати. В на- чале каждой строки в шести позициях печатается адрес первого данного этой строки. Участки отделяются друг от друга пропуском строк. Пример 1 LOGICAL Т, F N = 2 ** 31 Т = .TRUE. F = .FALSE. К = 1 CALL PDUMP STOP END РЕЗУЛЬТАТ: 0B288C вВВеВВВВ &&&&&&&! &&&&&&&& &&&&&&& 1 Пример 2. При наличии в некотором программном модуле объявле- ния REAL *4 А (9), В (1В) оператор CALL DUMP (А (5), В (5), 5) эквивалентен оператору CALL DUMP (С (1), С ч 1В), 5) если при этом будут заданы предложения REAL А (9), В(1В), С(1В) EQUIVALENCE (А (4), С), (В (1), С (6)) Соответствующая карта эквивалентности имеет вид: С Задание. 1. Операторы NAMELIST, DISPLAY и подпрограммы DUMP, PDUMP осуществляют форматный вывод, но без использова- ния объявления FORMAT. Как определяется тип внешнего представ- ления при использовании перечисленных средств? 2. Какая ошибка содержится в следующем фрагменте: COMMON /X/ А, В, С, D COMMON X, Y, Z 301
REAL FIN (Ш), ST (28) CALL PDUMP (A, ST (28), 6) Порция 117 Подпрограммы SLITE и SLITET Первые версии ФОРТРАНа, разработанные до появления стандар- та, отражали технические особенности тех ЭВМ, на которых использо- вался язык. В частности, подпрограммы SLITE и SLITET обеспечива- ли возможность использования в ФОРТРАНе двоичных ключей на пульте ЭВМ, которые устанавливались вручную и могли анализиро- Таблица 28 Значение параметра Действие N = 0 N= 1, 2, 3, 4 Выключение всех индикаторов Включение индикатора N ваться программно. Для совместимости с ранними версиями языка используются подпрограммы SLITE и SLITET. В ФОРТРАН/ЕС ключи, обрабатываемые в SLITE и SLITET, на- зываются программными переключателями или индикаторами. Таких ключей — четыре; каждый из них может быть в состоянии «включено» или «выключено». Условно ключи можно рассматривать как логические переменные, принимающие значения .TRUE. (1) или .FALSE. (0). Программные переключатели не имеют имен. К ним можно обратиться только по номеру (1, 2, 3 или 4) и только посредством процедур SLITE и SLITET. SLITE используется для установки переключателей в заданное со- стояние. SLITE вызывается оператором CALL и имеет один входный параметр — переменную или константу целого типа, например, CALL SLITE (N) Значение параметра определяет действие подпрограммы согласно табл. 28. SLITET используется для проверки состояния индикатора. Под- программа вызывается оператором CALL и имеет два параметра: CALL SLITET (N, S) Номер проверяемого индикатора (1, 2, 3 или 4) задается’ первым пара- метром. При выполнении подпрограммы SLITET второму параметру, S, который должен быть переменной целого типа, присваивается одно 302
из двух значений: если в момент проверки индикатор был включен,— значение 1, если выключен,— значение 2. При любом S после проверки индикатора SLITET выключает индикатор с номером N. Порция 118 Подпрограмма EXIT Обращение к этой подпрограмме осуществляется с помощью опера- тора CALL EXIT Действие EXIT в основном совпадает с действием оператора STOP: управление пере- C MAIN PROG дается системе, которая завершает шаг задания. Однако EXIT не имеет параметров и, в отличие от оператора STOP, с ее помо- щью нельзя выдать сопутствующее сообщение на SYSLOG. Пример С MAIN PROG CALL A t SUBROUTINE A CALL А STOP END SUBROUTINE A CALL В ♦ SUBROUTINE 8 CALL В RETURN END R = FUN (С, Г) SUBROUTINE В R = FUN (C, D) FUNCTION FUN(X,Y) RETURN END FUNCTION FUN (X, Y) CALL EXIT 1 IF (X. LE. -0) GO TO 7 7 WRITE (15. 15) 15 FORMAT ('^ОШИБКА В FUN') CALL EXIT END SUBROUTINE EXIT Рис. 36 Таким образом, при ошибке во внешней процедуре можно не про- ходить цепочку по RETURN, передавая признак ошибки в головную программу (рис. 36). 303
Задание. 1. Как ФОРТРАН-программа может возвратить управле- ние операционной системе? 2. Можно ли в ФОРТРАН/ЕС завершить выполнение головной про- граммы во внешней процедуре? 3. В каких случаях выполнение внешней процедуры ФОРТРАН/ЕС может завершаться не по оператору RETURN? Порция 119 Особые ситуации Как известно, при выполнении арифметических операций могут возникать особые ситуации (называемые арифметическими), вызванные переполнением, исчезновением порядка или делением на нуль. Укажем на особенности ФОРТРАН/ЕС, связанные с обработкой особых си- туаций. Транслятор фиксирует особую ситуацию при обработке числовых данных в следующих случаях: ДЕЛЕНИЕ целых ДЕЛЕНИЕ вещественных ПЕРЕПОЛНЕНИЕ порядка вещественного ИСЧЕЗНОВЕНИЕ порядка вещественного При возникновении одной из перечисленных особых ситуаций вы- полнение программы прерывается и печатается соответствующее диаг- ностическое сообщение. Однако после печати сообщения об ошибке вы- полнение программы продолжается, и дальнейший результат, вообще говоря, неопределен. Особые ситуации при делении вызываются попыткой деления на О (для вещественных — на число, близкое к нулю). Переполнение и ис- чезновение порядка вещественных возникает тогда, когда при выполне- нии операции получен порядок, выходящий за допустимый диапазон (—64, 63). Особые ситуации, возникающие при выполнении операции над це- лыми числами, обладают одной особенностью. Дело в том, что транс- лятор ФОРТРАН/ЕС не фиксирует переполнения при выполнении над целыми числами таких операций, как сложение или умножение. Преры- вание программы в этих случаях блокировано и сообщения об ошибке не выдаются. Вследствие этого продолжается обработка кодов, не соот- ветствующих фактическому результату. Например, при выполнении оператора К = 2 ** 32 значением целой переменной К будет число —2 147 483 648, а не 4255735696. Задание. При выполнении приведенного ниже фрагмента про- граммы возникло прерывание. В чем состоит причина ошибки? 304
К = 2 DO I I = 1,40 К = К * 2 X = К Y = SQRT (X) 1 WRITE (3, 1-0) Y Порция 120 Подпрограммы DVCHK и OVERFL Подпрограммы DVCHK и OVERFL включены в состав основных и предназначены для проверки особых арифметических ситуаций. Си- туация деления на 0 проверяется обращением CALL DVCHK (J) J — целая переменная. Ее значение устанавливается в 1, если особая ситуация имела место, и в 2, в противном случае. Ситуация переполнения или исчезновения порядка, проверяется обращением CALL OVERFL (J) J устанавливается в 1 при переполнении, в 3 в случае исчезновения порядка, в 2, если особая ситуация не возникала. Пример действия подпрограммы OVERFL: R = 1Е + 65 R = R ** CALL OVERFL (I) 3 FORMAT (1Ш) WRITE (3,3) I END В результате будет напечатано значение переменной I, равное еди- нице. Порция 121 Особенности распределения памяти Особые ситуации неарифметического характера ФОРТРАН-транслятор распределяет память под переменные, вы- деляя полуслова с адресами, кратными двум, слова —четырем, двойные слова — восьми. Если это правило нарушается в результате неправиль- ного использования объявлений DIMENSION, EQUIVALENCE, COMMON, возникает так называемая ошибка спецификации, которая приводит к программному прерыванию. 305
Ошибки такого рода в некоторых случаях могут быть обнаружены во время трансляции. Рассмотрим пример. Пусть программный модуль содержит следую- щие предложения: DOUBLE PRECISION Al, VK1 COMMON /АР/ XM, VM, TM, Al, VK1 В результате трансляции память распределится следующим обра- зом: Имя Относительный 16-ричный адрес ХМ & VM 4 ТМ 8 Al С VK1 14 Транслятор выдает сообщение, указывающее на наличие ошибок распределения памяти для AI и VK1: ILF -02-01 COMMON BLOCK/AP^^^/ERRORS AI VK1 Действительно, шестнадцатеричные относительные адреса С и 14 не кратны восьми. Заметим, что исправить положение транслятор не может, так как имена принадлежат общему блоку памяти. Так как при этом значение LOAD = 4 (см. порц. 135), трансляция будет завершена и влияние ошибки обнаружится только при выполнении программы. В следующем примере в результате попытки записать константу повышенной точности в поле, адрес которого не кратен восьми (кратен 4), ошибка будет выявлена только при выполнении рабочей программы: DOUBLE PRECISION X, Y COMMON R, S, T EQUIVALENCE (S, X) X = e.6D£l (транслятор никаких сообщений об этой ошибке не выдает). При интер- претации в последнем примере система автоматически произведет вы- равнивание адреса на соответствующую границу слова и программа будет выполнена правильно. Однако выравнивание на границу занима- ет значительное время, поэтому такие ошибки желательно не допускать. При формировании адреса элемента массива по индексу, если индекс- ное выражение составлено неверно, может быть получен адрес, не принадлежащий массиву. В этом случае возникает ситуация неправиль- ной адресации. Аналогичной является ситуация защиты памяти, возникающая в случае, когда адрес, оставаясь в пределах памяти машины, выходит за рамки раздела памяти, отведенной для выполнения программы, 306
т. е. попадает в область, занятую программой, не связанной с данной. Границы раздела обычно указываются в распечатке протокола работы системы: подзаголовком LOCORE указывается нижний предел раздела, под заголовком HICORE — верхний. Ситуация защиты памяти может также возникнуть при наличии обращения к подпрограмме, которая по ошибке не присоединена к рабочей программе. .Ошибки индексации элементов массива могут привести к записи в область памяти вне границ массива, в том числе в область команд. Изменение содержимого полей команд приводит к искажению програм- мы и может привести к любой особой ситуации.
Глава VII ВВОД-ВЫВОД С ПРЯМЫМ ДОСТУПОМ К ДАННЫМ Порция 122 Запоминающие устройства прямого доступа Прямой доступ к данным предполагает наличие специальных устройств, реализу- ющих этот метод. Типичным устройством с прямым доступом в ЕС ЭВМ является маг- нитный диск. Как устройство более высокого уровня диск позволяет организовать и традиционный последовательный доступ. В этом случае диск может рассматриваться как магнитная лента. В ФОРТРАН/ЕС не требуется никаких специальных операто- ров для обработки файлов последовательного доступа, расположенных на дисках. Внешние носители информации ЭВМ, такие как перфокарты или магнитные лен- ты, обеспечивают только последовательный доступ к данным. Это означает, что для об- ращения к отдельной записи набора данных, хранящегося на таком носителе, необхо- димо обработать определенное количество предшествующих последовательно располо- женных записей. Такой поиск требует много времени, особенно в тех случаях, когда запись на ленте находится на большом расстоянии от головки чтения-записи. Если учесть, что вспомогательная память на внешних носителях значительно уве- личивает производительность вычислительной системы, то становится понятным стрем- ление использовать более эффективные запоминающие устройства, основанные на прямом (непосредственном) доступе к информации. Отличительной чертой запоминаю- щих устройств прямого доступа (ЗУПД) является то, что время поиска нужной запи- си практически не зависит от места расположения этой записи на носителе. Существует несколько типов ЗУПД, однако наибольшее распространение полу- чили магнитные диски. Диски объединяются в пакеты; устройство, с помощью кото- рого обслуживаются пакеты дисков, называется дисководом. На рис. 37 изображен пакет из 6 дисков, используемый в устройстве ЕС-5052. Верхняя поверхность верхнего диска и нижняя поверхность нижнего диска не исполь- зуются, поэтому пакет имеет десять рабочих поверхностей для хранения информации. 308
Каждая поверхность имеет 203 концентрически расположенные дорожки емкостью* 3625 байтов каждая. Дорожки нумеруются от 0 до 202 в направлении от наружного края диска к центру. Информация читается или записывается с помощью головок, установленных на дисководе и перемещающихся от дорожки к дорожке. Все головки могут быть установлены в процессе работы на дорожки с одним номером. Совокупность дорожек с одним номером на всех поверхностях называется цилиндром. Таким обра- зом, можно читать или записывать информацию на любой из 10 дорожек цилиндра без перемещения головок. Как и в лентопротяжных механизмах, рабочие поверхности перемещаются относительно головок, однако, в отличие от лент, диски находят- ся в постоянном вращении. Пакет дисков, так же как и бобина МЛ, является съемным Общее название для бобины МЛ и пакета дисков — том. Задание. Каким образом целесообразно размещать логически связанную ин- формацию: а) на смежных дорожках поверхности? б) на цилиндре? Порция 123 Физические записи Несмотря на то что перфокарты, магнитные ленты, бумага на построчно печатаю- щем устройстве или диски имеют существенно разные характеристики, для описания структуры этих носителей используется одно общее понятие физической записи. Фи- зическая запись — это порция обмена между основной памятью и внешним устрой- Таблица 29 Номер логиче- ского устройства Логическое устройство Ввод ПК Вывод ПК Печать Физическое устройство НМЛ Диски Пишущая машинка Последо- ватель- ный Прямой 1 2 3 4—14 15 SYS1PT) SYSIN J SYSPCH SYSLST /SYS001 1 SYS011J SYSLOG 80 80 80 80 121 * 260 256 80 81 ** 121 * от 18 до 260 80 81 ** 121* 260 1-н3625 256 ♦ _ Первея литера используется для управления печатью. ** — Первая литера используется для управления выбором кармана. ством. Физическая запись характеризуется размером, который задается программис- том в допустимых пределах. В принципе, размеры физических записей ограничены только размерами соответствующих носителей (80 колонок для перфокарт, 128 сим- волов для строк печатающего устройства и т. д.). Однако в рамках систем программиро- вания могут существовать собственные ограничения на размеры физических записей. В табл. 29 приводятся максимальные размеры физических записей (в байтах) для ло- гических устройств, принятые в ФОРТРАН/ЕС. 1Для устройства ЕС-5052. 309
В отличие от перфокарт, на непрерывных носителях (магнитные ленты, диски) физические записи отделяются друг от друга специальными интервалами (меж- блочными промежутками). Поэтому, чем короче записи, тем больше промежутков бу- дет сформировано на носителе. На промежутки расходуется поверхность носителя. Например, при длине записей в 30 байтов на дорожке можно разместить только 40 за- писей. В ФОРТРАНе подобные расчеты необходимо проводить только для дисков при прямом доступе. Для последовательного доступа размер физических записей определяется специ- фикациями, указанными в операторе FORMAT. При этом записи в наборе данных мо- гут быть разной длины. Для прямого доступа количество и размер физических записей указываются в объявлении DEFINE FILE (см. порц. 125); все записи должны быть одинаковой длины. Порция 124 Наборы данных в ФОРТРАН/ЕС Наборы данных, представленные на внешних носителях, называются файлами. Действие операторов READ и WRITE, использующих форматы, выполняется в два этапа: преобразование из внешнего представления во внутреннее при вводе или обрат- ное при выводе и собственно передача данных. При выполнении обмена между внеш- ней и основной памятью файлы рассматриваются как наборы некоторых физических записей, размеры которых могут определяться техническими характеристиками внеш- него носителя информации. При внутренней обработке файл интерпретируется как на- бор логических записей. Логическая запись — это строка символов внешнего представления набора вели- чин, структурированная в соответствии со списком ввода-вывода. Для создания и вы- вода логических записей внутреннее представление данных, указанных в списке вы- вода, преобразуется во внешнее согласно выбранному формату и помещается в соот- ветствующие позиции носителя, образуя физическую запись. При вводе физическая запись пересылается в основную память и из нее выделяются согласно списку ввода и указанного формата элементы логической записи, которые преобразуются во внут- реннее представление. Таким образом, структура логической записи и ее длина опре- деляются спецификациями формата. Начало логической записи определяется в формате символами ( и / , конец — символами / и ) . Размеры физических записей необходимо учитывать при программировании опе- раций ввода-вывода. Например, при вводе информации с перфокарт не может быть ис- пользована следующая последовательность спецификаций формата, так как она определяет физическую запись недопустимой длины: READ (1,1) А 1 FORMAT (15F6.2) Определяя те или иные форматы в объявлениях программы на ФОРТРАНе, мы тем самым задаем те или иные структуры логических записей, выделяемых из наборов данных. В один и тот же файл на разных этапах работы мы можем, вообще говоря, направ- лять разные по структуре логические записи. С другой стороны, применяя к одной и той же физической записи разные форматы, можно получать разные логические записи. Для ввода-вывода по форматам размеры логических записей не должны превы- шать размеров используемых физических записей. При бесформатно.м обмене преоб- разования не выполняются и длина логической записи определяется как сумма длин внутреннего представления каждого элемента списка ввода-вывода. Весь список вво- да-вывода определяет одну логическую запись; при этом допускается размещение ло- гической записи в нескольких физических. Как может быть распределена внешняя память для файла? Во-первых, на одном носителе может быть несколько файлов, и в этом случае 310
носитель (том) называется многофайловым. Во-вторых, файл может размещаться на нескольких носителях, и в этом случае называется многотомным. В-третьих, распо- лагаясь на одном томе, файл может занимать несколько несмежных участков; такой файл называется многоучастковым. В ФОРТРАН/ЕС приняты следующие ограничения на распределение файлов на томах. Не допускаются: многотомные файлы; многоучастковые файлы; многофай- ловые тома на магнитной ленте. Физическая структура запоминающих устройств Для иллюстрации структур носителей и наборов данных воспользуемся диаграм- мами структур данных (рис. 38). Диаграммы используют следующие обозначения: 1. Прямоугольник, в котором записывается имя элемента структуры, например ЦИЛИНДР. Прямоугольник может содержать несколько имен понятий, синонимич- Рис. 38 ных в рамках данной структуры, например УСТРОЙСТВО, ТОМ, ЦИЛИНДР. В этом случае имена в прямоугольнике отделяются вертикальными пунктирными линиями. 2. Прямоугольники соединяются линиями со стрелками или без них. Пунктир- ная линия означает временную связь между элементами структуры, например такую, которая существует между дисководом и пакетом дисков. Сплошная линия означает постоянную связь, например «диск-дорожка». Сплошные и пунктирные линии без стрелок обозначают связь 1 : 1 и читаются «одному объекту соответствует один объект», на- пример «одному дисководу соответствует один пакет». Ли- нии со стрелками обозначают связь 1 : К и читаются «объ- ект состоит из К объектов», например «цилиндр-до- рожка». Задание. 1. Барабан построчно печатающего устрой- ства содержит 128 символов. Значит ли это, что можно создать физическую запись для этого носителя из 128 Рис. 39 литер? 2. Занимает ли управляющая литера, т. е. первая литера физической записи в объявлении FORMAT, место на барабане печатающего устройства? 3. Переменная TEXT имеет описание COMPLEX * 16 TEXT (2Я) 311
‘Сколько физических записей потребуется для логической записи, определяемой опе- ратором WRITE (2) TEXT 4. Известно ли Вам устройство (носитель), физическая структура которого изо- бражена на рис. 39? Порция 125 Операторы прямого доступа в ФОРТРАН/ЕС Для определения файлов прямого доступа используется специальное объявление DEFINE FILE. Следует подчеркнуть, что в файлах прямого доступа идентифициру- ется каждая физическая запись. В качестве идентификаторов записей используются целые положительные числа (индексы) 1, ..., N, где N — количество записей в файле. Нумерация записей позволяет обращаться к любой из них, без просмотра всех пред- шествующих, как это требуется при последовательном доступе. К файлам прямого доступа нельзя применять операторы REWIND, BACKSPACE, а также оператор ENDFILE. Для поиска записей в файле прямого доступа использу- ется оператор FIND. Для обмена между устройством прямого доступа и оперативной памятью используются операторы READ и WRITE специального вида. Таким обра- зом, имеется четыре предложения для работы с файлами прямого доступа: объявление DEFINE FILE, оператор WRITE, оператор READ, оператор FIND. Объявление DEFINE FILE Формат этого объявления имеет вид DEFINE FILE a (d, с, d, е) Здесь а, Ь, с — целые без знака; а — обозначает номер файла, b — количество в нем записей, с — размер каждой из них (все записи имеют один и тот же размер); .d — параметр, определяющий единицу измерения размера и способ передачи данных: Параметр d Единица измерения Способ передачи L Байт Любой Е Байт По формату U Слово Без формата £ — переменная целого типа, называемая связанной переменной и принимающая зна- чение индекса записи в файле. Пример DEFINE FILE 12 (Ш#, 12-0, L, KOUNT) Номер файла (в данном примере 12) должен выбираться с учетом табл. 29. Объяв- ление определяет файл, состоящий из 100 записей размером по 120 байтов; файл до- пускает как форматный, так и бесформатный обмен. В качестве связанной с файлом переменной использована переменная KOUNT. В одном объявлении DEFINE FILE может быть дано описание нескольких файлов прямого доступа. Например, DEFINE FILE 9 (6,1-0'-0', L, L), 11 (15, 3-0', U, INDEX). Областью действия объявления DEFINE FILE (в отличие от других объявлений) является вся выполняемая программа. При этом появление объявления DEFINE FILE должно предшествовать выполнению всех тех операторов READ, WRITE и FIND, которые осуществляют обмен с указанным в нем файлом (в каком бы програм- мном модуле они не встречались). Других ограничений на место расположения объяв- ления файлов между предложениями язык не накладывает. 312
Программа может содержать несколько объявлений DEFINE FILE (заданных в разных программных модулях), определяющих файлы прямого доступа с одним и тем же номером. Однако в ней будет иметь силу лишь то из них, которое в процессе выполнения программы встретится первым. Связанная переменная Значение связанной переменной может определяться так же, как и любой другой переменной целого типа. Однако существенно то, что это значение также определяют (и переопределяют) соответствующие операторы READ, WRITE и FIND, а именно: после выполнения операторов READ и WRITE над некоторым файлом прямого доступа значение связанной с этим файлом переменной автоматически становится рав- ным номеру записи, следующей за переданной; при выполнении оператора FIND над файлом прямого доступа связанной с ним переменной присваивается значение номера записи, указанное в этом операторе. В связи с тем что значение связанной переменной задает номер следующей или текущей записи в последовательности, употребление ее одновременно в качестве но- мера записи в операторах ввода-вывода приводит фактически к использованию файла прямого доступа как последовательного. В то же время наиболее характерная обработ- ка файлов прямого доступа подразумевает произвольное формирование номеров за- писей. Таким образом, эффект использования связанной переменной невелик, тем более что ее значение может быть легко получено из значения выражения, указываю- щего номер записи. Если файл прямого доступа используется лишь в одном программном модуле, то его объявление следует дать в этом же модуле, выбрав в качестве связанной с ним некоторую локальную переменную. Если значение связанной переменной используется для контроля или как номер записи в операторах ввода-вывода в других модулях, то для придания этой перемен- ной глобального смысла необходимо воспользоваться объявлением общих данных COMMON или аппаратом параметров процедур. В последнем случае связанная пере- менная, используемая в качестве формального параметра, должна вызываться по адре- су, а не по значению (т. е. соответствующий формальный параметр в заголовке про- цедуры должен быть заключен в наклонные черты). Использование связанной переменной в качестве номера записи в операторах ввода-вывода в некоторых случаях затрудняет восприятие алгоритма, так как значе- ние этой переменной изменяется неявно. Например, в следующем фрагменте про- граммы DEFINE FILE 8 (Ш, 8#, L, I) FIND (8'1) DO 5 К = 1, 10 5 READ (8' I, 1) A (I) неявно задано присвоение значений 1, 2, ..., 10 связанной переменной I (поскольку каждое выполнение оператора READ вызывает увеличение I на единицу). Более простой и наглядной является эквивалентная программа вида DEFINE FILE 8 (Ш, 8Я, L, I) DO 5 К = 1, Ш 5 READ (8' К, 1) А (К) Задания, 1. Эквивалентны ли понятия «файл на дисках» и «файл прямого до- ступа»? 2. Определены ли операторы REWIND и BACKSPACE для а) файла на перфо- картах? б) файла прямого доступа на дисках? 3. Если последовательный файл создается на дисках, должен ли он быть описан в объявлении DEFINE FILE? 4. Какие операции применимы к файлу, описанному в объявлении DEFI-NE FILE, т. е. к файлу прямого доступа? 313
5. Согласны ли Вы со следующими утверждениями: а) файл представляется в программе на ФОРТРАН/ЕС с помощью имени; б) массивы в ФОРТРАН/ЕС могут размещаться только в файлах последователь- ного доступа. 6. Можно ли в одном объявлении DEFINE FILE описать несколько файлов пря- мого доступа? Можно ли один и тот же файл прямого доступа описать в различных объявлениях DEFINE FILE? 7. Может ли объявление DEFINE FILE принадлежать телу цикла DO? 8. Укажите область действия объявления DEFINE FILE. 9. Можно ли использовать буквы L, U, Е, задающие характеристики файла пря- мого доступа, в качестве идентификаторов переменных? 10. Перечислите предложения языка ФОРТРАН/ЕС, предназначенные для обес- печения прямого доступа к файлам. 11. Как идентифицируются записи в файле прямого доступа? 12. Какая переменная называется связанной? Какие операторы автоматически изменяют значение связанной переменной? 13. Можно ли назвать букву U в объявлении DEFINE FILE 1# (20, 15, U, К) идентификатором переменной? Будет ли распределена память для значений U? Объяс- ните специфику этого параметра. 14. Опишите файл с прямым доступом со структурой, аналогичной файлу на пер- фокартах. Порция 126 Операторы READ и WRITE для файлов прямого доступа Форматы операторов READ и WRITE для файлов прямого доступа имеют вид READ (p'q, f, ERR=m) a WRITE (p'q, f) a Здесь p — целое без знака, обозначает номер файла, соответствующего устройству прямого доступа; 4 р 14; q — выражение целого типа, значение которого определяет номер записи в фай- ле, подлежащей пересылке; f — метка объявления FORMAT или идентификатор массива, хранящего совокуп- ность спецификаций формата (этот параметр при бесформатном вводе-выводе опус- кается); ERR — ключевое слово, за которым после знака равенства указывается т — метка оператора, выполняемого в случае возникновения ошибки при передаче данных; а — список ввода-вывода (в который, в связи с особым назначением, не может быть включена переменная р, связанная с данным файлом). Например, в операторах, осуществляющих обмен по форматам READ (12’1, Ш) А, В, С WRITE (12’К, L&&) X, Y, Z 12 — номер файла прямого доступа (что отмечено апострофом); I, К — переменные, значения которых определяют номера записей, участвующих в операциях обмена; Ш — метка объявления FORMAT; L88 — имя массива, содержащего совокупность спецификаций формата; А, В, С и X, Y, Z — списки ввода и вывода. Структура списков ввода-вывода в рассматриваемых операторах та же, что и в операторах ввода-вывода в стандарте языка. Форматы, как и в других случаях, задают логическую структуру физической за- писи, размер которой определяется соответствующим объявлением DEFINE FILE. Каждая физическая запись, как и для прочих носителей, может содержать несколько элементов данных. Логическая запись, т. е. запись, определенная спецификациями фор- мата, должна находиться в границах физической записи. Все правила стандарта язы- ка, определяющие взаимодействие форматов со списком ввода-вывода, распростра- няются на файлы прямого доступа. 314
Пример. Пусть на устройстве ввода с перфокарт подготовлены данные — десять строк таблицы, каждая из которых содержит по 10 чисел. Для хранения в оператив- ной памяти одной строки таблицы определим массив: REAL R (Ш) Таблица должна быть передана в файл прямого доступа с номером 11. С этой целью введем объявление файла DEFINE FILE 11 (Ш, 8#, L, J) Строке массива в объявленном файле будет соответствовать одна запись. Чтение с перфокарт и перепись исходной таблицы в файл можно осуществить по- средством выполнения следующего фрагмента программы: REAL R (Ш) - DEFINE FILE 11 (Ш, 8Я, L, J) DO Ш I = 1, Ш READ (I, 1) R Ш WRITE (1Г1, 1) R 1 FORMAT (ЮТ8.6) Таким образом,’для пересылки таблицы, выполненной за 10 тактов цикла, использо- вано 10 слов внутренней памяти машины. Для вывода I-й строки на печатающее устройство по запросу, вводимому с перфо- карт, можно воспользоваться следующим фрагментом программы: 3 FORMAT (15) READ (1, 3) I IF (I.LE.tf.OR.I.GT.lBj GO TO 777 READ (1Г1, 1) R WRITE (3, 111) R 111 FORMAT (5X, ЮТШ.6) 1 FORMAT (10F8.6) 777 ............... Здесь меткой 777 помечен оператор, которому должно быть передано управление в том случае, когда вводимое значение переменной I оказывается выходящим за пределы допустимых значений номеров строк (записей файла). Задание. 1. Какой нестандартный символ используется в записи операторов прямого доступа? 2. Допустимо ли объявление 55 FORMAT (512#, ЮТ 12.6) в сочетании с предложениями REAL R (1##) INTEGER К (5) DEFINE FILE 8 (5#, 2##, L, IND) READ (8'25, 55) K,R 3. Сколько и какие записи будут прочитаны в данном ниже фрагменте программы? Каково будет значение переменной POINT после его завершения? INTEGER POINT REAL ARR (2#) DEFINE FILE 1*1 (8#, 2#, L, POINT) POINT = 6 READ (11' POINT, 7) ARR 7 FORMAT (4F5.3) 315
Порция 127 Бесформатные операторы чтения — записи при прямом доступе Если данные предназначены для временного хранения, целесообразно выполнять их пересылку без преобразсвания по форматам. Однако нельзя читать данные без фор- мат^ если они были записаны по формату. Бесформатный ввод-вывод при прямом досту ie осуществляется операт( рами READ и WRITE, в которых отсутствуют ссыл- ки на формат. Например: READ (8’VARY) X, Y WRITE (9’LOC-f- 5) А, В, С Здесь 8, 9 — номера файлов прямого доступа; VARY — переменная целого типа; LOC +5 — выражение целого типа. При передаче данных без формата осуществляется пересылка кодов во внутреннем представлении данных в памяти. Поэтому длина логической записи определяется по описанию типов элементов списка ввода-вывода. Эта длина не должна превышать раз- мера физической записи. Пример COMPLEX *8 X,Y,Z REAL V, Т READ (11'16) V, Т, Y, X, Z, LAM, DEL Согласно описаниям переменных списка ввода, для них выделяется 10 слов памя- ти (4+ 4+8+ 8 + 8 + 4 + 4 байтов). Поэтому объявление DEFINE FILE 11 (20, 12, U, LINK) допустимо, а объявление DEFINE FILE 11 (20, 8, U, POS) не до- пустимо. Задание. 1. В каких случаях размер записи в файле прямого доступа связан с размерами стандартных полей ЕС ЭВМ, т. е. с описателями типов ФОРТРАНа? 2. Если данные были записаны по формату, всегда ли совпадает их представление на носителе с представлением в оперативной памяти? Порция 128 Оператор FIND Формат этого оператора имеет вид: FIND (n'/n) Здесь п — целое без знака, обозначает номер файла прямого доступа; Ш — выра- жение целого типа, значение которого определяет номер записи в файле п. С помощью оператора FIND можно осуществить подводку устройства чтения- записи к началу требуемой записи файла прямого доступа независимо <тт вида опе- раций READ или WRITE. Например, в результате работы оператора FIND (9'20) будет найдена запись 20 файла 9, т. е. значением переменной, связанной с файлом 9, станет 20. Оператор FIND позволяет сократить общее время работы программы, так как поиск записи может быть совмещен во времени с выполнением других вычислений, не связанных с обращением к данному внешнему устройству. Например, при выпол- нении фрагмента программы FIND (11'25) DO 40 J = 1, N 40 PSI (J) = PSI (J) + ABS (V (J) — X (J)) WRITE (1Г 25, 400) PSI достигается выигрыш во времени, так как поиск записи осуществляется параллельно 316
с выполнением цикла. Во фрагменте DO4# J = 1, N 40PSI (J) = PSI (J) + VAR (J) FIND (11' 25) WRITE (11'25, 4^) PSI можно удалить оператор FIND, так как выполнение WRITE так или иначе включает поиск нужной записи. После выполнения оператора FIND значение связанной пере- менной равно 25, после выполнения оператора WRITE оно равно 26. Задание. 1. Чем отличаются между собой физическая структура носителя, логи- ческая структура файла и структура распределения внешней памяти для файла? 2. Сколько записей описывают объявления 1 FORMAT (IX, F8.4/I5/I5) 2 FORMAT (IX, F8.4/2I5) 3. Сколько физических записей размером 80 байтов потребуется для пересылки логической записи в следующем примере: DIMENSION А (4£), В (4Я), С (2£) WRITE (7) А, В, С 4. Известно, что оператор ФОРТРАНа может быть записан на нескольких перфо- картах. Существуют трансляторы, допускающие запись нескольких операторов на од- ной карте; в качестве разделителя операторов в этом случае используется денежный знак. Рассматривая условно каждый оператор как файл, а перфокарту как том, из Сра- зите структуру распределения внешней памяти под входные файлы такого транс- лятора. 5. Согласны ли Вы со следующими утверждениями: а) файл — это совокупность логически взаимосвязанных записей; б) файл — это такой набор данных, который является внешним по отношению к использующей его программе; в) ввод — это передача данных из файла в программу, вывод — передача данных из программы в файл. ~ 6. Размер физической записи для диска с прямым доступом ограничен 3625 бай- тами. Можно ли так разметить дорожку диска, чтобы она содержала 5 физических за- писей по 725 байтов? 7. Какую структуру отражают: а) объявление DEFINE FILE? б) объявление DIMENSION? в) список спецификаций формата между разделителями (, I и / ,) ? г) элементы спецификации w.d, например F12.6?
Глава VIII ФОРТРАН КАК ЭЛЕМЕНТ ДОС Порция 129 Этапы обработки программ и соответствующие компоненты ДОС В современных вычислительных комплексах трансляторы входят в состав так называемых операционных систем (ОС), охватывающих и организующих работу всего программного обеспечения и аппаратуры ЭВМ. ОС состоят из большого числа ко- мпонент разного назначения и управляют прохождением потока задач на ЭВМ, позво- ляют автоматизировать процесс составления, обработки и отладки программ. Назна- чение и возможности каждой компоненты системы ограничены и имеют смысл только в определенной совокупности; их взаимодействие и порядок работы осуществляются человеком с помощью специального языка управления системой. Всякий язык высокого уровня остается в значительной степени зависимым от той среды, операционной обстановки, в которой он функционирует. Человек, использую- щий ФОРТРАН в рамках ДОС ЕС, чаще всего будет иметь дело с соответствующим транслятором. Однако он должен иметь достаточное представление о других элементах операционной системы в связи с тем, что: 1. Доступ к ЭВМ и контакт с транслятором, как и с другими компонентами, воз- можны практически только посредством специальной управляющей программы опе- рационной системы. 2. Код, построенный в результате работы транслятора, является промежуточным. Для получения окончательного кода, непосредственно интерпретируемого машиной, требуется дополнительная обработка. 3. Управление выполнением программы — это процесс, не зависящий от исполь- зуемого языка и транслятора. Обработка программ, написанных на языке высокого уровня, расчленяется в ДОС ЕС на три основных этапа, что облегчает отладку, позволяя выполнять каждый этап независимо от другого. Первый этап — это трансляция программных модулей, называемых в рамках операционных систем ЕС ЭВМ исходными модулями. Относительно транслятора исход- ные модули являются входным набором данных, или входным файлом. Результатом работы транслятора является объектный модуль — программа на языке машинного уровня, не содержащая индивидуальных черт исходного языка. Адресация в объект- ном модуле — относительная, и для его выполнения требуется настройка на абсолют- ные адреса памяти. На этом уровне также не определены адреса внешних процедур- ных модулей и общих блоков. Таким образом, объектный модуль не является продук- том, готовым к выполнению. Дальнейшая обработка производится особой компонентой ДОС — Редактором связей (Linkage Editor). Входными данными для Редактора являются объектные модули. Редактор может обращаться к библиотеке, содержащей внешние процедуры ФОРТРАНа. Если редак- тирование предполагается выполнять сразу же после трансляции, то транслятор помещает на временное хранение построенные объектные модули в системный файл SYSLNK. В результате редактирования строится абсолютный модуль, или программная фаза, в которой определены все внешние ссылки и все относительные адреса откоррек- тированы в соответствии с действительным адресом загрузки программной фазы в опе- 318
ративную память. Абсолютный модуль может быть сразу же после редактирования загружен в память и выполнен или помещен в библиотеку абсолютных модулей для последующего выполнения. Схема обработки программ с помощью ДОС показана на рис. 40. Выполнение программы, которая может состоять из одной или нескольких фаз. начинается с момента, когда корневой (головной) фазе, загруженной в память, пере- дается управление. Процесс загрузки и выполнения программ осуществляется под контролем Супервизора. Супервизор, в отличие от транслятора или Редактора, является управляющей, а не обрабатывающей программой. К функциям Супер- визора относится обработка особых ситуаций, возникающих в ходе выполнения про- грамм — переполнения разрядной сетки, невер- ной адресации, ошибок ввода-вывода и др. Исходные, объектные и абсолютные моду- ли хранятся в библиотеках соответственно трех видов: библиотека исходных модулей SL (Source Library), библиотека объектных модулей RL (Relocaii- Ые Library), библиотека абсолютных модулей CL (Core Library). Библиотеки могут быть личными и систем- ными. Содержимое системных библиотек доступ- но для общего пользования; личные библиотеки должны быть предварительно сформированы про- граммистом. Абсолютные модули могут быть помещены в CL только Редактором. Для формирования SL, RL и корректировки всех библиотек использует- ся обслуживающая программа — Библиотекарь. Процесс занесения модуля в библиотеку называ- ется каталогизацией. Транслятор не помещает Рис. 40 объектные модули в RL; однако в специальном режиме работы можно вывести результаты работы транслятора на перфокарты (или в формате перфокарты на диск или магнитную ленту) и впоследствии закаталогизи- ровать. Порция 130 Генерация системы Генерация — это процесс создания конкретного варианта операционной системы из отдельных компонент в соответствии с запросами пользователей и составом вычис- лительного оборудования ЕС ЭВМ. При генерации ДОС, которая выполняется систем- ными программистами, выбираются те возможности и компоненты, которые обеспе- чивают оптимальную эксплуатацию на данной конфигурации машины, в том числе такие параметры системы, которые полезно знать пользователю ФОРТРАНа. Неко- торые из режимов могут быть объявлены стандартными и в этом случае они вводятся в действие при обработке задания по умолчанию. Однако при необходимости пользова- тель может отменить отдельные из режимов в тех или иных пределах пакета заданий, используя специальные директивы или операторы языка управления заданиями. К числу режимов, которые могут быть заданы стандартно при генерации, от- носятся: 1. DECK — вывод объектных модулей на системное устройство перфорации. 2. LISTX — вывод результатов трансляции на системное устройство печати. 3. LIST — вывод исходного текста с описанием хода трансляции на системное устройство печати. 319
4. ERR — вывод на системное устройство печати ошибочных исходных операто- ров с сообщениями об ошибках, если отменен режим LIST. 5. LOG — вывод на системное устройство печати директив и операторов управ- ления заданиями, которые предъявляются системе. 6. DUMP — вывод на системное устройство печати содержимого основной памя- ти в шестнадцатеричном коде в случае аварийного завершения программы. Кроме того, в ходе генерации ДОС можно определить размер страницы устройства печати и формат печати даты: LINE — количество строк на странице системного устройства печати. Минимум — 30, максимум — 99. DATE — формат при печати даты: день, месяц, год или месяц, день, год. При многопрограммном режиме работы ЕС ЭВМ пользователю часто необходимо знать объем памяти, которым он располагает. При генерации ДОС задается распре- деление памяти между разделами, отведенными для одновременного выполнения отдельных программ, а также осуществляются стандартные назначения физических устройств логическим (см. порцию 132). Управление работой ДОС Управление работой операционной системы осуществляется обычно с помощью некоторого языка. В системе программирования ЕС ЭВМ такой язык называется язы- ком управления заданиями (ЯУЗ). Задание в терминах ЕС ЭВМ — это независимая единица работы системы. Задания в ДОС ЕС могут объединяться в пакет и обрабаты- ваться последовательно. Воспринимая задания, ДОС выполняет те или иные действия над модулями и дру- гими наборами данных. Операторы ЯУЗ обрабатываются в системе специальной про- граммой управления заданиями. Язык управления заданиями состоит из директив и операторов. Различие между последними состоит в том, что действие директивы постоянно, т. е. распространяется на весь пакет заданий и отменяет стандартные режимы, заданные при генерации; опе- раторы действуют только в рамках одного задания, временно отменяя действие дирек- тивы. При этом не для всех операторов определены соответствующие директивы. Та- ким образом, управляющие воздействия могут быть стандартными, постоянными (установленными директивами) и временными (объявленными операторами языка уп- равления). Директивы и управляющие операторы передаются в систему через устройство SYSRDR или SYSLOG, а исходные наборы данных, например текст на ФОРТРАНе,— через SYSIPT. Обычно SYSRDR и SYSIPT назначается одно и то же физическое уст- ройство (в этом случае логическое устройство задается одним общим именем SYSIN). Задание, 1. Какими объектами оперирует ДОС? 2. Что такое задание и на каком языке оно записывается? 3. Чем различаются действия операторов и директив в рамках одного задания? 4. Укажите область действия стандартных режимов, директив и операторов ЯУЗ. 5. Могут ли какие-либо обрабатываемые файлы находиться непосредственно в задании? 6. Какое логическое устройство используется в ДОС для ввода управляющих операторов? Порция 131 Оформление задания Задание — это последовательность управляющих операторов и директив. При описании формата управляющих операторов будем считать, что они наносятся на пер- фокарты, так как при представлении на других носителях сохраняются те же пра- 320
вила записи. Каждая перфокарта может содержать только один оператор в позициях 1—70. Основными элементами формата управляющих операторов являются: признак код операции поле операндов Элементы следуют в перечисленном порядке. Для большинства управляющих операторов признак задается двумя косыми чертами И в первых двух позициях и отделяется от последующего кода операции одним пробелом. Код операции записы- вается после признака через пробел. Признак и код операции в формате являются обязательными компонентами всех операторов. Поле операндов может быть заполнено пробелами (операнды отсутствуют) или списком операндов, записанным через один или несколько пробелов после кода операции. Операнды между собой разделяются запятыми; пробелы внутри поля операндов недопустимы. Порядок операндов в их списке произволен. После перечисления основных элементов через пробел можно записывать произ- вольный текст, который рассматривается системой как комментарий. Формат директив подобен формату соответствующих операторов; признаком ди- рективы является наличие хотя бы одного пробела в первых позициях карты. Специфические форматы следующего вида имеют три управляющих оператора, определяющие конец задания, конец набора данных, комментарий: /& /* * Эти операторы записываются в первых (одной или двух) позициях перфокарты. Оператор JOB Оператор JOB (Начать Задание) должен быть первым в задании. Если формиру- ется пакет заданий, этот оператор должен быть первым в пакете. Формат оператора следующий: //i_j JOB i—i {имя) i—i {комментарии) где {имя) — обозначает имя задания, состоящее не более чем из 8 алфавитно-цифро- вых символов. Например: //LJ JOB l_j STUDENT i—j ПЕТРОВА Оператор JOB возобновляет действие стандартных и постоянных режимов. Си- стема, выполняя этот оператор, всегда печатает его на SYSLOG и SYSLST с последую- щим указанием даты выполнения задания. Если включены системные часы (таймер), то, кроме даты, печатается время начала выполнения задания. Оператор /& Оператор /& завершает задание и должен быть последним оператором в задании. В операторе могут быть заданы комментарии, которые, однако, должны записываться с 14-й позиции. Оператор /& восстанавливает стандартные или постоянные режимы работы,, если они были изменены в рамках задания. При выполнении оператора на каждом из логических устройств SYSLOG и SYSLST печатается сообщение: EOJ {имя) I—j {комментарии) где {имя) — является именем завершаемого задания. Другими словами, оператор /& выполняет роль парного символа по отношению к оператору JOB. П 9-2712 321
Выполнение в задании оператора /& обозначает так называемое нормальное за- вершение этого задания. При возникновении в процессе выполнения задания особой ситуации, приведшей к «снятию» задания, выдается соответствующее диагностиче- •ское сообщение, а задание завершается до появления оператора /&. Оператор ЕХЕС По оператору ЕХЕС ДОС осуществляет вызов абсолютного модуля (фазы) из библиотеки CL в основную память и его выполнение. Общий вид оператора: //lj ЕХЕС (п) Здесь п — имя модуля, состоящее не более чем из 8 алфавитно-цифровых литер. В задании может быть несколько операторов ЕХЕС, каждый из которых опреде- ляет шаг задания. С помощью ЕХЕС может быть выполнена любая фаза — как компо- нента ДОС, так и программа пользователя. Фаза, полученная непосредственно после редактирования, до помещения в библиотеку абсолютных модулей не имеет имени. Такую, так называемую временную, фазу можно выполнить только непосредственно после редактирования в рамках одного задания. В этом случае в ЕХЕС используется пустой параметр. Перед выполнением фазы может возникнуть необходимость в выполнении неко- торых предварительных действий. Часто, например, требуется задать режимы работы системных компонент (транслятора, Редактора), выполнить разметку файлов прямого доступа, подготовить магнитную ленту для программ пользователя и т. п. В таком случае управляющие операторы, выполняющие подобные действия, должны пред- шествовать соответствующему оператору ЕХЕС. Управляющие операторы обычно вводятся с SYSIN, поэтому входные файлы на перфокартах могут включаться в текст задания непосредственно после оператора ЕХЕС. Например, исходные модули на ФОРТРАНе располагаются сразу после //ш ЕХЕС lj FFORTRAN, данные на перфокартах для непоименованной программы пользователя — после опе- ратора // lj ЕХЕС. Оператор / * Оператор /* (Конец Файла) используется при вводе входных наборов данных с устройства SYSIPT. Поскольку SYSIN обычно совмещает логические устройства SYSIPT и SYSRDR с одним и тем же физическим устройством, оператор /♦ указывает системе на конец данного файла. Оператор « Оператор ♦ предназначен для включения в задание комментариев и вывода их на SYSLOG. Общий вид оператора: * (комментарии) Этот оператор удобен для передачи сообщений на консоль оператора. Оператор и директива PAUSE Как оператор, так и директива PAUSE, если они включены в задание, приоста- навливают ввод в систему с SYSRDR управляющих операторов. На время паузы устанавливается связь системы с консолью оператора — диалоговый режим, в ходе которого можно вводить операторы ЯУЗ с устройства SYSLOG. При этом, в частности, можно выполнять непрограммные действия на внешних устройствах, например, уста- новку лент, дисков или пакетов перфокарт. Возобновить ввод управляющих операто- ров с SYSRDR можно директивой КТ (конец текста). 322
Формат оператора: Формат директивы: //lj PAUSE lj (комментарии) PAUSE lj (комментарии) Директива КТ Директива КТ прекращает связь консоли оператора с программой Управления заданиями и возобновляет автоматический (недиалоговый) режим управления. Директива КТ реализована аппаратно и вводится нажатием клавиши КТ на пульто- вой машинке. Пример задания на трансляцию в стандартном режиме: //lj JOB lj СОМР1ЬЕшЖУКОВ А. Г., ОТД. 66, КОМН. 202, ТЕЛ. 28—29—71 // ljPAUSEljYCTAHOBHTE ПАКЕТ № 5 НА SYSIPT, ЗАТЕМ НАЖМИТЕ КТ. И LJ EXEC L_J FFORTRAN /& Задание. 1. Сколько шагов указано в вышеприведенном задании? 2. В чем. состоит различие действий управляющих операторов и директив? 3. Чем отличается формат оператора Я УЗ от формата директивы? 4. Какие операторы имеют особый формат? 5. Перечислите основные элементы формата управляющих операторов. 6. В каких позициях карты записываются управляющие операторы? Допускают- ся ли для этих операторов карты продолжения? 7. В каких операторах допускаются комментарии? 8. Какие операторы восстанавливают стандартные режимы? 9. Чем отличается действие управляющего оператора PAUSE и оператора PAUSE языка ФОРТРАН? 10. Какая ошибка допущена в задании? И L_J JOB LJ ERR И lj OPTION lj LIST // lj EXEC lj FFORTRAN /♦ // lj EXEC lj LNKEDT // lj EXEC /& Порция 132 Внешние устройства, используемые в ДОС при обработке ФОРТРАН-программ, и их назначение Так как во многих случаях внешние устройства разных типов могут выполнять одни и те же функции, в ДОС вводится понятие логических устройств, которые задают- ся стандартными символическими именами. Логическому устройству, как устройству, идентифицируемому символическим именем, назначается при оформлении задания кон- кретное физическое устройство или оно определяется по умолчанию. Под назначением понимается установление соответствия между логическим и конкретным физическим устройством (диском, накопителем на МЛ, печатающим или перфорирующим устрой- ством, устройством ввода перфокарт). В рамках программы на ФОРТРАНе также ис- пользуются логические устройства, однако обращение к ним осуществляется не по именам, а по номерам. Все сведения по использованию логических устройств приведе- ны в табл. 30. 11* 323
Таблица 30 Логические устройства Имя логиче- ского устрой- ства Имя файла Назначение Тип физического устройства ФОРТРАН/ЕС Допусти- мые опе- рации Номер уст- ройства Применение операторов BACKSPACE, END FILE и REWIND * SYSIPT * SYSIN * SYSPCH * SYSLST * SYSLOG SYsetfi SYStfll SYSLNK SYSCLB SYSRLB SYSSLB IJSYSIN IJSYSIN IJSYSPH IJSYSLS IJSYSei TJSYS11 IJSYSLN IJSYSCL IJSYSRL IJSYSSL Ввод данных Системный ввод, если SYSRDR и SYSIPT на- значено то же устройство Системная перфорация Системная печать Связь с оператором ввод- вывод Ввод данных для редак- тора Личная CL Личная RL Личная SL ПК, МЛ, диски (поел, дост.) ПК, МЛ, диски (после- довательный доступ) ПК, МЛ, диски (поел. дост.) ПЧ, МЛ, диски (поел. дост.) консоль оператора ПЧ, ПК, МЛ, диски диск диск диск диск ввод ВВОД ВЫВОД вывод вывод ввод- вывод В I 1 1 2 3 15 4 14 замках не и нет нет нет нет нет Только для последо- вательного доступа языка ФОРТРАН [спользуется Звездочкой отмечены номера устройств, назначения которых не могут быть изменены программистом
Логические устройства подразделяются на системные и пользовательские. В табл. 30 перечислены системные логические устройства, которые используются при обработке ФОРТРАН-программ, но не могут быть использованы в программах на ФОРТРАНе. Стандартными назначениями, определяемыми при генерации, обычно являются следующие: SYSRDR, SYSIPT, SYSIN 1 устройство ввода перфокарт SYSPCH 2 устройство перфорации SYSLST 3 устройство печати SYSLOG 15 пультовая пишущая машинка Имя файла (набора данных), в отличие от имени логического устройства, не свя- зано с использованием того или иного физического устройства и используется для идентификации наборов. Использование в ФОРТРАНе номеров, однозначно соответствующих устройствам, приводит к тому, что полученная в результате трансляции программа не зависит от адреса физического устройства. Следует помнить, что это соответствие постоянно и не может быть изменено программистом. При выборе внешних устройств нужно учиты- вать существующие ограничения. Некоторые физические устройства в принципе не могут использоваться для ввода, например печатающее устройство, перфоратор; дополнительные ограничения вводятся системой; в частности, пишущая машинка в ФОРТРАНе не может использоваться для ввода. Задание. 1. Что такое логическое устройство? 2. Можно ли логическому устройству назначить любое физическое устройство? 3. Используются ли в ФОРТРАНе имена логических устройств? 4. Как в ФОРТРАНе осуществляется обращение к внешнему устройству? 5. Можно ли изменить соответствие между именами логических устройств и но- мерами устройств, используемыми в ФОРТРАНе? 6. Можно ли в ФОРТРАН-программе использовать SYSSLB? 7. Имеется ли различие между именем логического устройства и именем набора данных? 8. Может ли один и тот же оператор ФОРТРАНа при разных выполнениях про- граммы осуществлять вывод на разные физические устройства? 9. Какие логические устройства являются системными? 10. Какие ограничения имеются в ФОРТРАНе на использование пультовой пи- шущей машинки? 11. Будет ли выведен исходный текст программы на печатающее устройство, если задан режим LIST, а логическому устройству SYSLST назначена магнитная лента? Порция 133 Оператор и директива ASSGN Оператор и директива ASSGN служат для назначения логическому устройству конкретного внешнего устройства, представляемого с помощью так называемого фи- зического адреса. С помощью ASSGN можно также отменить назначение, т. е. отклю- чить на определенный период внешнее устройство. Рассмотрим несколько упрощенный формат оператора ASSGN: //i_j ASSGN i—i и, а Здесь п — символическое имя определяемого логического устройства, допустимое в ФОРТРАНе; а — адрес физического устройства, назначаемого этому логическому. При назна- чении а имеет вид: X’cwu’ где с и и — шестнадцатеричные цифры; с определяет номер канала ЭВМ, ии — номер устройства в этом канале. 325
Примеры //lj ASSGN i—i SYS ##1, Х'191' 191 — адрес накопителя на магнитном диске; //lj ASSGN lj SYS ##2, Х'28#' 2 8# — адрес накопителя на МЛ; //lj ASSGN lj SYSLOG, X'#1F' # 1F — консоль оператора; //lj ASSGN lj SYSLST, Х'##Е' # #Е — АЦПУ; //lj ASSGN lj SYSPCH, X'##D' # #D — вывод на ПК; //lj ASSGN lj SYSIN, X'##C' # #C — ввод ПК. При отключении логического устройства а задается строкой UA (unassigned) Задание параметра UA приводит к отмене назначения, причем при попытке ис- пользования соответствующего логического устройства задание будет снято. Задание параметра IGN приводит к тому, что попытки обращения к устройству игнорируются, но выполнение задания продолжается. С помощью параметра IGN нельзя отключать системный ввод; иными словами, в операторе ASSGN с параметром IGN не допуска- ются символические имена SYSRDR, SYSIN, SYSIPT. Кроме этого, IGN нельзя указывать для SYSCLB. В записи директивы ASSGN вместо наклонных черт используются пробелы. Кроме того, можно использовать дополнительный необязательный параметр TEMP: ljlj ASSGN lj и, a, TEMP Параметр TEMP переводит постоянное действие директивы во временное. Таким обра- вом, действие директивы ASSGN с параметром TEMP эквивалентно действию опера- тора ASSGN. Порция 134 Оператор и директива RESET F Оператор и директива RESET предназначены для восстановления стандартных и постоянных назначений внешних устройств. < Формат оператора: //lj RESET р Таблица 31 Наборы логических устройств р Набор устройств SYS PROG ALL SYS ппп Все системные Все личные Все Конкретное Для ФОРТРАН/ЕС ##1 < ппп < #11 326
где р — параметр, определяющий набор логических устройств, для которых будут восстановлены назначения. Значения р и соответствующие наборы логических устройств приводятся в табл. 31. Порция 135 Управление трансляцией Вызов транслятора с помощью управляющего оператора //о EXECljFFORTRAN может быть выполнен многократно в рамках одного задания. С помощью одного вызо- ва транслятора можно осуществить трансляцию нескольких программных модулей. Входной файл транслятора, состоящий из последовательно расположенных програм- мных модулей, поступает на трансляцию в результате выполнения указанного опера- тора // i—i EXEC i—i FFORTRAN. Конец файла задается управляющим операто- ром /♦. Управление трансляцией может осуществляться как в рамках задания, ограни- ченного операторами И l_j JOB и /&, так и вне его. Операторы //lj JOB и /& всегда восстанавливают действие стандартных режимов трансляции, заданных при генера- ции ДОС, или постоянных, заданных с помощью директив. Управлять трансляцией внутри задания, т. е. изменять стандартные или постоянные режимы, можно с по- мощью управляющих операторов // lj FTC и // i—i OPTION. Таким образом, режимы управления трансляцией могут вообще не указываться в рамках задания; в этом слу- чае будут использованы наиболее универсальные стандартные режимы. Оператор // lj FTC имеет более высокий приоритет, чем // l_j OPTION, т. е. он отменяет режимы, указанные в // l_j OPTION. Оператор И lj FTC обычно записы- вается непосредственно после оператора И lj EXEC lj FFORTRAN и должен быть единственным для каждого вызова транслятора. Управляющие параметры в // lj FTC могут перечисляться в произвольном порядке. Например: // lj FTC и LOAD = 4, NOLISTX, LIST, NAME = GLOBAL, LINECNT = = 7#, EBCDIC Параметры оператора имеют следующий смысл: EBCDIC или BCD — параметр внешнего кодирования исходного текста; рекомен- дуется использовать EBCDIC, который является стандартным; LOAD — п — параметр загрузки объектного модуля на SYSLNK. Здесь п = О, 4 или 8. Обычно LOAD = 4. Этот параметр указывает на то, что полученный объект- ный модуль будет редактироваться, если наибольший уровень ошибки не превышает заданный; NOLOAD — указывает на то, что объектные модули не будут редактироваться; NAME = (имя) — имя, которое будет присвоено головной программе (не более 8 символов). Стандартное имя — MAINPGM; LINECNT = пп — счетчик строк; указывает количество строк на странице прото- кола трансляции; 30 < пп < 99; LIST, NOLIST — задание или отмена печати исходных операторов ФОРТРАНа; печать ошибочных операторов выполняется; LISTX, NOLISTX — задание или отмена печати объектного модуля на SYSLST. Оператор // lj OPTION может содержать уже известные параметры управления трансляцией: LIST, NOLIST, LISTX, NOLISTX. Кроме того, в нем можно указать ре- жим вывода объектного модуля на SYSPCH — системное устройство перфорации: DECK перфорация NODECK отмена перфорации Стандартный режим обычно NODECK. Объектный модуль, выведенный на карты, может быть впоследствии каталогизирован в библиотеку или введен на SYSLNK для последующего редактирования с помощью оператора INCLUDE. 327
С помощью управляющих параметров DUMP или NODUMP оператора //lj OPTION может быть задан режим вывода или отмены вывода дампа на SYSLST. Дамп выводится только в случае аварийного завершения любого шага задания. Стандартным является обычно NODUMP. Отмена печати листингов транслятора, включая отмену печати ошибочных опе- раторов, дампов и др., может быть достигнута отключением устройства SYSLST. Для этого используется оператор ASSGN с параметром IGN: //ш ASSGN lj SYSLST, IGN В нужный момент действие стандартного или постоянного назначения можно восстановить оператором //lj RESET lj SYSLST Задание, 1. Почему строку END нельзя использовать в качестве признака конца файла? К чему приведет разделение программных модулей операторами /*? 2. Какие режимы трансляции устанавливаются оператором /7 lj JOB? 3. Какова область действия оператора FTC, а какова оператора OPTION? 4. С помощью каких параметров можно вывести объектный модуль на SYSLST? на SYSPCH? 5. Каким способом можно отменить печать исходного текста на SYSLST: а) опустив параметр, б) указав параметр, в) отключив устройство. 6. Означает ли включение режима DUMP обязательный вывод дампа? 7. Проверьте, можно ли в операторе OPTION указывать режимы, противореча- щие друг другу: И lj OPTION DECK, LIST, LISTX, NOLIST 8. Будут ли печататься ошибочные операторы ФОРТРАНа а) в области действия режима NOLIST? б) в области действия оператора И l_j ASSGN lj SYSLST, IGN? 9. Может ли транслятор отменить режим LINK? 10. В каких случаях используется логическое устройство SYSIN? 11. Нужна ли информация о режиме LINK для транслятора? Порция 136 Сообщения об ошибках, обнаруженных транслятором Каждое диагностическое сообщение транслятора состоит из кода и текстовой ча- сти (на английском языке). В табл. 37 (приложение 2) приведены номера сообщений и возможные причины возникновения ошибки. С каждой ошибкой связан уровень, ко- торый отражает серьезность ошибки и может принимать значения 0, 4, 8 и 16. Ошибки с уровнем 0 и 4 являются предупреждающими. При обнаружении таких ошибок транслятор создает объектный код, который может быть загружен для после- дующего редактирования и выполнения. Вследствие этого стандартное значение па- раметра LOAD обычно равно 4. Примером сообщения об ошибке уровня 0 может служить предупреждение о не- верном использовании метки перед объявлением или строкой END: ILF#43I ILLEGAL LABEL WRN. Запись 1ЕР#431 обозначает код ошибки; далее следует текстовая часть сообщения («НЕВЕРНАЯ МЕТКА»). Слово WRN. (warning) означает «предупреждение» и при- сутствует в некоторых сообщениях уровней 0 и 4. Обращаем Ваше внимание на то, что в таблице 37 в первой колонке указана лишь часть кода ошибки, расположенная между литерами ILF и литерой I — номер ошибки (в нашем примере он равен #43). 328
Имеется одно сообщение 1LF#32I NULL PROGRAM (ПУСТАЯ ПРОГРАММА), которое вообще не имеет уровня ошибки. Обычно такая ситуация возникает, если признак конца файла /* предшествует в задании исходным операторам ФОРТРАНа. В этом случае все следующие за /* карты ФОРТРАНа обра- батываются уже не транслятором, а управляющей программой ДОС и понимаются как неверные операторы управления заданием. Уровень 8 соответствует серьезным ошибкам, после которых трансляция некото- рых операторов не доводится до конца, а редактирование полученных объектных модулей, вообще говоря, не имеет смысла. Тем не менее, установив (с помощью опера- тора FTC) LOAD = 8, можно добиться редактирования модулей с ошибками уровня 8 (но не 16!). Сообщению I LF##9I ORDER, которое фиксирует неверный порядок сле- дования операторов в программном модуле, может соответствовать уровень 8 или 0. Ошибке присваивается уровень 0 только для случаев, когда объявление типа записано после оператора. В ходе работы транслятора возможны четыре ситуации уровня 16. Три из них сопровождаются сообщениями: ILF #281 NO CORE AVAILABLE ILF ИЗИ ROLL SIZE EXCEEDED ILF #441 ALLOCATION CANNOT CONTINUE и вызываются нехваткой ресурсов. Обычно они могут быть устранены разбиением программы на более мелкие единицы. Уровень ошибки, печатаемый в листинге для этих ошибок, не совпадает с фактическим и равен 0. Тем самым указывается, что при- чина останова — техническая. Ситуация уровня 16 с сообщением ILFH42I PROGRAM CHECK сигнализирует о неполадках транслятора (которые могут возникнуть также по техни- ческим причинам) и сопровождается выводом содержимого памяти в шестнадцатерич- ном коде. В этом случае процесс трансляции прекращается и задание снимается, т. е. следующие шаги задания не выполняются. Эта ситуация устраняется только систем- ным программистом. Задание. 1. Установите по табл. 37 различие между уровнями 0 и 4. 2. Сколько видов сообщений об ошибках выдает транслятор ФОРТРАНа? Можно ли код ошибки считать ее номером? 3. Можно ли количество кодов ошибок считать количеством ситуаций (причин ошибок), которые распознает транслятор? 4. Всегда ли уровень ошибки, печатаемый в листинге, равен истинному? Если наи- высший уровень ошибки в программе равен 0, означает ли это, что трансляция завер- шилась? 5. Пользуясь табл. 37, объясните различие между ситуациями a) ILF #271 ILLEGAL PROGRAM б) ILF #321 NULL PROGRAM в) ILF #421 PROGRAM CHECK 6. Можно ли редактировать объектные модули, в ходе создания которых возникла ситуация уровня 16? Какова особенность ситуаций уровня 16? 7. Чем отличаются ситуации с кодами ILF#1#I SIZE и ILF#38I SIZE WRN. О каких размерах идет речь в каждом случае? 8. Сравните ситуации, относящиеся к неверному использованию меток: ILF##2I LABEL 1LF##5I ILLEGAL LABEL ILF##6I DUPLICATE LABEL 329
ILFJ022I UNDEFINED LABELS ILFMSI ILLEGAL LABEL WRN. Какие из них локализованы, а какие могут быть обнаружены только после просмотра всфго модуля? Какие ситуации приводят к ошибке уровня 8? 9. Большая группа ошибок связана с противоречивыми описаниями или с несо- ответствием описания объекта его использованию. Проанализируйте причины оши- бок со следующими кодами: ILF^eil ILLEGAL TYPE ILF0J07I ID CONFLICT ILFtfUI CONVERT 10. Может ли транслятор напечатать сообщение ILF#211 UNCLOSED DO LOOPS несмотря на то, что метка, использованная в DO, имеется в программном модуле и предшествует оператору? Порция 137 Отладка ФОРТРАН-программ в ДОС ЕС Отладка заключается в последовательном исправлении синтаксических и смысло- вых ошибок в исходном тексте программы и во входных данных на внешних носи- телях. Кроме того, чтобы убедиться в универсальности применения программы к задачам соответствующего класса, эта программа должна быть проверена для различ- ных наборов данных. Все средства отладки делятся на общесистемные, средства транслятора и языко- вые. Общесистемные средства — это такие, которые контролируют программу в ходе ее выполнения, т. е. в период, когда она уже представлена в машинных кодах. Тран- слятор обнаруживает ошибки исходного текста. Языковые средства отладки — это те, которые имеются в рамках самого языка программирования. В ФОРТРАН/ЕС это специальные операторы отладки и служебные библиотечные программы. Наиболее простые ошибки — это те, которые обнаруживает транслятор. Трансля- тор является основным средством выявления синтаксических и некоторых смысловых ошибок. Однако диагностические возможности транслятора весьма ограничены. Во- первых, транслятор ФОРТРАНа всегда обрабатывает программные модули независи- мо друг от друга, поэтому он не может распознать ошибки, связанные, например, с согласованием списков формальных и фактических параметров. Во-вторых, при транс- ляции не контролируются такие ситуации, как неверное задание параметров цикла, неопределенность величин, выход значения индекса за допустимые пределы и т. п. В-третьих, транслятор в принципе не может распознавать ошибочные ситуации, ко- торые возникают на более поздних этапах обработки программы, т. е. при редактиро- вании и выполнении. Ошибки, которые обнаруживаются на этапе трансляции, могут быть: локализованными в операторе (уровни 0—8); общими для всего программного модуля (уровни 0 — 8); внешними по отношению к программному модулю (уровень 16). Первые два вида ошибок в отличие от третьего не приводят к аварийному завершению трансляции. Таким образом, программист получает всю информацию об обнаружен- ных ошибках в программе. Примеры локальных ошибок: 1. VARIABLE = PI/2. 2. IF (А — В) 15, 16 3. FORMAT (Ila, 3F12.6) 4. INTEGER * 2Х (Ш) Y (Ш) 5. DO f= 1. N 6. X == (X — Y (I) * Z (I) имя состоит более чем из шести литер меньше трех меток в арифметическом опера- торе IF не помечен оператор FORMAT пропущена запятая пропущена метка в операторе DO нарушен баланс скобок 830
7. R = SIGN (X) неверное количество аргументов при обра- щении к библиотечной функции 8. SUBROUTINE PRGM (X, Y, #.1) формальный параметр — константа Примеры ошибок, общих для программного модуля: 1. COMMON А (20) I = 1 IF (I.GT.2#) GO ТО 1 WRITE (3, 3) S 3 FORMAT (IX, F40.8) STOP END не определена метка 1. 2. DIMENSION BETA (200) READ (1, 3) В, K, (BETA (I)), I = 1, K) IF (K.LE.j0j GO TO 10 DO 20 J = 2, K, 2 IF (BETA (J). GT. BETA (J — 1)) GO TO 10 В = BETA (J — 1) BETA (J — 1) = BETA (J) BETA (J) = В 10 CONTINUE WRITE (3, 5) K, BETA ItfSTOP 888 END не закрыт цикл DO; не определена метка 20; повторное использование метки 10. При отладке следует учитывать, что объектный код оператора, содержащего ошиб- ку, чаще всего не формируется. Поэтому устранение ошибки в одном из операторов мо- жет привести к последующей правильной трансляции многих других операторов. Например: DIMENSION А (100/, В (100) DO 55 I = 1, 100 j = 100 — 1+ 1 • А (I) = В (J) Из-за ошибки в объявлении DIMENSION конструкция А (I) (в левой части оператора присваивания) оказывается недопустимой, так как она воспринимается как указатель функции. Обратите внимание на то, что выражение В (J) в правой части не воспринимается при этом как ошибочное и понимается транслятором как указатель функции. Так, если в модуле SUBROUTINE EXT (X, N, DX) REAL X (N) DIMENSION DX (2) DO 1 I = 1, N IF (X (N).LE.e) X (I) = X (N) + DX (1) 1 IF (X (N).GT.e) X (I) = X (N) + DX (2) RETURN END удалить карту DIMENSION, транслятор не зафиксирует в нем ни одной ошибки. В полном соответствии со стандартом транслятор с ФОРТРАНа в системе про- граммирования ЕС ЭВМ фиксирует недопустимое использование имен. Например, если имя подпрограммы используется в том же программном модуле в качестве QQf
простой переменной или имя функции используется в списке ее формальных парамет- ров, то ошибка будет обнаружена. Ключевые слова ФОРТРАНа разрешается использовать в качестве имен. Поэто- му, если вместо запятой в операторе DO будет записана точка (например; DO 51 = = 1.5), транслятор воспримет такой оператор в качестве оператора присваивания (в нашем примере присваивающий переменной DO 51 значение константы 1.5), посколь- ку пробелы являются значащими литерами только в текстовых константах, а в осталь- ных случаях транслятором игнорируются. Приведем другой пример необнаруживаемой транслятором сшибки. Если в опе- ратор перехода вставлена лишняя литера «=», например, GO ТО = 5, то трансля- тор воспримет этот оператор в качестве оператора присваивания, левой частью кото- рого является переменная GO ТО. Л\ногие ошибки возникают из-за неправильной перфорации операторов, напри- мер, в результате того, что предложение оказывается отперфорированным не с седь- мой, а с шестой колонки и поэтому воспринимается как продолжение предыдущего. В подобных случаях диагностическое сообщение транслятора не следует восприни- мать буквально. Часто необходимо детально проанализировать сообщение и програм- му для установления подлинной причины ошибки. Задание, 1. Найдите ошибки и укажите, какие из них локальные. Для обнаруже- ния каких ошибок требуется рассмотреть весь или часть программного модуля? 1) REAL NUMBER (Ш)/6.#, 7Л, 5 * 5, 3 * #. / 2) А : = 0 * D А= С : D ЫИА= ABS (D) 3) 15 REAL А (2) /3 ♦#. 5/ 4) LOGICAL FUNCTION R (С, D) LOGICAL C, D X = C. AND.. NOT. D R = X END 5) FUNCTION FUN (Z, MULT, C, Z) 6) DIMENSION А (Ш, Ш) A (J) == В (J) -j- C (J) 7) IF (X — Y) 6, 7, 6 X = -x Порция 138 Протокол транслятора Обычно для программ, находящихся в процессе отладки, устанавливается режим LIST, согласно которому транслятор выводит определенную информацию о компи- лируемой программе. Ошибочные операторы и сообщения об ошибках печатаются на SYSLST, незави- симо от режимов трансляции и в том случае, когда задан режим NOLIST. Сообщения о локализованных ошибках печатаются непосредственно под пред- ложением, содержащим ошибки, причем литера, в окрестности которой обнаружена ошибка, снизу помечается литерой ф. Одна и та же ошибочная ситуация может со- провождаться несколькими диагностическими сообщениями. Сообщения об общих для всего программного модуля ошибках печатаются после просмотра всего его текста. Сообщения о системных ситуациях печатаются в момент их возникновения. После отработки модуля в целом, также независимо от режимов, всегда печата- ются объем объектного модуля в байтах и уровень ошибки, зафиксированной трансля- тором. ЯЯ9
Пример TOTAL MEMORY REQUIREMENTS 0'0'0'B70' BYTES HIGHEST SEVERTY LEVEL OF ERRORS FOR THIS MODULE WAS 0 Полная распечатка текста исходного модуля (включая сообщения об ошибках) и таблицы распределения памяти печатаются на SYSLST только в случае задания ре- жима LIST. Для различных типов объектов создаются отдельные таблицы: скалярных величин (SCALAR МАР); массивов (ARRAY МАР); операторов FORMAT (FORMAT STATEMENT MAP); общих объектов (COMMON BLOCK 1{имя}1 MAP SIZE {размер в байтах)); внешних программных модулей (SUBPROGRAMS CALLED); меток операторов (STATEMENT LABEL MAP); эквивалентных имен (EQUIVALENCE DATA MAP); списков NAMELIST (NAMELIST MAP). Здесь в скобках приведены заголовки соответствующих таблиц. При этом для внешних программных модулей в таблице SUBPROGRAMS CALLED указываются адреса данного программного модуля, в которые редактором будут засланы абсолют- ные адреса соответствующих внешних процедур. В указанных выше таблицах печатаются имена объектов и начальные адреса выде- ленных для них участков памяти. Эти адреса являются относительными для данного программного модуля или общего блока (т. е. предполагается, что начальный адрес этого модуля или общего блока равен нулю) и печатаются в шестнадцатеричном коде. Таблиц NAMELIST и COMMON столько, сколько общих блоков и списков имен имеется в программном модуле. Для общего непоименованного блока в позиции имени соответствующего заголовка таблицы проставляется пробел. Таблица распределения меток предложений печатается только в тех случаях, когда отменен режим LISTX, так как печать объектного модуля содержит об этом бо- лее подробную информацию. Так как в таблицы помещаются все используемые в программе имена, в том числе и неописанные, просмотр этих таблиц облегчает поиск ошибочных имен при отладке программ, например, появившихся в результате ошибок перфорации. Таблицы распределения памяти, как и сообщения об ошибках, являются важным, средством отладки программ. Просмотр списков вызываемых процедур позволяет уста- новить, какие из массивов не описаны и ошибочно причислены к именам внешних фу я кций. Сообщения об ошибках, связанные с невозможностью распределения памяти в общем блоке (код ошибки ILF-0'2,0'1), печатаются в таблице распределения памяти для общих блоков. Часто распределение оказывается невозможным в связи с выравни- ванием на границы соответствующих стандартных полей. Например, в общем блоке COMMON / BLOCK / X, Y, Z, W REAL X, Y, Z REAL * 8 W переменная W не может быть распределена, так как при распределении ее адрес от- носительно начала блока (12) не кратен 8. Выравнивание на границу при трансляции общих блоков (в отличие от распределения памяти в других случаях) не производится по очевидной причине: один и тот же общий блок может в разных программных моду- лях отводиться под объекты разных типов. Распределение памяти в общем блоке не может быть также выполнено, если для массива указана переменная размерность или возникло противоречие в связи с применением к объектам COMMON объявления EQUIVALENCE. Во всех этих случаях в сообщении с кодом ILF-0'20'1 печатаются имена тех объектов, которые остались нераспределенными. Задание. 1. В чем причина ошибки? FUNCTION GET (STR, I) DATA BLANK /’ lj 7 LOGICAL * 1 STR (1), S EQUIVALENCE (S, BLANK) 333
#1) ILFM8I ALLOCATION Ц S = STR (I) GET = BLANK RETURN END 2. Исправьте ошибку в программе: LOGICAL В, С, А EQUIVALENCE (В, Y), (С, Z) INTEGER Y, Z /15, 8/ #1) ILFtfim SIZE П COMPLEX ♦ 16 C16 /’ COMPLEX ♦ 16 DATA’/ WRITE (3, 1) C16 WRITE (3, 2) C16 1 FORMAT (IX, A16) 2 FORMAT (IX, 2A8) A= B. AND.. NOT. C WRITE (3,3) A 3 FORMAT (IX, Z8) STOP END 3. В программе на ФОРТРАНе имеется описание INTEGER ABCDE и оператор ABCDE = ABODE + 1 в котором допущена (во время перфорации) ошибка: в правой части содержится ABODE вместо ABCDE. Будет ли эта ошибка обнаружена транслятором ФОРТ- РАН/ЕС? Что Вы можете сказать об аналогичной ситуации в АЛГОЛ/60? begin ... integer ABCDE; ABCDE = ABODE + 1; Трансляторы с ФОРТРАНа в операционных системах ДОС и ОС В системе ДОС (Дисковая Операционная Система) имеются трансляторы с язы- ков Базисный ФОРТРАН и ФОРТРАН/ЕС. Оба транслятора отвечают требованиям соответствующих стандартов. Язык Базисной ФОРТРАН является подмножеством ФОРТРАНа. Программы, написанные на Базисном ФОРТРАНе, могут транслироваться транслятором с ФОРТРАНа. Использование Базисного ФОРТРАНа требует меньших ресурсов ЭВМ, чем использование ФОРТРАН/ЕС. Для выполнения трансляции с Базисного ФОРТРАНа используется управляю- щий оператор //ЕХЕС FORTRAN в отличие от //ЕХЕС FFORTRAN для подключения транслятора с ФОРТРАНа. В отличие от ФОРТРАНа, допускающего трансляцию нескольких исходных мо- дулей в одном шаге задания, в Базисном ФОРТРАНе допускается трансляция только одного модуля. В системе ОС (Операционная Система) имеются два транслятора с языка ФОРТРАН: ФОРТРАН G и ФОРТРАН Н. 334
ФОРТРАН G практически не отличается от транслятора с ФОРТРАНа в системе ДОС ЕС; в ФОРТРАНе Н не допускается использование операторов отладки. Основной особенностью транслятора ФОРТРАН Н является то, что он оптимизи- рует объектную программу. В сравнении с ФОРТРАНОМ G ФОРТРАН Н порожда- ет более эффективный объектный код. Очевидно, что более качественный, т. е. более компактный и более быстрый при выполнении, код требует больших затрат времени на его построение. Эти особенности трансляторов определяют сферу их применения: при большом количестве разовых задач целесообразно использовать ФОРТРАН G, при создании программы широкого потребления — ФОРТРАН Н. Управление трансляцией Управление трансляцией во всех трансляторах задается указанием режимов. Для трансляторов ДОС режимы трансляции указываются в управляющих опе- раторах OPTION и FTC; для трансляторов ОС режимы трансляции устанавливаются с помощью параметров в операторах ЕХЕС, вызывающих соответствующий тран- слятор. Таблица 32 Основные режимы трансляции № п/п Действие режима Задание и отмена режима в ОС в ДОС 1 2 3 4 5 Вывод распечатки исходной програм- мы и сообщений транслятора на си- стемное устройство печати Вывод таблиц распределения памяти на системное устройство печати Вывод объектного модуля на систем- ное устройство перфорации Вывод объектного модуля в файл для обработки Редактором Вывод объектного модуля на систем- ное устройство печати SOURCE (NOSOURCE) MAP (NOMAP) DECK (NODECK) LOAD (NOLOAD) LIST (NOLIST) LIST (NOLIST) LIST (NOLIST) DECK (NODECK) LINK (NOLINK) LISTX (NOLISTX) При трансляции с Базисного ФОРТРАНа в ДОС можно использовать следующие режимы: CATAL LINK, NOLINK DECK, NODECK LIST, NOLIST ERRS, NOERRS В трансляторах ОС используются некоторые режимы трансляции, имеющиеся в ДОС, однако задающие их ключевые слова не всегда совпадают. Кроме того, в ОС введены режимы, регулирующие процесс оптимизации исходного текста при исполь- зовании транслятора ФОРТРАН Н. В табл. 32 перечислены основные режимы работы транслятора G и Н ОС в сравне- нии с соответствующими режимами ДОС. 335
Режимы оптимизации для транслятора ФОРТРАН Н Сущность оптимизации состоит в улучшении структуры, объема и быстродействия порождаемого в результате трансляции кода. ФОРТРАН Н обеспечивает выполнение одного из двух видов (уровней) оптимиза- ции: частичную оптимизацию (уровень 1) и полную оптимизацию (уровень 2). Уровень может быть равным 0, что соответствует отмене режима оптимизации. Уровень оптимизации, как и прочие режимы трансляции, задается в ОС в опера- торах ЕХЕС. Общий вид режима, задающего уровень оптимизации, следующий: ОРТ = (i), где 1=0,1 или 2. При частичной оптимизации рассматриваются отдельные участки программы, при полной — анализируется структура и качество всего исходного модуля в целом. В связи с этим при ОРТ=2 можно дополнительно задавать специальные режимы: EDIT и XREF. Режим EDIT задает распечатку структуры исходного текста, а XREF — списка перекрестных ссылок для переменных и меток. Отмена этих режимов указывается ключевыми словами NOEDIT и NOXREF соответственно. Управление заданиями в ОС При составлении заданий по обработке ФОРТРАН-программ в ОС используются следующие управляющие операторы: Ключевое слово Действие оператора JOB Начало задания и его описание ЕХЕС Начало шага задания и его описание DD (data definition) Описание наборов данных (файлов) и распределение устройств ввода-вывода /* Конец файла //♦ Комментарии И Конец задания Управляющие операторы перфорируются в колонках I—71. В колонках 1 и 2 записываются две наклонные черты. Далее записывается имя (задания, шага задания или набора данных) и затем, через пробел, указываются параметры, которые отделя- ются друг от друга запятыми. Рассмотрим наиболее типичные формы управляющих операторов, используемых при обработке ФОРТРАН-программ в ОС, структуру заданий и соответствующие им аналоги в ДОС. Оператор JOB Так же, как и в ДОС, оператор JOB должен быть первым в тексте задания. Обя- зательным в этом операторе является указание имени задания. В отличие от операто- ра JOB, используемого в ДОС, имя пишется с третьей колонки после символов//. Имя задания может содержать от 1 до 8 буквенно-цифровых символов, например: //STAGE ш JOB В ДОС соответствующий оператор имеет вид: //lj JOB lj STAGE Все параметры, следующие в операторе JOB после слова JOB, необязательный могут быть опущены. В этом случае они устанавливаются по соглашениям, заданным при генерации системы. К таким параметрам относится, например, параметр 336
MSGLEVEL (Message Level), который задает режимы вывода на системное устройство печати операторов управления заданием. Общий вид этого параметра следующий: MSGLEVEL = (t, /) где i может принимать значения: О — печатать только оператор JOB; 1 — печатать все управляющие операторы; 2 — печатать только управляющие операторы входного потока, a j может принимать значения: О — печатать сведения о распределении устройств ввода-вывода при аварийном завершении задания; 1 — печатать эти сведения в любом случае. Пример //STUD lj JOB lj MSGLEVEL = (2, tf) Оператор ЕХЕС Оператор EXEC является первым в шаге задания и указывает имя той программы или каталогизированной процедуры, которую необходимо выполнить. Каталогизированная процедура — это текст-заготовка, представляющий собой последовательность управляющих операторов для вызова системных компонент (трансляторов, Редактора, а также рабочей программы) и для задания режимов и опи- сания наборов данных. В ОС имеются четыре каталогизированные процедуры, используемые для вызо- ва транслятора ФОРТРАН G: Имя каталогизированной процедуры Действие FORTGC Трансляция FORTGCL FORTGLG FORTGCLG Трансляция и редактирование Редактирование и выполнение Трансляция, редактирование и выполнение Для использования транслятора ФОРТРАН Н имеются следующие 5 каталоги- зированных процедур: ♦ FORTHC Трансляция FORTHCL FORTHLG FORTHCLG Трансляция и редактирование Редактирование и выполнение Трансляция, редактирование и выполнение FORTHCLD Трансляция и загрузка Использование каталогизированных процедур освобождает пользователя от де- тального программирования задания. Примеры 1. // EXEC lj FORTGC (эквивалентно // lj EXEC lj FFORTRAN в ДОС) 2. :/ STEP lj EXEC ш FORTGCLG Каталогизированные процедуры задают режимы трансляции, указанные при ге- нерации системы, которые не всегда соответствуют потребностям пользователя. Для того чтобы изменить стандартные режимы, заданные при генерации, в операторе ЕХЕС, вызывающем каталогизированную процедуру, необходимо указать требуемые 337
режимы по следующему формату: PARM. FORT = ’($>’ где $ — список режимов. Пример - // ЕХЕС ш FORTHCLG, PARM.FORT = ’SOURCE, МАР, ОРТ = Г Объявление DD Объявление DD предназначено для описания наборов данных, используемых в задании. В табл. 33 показано соответствие между номерами файлов и именами логических устройств и именами наборов данных в системах ДОС и ОС, используемых при обра- ботке и выполнении ФОРТРАН-программ. Таблица 33 Соответствие номеров файлов именам логических устройств и наборов данных Назначение ДОС ОС Номер файла Имя логического устройства Номер файла Имя набора данных Системный ввод 1 SYSIN SYSIPT 5 SYS1N Системный перфовывод 2 SYSPCH 7 SYSPUNCH Системная печать 3 SYSLST 6 SYSPRINT Входная информация (объ- ектный модуль) для ре- дактора — SYSLNK — SYSLIN Рассмотрим объявления DD для случая, когда используются каталогизированные процедуры, а данные для транслятора, редактора и рабочей программы находятся во входном потоке (в задании) и вводятся с устройства SYSIN. Входные наборы данных на перфокартах, включаемые во входной поток, должны помещаться непосредственно после соответствующего объявления DD, которое имеет в этом случае формат // (имя) DD ♦ и завершается оператором /♦. Ниже приводятся форматы объявления DD для различных наборов данных: И FORT. SYSIN i—i DD lj * — ввод исходного текста ФОРТРАН-программы // LKED. SYSIN lj DD l_j ♦ — ввод объектного модуля для редактирования // GO. SYSIN i—i DD lj ♦ — ввод данных для рабочей программы. Операторы /*, //♦, // Оператор /♦ задает конец файла во входном потоке и эквивалентен оператору /♦ в ДОС. Оператор //* используется для комментариев и имеет формат //♦ (комментарии) Оператор // задает конец задания и эквивалентен оператору /& в ДОС. 338
Таблица 34 Типовые задания с использованием каталогизированных процедур Процедура Функция Задание FORTGC Трансляция / / {имя задания) JOB / / ЕХЕС FORTGC //FORT. SYSIN DD* Первая исходная программа на ФОРТ- РАНе Последняя исходная программа на ФОРТРАНе / * // FORTGCL Трансляция и редак- тирование / / {имя задания) JOB / / ЕХЕС FORTGCL //FORT. SYSIN DD* Первая исходная программа на ФОРТ- РАНе Последняя исходная программа на ФОРТРАНе / » // FORTGLG Редактирование и выполнение / / {имя задания') JOB / / ЕХЕС FORTGLG / / LKED. SYSIN DD * Первый объектный модуль Последний объектный модуль / * / / GO SYSIN DD * Исходные данные рабочей программы I * FORTGCLG Трансляция, редак- тирование и выпол- нение / / (имя задания) JOB / / ЕХЕС FORTGCLG //FORT. SYSIN DD* Первая исходная программа на ФОРТ- РАНе Последняя исходная программа на ФОРТРАНе / * //GO. SYSIN DD* Исходные данные рабочей программы / * 22* 339
В табл. 34 приведены типовые задания с использованием каталогизированных процедур. Форматы предложений ФОРТРАН/ЕС При представлении общих форматов предложений языка приняты следующие обо- значения: 1. Прописные латинские буквы используются только для записи ключевых слов языка. 2. Семь основных литер: =()/,' ♦ представляют самих себя. 3. Строчные русские буквы используются для записи метапонятий языка, т. е. общих синтаксических конструкций, вместо которых при записи конкретного предло- жения должны быть поставлены определенные языковые конструкции. Таковы: Метапонятие в формате переменная выражение метка целое устройство идентификатор имя-блока имя-списка список-фактических-параметров список-формальных-параметров список-элементов список-элементов-1 сп исок-элементов-2 список-элементов-3 список-элементов-4 список-элементов-5 список-элементов-6 список-констант список-размерностей список-формата список-меток целое-1 целое-2 целое-3 арифметическое-выражение Языковая конструкция идентификатор простой переменной или пере- менной с индексами арифметическое или логическое выражение метка константа целого типа или идентификатор переменной целого типа положительная константа целого типа или идентификатор переменной, значением которой является номер устройства идентификатор идентификатор идентификатор список фактических параметров список формальных параметров список, элементами которого являются иден- тификаторы простых переменных, массивов или описатели массивов список, элементами которого являются иден- тификаторы простых переменных или пере- менных с индексами список, элементами которого являются иден- тификаторы простых переменных или описа- тели массивов список, элементами которого являются иден- тификаторы простых переменных, перемен- ных с индексами или имена массивов список, элементами которого являются имена простых переменных или имена массивов список, элементами которого являются бук- венные символы или пары буквенных симво- лов, упорядоченных по алфавиту и разделен- ных литерой «—» список, элементами которого являются имена внешних процедур список констант список размерностей список формата список меток целое целое целое арифметическое выражение 340
логическое-выражение метка-1 метка-2 метка-3 простой-оператор восьмеричное размер режим запись текст десятичное логическое выражение метка метка метка оператор, отличный от оператора DO или ло- гического оператора IF строка, состоящая не более чем из 5 восьме- ричных цифр целая константа 1, 2, 4, 8 или 16 режим отладки выражение целого типа, значением которого является номер записи текстовая константа, заключенная в апострофы строка, состоящая не более чем из 5 десятич- ных цифр 4. В квадратные скобки заключены те части языковых конструкций, вхожде- ние которых в формат предложения является необязательным. Другими словами, на- личие квадратных скобок в формате предложения означает, что языком допускаются два вида форматов — один получается при удалении из общего формата содержащихся в нем квадратных скобок, а второй при их удалении вместе с содержащейся внутри этих скобок языковой конструкцией. 5. Фигурные скобки используются с двоякой целью: а) наличие после закрывающей фигурной скобки многоточия означает допусти- мость в записи нескольких конструкций, тип которых определяется содержимым этих фигурных скобок; б) наличие нескольких конструкций, записанных в виде столбца внутри фигур- ных скобок, означает возможность выбора при построении конкретного представи- теля данного вида предложения любой из этих конструкций. Форматы предложений идентификатор (список-формальных-параметров) = выражение переменная = выражение ASSIGN метка ТО идентификатор АТ метка BACKSPACE устройство BLOCK DATA CALL идентификатор [(список-фактических-параметров)] COMMON \ /имя-блока/список-элементов}... /COMPLEX а DOUBLE PRECISION список-элементов INTEGER LOGICAL Ireal J [COMPLEX INTEGER LOGICAL [REAL r /COMPLEX DOUBLE PRECISION INTEGER LOGICAL L ‘real CONTINUE DATA список-элементов-З/спцсок-конс/пан/л/ {, список-элементов-3/ список-кон- стант/} ... [♦размер] идентификатор [*размер] [(список-размерностей)] [/список- констант/] {, идентификатор [*размер] [(список-размерностей)] [/список-констант/]}... FUNCTION идентификатор [*размер] (список-формальных-параметров) 341
DEBUG [режим] {.режим} ... DIMENSION идентификатор (список-размерностей {, идентификатор (список* размерностей)} ... DISPLAY список-элементов-4 DO метка идентификатор = целое-1, целое-2 [, целое-3] ENDFILE устройство EQUIVALENCE (список-элементов-1) {, (список-элементов-1)} ... ENTRY идентификатор [(список-формальных-параметров)] EXTERNAL список-элементов-6 FIND (устройство' запись) FORMAT (список-формата) GO ТО метка GO ТО идентификатор, (список-меток) GO ТО (список-меток), идентификатор IF (арифметическое-выражение) метка-1, метка-2, метка-3 IF (логическое-выражение) простой-оператор IMPLICIT (COMPLEX INTEGER LOGICAL REAL [* размер] (список-элементов-5) COMPLEX) INTEGER LOGICAL REAL [ * размер] (список-элементов-5 ) NAMELIST /имя-списка/ список-элементов-4 {, /имя-списка/ список-элементов-4}... PAUSEfteKCT™4HOe1} PR1NT {идентификатор} I’ список-злементов-З] PUNCH . I [, список-элементов-3] (идентификатор) l’ J (устройство Г (метка 11 [ERR = метка] [, END = метка]) [список-' [, (идентификатор) J элементов-3] (устройство, имя-списка) (устройство' записьГ (метка 11 [, ERR = метка]) [список-эле мен- ’ [, (идентификатор)] тов-3] ({идентификатор}) [список-злементов-З] READ I RETURN [целое] REWIND устройство STOP [десятичное] SUBROUTINE идентификатор [(список-формальных-параметров)] TRACE TRACE WRITE OFF ON (устройство ['запись] [. {идентификатор}]) [список-элементов-З] 342
ПРИЛОЖЕНИЕ 1 Таблица 35 Основные внешние функции: логарифмические, показательная и квадратный корень Функция Имя функции Аргумент Тип функции Номер сооб- щения об ошибке количе- ство тип у = In X ALOG 1 REAL * 4 REAL * 4 253 DLOG 1 REAL * 8 REAL »8 263 CLOG 1 COMPLEX * 8 COMPLEX♦8 273 CDLOG 1 COMPLEX * 16 COMPLEX * 16 283 У — lgx ALOG 10 1 REAL * 4 REAL * 4 253 DLOG 10 1 REAL * 8 REAL * 8 263 у = ех EXP 1 REAL * 4 REAL * 4 252 DEXP 1 REAL * 8 REAL * 8 262 CEXP 1 COMPLEX * 8 COMPLEX*8 271 272 CDEXP 1 COMPLEX * 16 COMPLEX * 16 281 282 У = У~ SQRT 1 ‘ REAL * 4 REAL * 4 251 DSQRT 11 REAL * 8 REAL * 8 261 CSQRT 1 COMPLEX * 8 COMPLEX ♦ 8 — CDSQRT 1 COMPLEX * 16 COMPLEX * 16 — 343
Продолжение табл. 35 Функция Имя функции Аргумент Тип функции TT -r - 1 Номер сооб- щения об ошибке CJ £ о тип Обратные тригонометрические функции у = arcsin х ARSIN 1 REAL * 4 REAL * 4 257 DARSIN 1 REAL * 8 REAL♦8 267 у — arccos х ARCOS 1 REAL*4 REAL * 4 257 DARCOS 1 REAL * 8 REAL * 8 267 у arctg х ATAN 1 REAL * 4 REAL * 4 — DATAN 1 REAL * 8 REAL * 8 — у = arctg х2 #= 0 ATAN2 2 REAL * 4 REAL * 4 255 DATAN2 2 REAL * 8 REAL * 8 265 Тригонометрические функции у = sin х SIN 1 REAL * 4 (в радианах) REAL * 4 254 DSIN 1 REAL * 8 (в радианах) REAL * 8 264 CSIN 1 COMPLEX * 8 (в радианах) COMPLEX * 8 274 275 CDSIN 1 COMPLEX * 16 (в радианах) COMPLEX * 16 284 285 у — cos X COS 1 REAL * 4 (в радианах) REAL * 4 254 DCOS 1 REAL * 8 (в радианах) REAL * 8 264 CCOS 1 COMPLEX * 8 (в радианах) COMPLEX * 8 274 275 CCCOS 1 COMPLEX * 16 (в радианах) COMPLEX » 16 284 285 344
Продолжение табл. 35 Функция Имя функции Аргумент Тип функции Номер сооб- щения об ошибке Q 5 о oS s о тип У = tgx TAN 1 REAL ♦ 4 (в радианах) REAL * 4 258 259 DTAN 1 REAL * 8 (в радианах) REAL * 8 268 269 У = ctgx COTAN 1 REAL * 4 (в радианах) REAL * 4 258 259 DCOTAN 1 REAL * 8 (в радианах) REAL * 8 268 269 Гиперболические функции ех — е~х SINH 1 REAL * 4 REAL * 4 256 9 2 DSINH 1 REAL * 8 REAL ♦ 8 266 ' „ ех + е~л COSH 1 REAL * 4 REAL ♦ 4 256 9~- i" DCOSH 1 REAL * 8 REAL * 8 266 ех — е~~х TANH 1 REAL * 4 REAL » 4 — У= ех+ е~х DTANH 1 REAL♦8 REAL * 8 — Специальные функции У — И CABS 1 COMPLEX*8 REAL * 4 — CDABS 1 COMPLEX * 16 REAL * 8 — У- (*« “ /л J 0 ERF 1 REAL * 4 REAL » 4 — DERF 1 REAL * 8 REAL * 8 — X ERFC 1 REAL ♦ 4 REAL * 4 — DERFC 1 REAL ♦ 8 REAL ♦ 8 — 345
Продолжение табл. 35 Функция Имя функции Аргумент Тип функции Номер сооб- щения об ошибке количе- ство тип и = Г (х) ux~le~u du 0 GAMMA 1 REAL * 4 REAL * 4 290 DGAMMA 1 REAL * 8 REAL * 8 300 у = In Г (х) = ~ ln^ ux~l е~и du 0 ALGAMA 1 REAL * 4 REAL * 4 291 DLGAMA 1 REAL * 8 REAL * 8 301 у = max (хъ х2, МАХО >2 INTEGER * 4 INTEGER * 4 — АМАХО >2 INTEGER * 4 REAL * 4 — МАХ1 >2 REAL * 4 INTEGER * 4 — АМАХ1 >2 REAL * 4 REAL * 4 — DMAX1 >2 REAL ♦ 8 REAL * 8 — у = min (х1( х2, ...,хп) MINO >2 INTEGER * 4 INTEGER » 4 — AMINO >2 INTEGER * 4 REAL * 4 — MINI >2 REAL * 4 INTEGER * 4 — AMIN1 >2 REAL * 4 REAL * 4 — DMINl >2 REAL * 8 REAL » 8 — Таблица 36 Встроенные функции Функция Имя функции количе- ство Аргументы тип Тип функции У =1*1 IABS 1 INTEGER * 4 INTEGER * 4 ABS 1 REAL•4 REAL * 4 DABS 1 REAL * 8 REAL * 8 346
Продолжение табл. 36 Функция Имя функции Аргументы Тип функции количе- ство тип Вычисление целой части у = И AINT 1 REAL »4 REAL * 4 INT 1 REAL * 4 INTEGER * 4 IDINT 1 REAL * 8 INTEGER*4 Вычисление остатка от деления MOD 2 INTEGER * 4 INTEGER * 4 AMOD 2 REAL * 4 REAL * 4 DMOD 2 REAL * 8 REAL * 8 Преобразование целого к вещественному FLOAT 1 INTEGER * 4 REAL * 4 DFLOAT 1 INTEGER * 4 REAL * 8 Преобразование к цело- му IFIX 1 REAL * 4 INTEGER * 4 IIFIX 1 REAL * 4 INTEGER * 2 Присвоение знака у = = sign. х2 • | Xj | Х2 =/= 0 ISIGN 2 INTEGER * 4 INTEGER * 4 SIGN 2 REAL * 4 REAL * 4 DSIGN 2 REAL * 8 REAL * 8 Неотрицательная раз- ность у = — min (Хр х2) IDIM 2 INTEGER * 4 INTEGER * 4 DIM 2 REAL * 4 REAL * 4 Усечение младших раз- рядов мантиссы SNGL 1 REAL * 8 REAL * 4 х = Re (г) REAL k COMPLEX * 8 REAL♦4 у = 1т (г) AIMAG 1 COMPLEX * 8 REAL♦4 Увеличение точности DBLE 1 REAL♦4 REAL * 8 2 = X 4- i у CMPLX 2 REAL * 4 COMPLEX * 8 DCMPLX 2 REAL * 8 COMPLEX * 16 z = x — iy CONJG 1 COMPLEX * 8 COMPLEX « 8 DCONJG 1 COMPLEX * 16 j ' COMPLEX * 16 347
Таблица 37 Номер сообщения Код воз- врата Операци- онная си- стема Причина ##1 8 ДОС, ОС Тип константы, переменной или выражения не со- ответствует их использованию ##2 0 ДОС, ОС Предложение, на которое возможна ссылка или передача управления, не помечено ##3 8,0 ДОС, ОС Символическое имя состоит более чем из 6 литер ##4 0 ДОС, ОС Пропущена запятая в предложении 8 ДОС. ОС Неправильное использование метки предложения ##6 8 ДОС, ОС Указанная метка уже использовалась как метка другого предложения ##7 8 ДОС, ОС Использование символического имени находится в противоречии с его определением в предыдущих предложениях ##8 8 ДОС, ОС Распределение памяти не может быть выполнено из-за неправильного использования символического имени ##9 0/8, 8 ДОС, ОС Неверный порядок следования предложений 010 8 ДОС, ОС Число, используемое в операторе, находится за пределами допустимой области значений #11 8 ДОС, ОС Используется элемент массива, имя которого не было определено #12 8 ДОС, ОС Количество индексов, используемых для указания элемента массива, не соответствует размерности массива или размерность массива больше 7 #13 ) 8 ДОС, ОС Формат предложения не соответствует синтаксису языка ФОРТРАН #14 8,0 ДОС, ОС Тип константы, присваиваемой в объявлении DATA или объявлении типа, не соответствует типу сим- волического имени #15 0 ДОС, ОС Отсутствует карта END в исходной программе #16 8 ДОС, ОС Неправильное использование оператора #17 0 ДОС, ОС Предупреждение о неправильном использовании оператора #18 4 ДОС, ОС Количество аргументов, указанных при обраще- нии к программе библиотеки ФОРТРАНа, неверное #19 0,4 ДОС, ОС Имени функции или имени входа не присвоено значение в процедуре FUNCTION #2# 4 ДОС, ОС Переменным или массивам из именованной общей области не может быть распределена память из-за ошибок #21 8 ДОС, ОС В программе есть незакрытые циклы DO #22 8 ДОС, ОС Указанные метки предложений не определены в исходной программе #23 4 ДОС, ОС Переменным не может быть распределена память из-за противоречия между группами EQUIVALE- NCE #24 4 ДОС, ОС В объявлении EQUIVALENCE используется эле- мент массива, который не определен в программе #25 4 ДОС, ОС Ошибки при определении массива с регулируемы- ми размерами 348
Продолжение табл. 37 Номер сообще- ния Код воз- врата Операци- онная си- стема Причина #26 4 дос, ос В модуле BLOCK DATA присваиваются начальные значения переменным, не принадлежащим имено- ванной общей области 027 0 ДОС В программе отсутствуют операторы 8 ОС Предложение содержит более 19 строк продолже- ния #28 16 ДОС, ОС Трансляция прекращается из-за недостатка памяти для размещения таблиц #29 0 дос Допущена ошибка в операторе FTC #29* — ОС Произошла ошибка во время перфорации объект- ного модуля при задании режима DECK #3#* 16 ОС Произошла ошибка во время построения загрузоч- ного модуля при задании режима LOAD #31* 16 дос, ос Превышен размер таблицы, используемой транс- #32 —, 0 ДОС, ОС Оператор конца файла /* предшествует предложе- ниям ФОРТРАНа #33 0 ОС Количество строк с комментариями между двумя предложениями превышает 30 #34* 8/16 ОС Произошла ошибка ввода-вывода во время транс- ляции #35* — ОС Не может быть использован набор данных из-за отсутствия оператора DD #36 0 ОС Метка присвоена объявлению #37 4 ОС Повторно определяется массив #38 4 ДОС, ОС Размер текстовой константы в объявлении DATA или объявлении типа превышает размер перемен- ной или элемента массива #39 8 ДОС Переменной, эквивалентной переменной из общей области, присваивается начальное значение в объ- явлении DATA или в объявлении типа не в мо- дуле BLOCK DATA #39 0 ОС В процедуре отсутствует оператор RETURN #4#* 8 ОС Ошибка в модуле BLOCK DATA #42* 16 дос Произошло программное прерывание во время вы- полнения трансляции #43 0 ДОС Объявление имеет метку #44* 16 ДОС Трансляция прекращается из-за недостатка основ- ной памяти Таблица 38 Сообщения о программных прерываниях при выполнении рабочей программы в операционной системе ДОС Номер сообщения Причина прерывания 225 Произошло программное прерывание из-за переполнения или ис- чезновения порядка или при делении. 349
Продолжение табл. 38 Номер сообщения Причина прерывания Значение i в старом PSW указывает причину прерывания: Значение i Причина прерывания 9 Деление с фиксированной точкой В Десятичное деление С Переполнение порядка D Исчезновение порядка F Деление с плавающей точкой Если прерывание является следствием переполнения или исчез- новения порядка, печатается также неверный результат; если прерывание возникло при делении, результат устанавливается равным делимому. Выполнение программы продолжается 226 Произошло неарифметическое программное прерывание. Значение i в старом PSW указывает причину прерывания: Значение i Причина прерывания 1 Операция 2 Привилегированная операция 3 Команда ВЫПОЛНИТЬ 4 Защита 5 Адресация 6 Спецификация 7 Данные Если имело место выравнивание на границу при прерывании по спецификации, то в тексте сообщения печатается литера А. В этом случае сообщение печатается не более 10 раз, и выполне- ние программы продолжается. Для остальных причин прерыва- ния выполнение программы прекращается. Таблица 39 Сообщения о программных прерываниях при выполнении рабочей программы в операционной системе ОС Номер со- общения Причина прерывания Стандартное корректирующее действие 2071 Произошло программное прерывание из-за переполнения порядка (код прерывания i = С) Результат устанавливается рав- ным наибольшему допустимому числу с плавающей точкой 2Я81 Произошло программное прерывание из-за исчезновения порядка (код прерывания i = D) Результат устанавливается рав- ным нулю 350
Продолжение табл. 39 Номер со- общения Причина прерывания Стандартное корректирующее действие 2Я91 Произошло программное прерывание при делении (коды прерывания i = 9, В, F) Результат устанавливается рав- ным делимому 2101’3 Произошло программное прерывание по спецификации (код прерывания 1 = 6) Делается попытка устранить нарушение границы. В резуль- тате выравнивания на границу могут возникнуть прерывания с кодами i = 4, 5, 7. В этом случае выполнение программы прекращается 21 Я2,3 Произошло программное прерывание. Значение в старом PSW указывает причину прерывания Значение i Причина прерывания 6 Спецификация 9 Деление с фикси- рованной точкой В Десятичное деление С Переполнение порядка D Исчезновение порядка F Деление с плаваю- щей точкой 1. Если код прерывания i = = 6, то делается попытка устранить нарушение границы и продолжить выполнение про- граммы Выполнение программы прекра- щается только в том случае, если в результате выравнива- ния на границу возникло пре- рывание с кодами i = 4, 5, 7 2. Если прерывание связано с переполнением (i = С) или ис- чезновением (i = D) порядка, то результат устанавливается равным соответственно наи- большему допустимому числу с плавающей точкой или нулю. Выполнение программы продол- жается. 3. Если прерывание возникло при делении Ji = 9, В, F), то результат * устанавливается равным делимому. Выполнение программы продолжается 24Й-1’2 Произошло программное прерывание по одной из следующих причин: Код Причина прерывания прерывания 1 Операция 2 Привилегированная операция 3 Команда ВЫПОЛНИТЬ Выполнение программы пре- кращается 351
Продолжение табл. 39 Номер со- , общения Причина прерывания Стандартное корректирующее действие 4 Защита 5 Адресация 7 Деление 1 Используются средства расширенно.} обработки ошибок. 2 Средства расширенной обработки ошибок не используются 3 Используется режим выравнивани я на границу. Таблица 40 Сообщения об ошибках при выполнении операторов ввода>вывода ФОРТРАНа в операционной системе ДОС Номер со- общения Причина 2#6 2-07 2-08 209 210 211 212 213 216 217 218 219 221 223 224 227 Размер массива в данных ввода объявления NAMELIST больше определенного в объявлении DIMENSION Имя переменной или массива в данных ввода объявления NAMELIST не определено в объявлении NAMELIST или отсутствует разделитель между переменными Имя переменной, массива или индекс элемента в данных ввода объ- явления NAMELIST продолжается в следующей записи В данных ввода объявления NAMELIST индекс используется с име- нем, которое не было определено как имя массива, или величина индекса больше допустимой Ошибка в исходном операторе, в результате которой оператор не был полностью протранслирован. Печатается номер ошибочного опе- ратора и имя программы При чтении или записи по формату обнаружен недействительный код формата Выводится по формату запись, размер которой превышает макси- мально допустимый для данного устройства, или читается по формату из записи больше данных, чем она их содержит Из записи файла последовательного доступа читается без формата больше данных, чем она их содержит Данные вводятся с устройства, которое может использоваться только для вывода Данные выводятся на устройство, которое может быть использовано только для ввода Номер файла не из диапазона 1 —15 При выполнении оператора READ обнаружен конец файла Операторы ENDFILE, REWIND, BACKSPACE выполняются для не- ' допустимого устройства или метода доступа При вводе по формату в данных обнаружена неверная литера Номер программного переключателя отличен от 1—4 (обращение по имени SLITET) или от 0—4 (обращение по имени SL1TE) В объявлении DEFINE FILE номер файла указан не из диапазона 4—14 либо размер записи или количество записей меньше или равно нулю 352
Продолжение табл. 40 Номер со- общения Причина 228 В объявлении DEFINE FILE размер записи превышает 3625 байтов или 7294 байта (соответственно для накопителей на дисках типа ЕС-5052 или ЕС-5061) 229 Оператору ввода-вывода прямого доступа FIND, READ или WRITE логически не предшествует объявление DEFINE FILE 230 Оператор ввода-вывода прямого доступа FIND, READ или WRITE обращается к устройству, которое не является накопителем на маг- нитных дисках 231 Номер записи в операторе ввода-вывода прямого доступа FIND, READ или WRITE меньше или равен нулю или больше допустимого, указанного в объявлении DEFINE FILE 233 Оператор CALL OPSYS содержит недействительный параметр 236 Основная память раздела для размещения области ввода-вывода и таблиц DTF при выполнении оператора ввода-вывода недостаточна 237 Запись на дисках при выполнении оператора READ или WRITE не найдена 238 После выполнения оператора ввода-вывода последовательного досту- па делается попытка выполнить оператор ввода-вывода прямого дос- тупа для того же файла 239 Возникла неисправимая ошибка ввода-вывода при передаче данных 24^ При вводе данных по коду формата Z обнаружена недопустимая ли- тера Таблица 41 Сообщения об ошибках при выполнении операторов ввода-вывода ФОРТРАНа в операционной системе ОС Номер сооб- щения Причина Стандартное корректирующее действие при использовании средств расширенной обработки ошибок 211 Ошибка при задании форматов в массиве Форматы, начиная с оши- бочного, игнорируются 212 Выводится по формату запись, размер ко- торой превышает максимально допустимый для данного устройства, или читается по формату из записи больше данных, чем она их содержит Ввод: оставшаяся часть списка ввода-вывода игно- рируется Вывод: производится вывод следующей записи 213 Из записи файла последовательного досту- па читается без формата больше данных, чем она их содержит Оставшаяся часть списка ввода-вывода игнорируется 214 При вводе или выводе данных без формата с помощью операторов последовательного доступа в параметре DCB оператора DD указан неверный формат записей (F, U или V) Ввод: запрос ввода-вывода игнорируется Вывод: параметр RECFM за- меняется на VS 12 9-2712 353
Продолжение табл. 41 Номер сооб- щения Причина Стандартное корректирующее действие при использовании средств расширенной обработки ошибок 215 При вводе числового данного по коду фор- мата I, F, Е или D обнаружена недопус- тимая литера Литера заменяется нулем 216 Неверно указан номер программного пере- ключателя при обращении к служебной программе по имени SLITE или SLITET Для имени SL1TE оператор игнорируется Для имени SLITET пере- ключатель выключается и устанавливается равным 2 217 При выполнении оператора READ обнару- жен конец файла Порядковый номер файла увеличивается на 1, и чи- тается следующий файл 218 Ошибка ввода-вывода Запрос ввода-вывода игно- рируется. Если задан пара- метр ERR, управление пе- редается метке, указанной в этом параметре 219 Отсутствует оператор DD для файла Запрос ввода-вывода игно- рируется 22# Номер файла не входит в диапазон номеров, установленный при генерации операционной системы Запрос ввода-вывода игно- рируется 221 Размер массива в данных ввода объявления NAMELIST больше определенного в объ- явлении DIMENSION Оставшиеся запросы списка NAMELIST игнорируются 222 Имя переменной или массива в данных вво- да объявления NAMELIST не определено в объявлении NAMELIST или отсутствует разделитель для переменных Оставшиеся запросы списка NAMELIST игнорируются 223 Имя переменной, массива или индекс эле- мента массива в записи ввода объявления NAMELIST продолжается в следующей запи- си Оставшиеся запросы списка NAMELIST игнорируются 224 В данных ввода объявления NAMELIST ин- декс используется с именем, которое не было определено как имя массива, или ве- личина индекса больше допустимой Оставшиеся запросы списка NAMELIST игнорируются 225 При вводе данных по коду формата Z об- наружена недопустимая литера Литера заменяется нулем 23# Ошибка в исходном предложении. Печатают- ся номер ошибочного предложения и имя программы Выполнение программы прекращается 231 Оператор ввода-вывода прямого доступа ис- пользуется без объявления DEFINE FILE или оператор ввода-вывода прямого доступа используется для последовательного файла, или оператор ввода-вывода последователь- ного доступа используется для файла пря- мого доступа Запрос ввода-вывода игно- рируется 354
Продолжение табл, 41 Номер сооб- щения Причина Стандартное корректирующее действие при использовании средств расширенной обработки ошибок 232 233 234 235 236 237 240 Номер записи в операторе ввода-вывода пря- мого доступа меньше или равен нулю или больше максимального номера записи, ука- занного в объявлении DEFINE FILE Длина записи файла прямого доступа пре- вышает (32 К—1) байтов Файл сообщений об ошибках определяется как файл прямого доступа Файл, который уже использовался как файл последовательного доступа, определя- ется как файл прямого доступа Оператор READ прямого доступа выдается для файла, который не был создан Длина записи не соответствует длине, ука- занной в объявлении DEFINE FILE Аварийное завершение программы. Систем- ный код — ХХХХ. Код — ФОРТРАНа — XX Запрос ввода-вывода игно- рируется Длина записи устанавлива- ется равной 32К байтов Объявление DEFINE FILE игнорируется Объявление DEFINE FILE игнорируется Запрос ввода-вывода игно- рируется Запрос ввода-вывода игно- рируется Корректирующее действие не выполняется Таблица 42 Сообщения об ошибках при выполнении математических программ библиотеки ФОРТРАНа в операционных системах ДОС и ОС Номер сооб- щения Причина Стандартное корректирующее действие в операционной систе- ме ОС при использовании средств расширенной обработки ошибок 241 Попытка возвести целое основание в целую степень, если основание равно 0, а показа- тель степени отрицательный или нулевой Результат устанавливается равным нулю 242 Попытка возвести вещественное основание длиной 4 в целую степень, если основание равно нулю, а показатель степени отрица- тельный или нулевой Результат устанавливается равным нулю 243 Попытка возвести вещественное основание длиной 8 в целую степень, если основание равно нулю, а показатель степени отрица- тельный или нулевой Результат устанавливается равным нулю 244 Попытка возвести вещественное основание длиной 4 в вещественную степень длиной 4, если основание равно нулю, а показатель степени отрицательный или нулевой Результат устанавливается равным нулю 245 Попытка возвести вещественное основание длиной 8 в вещественную степень длиной 8, если основание равно нулю, а показатель степени отрицательный или нулевой Результат устанавливается равным нулю 12* 355
Продолжение табл. 42 Номер сооб- щения Причина Стандартное корректирующее действие в операционной систе- ме ОС при использовании средств расширенной обработки ошибок 246 Попытка возвести комплексное основание длиной 8 в целую степень, если основание равно нулю, а показатель степени отрица- тельный или нулевой Результат устанавливается равным 0.0 + O.Oi 247 Попытка возвести комплексное основание длиной 16 в целую степень, если основа- ние равно нулю, а показатель степени от- рицательный или нулевой Результат устанавливается равным 0.0 + 0.0/ 251 Попытка вычислить квадратный корень ве- щественного аргумента длиной 4, значение которого отрицательно Результат устанавливается равным К| х | 252 Попытка вычислить показательную функ- цию для вещественного аргумента длиной 4, значение которого больше 174.673 Результат устанавливается равным наибольшему допус- тимому числу с плавающей точкой 253 Попытка вычислить логарифм вещественно- го аргумента длиной 4, значение которого отрицательное или нулевое, или попытка возвести отрицательное основание в вещест- венную степень Если аргумент нулевой, ре- зультат устанавливается равным а, где а — наиболь- шее допустимое число с плавающей точкой. Если ар- гумент отрицательный, ре- зультат полагается равным In | х | или 1g | х | 254 Попытка вычислить синус или косинус ве- щественного аргумента длиной 4, если аб- солютное значение аргумента больше или равно л-218 Результат устанавливается /Г равным — 255 Попытка вычислить арктангенс частного двух вещественных аргументов длиной 4, равных нулю Попытка вычислить гиперболический синус или косинус вещественного аргумента дли- ной 4, если абсолютное значение аргумен- та больше или равно 175. 366 Результат устанавливается равным нулю 256 Результат устанавливается равным наибольшему допус- тимому числу с плавающей точкой 257 Попытка вычислить арксинус или арккоси- нус вещественного аргумента длиной 4, если абсолютное значение аргумента боль- ше единицы Результат устанавливается равным нулю 258 Попытка вычислить тангенс или котангенс вещественного аргумента длиной 4, если абсолютно^ значение аргумента больше или равно л-218 Результат устанавливается равным единице 259 Попытка вычислить тангенс или котангенс вещественного аргумента длиной 4, если значение аргумента близко к особой точке: л — . п — дЛя тангенса, Результат устанавливается равным наибольшему допус- тимому числу с плавающей точкой 356
Продолжение табл. 42 Номер сооб- щения Причина Стандартное корректирующее действие в операционной систе- ме ОС при использовании средств расширенной обработки ошибок 261 п — нечетное целое; л-п — для котангенса, п — целое Результат устанавливается Попытка вычислить квадратный корень ве- щественного аргумента длиной 8, если ар- гумент отрицательный равным /| х | Результат устанавливается 262 Попытка вычислить показательную функцию вещественного аргумента длиной 8, если значение аргумента больше 174.673 равным наибольшему до- пустимому числу с плаваю- щей точкой 263 Попытка вычислить логарифм вещественно- го аргумента длиной 8, если аргумент от- рицательный или нулевой, или попытка возвести отрицательное основание в вещест- венную степень Если аргумент нулевой, результат полагается рав- ным а, где а — наиболь- шее допустимое число с плавающей точкой. Если аргумент отрицательный, ре- зультат полагается равным 1g | х | или in | х | 264 Попытка вычислить синус или косинус ве- щественного аргумента длиной 8, если аб- солютное значение аргумента больше или равно л-260 Результат устанавливается К2" равным — 265 Попытка вычислить арктангенс частного двух вещественных аргументов длиной 8, если оба аргумента равны нулю Результат устанавливается равным нулю 266 Попытка вычислить гиперболический синус или косинус вещественного аргумента дли- ной 8, если абсолютное значение аргумента больше или равно 175 3G6 Результат устанавливается равным наибольшему до- пустимому числу с плаваю- щей точкой 267 Попытка вычислить арксинус или арккоси- нус вещественного аргумента длиной 8, ес- ли абсолютное значение аргумента больше единицы Результат устанавливается равным нулю 268 Попытка вычислить тангенс или котангенс вещественного аргумента длиной 8, если абсолютное значение аргумента больше или равно л-260 Результат устанавливается равным единице 269 Попытка вычислить котангенс веществен- ного аргумента длиной 8, если значение ар- гумента близко к особой точке: л • п — для тангенса, п — нечетное целое; л-и — для котангенса, п — целое Результат устанавливается равным наибольшему до- пустимому числу с плаваю- щей точкой Результат устанавливается 271 Попытка вычислить показательную функ- цию комплексного аргумента длиной 8, ес- ли значение действительной части аргумен- та больше 174.673 равным (a cos х2 + sin х2), где х2 — мнимая часть ар- гумента, а — наибольшее до- пустимое число с плаваю- щей точкой 357
Продолжение табл. 42 Номер сооб- щения Причина Стандартное корректирующее действие в операционной систе- ме ОС при использовании средств расширенной обработки ошибок 272 Попытка вычислить показательную функ- цию комплексного аргумента длиной 8, ес- ли абсолютное значение мнимой части ар- гумента больше или равно л-218 Результат устанавливается равным 0.0 + 0.0/ 273 Попытка вычислить ^логарифм комплексно- го аргумента длиной 8, если мнимая и действительная части аргумента равны нулю Результат устанавливается равным — а + 0.0, где а — наибольшее допустимое число с плавающей точкой 274 Попытка вычислить синус или косинус комплексного аргумента длиной 8, если абсолютное значение действительной части аргумента больше или равно л-218 Результат устанавливается равным 0.0+0.0/ 275 Попытка вычислить синус или косинус комплексного аргумента длиной 8, если аб- солютное значение мнимой части аргумента больше 174.673 Если мнимая часть аргумен- та больше нуля, то для си- нуса результат устанавли- а вается равным (sin хг + + /COSXJ, а для косину- fl са (cos хг — i sin xx) Если мнимая часть аргумен- та меньше нуля, то для си- нуса результат устанавли- а вается равным (sin хх — — icosxj, а для косину- fl са -у (cos хг + i sin хг), где а — наибол ьшее допу- стимое число с плавающей точкой, хх—действитель- ная часть аргумента 281 Попытка вычислить показательную функ- цию комплексного аргумента длиной 16, если значение действительной части аргу- мента больше 174.673 Результат устанавливается равным a (cos х2 + i sin х2), где а — наибольшее допу- стимое число с плавающей точкой, х2 — мнимая часть аргумента 282 Попытка вычислить показательную функ- цию комплексного аргумента длиной 16, если абсолютное значение мнимой части ар- гумента больше или равно л-250 Результат устанавливается равным 0.0+0.0/ 283 Попытка вычислить логарифм комплексного аргумента длиной 16, если действительная Результат устанавливается равным — а + 0.0/, где 358
Продолжение табл. 42 Номер сооб- щения Причина Стандартное корректирующее действие в операционной систе- ме ОС при использовании средств расширенной обработки ошибок 284 285 29# 291 з#е ЗШ и мнимая части аргумента равны нулю Попытка вычислить синус или косинус ком- плексного аргумента длиной 16, если абсо- лютное значение действительной части ар- гумента больше или равно л-260 Попытка вычислить синус или косинус комплексного аргумента длиной 16, если абсолютное значение мнимой части аргумен- та больше 174.673 Попытка вычислить гамма-функцию веще- ственного аргумента длиной 4, если значе- ние аргумента меньше или равно 2 ли- бо больше или равно 57.5744 Попытка вычислить логарифм гамма-функ- ции вещественного аргумента длиной 4, ес- ли значение аргумента меньше или равно нулю или больше или равно 4.2937-1073 Попытка вычислить гамма-функцию веще- ственного аргумента длиной 8, если значе- ние аргумента меньше или равно 2“2э2 ли- бо больше или равно 57.5744 Попытка вычислить логарифм гамма-функ- ции вещественного аргумента длиной 8, ес- ли значение аргумента меньше или равно нулю или больше или равно 4.2937-1073 а — наибольшее допустимое число с плавающей точкой Результат устанавливается равным 0.0 + 0.0/ Если мнимая часть аргу- мента больше нуля, то для синуса результат устанав- ливается равным а (sin хх + i cos хх), а для а косинуса -у (cos хх — — ts/nxx). Если мнимая часть аргумента меньше ну- ля, то для синуса резуль- тат устанавливается равным а -^-(smxy —i cos х^, а для a косинуса равным (cos xx + + i sin xx), где a — наи- большее допустимое число с плавающей точкой, хх — действительная часть аргу- мента Результат устанавливается равным наибольшему до- пустимому числу с плаваю- щей точкой Результат устанавливается равным наибольшему допус- тимому числу с плавающей точкой Результат устанавливается равным наибольшему до- пустимому числу с плаваю- щей точкой Результат устанавливается равным наибольшему до- пустимому числу с плаваю- щей точкой 359
Таблица 43 Сообщения о неверном использовании средств расширенной обработки ошибок в операционной системе ОС Номер со- общения Причина 9#£ Количество ошибок с указанным номером превышает значение, задан- ное в таблице режимов. Выполнение программы прекращается 9#1 Произошло повторное обращение к монитору ошибок при обработке ошибки с указанным номером. Выполнение программы прекращается 9#2 Для ошибки с указанным номером не отведена запись в таблице ре- жимов, т. е. номер ошибки не входит в диапазон номеров, заданный при генерации операционной системы. Запрос игнорируется, выпол- нение программы продолжается 9ЯЗ Сделана попытка изменить запись в таблице режимов, для которой модификация запрещена. Запрос на изменение игнорируется, и вы- полнение программы продолжается 9Я4 При выполнении корректирующих действий по ошибкам ввода-вывода делается попытка использовать операторы ввода-вывода, отладки и об- ращения к PDUMP или ERRTRA. Выполнение программы прекращается ПРИЛОЖЕНИЕ 2 ДИАГНОСТИЧЕСКИЕ СООБЩЕНИЯ ТРАНСЛЯТОРОВ В таблице 37 приводится список сообщений об ошибках в исходной программе на ФОРТРАНе и сообщения о состоянии транслятора, выдаваемые трансляторами ФОР- ТРАН ДОС и ФОРТРАН GOC. Для каждого сообщения указывается его номер, код возврата, характеризующий уровень ошибки, и причина, вызвавшая появление со- общения.Сообщения о состоянии транслятора помечены литерой «*». Наличие в таблице одного кода возврата указывает, что он одинаков для опе- рационных систем ДОС и ОС; при различии этих кодов они указываются через запя- тую. В случае, когда код возврата для ошибки может принимать ряд различных значений, эти значения разделены литерой «/». ПРИЛОЖЕНИЕ 3 ДИАГНОСТИЧЕСКИЕ СООБЩЕНИЯ РАБОЧЕЙ ПРОГРАММЫ В табл. 38—42 приведены сообщения о программных прерываниях и ошибках при выполнении операторов ввода-вывода и математических программ библиотеки ФОРТРАНа в операционных системах ДОС и ОС. Указываются номер каждого сооб щения и причина, вызвавшая появление сообщения. 360
ОТВЕТЫ К ЗАДАНИЯМ ГЛАВА I Порция 1 1. Исходная программа — это описание алгоритма решения задачи на одном из языков программирования (например, на ФОРТРАНе); рабочая программа — про- грамма, полученная в результате работы транслятора. 2. Транслятор переводит программу с некоторого языка программирования на язык конкретной вычислительной машины и определяет синтаксические ошибки^ допущенные при написании исходной программы. 3. Выполняемая программа на ФОРТРАНе может состоять из головного модуля или из головного модуля и ряда процедурных модулей и модулей-блоков данных. 4. Предложения ФОРТРАНа подразделяются на выполняемые, или операторы, и невыполняемые, или объявления. 5. Первым предложением процедурного модуля должно быть объявление, представляющее собой заголовок модуля. В головном модуле заголовок отсутст- вует. 6. Объявления спецификаций; объявления начальных данных; объявления фор- мата; объявления внутренних функций; объявления заголовков модулей. Порция 2 1.11. 2. Вместо литеры $ («денежный знак») используется литера ф, которая относит- ся к буквам. Введены дополнительно специальные литеры & и '. Порция 3 1.29, 47. 2. См. табл. 4, 5. 3. См. табл. 6. Порция 4 1. Целые, вещественные, повышенной точности, комплексные, логические, тек- стовые. В ФОРТРАН/ЕС, кроме того, шестнадцатеричные. Порция 5 1. Константа — это данное, которое записывается в программе в явном виде. 2. Можно. 3. Определяет. 4. Константой целого типа называется константа, обозначаю- щая целое десятичное число и не содержащая в своей записи точки и порядка. Порция 6 1. В ответах приведено по одному из возможных вариантов записи вещественных констант: а) 347.#; б) 74.32; в)—51##.; г) 1.Е15; д) 834Е — 1#; е) — 2#.#; ж) —45.21Е — 12. 361
2. а) запятую употреблять в записи констант нельзя, б) показатель степени дол- жен быть целым, в) запятую использовать нельзя, г) нет десятичной точки, д) показа- тель степени должен быть целым, е) число слишком велико для большинства ЭВМ. 3. а) да, б) jja, в) да, г) нет, д) да, е) да. Порция 7 1. 3.14159265358979D0. 2. а) (5.2, 3.7); б) (3., 4.); в) (З.Е—2, 0.75); г) (1.5, — 1.); д) (5., —5.) ; е) (0., 1.73205); ж) (1.414213, 0.). 3. Две: .TRUE.. FALSE. 4. а) 7НТАБЛИЦА; б) 22НРЕЗУЛЬТАТЫ lj lj ВЫЧИСЛЕНИЙ; в) 14НСИМПЛЕКС-МЕТОД; г) 14НМЕХ. lj МАТ. ш Ф-Т.; д) 2HY = ; е) 7HZ(2,3)=; ж) 7HSIN (2) = 5. Первая форма записи текстовых констант в ФОРТРАН/ЕС совпадает со стан- дартом. Запись в форме 2: а) 'ТАБЛИЦА'; б) 'РЕЗУЛЬТАТЫ lj lj ВЫЧИСЛЕНИЙ'; в) 'СИМПЛЕКС- МЕТОД'; г) 'МЕХ. lj MAT. lj Ф-Т.'; д) 'Y = '; е) 'Z (2, 3) = '; ж) 'SIN (2) ='. Порция 8 1. RUNGKT, R, KI, DITTO, AMODX, PROG, SYMP lj 1, DUMP, ERRSET. Порция 9 1. Внутренняя (оперативная) и внешняя. 2. Режим чтения (снятия копий с кодов, хранящихся в некотором поле памяти) и режим записи (посылка кодов в поле памяти). 3. Байты — это минимальные адресуемые поля памяти. 4. Описание имени служит информацией для выделения соответствующего поля памяти данному, обозначаемому этим именем. Порция 11 1. Простые переменные и переменные с индексами. Именем; именем соответствую- щего массива, за которым в скобках следует список индексов. 2. Массив — это упорядоченная совокупность величин одного и того же типа. Каждая отдельная из этих величин — элемент массива. Массив обозначается его име- нем, элемент массива — переменной с индексами. 3. Количеством верхних границ индексов, указанных в описателе массива. 4. Имя массива, за которым в круглых скобках указан список верхних границ индексов. Описатель может быть указан в объявлениях размерности, типа или общих блоков. 5. Наибольшие и наименьшие значения, которые могут принимать индексы дан- ного массива; 1. 6. Описатель массива — это конструкция, определяющая имя массива, размер- ность и верхние границы индексов по соответствующим измерениям. Переменная с индексами — обозначение отдельного элемента, входящего в состав соответствую- щего массива. Описатель массива характеризует структуру массива и используется в объявлениях типа, размерности и общих блоков. Переменная с индексами — это первичное выражение. Синтаксическое различие состоит в том, что индексы перемен- ной с индексами могут задаваться не только константами и переменными, как в описа- теле массива, но и выражениями целого типа допустимого стандартом вида. 7. А (1, 1), А (2, 1), А (1,2), А (2, 2), А (1,3), А (2, 3). 8. Для обращения к элементам соответствующего массива. 362
9. Нет, однако см. порц. 107. 10. а) 14, 16, 18; б) 6, 7, 11, 12; в) 7, 11. Замечание. Конструкция М (I, М) — недопустима в языке, поскольку имя М не может одновременно обозначать массив и простую переменную. Конструкция L (К (I)) не допускается стандартом языка в качестве переменной с индексами: стандарт за- прещает индексирование индексов. В языке ФОРТРАН/ЕС эта конструкция может быть использована в качестве индексированной переменной. 11. Адрес фиксированного поля памяти; содержимое этого поля; адрес отдельного поля памяти из совокупности полей, отводимых под массив; содержимое этого поля. 12. Обращение к переменной — это присвоение ей значения или извлечение ее значения. Порция 12 1. Позиция элемента массива в упорядоченном множестве его элементов. 2. 16 3.143 4. В (1, 1, 1), В (2, 1, 1,), В (1, 2, 1), В (2, 2, 1), В (1,3, 1), В (2, 3, 1), В (1, 1, 2), В (2, 1, 2), В (1, 2, 2), В (2, 2, 2), В (1,3, 2), В (2, 3,2) 5. Нет. 6. Да. Порция 13 1. См. стр. 30 Порция 14 1. DIMENSION А (6, 17), G (3, 4), D (3), DX (6, 2, 2) 2. а) описатели массивов должны отделяться друг от друга запятыми; б) граница индекса в описателе массива не может быть представлена выражением; в) имя массива не может быть и именем переменной (представляющей границу индекса этого масси- ва); г) граница индекса не может представляться отрицательной константой. Порция 15 1. Пять. 2. Можно лишь при условии, что эти имена не встречаются в данном програм- мном модуле в описателях массивов (в объявлениях размерности или общих блоков), а также не используются в качестве имен функций (т. е. не встречаются в указа- телях функций). Имя S21 не может быть в данном программном модуле именем простой переменной. 3. Нет, так как имя переменной или массива может в одном программном модуле содержаться только в одном объявлении типа. 4. Можно при условии, что эти имена не используются в качестве имен функ- ций. Порция 17 1. Шесть: целый, вещественный, повышенной точности, комплексный, логиче- ский, текстовый. 2. Пять: те же, что и данные, кроме текстового. 3. Идентификатор в этом случае может принадлежать к любому типу. 4. Тип константы определяется формой ее записи. 5. COMPLEX W, Z2 LOGICAL Gl, G2 DOUBLE PRECISION Al, A2 363
Порция 19 1. 1), 2). Нет. В одном программном модуле описатель массива может задаваться только в одном объявлении (типа, размерности или общих блоков). 2. 1) Переменная или функция, или массив U и двумерный массив V описаны как комплексные стандартной длины (8 байтов). Пяти первым элементам массива V присваиваются одинаковые начальные значения (1.0, 1.0), четырем последним элемен- там — значения (0., 1.). 2) Одномерный массив К описан как массив вещественного типа, элементы кото- рого имеют стандартную длину (4 байта); всем элементам массива К присваиваются значения 0.0. Элементы двумерного массива вещественного типа А имеют стандартную длину (4 байта); первым пятнадцати элементам этого массива присваивается одинако- вое значение (3.2Е — 5), остальным десяти — значение 1.0. 3) Это объявление описывает X как переменную или функцию, или массив веще- ственного типа размером 8 байтов (в случае массива каждому из его элементов в памяти машины будет отведено по 8 байтов); RE — как вещественную переменную размером 8 байтов, которой присваивается начальное значение 2.7536796522; массив МАС1 — как массив вещественного типа стандартного размера, первым четырем элементам которого собтветственно присваиваются значения 2.5, 3.5, 4.5, 5.5; остальным восьми элементам присваивается значение 1.0; массив ТЕКСТ описан как массив веществен- ного типа, элементам которого, имеющим размер 8 байтов, присваиваются текстовые значения (по 8 литер в поле каждого элемента массива). Порция 20 1. 1) Нет, так как перекрытие диапазонов (Е — N) и (L — Р) недопустимо даже в соглашениях, задающих определение одного и того же типа. 2) Нет, описатель DOUBLE PRECISION в объявлении IMPLICIT недопустим. 2. ZON — комплексного типа, 8 байтов; Т1 — целого типа, 2 байта; BOOL, SWING, L — вещественного типа, 4 байта; L2 — целого типа, 4 байта. 3. IMPLICIT INTEGER (I — N), REAL (А - Н, О — Z, Д) Порция 21 1. а) Число констант меньше числа переменных; DATA А, В, С, D /2.7, 3*4. -07 б) Если SIN в данном программном модуле используется как имя функции, то ошибкой является задание указателя этой функции в объявлении DATA; если SIN используется как имя массива, то ошибка состоит в указании индекса в виде перемен- ной; правильным будет объявление: DATA S, Ml, М2/3.3, 2*2/ в) Индекс в объявлении DATA не может быть задан в виде переменной; DATA R, Х/2. #, И.#/, А (1), А (2), А (3) /3 * 1.-07 2. DOUBLE PRECISION А (6) DATA А/ 'ЗНАЧЕНИЯ ПЕРЕМЕННЫХ ПОСЛЕ ВЫПОЛНЕНИЯ ПРОГРАМ- МЫ Ш L-J '/ 3. 5; 5—поскольку объявление DATA присваивает переменной I значение 10 до выполнения программы, оператор I = 5 изменит это значение. Порция 22 1. Для обращения к алгоритмам, вычисляющим значение той или иной функции. 2. 3, 4, 5, 6, 7, 8, 9, 10; 6, 7, 9, 10. 3. Если переменная N описана в данном программном модуле как переменная вещественного типа. Переменную с индексами, описатель массива. 364
Порция 23 1. а) 1) А + В; 2) (А + В) + С; б) 1) С ** 2; 2) А ♦ В; 3) (А * В) + (С ** 2); в) 1) X * Y; 2) А/В; 3) (X ♦ Y) + (А/В); г) 1) X ♦* 3; 2) С ♦ D; 3) А + В; 4) (А + В) + (С ♦ D); 5) (А + В) + (С ♦ D) + (X ** 3). 2. 1) б), 2) а), 3) а). 3. a) EXP (SQRT (2.) * X) б) (1.— Q ** N)/(l.-Q) в) #.5 * ALOG ((1. + SIN (X ♦* 2))/(1.+ COS (X) *♦ 2)) г) EXP (—X ** 2) + EXP (EXP (X ** 2)) д) (ALOG (X ** 2 + SQRT (1.+ X ♦♦ 2 + X ** 4)))/SQRT (1.+ X ** 2 + + X ** 4) e) EXP (A ♦ X) ♦ SIN (ALPHA * X + GAMMA) ♦♦ 2 ж) В * SIN ((2. * X) ** 2) + C ♦ COS ((3. * X) *♦ 2) *♦ 2 з) ALOGie (1. + SIN (X ♦♦ 2) I COS (X ** 2)) и) (X + SQRT (1. + SQRT (1. + X *♦ 2))) ** #.2 к) A (I, К) * В (К, J) 4. 1) a) 3; 2) a) 0; 6) 4; 6) 0; в) 6; в) 0. 5. a) (2., 1.) * U ♦* 2 — 2. ♦ V+ (0., 1.) * W 6) (3.— Z) / (2. + Z ** 2) + 3.2 ♦ C * CSIN (Z) в) U*(V- (0., l.))/(2., 1.) *♦ 3 r) (5.2,— 3.7) ** 2/ (2.3, 3.2) * U — 3. * (0., 1.) * (W + U) ** 2 д) (1. + 2. * V — 3. ♦ W ♦♦ 2) / ((#., 2.) * (W — U)) +((#., l.)*U — — V)/5. e) W — W ♦* 2/2. + W ** 3/6. — W ** 5/12#. ж) CEXP (A * Z) * CSIN (Z) + CEXP (—В * Z) * CCOS (Z) з) (A ♦ CSIN (Z) ♦♦ 2 + D * CLOG (Z))/(C + D) Порция 24 Для заданий 1 и 2 приводится по одному из возможных вариантов: 1. Y ** 2.LE. X. AND. Y. GE. X 2. Y. LE. (— X ** 2). OR. Y. GT. 0. 0 3. а) рис. 12, б) рис. 10, в) рис. 11. 4. а) рис. 15, б) рис. 13, в) рис. 14. 5. X. LE.. 5. AND. Y. LE..5. AND. Y. GE.—.5 ГЛАВА П Порция 25 1. Одна. 2. Нужно записать литеру С в первой позиции этой строки. 3. В позиции 6 строки продолжения нужно записать литеру, отличную от про- бела и цифры 0. 4. LJ l_j LJ 25 l_j А = 15.37 l_jl_jlj15ljQ = 2. *А**2 — 422.# * А/3.# — 1.7 5. См. стр. 66. 6. Нет, предложение может записываться с любой позиции, начиная е седьмой; комментарий — с любой, начиная со второй. 7. В ФОРТРАН/ЕС число строк комментариев между двумя предложениями не должно превышать 30. 8. Одинаковы. 9. Одинаковы. 365
Порция 27 1. а) 14.0 е) 6.0 б) 0.0 ж) 6.5 в) 12.4 з) 150.0 г) 39 и) 150.0 Д) 36 к) 0 2. Нет. 3. А = 81.0 В = —81.0 4. а) V = А/(В * SQRT (А ♦* 2 + В ** 2)) * ATAN (А * X/SQRT (X ** 2 + -|- А ** 2)) б) V = 3.1416/3. * R ** 2 * Н в) U = 3.1416/3.* (R ** 2 + R1 ** 2 + R * Rl) * Н г) У = 2. * SIN ((5. * X) ** 2) ** 3 + 3. * COS ((2. * X) ** 3) ** 2 д) А = SQRT (В ** 2 + С ** 2 — 2. * В * С * COS (А)) 5. а) С (I, J) = А (I, К) * В (К, J) б) С (I, J) = А (I + С2) * В (2, J + 1) в) U = Х/(1. + X ** 2/(1. + X ** 3/3.0)) г) Z = X ** 2 + У ** 2 U = Z ** (1./3.)/(1. + Z) V - (1. + Z)/(3. + SQRT (Z)) W = (U + V) ** N/(2./5. + 3. * и — V) 6. C= A A= В В = C Порция 28 1. a) AL = Y. LE. — (X ** 2). OR. Y. GE.0.0 6) BL = X ** 2+ Y ** 2.LE.1.0.AND. Y ** 2.LE.X 2. 1) Правильно. 2) Переменной целого типа нельзя присваивать логическое значение. 3) Логическая и вещественная переменные не могут соединяться знаком арифметической операции. 4) Логической переменной нельзя присваивать числовое значение. 5) и 6) Логическая переменная не может быть операндом арифметического выражения. 7) и 8) Правильно. 3. a) U= Y.LE.l.—X.AND.X.GE.0.0.AND.Y.GE.0.0 б) U = X * X + Y * Y.LE.1.0.AND.X * Y.LE.0.0 в) U= (Y.GE.(—X — 1.).AND.X.LE.0.0.AND.Y.LE. * O.O).OR.(Y.EQ.X.AND.X.GE.0..AND.X.LE.2.) г) U = (X.LE.0.0.AND.X * X + Y * Y.LE.l.).OR.(X. * GT.0.0.AND.Y.LE.1.— X.AND.Y.GE.0.0).OR.(Y. * GE.X — 1..AND.Y.LE.0.0.AND.X.GT.0.0) 4. a) W = X.LE.Y 6) W = A.LT.B.AND.A.LT.C.OR.A.GT.B.AND.A.GT.C в) W= V1.OR.V2.OR.V3.OR.V4 r) W = .NOT.U 5. 1) L = .TRUE. 3) V = .FALSE. U = .FALSE. L = .TRUE. V = .TRUE. W = .FALSE. W = .FALSE. U = .FALSE. 2) V = .TRUE. 4) L = .TRUE. W = .FALSE. V = .TRUE. W = .FALSE. U = .TRUE. 366
Порция 29 1. Правильная запись оператора a) GO ТО (3, 24), INT б) GO ТО (3, 2), INT в) GO ТО (3, 4, 5), КАМА г) GO ТО (3, 4), К1 2. GO ТО (1, 1,7, 1,7, 7, 7, 1), К 7 К = 0 1 {продолжение программы} Ошибка в задании список меток не заключен в скобки; пропуще- на запятая перед управляющей переменной; нет запятой после скобок; управляющая переменная должна быть це- лого типа; десятичная точка недопустима в записи метки. Порция 30 1. Правильная запись Ошибка в задании оператора a) GO ТО I, (1, 2, 3, 4, 5) б) GO ТО К35, (3, 15, 5, 23, 53) в) GO ТО КА, (19, 2£, 21, 22, 23) г) ASSIGN 3 ТО IR д) ASSIGN 3 ТО М GO ТО М, (1, 2, 3, 4, 5) пропущена запятая после имени переменной I; в списке меток должна быть метка 5; управляющая переменная должна быть цело- го типа; значение метки может быть присвоено только в операторе ASSIGN; переменная, которой присвоено значение метки, может быть использована только в операторе GO ТО по предписанию Порция 31 1. Смысл оператора GO ТО по предписанию не изменится, вычисляемого опера- тора GO ТО — изменится. 2. Если добавляемая метка отлична от всех меток, перечисленных в списках вычисляемого оператора GO ТО и оператора GO ТО по предписанию, то возможности каждого из этих операторов расширяются за счет появления еще одной программной ветви, на которую они могут передавать управление. Если добавляемая метка совпадает с одной из имеющихся в списке оператора GO ТО по предписанию, то возможности этого оператора не изменяются. В аналогичной ситуации для вычисляемого оператора GO ТО возможности последнего расширяются за счет того, что управляющей переменной может быть присвоено еще одно значение, соответствующее номеру позиции соответствующей метки. 3. а) недопустима, если после первого оператора нет соответствующего операто- ра ASSIGN; б) допустима, если между указанными операторами значение переменной К не переопределено; в) недопустима; в списке вычисляемого оператора GO ТО должны быть указаны метки (целые без знака), а не переменные. 4. а), г). 5. Да; нет. Порция 32 1. 1) IF (X — Ш.) 1, 2, 3 1 F= X — I.jQ' GO ТО 4 2 F = 3. * X ** 2 4. GO TO 4 2) IF (X) Ш, 15, 15 Ш F = 2. * X + 5.# GO TO 20 15 IF (X — 1.) 25, 30, 30 25 F = X * X — 2.3 367
3 F = 7.1 * X — 5.6 4 {продолжение программы) 3) IF (X * X + Y ♦ Y - 4.#) 5, 5, 6 5 F=X*X + Y*Y GO TO 7 6 F=Y*Y — X*X 7 {продолжение программы) 2. IF (X — Y) 5, 5, Ш 5 Z = X GO TO 15 1Я Z=Y 15 {продолжение программы) GO TO 20 30 F=X — 0.5 20 {продолжение программы) или Z = X ♦ X + Y * Y IF (Z — 4.) 5, 5, 6 5 F= Z GO TO 7 6 f=Y*Y — X*X 7 {продолжение программы) Порция 33 1. IF (L1.AND.L2) A = A + 1.0 2 {продолжение программы) 2.a) IF (X.GE. 12.7) GO TO 5 F = X * X + 4. * X GOTO \0 5 F = 2. * X — COS (X) 10 {продолжение программы) 6) IF (X.LT.3.25) F = X ♦ SIN (X) IF (X.EQ.3.25) F = 3.— X ♦ X IF (X.GT.3.25) F = X ♦ X ♦ SIN (X {продолжение программы) или F = X * X * SIN (X * X) ** 2 IF (X. LT.3.25) F = X * SIN (X) IF (X.EQ.3.25) F = 3.—X * X {продолжение программы) 3. 2), 3), 5), 6). или F = X * X + 4. * X IF (X.GE. 12.7) F = 2. * X — COS (X) {продолжение программы) * X) *♦ 2 Порция 35 1. В приведенных фрагментах многоточием обозначены участки программ, в ко- торых должны быть определены используемые в них массивы X и Y (и их размер N). Используя оператор DO а) SP = 0.0 DO \0 I = 1,N \0 SP = SP+ X (I) * Y (I) {продолжение программы) Без оператора DO б) REAL М SP = 0.0 I = 1 5 SP = SP + X (I) * Y (I) 1=1+1 IF (N — I) 15, 5, 5 15 {продолжение программы) REAL M M = 0.0 DO 5 I = I, N 5 M = M + X (I) *♦ 2 M = (SQRT (M)) M = 0.0 I = 1 5 M = M + X (I) ** 2 1=1+1 IF (N.GE.I) GO TO 5 368
М = (SQRT (М)) 2. В приведенных фрагментах многоточием обозначены участки программ, в ко- торых должны быть определены используемые в них массивы А и В. a) DIMENSION А (50), В (50) s = 0.0 DO 7 I = 1, 50 J = 51 - 1 7 S = S + А (I) * В (J) б) DIMENSION А (50), В (50) S = 0.0 I = 1 5 J = 51 — I S = S + А (I) * В (J) 1=1+1 IF (I — 50) 5, 5, 6 6 {продолжение программы) Примечание. В приведенных фрагментах программы оператор J = 51 — I введен в связи с тем, что запись (51 — I) в стандарте ФОРТРАНа недопустима для индексно- го выражения. В языке ФОРТРАН/ЕС этот оператор может быть опущен, а индекс переменной В должен быть заменен выражением 51 — I. 3. S = 0.0 L = 3* N — 2 DO 15 К = I,L, 3 15 S = S + А (К) * А (К + 1) ♦ А (К + 2) {продолжение программы) Порция 36 1. DIMENSION А (15, 15), X (15), В (15) DO 5 I = 1, 15 В (1) = 0.0 DO 5 J = 1, 15 5 В (I) = В (I) + A (I, J) ♦ X (J) 2. M = N — 1 DO 25 1= 1,M L= I + 1 DO 25 J = L, N U= A (I, J) A (I, J) = A (J, I) 25 A (J, I) = U {продолжение программы) Порция 37 1. Глубина вложенности операторов цикла стандартом языка не ограничена. 2. Могут. 3. См. стр. 98. 4. Конечным оператором тела оператора DO может быть только оператор, не вызывающий передачи управления. 13 9—2712 369
Порция 38 1. Вычисление суммы элементов матрицы, лежащих выше главной диагонали, включая элементы диагонали. 2. а) пересечение тел циклов недопустимо; б) фрагмент эквивалентен приведен- ному в задании 1; в) переменная I в программе не определена; г) переменная I в про- грамме не определена; имеет место пересечение тел циклов; используется один и тот же параметр цикла во внешнем и внутреннем операторах DO. Порция 39 1. а) {Ввод значений EPS, XI, Yl, Zl, АП, А12, А13, А21, А22, А23, А31, А32, АЗЗ, Bl, В2, В3> DO Ш I = 1, IW Х0= XI Y# = Y1 Z# = Zl XI = All * ХИ + A12 * YjO'H- A13 * ZH + Bl Yl = A21 * ХИ + A22 * YH + A23 * ZH + B2 Zl = A31 * ХИ + A32 * YH + A33 * ZH + B3 IF(ABS (XI — ХИ).LT.EPS.AND.ABS (Yl — YH). LT.EPS * .AND.ABS (ZH — Zl). LT. EPS) GO TO 5 Ш CONTINUE {печать текста ПРОЦЕСС РАСХОДИТСЯ) 5 {печать числа итераций и значений переменных XI, Y1, Z1 > STOP END (Литера ♦ в строке перед оператором с меткой Ш — символ продолжения опера- тора). б) Для выполнения этого задания необходимо включить в программу, приведен- ную в задании а), предложение DIMENSION А (3, 3), В (3) и вместо ввода коэффициентов Al 1, А12, ... указать ввод массивов А и В; в операторах XI = , Yl = , Z1 = заменить В1 на В (1), В2 на В (2), ВЗ на В (3), А 11 на А (1,1) и т. д. В остальном про- граммы будут эквивалентны. в) Для выполнения этого задания в программе, приведенной в задании 1, следует произвести следующие изменения: 1) Включить объявление DIMENSION А (12); указать ввод массива А. 2) В операторах XI = заменить: АП на А (1) А21 на А (2) А31 на А (3) А12 на А (4) А22 на А (5) А32 на А (6) А13 на А (7) А23 на А (8) АЗЗ на А (9) В1 на А (10) В2 1 4а А (11) ВЗ на А (12) 370
2. Полагая, что в программе, выполняемой до приведенного ниже фрагмента, решающего поставленную задачу, определены значения: переменной целого типа N, определяющей порядок решаемой системы уравнений; элементов массива A (N, N) — коэффициентов при неизвестных; элементов массива В (N) — свободных членов урав- нений; элементов массива VAL (N) — начальных приближений; переменной вещест- венного типа EPS (заданная точность приближений); К — максимальное число до- пустимых итераций, при превышении которого процесс считается расходящимся (пе- ременная целого типа), реализуем следующий алгоритм. Введем в рассмотрение массив логических переменных размерности N — массив BOOL (N). В начале выполнения настоящего фрагмента заполним его значениями .TRUE., а в дальнейшем после вычисления каждого из новых приближений будем сохранять значение соответствующего (по номеру) элемента или заменять его значе- нием .FALSE, в зависимости от того, является ли разность между двумя очередными приближениями меньшей EPS или превосходит это число. Если все элементы массива BOOL после вычисления очередной итерации ока- жутся равными .TRUE., итерационный процесс является успешно завершенным и выдается результат на печать — число итераций и решение; если число итераций превышает число К, выдается сообщение «ПРОЦЕСС РАСХОДИТСЯ». В обоих слу- чаях осуществляется выход на продолжение программы (здесь и далее предполагается, что N задано в виде константы целого типа). DIMENSION VAL# (N), A (N, N), В (N), VAL (N), BOOL (N) LOGICAL BOOL (ввод A, B) DO 1# L= 1, К DO 2 I = 1, N BOOL (I) = .TRUE. 2 VAL# (I) = VAL (I) C DO 4 I = 1, N VAL (I) = В (I) DO 3 J = 1, N 3 VAL (I) = VAL (I) + VAL# (J) * A (I, J) IF (ABS (VAL (I) — VAL# (I)).LT.EPS) GO TO 4 BOOL (I) = .FALSE. 4 CONTINUE C DO 5 I = 1, N IF (.NOT. BOOL (I)) GO TO 1# 5 CONTINUE GO TO 6 1# CONTINUE (печать текста ПРОЦЕСС РАСХОДИТСЯ) GO ТО 12 6 (печать числа итераций и решения) 12 (продолжение программы) 3. Для получения необходимого фрагмента программы достаточно в приведен- ном решении предыдущего примера в операторе с меткой 3 заменить лишь единствен- ное имя VAL# именем VAL. Действительно, в этом случае при вычислении каждой последующей итерации для z-й переменной будут приниматься в расчет вместо пре- дыдущих вновь вычисленные значения для всех J < i (для J i эти значения еще не перевычислялись и VAL (J) = VAL# (J)). 4. DIMENSION A (N) DO 5 1 = 1, N М = 1 — 1 IF (A (I).LT.#.#) GO ТО 7 13 371
5 CONTINUE M = N 7 {продолжение программы) ГЛАВА III Порция 40 1. а) В файл с номером 3 будет передано 10 пар значений, первым из которых является диагональный элемент матрицы А, а вторым — соответствующая координата вектора В. б) В файл с номером 3 будут переданы столбцы матрицы А: вначале второй, третий, ..., десятый, а затем первый. в) В файл с номером 3 будет передана строка, состоящая из 120 литер «тире» (напечатана черта). 2. Первым оператором из файла с номером 1 будет передана матрица А строками, а вторым — столбцами. Порция 42 1 См. стр. 113 2. Литеры «,» и «/». 3. 3 FORMAT (316, 4ЕШ.2) 4. а) список форматов полей в объявлении FORMAT не заключен в скобки; б) суммарный размер полей форматов превышает 80 колонок. 5. READ (1,3) R,S,T, I, J, К, L, M, N, IR, KR,LR,MR,NR 3 FORMAT (3F15.3/(316)) 6. Три. 7. а) все пять значений должны быть отперфорированы на одной перфокарте; б) каждое из значений переменных должно быть отперфорировано на отдельной перфокарте. 8. а) на одной строке; б) каждое значение — с новой строки. Порция 46 1. 437.83 4. 1.73 • 103 2. —43.783 5. 1.73 • 10? 3. -4378.1 6. 173 • 10? 7. 17.3 • 10а 8. 17.35 * 10”4 9. 17.35 . Ю^4 10. 17.35 И. 12345.67891011 Порция 47 1. a) READ (1, 5) А 5 FORMAT (8Fie.3) б) READ (1,6) ((A (I, J), J = 1, Ш), I = 1, 1^) 6 FORMAT (8ЕШ.З) a) WRITE (3,5) А 5 FORMAT (ШХ, ШЕИ.З) б) WRITE (3,6) ((A (I, J), J = 1,Ш), I =- 1,Ш) 6 FORMAT (ШХ, ШЕИ.З) 372
2. 2 3 4 12345 6789012345 67890123456789012345678901234567 0.2874Еш05 1 170.1—II—II—I LJ 2525.1—I L_j i—ii_j — 0.3200E — 05 —0.7600E — 05 —0.1235E — 04 3. WRITE (3, 5) Q, S, P, T, R, U 5 FORMAT (2G 15.4) Порция 49 1. COMPLEX * 16 AR (4) /’ НЕЛЬЗЯ’, ’ТУПОУГОЛЬНЫЙ’, ♦ ’ОСТРОУГОЛЬНЫЙ’, ’ПРЯМОУГОЛЬНЫЙ’ I WRITE (3, 1) 1 FORMAT (5X, ’N’, 10X, ’A’, 10X, ’В’, 10X, ’С’, 10X, ’ХАРАКТЕРНО’ ♦ ТИКА’) 5 FORMAT (3F6.2) 10 FORMAT (4X, 12, 3X, 3F11.3, 7X, 2A8) DO 50 N = 1,50 READ (1,5) А, В, C IF (A.GE.B) GO TO 20 U = A A = В В = U С А БОЛЬШЕ В 20 IF (A.GE.C) GO TO 30 U = A A = C c= и С А БОЛЬШЕ В, А БОЛЬШЕ С 30 1=4 IF (A.GE.B + С) I = 1 LJ — A * A — В * В — С * С IF (U.GT.1E — 6) I = 2 IF (U.LT.(— IE — 6)) I = 3 50 WRITE (3, 10) N, А, В, C, AR (I) STOP END 2. a) WRITE (3, 10) C 10 FORMAT (40X, 37НВЫВОД ЭЛЕМЕНТОВ МАТРИЦЫ С ПО ♦СТОЛБЦАМ/ * (20Х, 8F10.3)) б) WRITE (3, И) ((С (I, К), К— 1,8), I = 1,10) 11 ^FORMAT (40Х, 36НВЫВОД ЭЛЕМЕНТОВ МАТРИЦЫ С ПО СТРОКАМ/ ♦ (10Х, 10F10.3); 3. uuuuuuuu COMPLEX * UUUUUUUU16U DATA СО М Р L Е X * 16 lj DATA Порция 50 1. Нет; нет. 2.0 3. ФОРТРАН u u uHE u и ТОЛЬКО ш ТРАНСЛЯТОР l_j ФОРМУЛ Порция 51 1. lj lj i_j lj 72532 lj i_j lj 890001 ш l_j l_j l_j 1.325 373
Порция 52 1. REWIND, BACKSPACE, ENDFILE 2. Вспомогательные операторы ввода-вывода используются при работе с после* довательными файлами (магнитной лентой). Порция 53 1. Нет. 2. Нет. 3. Нет. 4. Да. 5. Нет. 6. Нет. 7. Должен, в этом состоит отличие способов связи объявлений FORMAT и NAMELIST с операторами ввода-вывода. 8. Нет. 9. Может. Порция 54 1), 2) ГЛАВА IV Порция 55 1. В языке ФОРТРАН имеется два класса вычислительных процедур: процедуры- функции и процедуры-подпрограммы. 2. Классы функций: внутренние, встроенные, внешние. Порция 56 1. Имена функций и подпрограмм вводятся для возможности обращения к ним. 2. Определенные имена закреплены для встроенных и основных внешних функций. 3. Имена встроенных функций: Имя Тип аргумента Тип функции МАХО целый целый МАХ1 вещественный целый DMIN1 повышенной точности повышенной точности REAL комплексный вещественный IFIX вещественный целый Имена основных внешних функций Имя Тип аргумента Тип функции ЕХР вещественный вещественный СЕХР комплексный комплексный ALOG 10 вещественный вещественный DCOS повышенно;! точности повышенной точности CCOS комплексный комплексный ATAN вещественный вещее «венный 374
Порция 57 1. При обращении к процедуре задаются фактические параметры. 2. По значению и по наименованию, см. стр. 152. 3. По наименованию. 4. Именем переменной, име- нем переменной с индексами или именем массива. 5. Списки формальных и фактиче- ских параметров должны быть согласованы в типе, числе и иорядке следования в них соответствующих параметров. 6. Нет. Порция 58 1. Имя массива или элемента массива. 2. Различные формальные параметры не могут быть заданы одинаковыми имена- ми; фактические могут. Порция 59 1. а) 90; б) 35; 2. См. стр. 158. Порция 60 1. В языке ФОРТРАН допустимо использование функций пяти типов: целого комплексного вещественного логического повышенной точности 2. Тип внутренней функции задается так же, как и тип простых переменных. 3. Неявно тип внешней функции может быть задан для целого и вещественного типов посредством первой буквы имени. 4. В стандарте ФОРТРАНа тип функции может быть задан только в ее заголовке FUNCTION, т. е. для определения логической функции Z (X) необходимо записать: LOGICAL FUNCTION Z (X) Для ФОРТРАН/ЕС такое описание типа функции допустимо. Порция 61 1. 1) Недопустима. Имя встроенной функции не может быть одновременно име- нем переменной в одном и том же программном модуле. 2) Недопустима. В выражении используются данные разных типов. 3) Недопустима. 4) Допустима. 5) Недопустима. Результатом выполнения функции FLOAT будет данное вещественного типа, которое нельзя использовать в одном выражении с целым. 6) Допустима при условии, что AMOD является некоторой функцией от одного аргумента (тем самым отличной от встроенной функции AMOD, которая является функцией от двух аргументов). 7) Допустима. 8) 2—7. 2. DIMENSION ERR (15) X = 0.0 DO 15 I = 1, 15 X = X + e.25 15 ERR (I) = ERF (X) WRITE (6, 20) ERR 20 FORMAT (5X, 5E15.7) STOP END 375
Порция 62 1. Переменная К в этой программе определяет номер строки вывода. Последнее еиачение, присвоенное переменной К, равно 98. 2. Pl = Р (1.7,— 2.41) Р1 = Р(— 2.41, 1.7) 3. U (X, У) = X + Y V (X, У) = X * X + SIN (У) F (W, Z) = EXP (W * Z) 4- Z + з.а W (X, У) = ALOG (г (U (X, У), V (X, У))) + SQRT (U (X, У) ♦ V (X, У)) WRITE (3,3) X = Я.2 У = —Я.28 DO 8 К = 1, И НХ = К X = X + Я.1 ♦ НХ DO 7 L = 1,4 НУ = L У = У + НУ W1 = W (X, У) WRITE (3, 2) X, У, W1 7 CONTINUE У = 6.1 DO 8L = 1,11 НУ = L У = У + £.2 * НУ Wl = W(X, У) WRITE (3, 2) X, У, W1 8 CONTINUE 2 FORMAT (5Х, F1H.4, 2 (1ЯХ, Fie.4)) 3 FORMAT (5Х, ШНЗНАЧЕНИЕ uX, ШХ, ШНЗНАЧЕНИЕ ш У, ШХ, *1ЯНЗНАЧЕНИЕ lj W) STOP END 4. NATS (N) = (N + 1) * N/2 5. INTS (M, N) = (M + N) * (N — M + 1 )/2 6. R (A) = A + SQRT (1. + A + 2. ♦ A * A + 3. ♦ A ♦* 3) Z = R (X) U = (7.83 * X + 3.75)/R (X ** 2) V = (3.41 * X + Y * (R (X)))/(Y - R (X)) W = (1.25 * X — 8.55 * Y)/R (SIN (Z)) . R = F (F (3., 2.), F (5., 3.)) + 200. = F (5., 16.) + 200. = 25. — 256. + 4- 200. = —31. Порция 63 1. Имена простых переменных, имена массивов, описатели массивов. 2. Да, для идентификации массива, простой переменной или внутренней функции. 3. COMMON Т/ А (3, 4), В (3, 4) Порция 64 1. Размер общего блока — это сумма единиц памяти, необходимой для размеще- ния объектов, указанных в объявлениях COMMON и EQUIVALENCE. 2. Нет (см. стр. 173). Да. 376
Порция 65 1. Помеченными общими блоками удобно пользоваться в том случае, когда про- грамма состоит из ряда модулей, общие данные для которых могут быть сгруппирова- ны (объединены в блоки). Порция 66 1. а) Пропущена запятая между списками переменных, б) Третий список содер- жит две переменные, определенные ранее как эквивалентные (А и F). в) Такое совме- щение по памяти элемента массива из общего блока В (2, 1) и элемента массива R (4) недопустимо в стандарте ФОРТРАНа. 2? REAL X (2), DELX, DELY, DELS COMPLEX XY EQUIVALENCE (XY, X, DELX), (X (2), DELY) SUM = #. DO 3# I = 2, N DELX = X (I) — X (I — 1) DELY = Y (I) — Y (I — 1) DELS = CABS (XY) 3# SUM = SUM + DELS 3. 1), 2), 3) Порция 67 1. INTEGER FUNCTION Al (AK) COMPLEX AK DIMENSION AK (1^) A = и.а DO 1 I = 1,1^ IF (CABS (AK (I)) — A) 1, 2, 2 2 A = CABS (AK (I)) Al = I I CONTINUE RETURN END 2. COMPLEX FUNCTION A3 (AK) COMPLEX AK (2И) M = 1 A = CABS (AK (1)) DO 1 I = 2, 2# IF (CABS (AK (I)) — A) 2, 1, 1 2 A = CABS (AK (I)) M= I 1 CONTINUE АЗ = А К (M) RETURN END 3. FUNCTION F(B) REAL В (2#, 3^), A EQUIVALENCE (В (1, 1), A (1)) AMIN = ABS (A (1)) AMAX = ABS (A (1)) DO 1 I = 2, 6ИИ 377
IF (ABS (A (I)) - AMIN.LT.e.H) AMIN = ABS (A(I)) IF (ABS (A (I)) — AMAX.GE.e.tf) AMAX = ABS (A (I)) I CONTINUE F = AMAX — AMIN RETURN END 4. Необходимо: а) Во втором предложении описатель REAL заменить описате- лем COMPLEX, б) Идентификатор встроенной функции ABS во всех указателях этой функции заменить идентификатором основной внешней функции CABS. Порция 68 1. Нельзя. 2. Внешнюю функцию можно обозначить идентификатором, закреп- ленным за встроенной функцией, однако в этом случае встроенная функция с этим идентификатором в данном программном модуле не может быть использована. То же касается и основных внешних функций. Одним идентификатором нельзя обозначить внутреннюю функцию и внешнюю, к которой имеется обращение в данном программном модуле. 3. Момент завершения выполнения процедуры определяется выполнением опера- тора RETURN. 4. а) Нет, так как функция 0 обращается сама к себе посредством функции у. б) Допустимо. в) Недопустимо, так как функция а обращается сама к себе посредством функ- ции 0. 5. Формальные параметры X и Y являются идентификаторами внешних функций, параметр Z является идентификатором простой переменной. В ФОРТРАН/ЕС X и Y могут быть массивами. Порция 69 1. FUNCTION СРАВН (X, Y, Z) IF (X — Y) 5, 6, 5 6 СРАВН = 3. RETURN 5 IF (X — Z) 7, 8, 7 8 СРАВН = 4. RETURN 7 СРАВН = 6. RETURN END или IF (X.EQ.Y) GO TO 5 IF (X.EQ.Z) CO TO 6 СРАВН = 6.Я GO TO 7 5 СРАВН = з.я GO TO 7 6 СРАВН = 4.-0' 7 RETURN END 2. FUNCTION SMALL (A, N) DIMENSION A (I###) SMALL = A (1) DO 1 I = 2, N IF (SMALL —A (I)) 1, 1,2 378
2 SMALL = A (I) 1 CONTINUE RETURN END 3- LOGICAL FUNCTION SI (А, В, C) COMMON S P = (A + В + C)/2. . false IF (A + B.GT.C. AND.В + C.GT.A.AND.C + A.GT.B) SI = .TRUE. IF (SI) S = SQRT (P * (P — A) * (P — В) * (P — СП RETURN END Порция 70 1. Да. 2. Да. 3. 4. LOGICAL FUNCTION SIM (A, N) DIMENSION A (N, N) N1 = N — 1 DO2 I = 1, N1 Il = I + 1 DO 2 J = II, N IF (A (I, J). NE.A (J, I)) GOTO3 2 CONTINUE SIM = .TRUE. RETURN 3 SIM = .FALSE. RETURN END a) FUNCTION PS (A, N) 6) FUNCTION SP (A, N) DIMENSION A (N, N) DIMENSION A (N, N) PS = 1.И SP = 0.0 DO 35 К = 1, N DO 35 К = 1, N S = 0.0 P = 1.0 DO 25 L = 1, N DO 25 L= 1, N 25 S = S + A (K, L) 25 P = P * A (K, L) pc = pc * С cp — SP 4- p 35 CONTINUE 35 CONTINUE RETURN RETURN END END в) и г) аналогичны а) и б) соответственно. Порция 71 1. Между заголовком и заключительной строкой в теле подпрограммы запреще- но использование объявлений SUBROUTINE, FUNCTION, BLOCK DATA. 2. Идентификатор внешней функции используется в теле функции в роли иден- тификатора переменной, значение которой в этом теле должно определяться. Обраще- ние к внешней функции осуществляется посредством указателя. Идентификатор подпрограммы используется при обращении к подпрограмме в операторе CALL. Порция 72 1. Идентификаторы процедур используются в вызываемых и вызывающих модулях. 379
Идентификатор подпрограммы должен появиться в вызываемом модуле в объяв- лении SUBROUTINE; в вызывающем — в операторе CALL. Идентификатор внешней функции в вызываемом модуле должен появиться в объявлении FUNCTION и хотя бы в одном из операторов, определяющих его значение как значение данной функции; в вызывающем — в указателе этой функции. 2. При наличии в программном модуле косвенного обращения к внешним проце- дурам в этом программном модуле обязательно наличие объявления EXTERNAL. 3. В список идентификаторов в объявлении EXTERNAL должны быть включены все идентификаторы тех внешних процедур, которые используются в теле данного про- граммного модуля в качестве фактических параметров. 4. Наличие объявления EXTERNAL в некотором программном модуле говорит о том, что в нем имеется косвенное обращение к внешним процедурам. 5. SUBROUTINE ALK (А, А2) DIMENSION А (Ш#) SUM = 0.0 DO 1 J = 1,100 1 SUM = SUM + A (J) A2= suM/ше.е RETURN END 6. SUBROUTINE INV (X, Y, K) DIMENSION X (K), Y (K) DO 10 J = 1, К № К — J+ 1 10 Y (N) = X (J) RETURN END 7. SUBROUTINE MINST (A, N, S, K, L) DIMENSION A (N, N) S= 0.0 K= 1 DO 10 J = I, N SI = 0.0 DO 5 I = 1, N 5 SI = SI + ABS (A (I, J)) IF (S.GT.S1) GO TO 10 3= SI K= J 10 CONTINUE S = A (1, K) L= 1 DO 15 I = 2, N IF (S.LT.A (I, K)) GO TO 15 S = A (I, K) L = I 15 CONTINUE RETURN END Порция 73 1. SUBROUTINE CP (A, K, Cl, N) DIMENSION A (5#) Cl = 0.0 К = 0 380
DOI J = 1, N Cl = Cl + A (J) IF (A (J)) 1, 2, 1 2 K= K+ 1 1 CONTINUE AN = N Cl = Cl/AN RETURN END 2 . CALL CP (B, KN, VCP, 4в) VCP = VCP ** 2 Порция 74 1. Исходные данные в подпрограмму могут быть переданы посредством аппарата Ьормальных-фактических параметров или через общие блоки памяти. 2. Результаты выполнения подпрограммы могут быть использованы в вызываю- щем модуле посредством фактических параметров, соответствующих формальным, вызываемым по наименованию, или через общие блоки памяти, или могут быть выда- ны во внешнюю среду посредством операторов вывода. 3. Да. Это может иметь место вследствие изменения значений переменных из общего блока памяти. 4. Через общий блок памяти или посредством операторов вывода. Порция 75 1. Формальные параметры не могут быть использованы в объявлениях COMMON, EQUIVALENCE и DATA. Порция 77 1. Если результаты выполнения процедуры должны быть выданы при ряде обра- щений к ней в различные поля памяти, необходимо воспользоваться аппаратом фор- мальных-фактических параметров. Если при различных обращениях к данной процедуре могут быть использованы одни и те же поля, вместо аппарата формальных-фактических параметров можно вос- пользоваться объявлением COMMON. Аппарат COMMON не пригоден для передачи параметров — имен внешних процедур. Порция 78 М = (К + 4) ♦♦ 2 RETURN END INTEGER FUNCTION М (К) или INTEGER FUNCTION М (К) N = К М = (К + 4) ♦♦ 2 N = N + 4 RETURN М = N ** 2 END RETURN END Порция 79 1. Нет, поскольку в операторе CALL метки-фактические параметры должны ука- зываться явно. 2. Нет, поскольку переменная, которой присвоено значение операто- ром ASSIGN, может использоваться только в операторе GO ТО по предписанию 3. Нет; нет. 381
5. Нет. 6. Запись допустима и не всегда приводит к зацикливанию. так как помимо оператора RETURN 1 в теле процедуры S могут встречаться операторы RETURN, передающие управление в вызывающий программный модуль оператору, следующему за указанным оператором 1 CALL S (& 1, X, Y) 7. GO ТО (1, 20, 30, 400), I Порция 80 1. Счетчик реализован по вычитанию операторами: К = К-1 IF (К. EQ. 0) RETURN 2. Точка входа — оператор CALL, выхода — RETURN; К = 0. 3. С помощью оператора RETURN 1; нет. Порция 81 1. 5 Порция 83 1. Объявление EXTERNAL необходимо в том случае, когда в данном програм- мном модуле имя некоторой функции используется в качестве фактического пара- метра. 2. Нет, так как это означало бы рекурсивное обращение к данному програм- мному модулю, запрещенное синтаксисом языка ФОРТРАН. 3. Наличие имени встроенной функции в списке объявления EXTERNAL озна- чает, что в данном программном модуле соответствующая функция не используется и выполняемая программа включает внешнюю процедуру, обозначенную этим име- нем. Наличие указателя -анной встроенной функции в правой части оператора при- сваивания означает обращение не к встроенной функции, а к соответствующей внеш- ней (с этим же именем). Порция 84 1. В случае, когда выполнение функции сводится к выполнению одного операто- ра присваивания. 2. Используя встроенную функцию FLOAT, необходимый фрагмент программы представим в виде: REAL X (100), Y (100) Р4 (I) = X (I) * X (I) + Y (I) * Y (I) С (I) = FLOAT (I) Т (I) = С (I) * С (I) * (1. + С (I)) + COS (2. * С (I)) + SQRT (Р4(1)) R = 0.0 DO 1 I = Nl, N2 1 R = R + Т (I) R = R + SQRT (Р4 (5#)) + SQRT (Р4 (100)) END 382
EXTERNAL P1,P2, РЗ, P4 COMMON XI (ШЯ), Y (100) CALL P4 (5И, SI) CALL P4 (100, S2) CALLT(N1, N2, Pl, S3) CALL T (N3, N4, P2, S4) CALL T (N5, N6, P3, S5) CALL T (N7, N8, P4, S6) R = SI + S2 + S3 + S4 + S5 + S6 END SUBROUTINE T (N, M, F, S) S= 0.0 DO 1 I = N, M CALL F (I, U) 1 s= S+ U RETURN END SUBROUTINE Pl (I, S) S = I * I RETURN END SUBROUTINE P2 (I, S) A = I S = COS (2.0* A) RETURN END SUBROUTINE РЗ (I, S) S = I ** 3 RETURN END SUBROUTINE P4 (I, S) COMMON X (100), Y (100) S = SQRT (X (I) *♦ 2 + Y (I) *♦ 2) RETURN END 4. 1) Допустима. 2) Допустима. 3) Недопустима. Процедура Т должна быть внешней (что следует из указания ее имени в объявлении EXTERNAL) и одновременно внутренней функцией (что сле- дует из употребления этого имени со списком формальных параметров в левой части оператора присваивания). 4) Недопустима. Формальные параметры не могут быть включены в список объяв- ления COMMON. 5. Нет, так как в этом случае каждый получаемый результат при очередном вы- зове процедур будет уничтожать предыдущий. Порция 85 1. Чтобы иметь возможность сравнивать элементы массива S (логического типа) с константами целого типа. 383
Порция 87 .1. Да. 2. Нет. 3. Нет. 4. Нет. Обращение CALL Л (X, Y) является рекурсивным. 5. Да. 6. | | | | | | I | | | 1 | I | | I I I I I I 3 Переменная М сохранит исходное значение, поскольку при вызове по главному входу будет произведена лишь начальная установка параметра I; переменная N при- мет новое значение согласно вызову по значению-результату. 7. Нет, так как это вызовет неопределенность I при обращении по входу Р2. 8. 3 2 I 1 9. Переменная S введена для того, чтобы значение GETSY (CHAR, 1) не пере- вычислялось в цикле. Порция 88 1. Размеры массивов могут быть заданы: а) в объявлении типа, б) в объявлении DIMENSION, в) в объявлении COMMON, однако в том случае, когда ни имя массива, ни эти размеры не являются формальными параметрами. 2. Массивы, хотя бы один из размеров которых определяется идентификатором (целого типа). 3. Такой список должен включать как имена регулируемых массивов, так и пере- менные, определяющие их размеры (в ФОРТРАН/ЕС переменные, определяющие ре- гулируемые размеры, должны быть ьключены либо в общую область COMMON, либо в список формальных параметров). 4. Минимальное — четыре: три идентификатора этих массивов и один — опре- деляющий их размеры. Например: A (N), В (N, N), С (Ш, N, N). Максимальное — 12: три имени массивов и по три параметра, задающих размеры для имени каждого из массивов. В этом случае все размеры должны определяться различными именами. В ФОРТРАН/ЕС допускаются массивы, имеющие до семи измерений, максимальное число указанных параметров может оказаться большим. 5. Нет. Эта процедура должна иметь по меньшей мере два формальных парамет- ра: имя регулируемого массива и имя его размера; в случае ФОРТРАН/ЕС таким па- раметром должно быть хотя бы одно имя указанного массива. 6. В качестве параметров циклов нельзя использовать формальные параметры, определяющие регулируемые размеры, так как языком запрещено их переопре- деление. 7. I) Недопустима. Имя М, определяющее регулируемые размеры массива А, ста- новится неопределенным при выполнении оператора ASSIGN, что запрещено языком. 2) Недопустима. Имя, определяющее регулируемые размеры массива, не может использоваться в качестве параметра цикла. 3) Допустима. 4) Недопустима. Имя, определяющее регулируемые размеры массива, не может быть использовано в каче- стве управляющей переменной оператора GO ТО. 5) Допустима. 6) Недопустима. Имя, определяющее регулируемые размеры массива, не может быть переопределено в теле процедуры. 8. S = SP (A, N, М, 2, 3) SI = SP (A, N, М, 3, 5) S2 = SP (A, N, М, 2, 2) + SP (A, N, М, 3, 3) 9. Число формальных параметров в подпрограмме LOG не может быть уменьшено в связи с тем, что обрабатываемые массивы имеют регулируемые размеры. В ФОРТРАН/ЕС это число может быть уменьшено. 10 IF (A (J, 1))3, 2, 3 2 CONTINUE 384
В (I) = .FALSE, GO TO 4 3 В (I) = .TRUE. 4 CONTINUE RETURN END 11. Нет. Размеры массивов могли быть описаны в объявлениях типа: SUBROUTINE LOG (А, М, N, В) LOGICAL В REAL А (М, N) 12. Тот же результат (логический вектор В) может быть получен при выполнении следующей программы, содержащей вместо 13 только 10 предложений: SUBROUTINE LOG (А, М, N, В) LOGICAL В DIMENSION А (М, N), В (N) DO 2 I = 1, N В (I) = .FALSE. DO 2 J = 1, М IF (A (J, I). NE. 0.) В (I) = .TRUE. CONTINUE 2 RETURN END Однако по времени выполнения эта программа уступает программе, приведенной в порции 88: просмотр элементов столбцов в ней продолжается и после того, как встре- тился ненулевой элемент; соответственно этому производится повторное присваивание элементу массива В (I) значения .TRUE.. Ниже приведен еще один вариант программы, содержащий 11 предложений, но свободный от указанного недостатка: SUBROUTINE LOG (А, М, N, В) LOGICAL В DIMENSION А (М, N), В (N) DO 3 I = 1, N В (I) = .FALSE. DO2 J = 1, М IF (A (J, I)) 3, 2, 3 2 CONTINUE 3 В (I) = .TRUE. RETURN END Порция 89 1. BLOCK DATA COMMON/BLOCK5/A, В, С, Р, BOOL3 LOGICAL BOOL3 INTEGER А (2, 2), В (2, 2) DATA А (1, 1), А (2, 1), В (1, 1), С, BOOL3/2, 3, 4, 77. 7, -.FALSE ./ Порция 90 1. a) F (I) = FLOAT (I) ** 2 + SIN (FLOAT (1) + 1.) + FLOAT (К) 6) F (К, Т) - SQRT (FLOAT (К)) (FLOAT (К) + Z + Т) ** (1./3.) в) М (S, К) = IFIX (S) + (L 4- 2 * К) ** 3 385
2. FUNCTION G (X, A) IF (X) 1, 2, 2 1 G = A ♦ X ** 2 RETURN 2 G = A * X *♦ 3 RETURN END 3. SUBROUTINE M (А, В, C) DIMENSION А (Ш, Ш), В (Ш, Ш), С (Ш, Ш) DO 5 I = 1, Ш DO 5 J = 1, Ш C (I, J) = 0.0 5 DO 5 K= 1, 10 С (I, J) = С (I, J) + A (I, К) * В (К, J) RETURN END DIMENSION В (10, Ш), BM (Ш, 10), А (Ш, Ш) READ (1, 1) В, ((BM (I, J), J = 1, Ш), I = 1, IBj 1 FORMAT (5F14.4) CALL M (B, BM, A) DO 5 I = 1, 10 DO 5 J = 1, 10 5 A (I, J) = G (A (I, J), 5.0) WRITE (3, 2) ((A (I, J), J = 1, 10), I = 1, Ш) 2 FORMAT (4X, 5F1H.4) STOP END ГЛАВА V v П о p ц и я 91 1. В этом операторе выражение в правой части — вещественного типа. В стан- дарте ФОРТРАН ее заменить нельзя, в ФОРТРАН/ЕС — можно. 2. Переменная Ml введена потому, что конечный параметр цикла не может быть выражением, содержащим знак операции. Переменная А К введена для преобразования целого значения К в вещественное, что необходимо для его использования в выражении вещественного типа (в следующем операторе). В программе на ФОРТРАН/ЕС можно исключить переменную АК. 3. Объявления FORMAT могут быть помещены в любое место программного модуля до заключительной строки. Оператор Ml = М — 1 может быть переставлен с одним или двумя ему предшествующими. 4. В — Н — фактический параметр. F (A), F (В), F (В — Н), F (А + 2. * АК * Н) — указатели функции F. 5. Потребуется в программу дополнительно включить пять операторов вызова этой подпрограммы (по числу используемых в ней указателей функции F), указав при этом для первых трех операторов различные фактические параметры — идентифи- каторы результатов и соответственно заменив слагаемые в операторе присваивания, содержащем сумму трех указателей функции F. Аналогичные преобразования необхо- димо произвести для выполнения оператора с меткой 5. Другими словами, вместо оператора J = F (А) + F (В) + 4.* F (В — Н) в приведенной программе следует записать следующие четыре оператора: CALL F (A, Y1) 386
CALL F (В, Y2) CALL F (В — H, Y3) Y = Y1 + Y2 + 4. * Y3 а вместо оператора J = J 4. * F (A + (2. ♦ АК — 1.) * H) + 2. * F (A + 2. ♦ АК ♦ H) три опе- ратора: CALL F ((A + (2. * AK — L) ♦ H), Yl) CALL F ((A + (2. * AK ♦ H)), Y2) J = J -f- 4. * Yl + 2. ♦ Y2 Порция 92 1. В приведенной в тексте программе следует заменить оператор, помеченный меткой 5, оператором (сохранив за ним эту метку): X = (X# * F (XI) — XI ♦ F (XBj)/(F (XI) — F (X#)) 2. Переменная К принимает значения 1, 2 и 3. 3. Этот оператор можно заменить следующим: К = IFIX (Х)/2 4- 1 где IFIX — встроенная функция, преобразующая аргумент вещественного типа к целому типу. В ФОРТРАН/ЕС — можно. 4. При X = 4 величина К принимает значение 3. В этом случае, как и при 2 < X < 4, необходимо перейти к оператору с меткой 12. 5. Можно, для этого надо пометить один из них какой-либо меткой, а второй за- менить оператором безусловного перехода на эту метку. 6. Внутреннюю функцию F (X) необходимо поместить перед оператором READ (1,4) А, В, М, т. е. сразу за объявлением REAL J. Порция 93 1. Программные модули могут быть заданы в любом порядке. Объявления FORMAT могут быть помещены в любом месте головного модуля до заключительной строки END. 2. а) В приведенной в тексте программе необходимо заменить иервое предложение двумя следующими: FUNCTION SIMP (А) COMMON В, М б) В приведенной в тексте программе необходимо первое предложение заменить объявлением FUNCTION SIMP (А) и идентификаторы В и М всюду заменить константами 10.0 и 200 соответственно. Оператор КМ = М — 1 нужно при этом заменить оператором КМ = 199. Порция 94 1. Указанное в задании размещение заданных массивов на перфокартах не позво- ляет для их ввода использовать идентификаторы этих массивов. В связи с этим для за- писи оператора READ без списка типа цикл требуется непосредственное перечисле- ние всех переменных с индексами в порядке размещения их значений на перфокартах, т. е. в виде: READ (1,4)М, А (1), В (1), А (2), В (2) и т. д. При этом список оператора READ будет содержать 41 элемент. Во избежание столь громоздкой записи можно поступить следующим образом. 387
Введем в рассмотрение дополнительно массив С (40), в который введем всю инфор- мацию, составляющую массивы А и В. При этом начало программы придется записать в виде: REAL Ml DIMENSION Ml (2a), A (2a), В (2a), C (4a) READ (1, 4) M, C 4 FORMAT (I5/(2Fia.3)) DO 8 I = 1, 2a к = 2 * I — 1 L = 2 ♦ I A (I) = С (K) 8 В (I) = C (L) 2. а) арифметический оператор присваивания, б) переменная с индексом, в) ве- щественная константа, г) указатель функции (внешней), д) список фактических пара- метров, заданных переменными, е) переменная целого типа, ж) переменная целого типа, з) объявление FUNCTION (заголовок внешней функции), и) список формаль- ных параметров, к) заключительная строка. Порция 95 1. Из уравнения эллипса имеем: 'И- (''<’» ° Программа вычисления длины четверти дуги эллипса (А = о, В = Ь) может быть представлена в виде: COMMON А, В EXTERNAL Fl READ(1, 1) А, В,М 1 FORMAT (2F1H.3, 15) L = SIMP2 (#, А, М, F1) WRITE (3, 1) L STOP END FUNCTION Fl (X) COMMON A, В Fl = SQRT (1. + В * В ♦ X ♦ X/A * А/ (A * A — X ♦ X)) RETURN END 2. EXTERNAL SIN2 READ (1,1) M 1 FORMAT (15) V = SIMP2 (#,3.1416, M,SIN2) * 3.1416 WRITE 3,2 2 FORMAT (F12.2) STOP END FUNCTION SIN 2(X) SIN2 = SIN (X) ** 4 RETURN END 3. Наличие объявления EXTERNAL в приведенной программе обязательно, так как идентификаторы внешних функций Tl, Т2 и ТЗ используются в качестве фактиче- ских параметров в этом программном модуле (в указателе функции SIMP). 388
В предыдущих программах косвенное обращение к внешним процедурам отсут- ствовало. 4. 4 FORMAT (16, 2F12.6) EXTERNAL Fl READ (1, 4) Ml, A, B* Q = 2. * 3.1416 * SIMP (A, B, Ml, Fl) WRITE (3, 7) Q 7 FORMAT (5X, 4HQ l_j = l_j, F9.4) STOP END FUNCTION SIMP (А, В, M, F) END FUNCTION Fl (X) {вычисление значения Fl (x)) RETURN END Порция 97 1. Чтобы отказаться от модуля BLOCK DATA, начальные значения переменным II и 12 можно присвоить в головном модуле (операторами присваивания, выполненны- ми один раз, но не объявлением DATA!). Начальные значения обеим переменным II и 12 задать непосредственно в подпрограмме FIB нельзя. 2. COMPLEX А (2) DATA А (1), A (2)/8Hlji_jl_jl_jIljljlj, 8Hljl_jl_jSljljljl_j/ COMMON/В/П, 12 Il = 1 12= 1 WRITE (3, 1) A 1 FORMAT (ЗХ, 2A8) L= 0 DO3 1= 1,20 CALL FIB L = L + 12 El = FLOAT (I2)/FLOAT (L) 3 WRITE (3, 2) I, El 2 FORMAT (5X, 12, E16.7) STOP END Для формирования заголовка таблицы введен массив А комплексного типа, эле- ментам которого присваивается текстовое значение, состоящее из 16 литер. Передача начальных значений для подпрограммы FIB производится посредством общего блока В. В цикле формируется очередной член суммы, который используется для получения очередного члена St-; каждое полученное значение выдается здесь же в цикле на печать. Второй вариант решения, в котором мы опустили предложения, предназначенные для выдачи заголовка к таблице результатов и в котором результаты накапливаются в массив, а затем выдаются на печать посредством списка типа цикл: DIMENSION RS (20) COMMON/B/KF1, KF2 IS = 0 389
DO 1# I = 1,2# CALL FIB IS = KF2 + IS ‘10 RS (I) = FLOAT (KF2)/FLOAT (IS) WRITE (3, 4) (I, RS (I), I = I, 20) 4 FORMAT (5X, 12, E16.7) STOP END BLOCK DATA COMMON/B/I1, 12 DATA II, 12/1,1/ END SUBROUTINE FIB COMMON/B/ll, 12 L = 12 12= Il + 12 Il = L RETURN END 3. В общем случае не может, так как переменная V, принадлежащая общему бло- ку, должна для сохранения рекуррентного процесса выдачи очередного члена ряда Фибоначчи процедурой FIB сохранять свое значение. Оператор V = V — 2 * U можно допустить, если при этом перед ним ввести оператор W = V, а после него (и после использования в нем получаемого значения V) ввести оператор V = W Порция 98 1. COMPLEX А (2) INTEGER FIBO DATA Al, A2/8H 8Hi_jljljSIl_ji_jl_j/ Il = 1 12= 1 WRITE (3, 1) A 1 FORMAT (ЗХ, 2A8) W = 0. DO3 I = 1,2# U = FIBO (II, 12) w = W 4- U Si = u/w 3 WRITE (3, 2) I, SI 2 FORMAT (5X, 12, E16.7) STOP END Порция 100 1. Для указанной в задании замены необходимо соответствующие текстовые конс- танты отперфорировать и задать на вводе. Из объявления DATA необходимо изъять ту часть, которая касается задания начальных значений массива А. Оператор ввода массива А может быть представлен в виде: 390
READ (1, 3) A* 3 FORMAT (9A4) 2. SUBROUTINE GRAPH (YMAX, YMIN, F, X0, XN, S) DIMENSION В (ЗИ), A (4) DATA B/3£* , l_j 7, C/* i_j 7, A/’ ♦ *, ’u* ”, * l_ji_ii_i *7 X = XB' н = (YMAX — YMIN)/12#. Ш Y= F (X) К = (Y — YMIN)/H M = K/4 + 1 N = MOD (K, 4) + 1 В (M) = A (N) PRINT ЗЯ, В IF (X.LT.XN) GO TO 10 RETURN 30 FORMAT (1X.30A4) END FUNCTION F (X) F= X * X RETURN END EXTERNAL F CALL GRAPH (16., 0.0, F,— 4, 4, JO.25) STOP END Порция 103 1. Нет. Значение выражения A (I, J) * X (J) в варианте а) имеет тип REAL * 4. Перед сложением значение будет преобразовано к REAL * 8 функцией DBLE, т. е. в дополнительных младших разрядах мантиссы будут сформированы нули. В варианте б) операнды преобразуются к REAL * 8 перед умножением, поэтому результат умножения, участвующий в сложении, содержит ненулевые младшие раз- ряды мантиссы. 2. INTEGER * 2 в REAL * 4 для Y 0. Порция 105 1. .FALSE, из-за преобразования переменной А типа INTEGER * 4 к типу REAL * 4. ГЛАВА VI Порция 109 1. в. 2. DEBUG 3. Да Порция ПО 1. Нет. 2. STOP 20 (с печатью на SYSLOG), значение I выводится на SYSLST. 391
Порция 112 1. SYSLST. 2. Если в объявлении DEBUG задается только режим UNIT и в качестве файла отладки используется SYSLST, указанное объявление можно записать так: DEBUG Порция 113 1. В списке оператора DISPLAY не могут указываться переменные с индексами, а также списки типа цикл. Порция 115 1. Временными отрезками, границы которых определяются в момент выполнения операторов TRACE ON и TRACE OFF. Порция 116 1. Согласно объявлению типа данного и его размера. 2. Адрес А — глобальный, a ST (20) — локальный. Порция 118 1. С помощью оператора STOP и подпрограммы EXIT. 2. Да. 3. В случае, если выполнится оператор STOP или CALL EXIT. Порция 119 1. При некотором I произойдет переполнение целого; значение К (следовательно, X) станет отрицательным, для которого функция SQRT не определена. ГЛАВА VII Порция 122 1. На цилиндре. Порция 124 1. Нет. Дополнительные ограничения на длину физической записи накладывает транслятор с ФОРТРАНа. 2. Нет. 3. Ответ зависит от того, какое физическое устрой- ство будет назначено логическому с номером 2, указанному в операторе WRITE. Если этим устройством будет выходной перфоратор, то в данном случае будет сформи- ровано 4 физических записи; в случае магнитной ленты (МЛ) — две. Если в качестве такого устройства используется диск, количество записей будет определяться размет- кой файла, задаваемой в объявлении DEFINE FILE. 4. Барабан. Порция 125 1. Нет. Файл на дисках в ФОРТРАНе всегда имеет последовательную организа- цию, но может быть файлом с прямым или последовательным доступом. 2. а) Нет. б) Нет. 3. Нет. 4. Чтение, запись, поиск. 5. а) Нет (используется номер). 392
б) Нет. 6. Да; нет. 7. Да, но повторные его вынолнения игнорируются. 8. Абсолютный модуль. 9. Да. 10. WRITE, READ, FIND, DEFINE FILE. 11. С помощью индекса. 12. Указатель индекса записи. READ, WRITE. 13. Нет, параметр является интерпре- тируемым. 14. DEFINE FILE 14 (2ЯИ, 80, L, N) Порция 126 1. Апостроф. 2. В формате определена запись в 220 байтов (100+ 120), а в DEFINE FILE физическая запись имеет размер 200 байтов. Поэтому сочетание этих предложений недопустимо. 3. Будут прочитаны четыре записи с индексами 6, 7, 8, 9. Значение POINT равно 10. Порция 127 1. При бесформатном вводе-выводе. 2. Нет. Порция 128 1. Структура носителя определяется техническим исполнением. Структура фай- ла — организацией данных в программе. Внешняя память (набор носителей) распре- деляется под наборы файлов. На носителе может быть размещено несколько файлов, файл может быть размещен на нескольких носителях. 2. Три; две. 3. 400/80+1. 4. Набор многофайловых томов. 5. а) Да, б) да, в) да. 6. Нет, так как некоторая часть памяти расходуется на промежутки между физическими записями и для индексов но- меров записей. 7. а) файл, б) массив, в) запись, г) данное. ГЛАВА VIII Порция 130 1. Программами и наборами данных. 2. Задание — это программа на ЯУЗ, управляющая работой ДОС. 3. Директивы и операторы отличаются приоритетом. 4. Пакет заданий; пакет заданий; задание. 5. Да, если задание вводится с SYSIN. 6. SYSRDR Порция 131 1. Один: трансляция с ФОРТРАНа. 2. См. порцию 132. 3. Наличием признака. 4. /&; /*; ♦. 5. Признак, код, операнды. 6. I-?- 70. Не допускаются. 7. JOB; ♦; PAUSE. 8. JOB; /&. 9. Отличий нет. 10. Вы- полнение редактирования невозможно без указания режима LINK. Порция 132 1. Символическое имя, номер которого определяется при оформлении задания. 2. Нет. 3. Нет. 4. Через соответствующий номер, указанный в таблице 30. 5. Нет. 6. Нет. 7. Да, эти имена имеют различное назначение. 8. Да. 9. SYSLNK, SYSRLB и др. 10. Она может использоваться только для вывода. 11. Нет. Порция 135 1. Заключительная строка END не может обозначать конец файла, так как файл может состоять из нескольких программных модулей. Разделение модулей оператора- ми /♦ приведет к тому, что модули, расположенные после /*, не войдут в файл и опе- раторы языка ФОРТРАН будут ошибочно восприниматься как управляющие. 2. Стан- дартные. 3. Шаг задания; задание. 4. LIST, DECK. 5. Вторым и третьим способами. 6. Нет. Устройство вывода может быть отключено. 8. а) Да; б) нет. 9. Да. 10. Для ввода управляющих операторов. 11. Да. 393
Порция 136 2. Четыре. Да. 3. Нет, например, сообщению SINTAX соответствуют различные ошибки. 4. Да; да. 5. а) в программе нет цператоров, б) в задании нет исходного текста программы, в) программное прерывание во время трансляции. 6. Уровень 16 указы- вает на сбой в системной компоненте, поэтому дальнейшая обработка программы не- возможна. 7. В первом случае имеются в виду превышение диапазона числовых кон- стант и недопустимое указание размера в объявлениях типа. Во втором случае гово- рится о несоответствии размера текстовых констант в объявлении типа или DATA. 10. Да, если области действия циклов перекрываются. Порция 137 1. 1) Тип константы не соответствует типу переменной. Локальная. 2) Локальные ошибки. Использование недопустимой литеры (:); имя записано в поле метки. 3) Коли- чество констант превышает количество элементов списка переменных. Локальная. 4) В операторах X = С. AND.. NOT. D R = X тип переменной X должен быть логическим. Отсутствует оператор RETURN. 5) В списке формальных параметров не должно быть повторяющихся идентифи- каторов. 6) Переменная А может использоваться только с двумя индексами. 7) Опера- тор, следующий после оператора IF, должен быть помечен. Порция 138 1. Объявление EQUIVALENCE должно предшествовать объявлению DATA BLANK /’i—17, задающему начальное значение эквивалентному имени. 2. При присваивании начальных значений переменным в объявлении типа для каждого определяемого объекта в наклонных чертах записывается единственная константа. Список констант в этом объявлении может быть использован только тогда, когда определяемый объект является именем массива. Ошибочное объявление должно быть записано следующим образом: INTEGER Y /15/, Z/8/ 3. Транслятор ФОРТРАН/ЕС выделит переменной ABODE память (по умолча- нию — REAL * 4). Ошибка этим транслятором не обнаруживается; результат даль- нейшего выполнения программы непредсказуем, поскольку при выполнении указан- ного в задании оператора присваивания будет использован случайный код, содержа- щийся в выделенном для переменной ABODE поле памяти. Транслятор АЛГОЛ-60 подобную ошибку обнаружит: идентификатор ABODE не описан. СПИСОК ЛИТЕРАТУРЫ I. К р и н и ц к и й Н. А., Миронов Г. А., Ф р о л о в Г. Д. Программирование и алгоритмические языки.— М. : Наука, 1975. 2. С а л т ы к о в А. И., М а к а р е н к о Г. И. Программиро- вание на языке ФОРТРАН.— М.: Наука, 1976. 3. Б р и ч 3. С. и др. ФОРТРАН ЕС ЭВМ.— М.: Статистика, 1978.— 264 с.
ОГЛАВЛЕНИЕ Предисловие.................................................... 3 Как работать с пособием........................................ 5 Глава I. Представленние объектов обработки в ФОРТРАНе П о Р ц и я 1. Программа на ФОРТРАНе 6 П о Р ц и я 2. Алфавит ФОРТРАНа 9 По Р ц и я 3. Ключевые слова 11 П о Р ц и я 4. Типы данных 12 П о Р ц и я 5. Константы. Константы целого типа 13 П о Р ц и я 6. Вещественные константы 14 П о Р ц и я 7. Константы повышенной точности 16 П о Р ц и я 8. Имена (идентификаторы) 19 П о Р ц и я 9. Память ЭВМ 20 П о Р ц и я 10. Внутреннее представление объектов в ЕС ЭВМ 22 По Р ц и я 11. Переменные 24 П о Р ц и я 12. Правила записи индексов. Приведенный индекс 28 П о Р ц и я 13. Спецификация массивов 30 П о Р ц и я 14. Объявление DIMENSION 31 П о Р ц.и я 15. Объявления типа 32 П о Р ц и я 16. Объекты целого и вещественного типов .... 33 П о Р ц и я 17. Логические, комплексные и повышенной точности объекты 34 П о Р ц и я 18. Нестандартные данные в ФОРТРАН/ЕС .... 35 П о Р ц и я 19. Объявление типа данных в ФОРТРАН/ЕС . . . 36 П о Р ц и я 20. Объявление IMPLICIT 39 П о Р ц и я 21. Объявление DATA 42 П о Р ц и я 22. Функции и их указатели 46 П о Р ц и я 23. Выражения. Арифметические выражения . . . 49 П о Р ц и я 24. Логические выражения 55 Глава II. Операторы языка ФОРТРАН Порция 25. Бланк ФОРТРАН-программы..................... 62 Порция 26. Оператор присваивания ...................... 67 395
Порция 27. Оператор присваивания (продолжение) .... 68 Порция 28. Логический оператор присваивания................. 73 П о*р ц и я 29. Операторы перехода. Безусловный оператор GOTO. Вычисляемый оператор GOTO............. 75 Порция 30. Оператор присваивания метки ASSIGN. Оператор GOTO по предписанию ................................... 78 Порция 31. Сравнение вычисляемого оператора перехода и оператора перехода по предписанию...................... 80 Порция 32. Условные операторы....................... 82 Порция 33. Условный логический оператор............. 85 Порция 34. Операторы остановки...................... 87 Порция 35. Оператор цикла........................... 89 Порция 36. Вложенные циклы.......................... 94 Порция 37. Правила использования оператора DO...... 96 Порция 38. Оператор продолжения CONTINUE............ 99 Порция 39. Примеры использования оператора DO .... 101 Глава III. Операторы ввода-вывода............................ Порция 40. Общая характеристика операторов ввода-вывода 105 Порция 41. Операторы ввода и вывода......................107 Порция 42. Объявление FORMAT.............................113 Порция 43. Представление данных на внешних носителях 118 Порция 44. Описатели полей формата.........................119 Порция 45. Управление печатью .............................121 Порция 46. Форматы ввода-вывода числовой информации 122 Порция 47. Вывод по формату G..................................127 Ввод-вывод данных комплексного типа .... 128 Порция 48. Масштабный множитель................................129 Порция 49. Форматы ввода-вывода логических и текстовых значений ..................................................131 Порция 50. Дополнительные форматы в ФОРТРАН/ЕС ... 139 Порция 51. Бланк записи исходных данных............142 Порция 52. Вспомогательные операторы ввода-вывода . . . 143 Порция 53. Объявление NAMELIST (ФОРТРАН/ЕС) .... 144 Порция 54. Подготовка данных для ввода-вывода по NAMELIST.......................................................145 Глава IV. Функции и подпрограммы Порция 55. Классы функций и подпрограмм....................149 Порция 56. Имена функций и подпрограмм.....................150 Порция 57. Фактические и формальные параметры..............151 Порция 58. Связь между фактическими и формальными пара- метр а ми ...................................154 Порция 59. Вызов параметров в ФОРТРАН/ЕС...............155 Порция 60. Типы функций................................160 396
Пор циi По р ци j Порции По р ци j П о р ц и 1 Порции П О р ЦИ ! По Р Ц И ! По р ци1 По р ци ! П о р ц и 1 П о р ц и 1 П О р Ц и ! По р ц и । П © р Ц и ! Порция П о р ц и 1 П О р Ц и ! П О р Ц И ! П О Р Ц и ! П о р ц и : П о р ц и : П О р Ц И ! П о р ц и : П о р ц и П о р ц и : П о р ц и ! П о р ц и : П о р ц и ! П о р ц и : Глава П о р ц и : П о р ц и П о р ц и ! 61. Встроенные функции ...................... 62. Внутренние функции ...................... 63. Объявление_.О2МЖМ........................ 64. Соответствие общих блоков................ 65. Помеченные и непомеченные общие блоки . . . 66. Объявление EQUIVALENCE . .*.............. 67. Внешние функции.......................... 68. Связь внешней функции с вызывающим програм- мным модулем ................................ 69. Правила использования внешних функций . . . 70. Пример использования внешних функций . . . 71. Подпрограммы............................. 72. Идентификатор подпрограммы .............. 73. Вызов подпрограмм. Оператор CALL......... 74. Результаты выполнения подпрограммы . . . . 75. Некоторые ограничения на формальные парамет- ры внешних функций и подпрограмм .... 76. Интерпретация в ФОРТРАН/ЕС объектов, задан- ных формальными параметрами ................. 77. Формальные параметры и элементы общих блоков 78. Побочный эффект при вычислении внешних функций ..................................... 79. Передача меток через параметры в ФОРТРАН/ЕС Оператор RETURN ............................. 80. Выполнение подпрограмм в неявном цикле (ФОРТРАН/ЕС) ................................ 81. Источники неопределенности при вызове парамет- ров в ФОРТРАН/ЕС............................. 82. Примеры использования подпрограмм........ 83. Объявление EXTERNAL...................... 84. Косвенное обращение ..................... я 85. Массивы с регулируемыми размерами......... 86. Примеры использования массивов с регулируе- мыми размерами .............................. 87. Объявление ENTRY в ФОРТРАН/ЕС (дополни- тельные точки входа во внешнюю процедуру) . . 88. Примеры использования процедур........... 89. Модуль-блок данных....................... я 90. Структура ФОРТРАН-программы............... . V. /Методика конструирования программ я 91. Головной модуль и вызываемая им внешняя про- цедура ......................................... я 92. Методика использования внутренних функций 93. Внешняя процедура, вызывающая другую внеш- нюю процедуру .................................. 161 163 170 173 175 176 182 187 191 193 194 196 198 199 201 202 204 208 209 212 213 216 218 221 224 226 229 233 237 240 242 244 247
Порция 94. Элемент массива в качестве фактического пара- метра ...........................................249 П.о рци я 95. Идентификатор процедуры в качестве формаль- ного (фактического) параметра ....................................251 Порция 96. Интерпретация объектов памяти.............255 Порция 97. Подпрограммы без параметров...............258 Порция 98. Подпрограммы и внешние функции...........259 Порция 99. Фиксация числа обрабатываемых массивов 260 Порция 100. Вывод графиков.................................262 Порция 101. Анализ прямоугольной структуры (ФОРТ- РАН/ЕС) ....................................................264 Порция 102. Обработка матриц в ФОРТРАН/ЕС (регулиру- мые размеры массивов; спецификация формата, задаваемая в массиве) ......................................267 Порция 103. Особенности использования и преобразования объектов в ФОРТРАН/ЕС ......................................271 Порция 104. Умножение целых чисел с повышенной точнос- тью ........................................................275 Порция 105. Особенности использования текстовых констант в ФОРТРАН/ЕС................................................277 Порция 106. Поразрядная сортировка ........................278 Порция 107. Использование списковых структур...............280 Порция 108. О реализации рекурсивных процедур в ФОРТРАН/ЕС..................................................285 Глава VI. Средства отладки программ в ФОРТРАН/ЕС Порция 109. Предложения отладки...........................292 Порция НО. Взаимодействие пакета отладки с программным модулем...................................................294 Порция 111. Объявление DEBUG........................295 Порция 112. Режимы отладки..........................295 Порция 113. Оператор DISPLAY........................297 Порция 114. Объявление АТ...........................298 Порция 115. Операторы TRACE ON и TRACE OFF .... 299 Порция 116. Подпрограммы DUMP и PDUMP...............299 Порция 117. Подпрограммы SLITE и SLITET.............302 Порция 118. Подпрограмма EXIT.......................303 Порция 119. Особые ситуации.........................304 Порция 120. Подпрограмма DVCHK и OVERFL.............305 Порция 121. Особенности распределения памяти........305 Глава VII. Ввод-вывод с прямым доступом к данным Порция 122. Запоминающие устройства прямого доступа 308 Порция 123. Физические записи.............................309 398
Порция 124. Наборы данных в ФОРТРАН/ЕС 310 Порция 125. Операторы прямого доступа в ФОРТРАН/ЕС 312 Порция 126. Операторы READ и WRITE для файлов прямого доступа 314 Порция 127. Бесформатные операторы чтения-записи при прямом доступе 316 Порция 128. Оператор FIND 316 Глава VIII. ФОРТРАН как элемент ДОС Порция 129. Этапы обработки программ и соответствующие компоненты ДОС 318 Порция 130. Генерация системы 319 Порция 131. Оформление задания 320 Порция 132. Внешние устройства, используемые в ДОС при обработке ФОРТРАН-программ, и их назначение 323 Порция 133. Оператор и директива ASSGN 325 Порция 134. Оператор и директива RESET 326 Порция 135. Управление трансляцией 327 Порция 136. Сообщения об ошибках, обнаруженных трансля- тором . 328 Порция 137. Отладка ФОРТРАН-программ в ДОС ЕС 330 Порция 138. Протокол транслятора 332 П р и л о ж е н и е 1. Таблицы 343 П р и л о ж е н и е 2. Диагностические сообщения трансляторов 360 П р и л о ж е н и е 3. Диагностические сообщения рабочей про- граммы 360 Ответы к заданиям 361 Список литературы 395
Екатерина Логвиновна Ющенко Игорь Александрович Переход Ольга Павловна Платонова Алексей Андронович Ющенко ФОРТРАН Редактор Л. И. Мубаракшина Художественный редактор С. П. Духленко Технический редактор М. С. Чабан Корректор О. А. Савицкая Информ, бланк № 3037 Сдано в набор 24.10.79. Подп. в печать 13.05.80. БФ 06586. Формат 60х841/1в. Бума- га типогр. № 1. Лит. гари. Выс. печать. 23,25 усл. печ. л. 25,78 уч.-изд. л Тн* раж 20 000 экз. Изд. № 4746. Зак. 9—2712. Цена 95 к. Головное издательство издательского объединения «Вища школа», 252054, Киев-54, ул. Гоголевская, 7. Головное предприятие республиканского производственного объединения «Полиграфкнига» Госкомиздата УССР, 252057, Киев-57, Довженко, 3.