Fortran 90 ANSI Standard Fortran 90 является развитием языка Fortran 77, так что программа, написанная на Fortran 77, мо...
17 downloads
538 Views
1MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Fortran 90 ANSI Standard Fortran 90 является развитием языка Fortran 77, так что программа, написанная на Fortran 77, может быть скомпилирована и запущена как программа на Fortran 90. Стандарт Fortran 90 Standard вводит много новых средств для операций над массивами, новые методы спецификации точности, свободный формат исходного кода, рекурсию, динамические массивы и т.д.. Несмотря на то, что весь Fortran 77 включен в Fortran 90, новый стандарт ANSI предполагает, что некоторые средства из Fortran 77 'потеряют ценность'. Потеряют ценность средства, подобные классифицируемым как 'устаревшие' в последовательности ревизий и переносимые в будущие версии языка Fortran. Программы на текущем языке стандарта Fortran 77 могут успешно компилироваться компиляторами Fortran 90 без каких-либо изменений. Тем не менее структура программы на языке Fortran 90 может значительно отличаться от структуры эквивалентной программы на Fortran 77. Программист должен остерегаться смешения двух стилей. В такой же мере компилятор с Fortran 90 требует обеспечения объяснений для сообщений о некоторых кодах несоответствия (несогласования), то есть использование операторов или переменных, которые разрешены сверх множества правил, выходящих за пределы стандарта. Это поможет программисту написать правильный код. Как уже упомянуто, Fortran 90 добавляет к Fortran 77 небольшими средствами преимущества новых вычислений , в частности такого развития как новых важных динамических структур данных введения в параллельные архитектуры Объектно-ориентированные средства Fortran 90 имеет такие Объектно-ориентированные средства как: •абстрактные типы данных -- типы, определенные пользователем; •закрытие данных -- атрибуты PRIVATE и PUBLIC ; •инкапсуляция -- средства модулей и закрытых данных; •наследование и расширение – супертипы, оператор перекрытия и родовые процедуры; •полиморфизм -- пользователь может перекрывать ее с помощью перегрузки родовых программ; •повторное использование - через модули;
Краткий обзор наиболее важных средств Fortran 90 (материал взят из http://www.lahey.com/other.htm).
проекта
Lahey:
http://www.lahey.com/index.html,
Средства расширения языка
75 новых встроенных функций:
Структуры и производные типы
Манипуляции над битовыми
Указатели
Строковые переменные
Объявления свойств Семейство типов
Модули и процедуры
Конструкторы
Интерфейсы
Управление программой
Внутренние процедуры
DO / END DO
Рекурсия
DO WHILE
Необязательные параметры и ключевые слова
Конструкция CASE Другие средства CYCLE, EXIT Стандартная форма исходного текста Массивы Свободная форма исходного текста Управление векторами и матрицами Длинные имена Выражения для массивов Включение файлов Распределяемые (динамические) массивы Операции отношения Автоматические массивы Комментарий в конце подпрограммы Секция (вырезка) массива Fortran 90 в Lahey Конструкция WHERE
Возможности расширения языка Новый язык содержит возможности для пользователя расширять его собственными понятиями, например, для интервальной арифметики, арифметики рациональных или динамических символьных строк. Путем определения новых типов данных или операторов, и перегружаемых операций и процедур (так что вы можете использовать плюс + как символ сложения интервалов, а не только для обычных чисел), мы можем создать пакет (модуль) без использования препроцессора. Мы можем в скором времени ожидать число расширений для различных приложений в форме модулей от различных производителей. Некоторые уже доступны в NAG. Данные Структуры (производные типы) В Фортран раньше не разрешалось использование некоторых типов, определенных пользователем. Теперь это можно делать. Вы можете группировать Ваши данные, используя производные типы. При этом можно комбинировать встроенные типы (включая массивы и указатели). Доступ к компонентам новых типов осуществляется использованием уточнителя, а в качестве разделителя в нем знак процента. (Производные типы известны в VAX Fortran как записи.) Ниже приведен пример TYPE staff_member CHARACTER(LEN=20) :: first_name, last_name INTEGER :: identification, department END TYPE который может быть использован для того, чтобы описывать отдельные единицы. Комбинация индивидуальных единиц может создана таким образом TYPE(staff_member), DIMENSION(100) :: staff Отдельная единица может быть вызвана как staff(number), а поле может быть вызвано как staff(number)%first_name. Вы можете образовать гнездо определений TYPE company CHARACTER(LEN=20) :: company_name TYPE(staff_member), DIMENSION(100) :: staff END TYPE : TYPE(company), DIMENSION(10) :: several_companies Значительно более интересный пример - это разреженная матрица A, имеющаяс более сотни ненулевых элементов, которая может быть специфицирована следующим оператором
TYPE NONZERO REAL VALUE INTEGER ROW, COLUMN END TYPE и TYPE (NONZERO) :: A(100) Вы тогда получаете значение A(10), записав A(10)%VALUE. Присваивание может быть записано как A(15) = NONZERO(17.0,3,7) Для того, чтобы использовать в COMMON определенные пользователем в примере типы, или чтобы безусловно сделать так, чтобы два типа данных, которые выглядят как один и тот же, рассмотривались как идентичные, вы можете использовать оператор SEQUENCE, в последнем случае требуется , чтобы переменная была специфицирована как PRIVATE.
! Еще один пример, использующий производные типы и модули module pipedef type pipe ! определяется новый тип 'pipe', который real diameter ! включает две компоненты типа reals, real flowrate ! компоненту типа integer и компоненту типа character. integer length character(len=10) :: flowtype end type pipe end module pipedef
program main use pipedef ! Связывает с модулем pipedef программу main. type(pipe) water1, gas1 ! объявляет две переменные типа 'pipe'. water1 = pipe(4.5,44.8,1200,"turbulent") ! присваивает значение переменной water1.
gas1%diameter = 14.9 ! присваивает значение gas1%flowrate = 91.284 ! частям переменной gas1. gas1%length = 2550 gas1%flowtype = 'laminar' . . end program з Указатели Указатели позволяют программе вызвать более одной области памяти с одним именем. По сравнению с указателями языка С указатели в Fortran 90 более ограничены, и поэтому легче для отладки и оптимизации. Объекты данных с атрибутами-указателями могут иметь ассоциированную с ними память, выделяемую и возвращаемую, которую можно использовать динамически. Указатели могут быть ассоциированы с другими указателями и с другими объектами, облегчая работу с такими структурами данных как списки и деревья. з Вид семейства Тип семейства дает возможность пользователю запросить, какой встроеннный тип использован базовым для точности и диапазона значений. Это средства среду вычислений. Программисты, которые адресуют свои программы разным машинам, должны иметь дело с различным числом точных цифр. Используя семейство (kind), программист может специфицировать требуемую числовую точность. ! Пример, использующий атрибут KIND и функцию KIND . ! Этот пример потребует от компилятора символьный тип данных kind(2) ! Это допустимо в F90, но не обязательно. program main integer, parameter :: kanji_char_kind = 2 ! Используем атрибут kind, чтобы определить известный kind. character(kind = kanji_char_kind, len=20), dimension(20) :: name
! Используем функцию kind, чтобы определить kind из объекта известного kind. real(kind = kind(0.0d0)) :: pi=3.14159265359d0 open(unit=1, file='names', form='formatted', access='sequential') read(1,10) (name(i), i=1,20) write(*,20) name write(*,30) pi close(unit=1) 10 format(a20) 20 format(1x,t7,a20,t30,a20,t55,a20) 30 format(1x,1p,d18.11) end program з Объявления (декларации, спецификации) Объекты данных могут иметь комбинацию 12 различных атрибутов, таких как POINTER, SAVE, и т.д. Fortran 90 вводит "объектно-ориентированные " объявления, в которых объекты с одинаковыми комбинациями атрибутов могли быть декларированы со всеми их атрибутами в одном операторе. В одной строке могут теперь быть записаны: REAL, DIMENSION (3), PARAMETER :: & a = (/ 0.0, 0.0, 0.0 /), b = (/ 1.0, 1.0, 1.0 /) COMPLEX, DIMENSION(10) :: john Тогда как переменные a и b задают константный вектор из 3 элементов и значения с плавающей точкой 0.0 и 1.0, соответственно, в то время как john задается как вектор типа complex из 10 элементов типа complex, все еще не присвоены значения ни одной переменной. Двойная точность может быть реализована более общим методом, чтобы дать настраиваемую точность, даваемую параметром KIND, для которого точность мы определим полностью для всех типов переменных. INTEGER, PARAMETER :: LP = SELECTED_REAL_KIND(20) REAL (KIND = LP) :: X, Y, Z
Выше приведенные операторы объявляют переменные X, Y и Z как REAL с плавающей точкой с числом десятичных цифр, меньшим 20 с типом данных, называемым LP (где LP стандартное сокращение для LONG PRECISION). з Конструкторы Массив и объекты производных типов данных могут быть инициализированы в операторе объявления. Конструктор может быть использован как константа там, где ожидается массив или производный тип.
IMPLICIT NONE*
Если Вы хотите использовать алгол-принцип спецификации всех переменных, это достигается командой IMPLICIT NONE с явными описаниями типа. Эта стандартизация популярного расширения F77 делает обязательным для всех объектов данных явное объявление. з Управление программой
Программа на FORTRAN 77 была часто спроектирована по блок-схеме. Этот вид проектирования ведет естественно к коду, составленному из фрагментов проверки и ветвления программ, он будет труден для внесения изменений, в частности для увеличения размера программы, он потребует большой отладки и в нем будет очень мало повторного использования. Новые методы проектирования программ включают декомпозицию больших проблем на малые проблемы до тех пор, пока решения не станут тривиальными. Новый стандарт Fortran 90 предоставляет конструкции управления, которые делают более легкими реализацию новых методов проектирования программного обеспечения. В язык включены три новые конструкции для записи цикла. з DO / END DO* END DO заменяет традиционный помеченный оператор завершения CONTINUE для цикла DO. При этом метка в операторе DO не обязательна.
Ниже приводится пример бесконечного цикла, который может быть закончен условным оператором GOTO. name: DO выполняемые операторы END DO name
Обычный оператор цикла DO имеет следующую новую упрощенную форму без номера оператора, name: DO i = целое_выраж_1, целое_выраж_2 , целое_выраж_3 выполняемые операторы END DO name где i так называемая управляющая переменная, и где целое_выраж_3 необязательно. з DO WHILE*
Оператор обеспечивает повторение блока до тех пор, пока условие верно. name: DO WHILE (логическое_выражение) выполняемые операторы END DO name Имя здесь не обязательно, но может быть использовано для следующих циклов в целях индикации, когда нужны итерации, с операторами завершения CYCLE или EXIT. S1: DO IF (X Y ) THEN Z=X EXIT S1 END IF CALL NEW(X) END DO N=0
LOOP1: DO I = 1, 10 J= I LOOP2: DO K =1, 5 L=K N = N +1 END DO LOOP2 END DO LOOP1
В последнем случае конечные значения переменных будут следующими, в полном соответствии со стандартом, I = 11, J = 10, K = 6, L = 5, и N = 50. Именовать цикл не обязательно. Заметим, что этот тип имени ограничивает конструкции цикла DO, CASE или IF...THEN...ELSE...ENDIF. Старые возможности с номерами операторов все еще допустимы , также и в свободной форме. з Конструкция CASE *
Заменяет запутанную конструкцию IF/ELSE IF или вычисляемые GO TO. Делает код более легким для понимания и для записи. Новая команда такова SELECT CASE (выражение) CASE блок-переключатель блок CASE блок-переключатель блок CASE DEFAULT блок по умолчанию END SELECT Типичная конструкция: SELECT CASE(3*I-J) ! управляющая переменная это 3*i-j CASE(0) ! для значения нуль : ! вы вычисляете код здесь
CASE(2,4:7) ! для значений 2, 4, 5, 6, 7 : ! вы вычисляете код здесь CASE DEFAULT ! и для всех остальных значений ! вы вычисляете код здесь : ! END SELECT Если CASE DEFAULT отсутствует и не находится альтернатива, вычисление продолжается прямо с оператора, за END SELECT без выдачи сообщения об ошибке. Другой пример: INTEGER FUNCTION SIGNUM(N) SELECT CASE (N) CASE (:-1) SIGNUM = -1 CASE (0) SIGNUM = 0 CASE (1:) SIGNUM = 1 END SELECT END
! Еще один пример использования конструкции CASE ! (c)Copyright 1993, Lahey Computer Systems, Inc. All RIGHTS RESERVED ! Test: case1 ! ! Legal - все возможные типы case-значение-диапазон для integer*4 ! integer*4 i integer n /9/, a (9) /1,-11,81,31,41,51,61,71,25/ do 50 j = 1, n i = a (j) select case ( i ) case (1) print*,"should be 1, is ",i
case ( : -11 ) print*,"should be 11 or less, is ",i case ( 81 : ) print*,"should be 81 or greater, is ",i case ( 31 : 32 ) print*,"should be 31 or 32, is ",i case ( 41, 50:51, 61 :61, 71:72 ) print*,"should be 41, 50, 51, 61, 71, or 72, is ",i case default print,"should be any other number, is ",i end select 50 continue end з CYCLE, EXIT*
Прерывает отдельную итерацию цикла DO или весь цикл прежде чем завершится повторяемый блок. Уменьшает потребность в GO TO. з Конструируирование имен Names
Вы можете конструировать метки для IF, DO, и CASE, чтобы сделать код более читаемым и возможными CYCLE или EXIT к внешним уровням следующих циклов. з Массивы
Управление векторами и матрицами Это одна из самых важных частей нового стандарта. Определение массива порождает образ (shape), задаваемый числом его измерений (рангом) и протяженностью по каждому измерению. Два массива соответствуют друг другу, если они имеют один и тот же образ. Операции как правило поэлементные. Ранг массива не есть ранг матрицы в математическом смысле! REAL, DIMENSION(5,20) :: x, y REAL, DIMENSION(-2:2,20) :: z : z = 4.0*y*sgrt(x) REAL, DIMENSION(6) :: B REAL, DIMENSION(2,3) :: C B = (/ 1, 1, 2, 3, 5, 8 /) C = RESHAPE( B, (/ 2,3 /) ) где первый аргумент встроенной функции RESHAPE дает значение, а второй аргумент дает новый образ. Два дополнительных, но необязательных аргумента возможны у этой функции. Вышеприведенное можно записать более кратко с помощью атрибута PARAMETER. В первой строке ниже атрибут PARAMETER принудительный (если присваивание может быть выполнено в этой самой строке), но во второй строке он не обязателен. Атрибут PARAMETER означает, что неизвестное может не быть заменено во время выполнения программы. REAL, DIMENSION(6), PARAMETER :: B = (/ 11, 12, 13, 14, 15, 16 /) REAL, DIMENSION(2,3), PARAMETER :: C = RESHAPE( B, (/ 2, 3 /) ) Некоторые операторы для реальных параллельных вычислений не включены в Fortran 90. См. HPF. з Выражения для массивов
Компилируемый цикл DO может быть теперь свернут в один оператор. Используем целиком массивы в выражениях или как аргументы встроенных функций.
! Пример программы, использующей атрибуты внутри типа stmt, и выражение для массива.
program main ! Объявляем dim1 как parameter, со значением 5. integer, parameter :: dim1=5 ! Объявляем res, x, & y как 5-элементные массивы, и инициализируем x & y. real, dimension(dim1) :: res, x=(/1.,2.,3.,4.,5./),y=(/5.,4.,3.,2.,1./) ! Прибавим соответствующие элементы из x & y, и присвоим res. res = x + y ! Все элементы из res будут равны 6. write(*,10) res 10 format(1x,5(f3.0,4x)) end program з Распределяемые (динамические) массивы *
Память для массивов может распределяться во время выполнения. Fortran 90 содержит четыре различных способа для обеспечения динамического доступа. Первый путь - использование указателей для вектора и матрицы. Второй способ - использование распределяемого массива, то есть с помощью операторов ALLOCATE и DEALLOCATE вы получаете и возвращаете область памяти для массива с типом, образом и именем (и возможно и другими атрибутами), которая специфицирована заранее с дополнительным атрибутом ALLOCATABLE. REAL, DIMENSION(:), ALLOCATABLE :: x : Allocate(x(N:M)) ! N и M целые выражения. : x(j) = q ! Некое присваивание массива. CALL sub(x) ! Использование массива в подпрограмме. : DEALLOCATE (x)
Освобождение происходит автоматически (если атрибут SAVE не был задан), когда достигается RETURN или END в этой программной единице. Третий вариант - это автоматический массив, это почти такой же как в старом Fortran, где x в примере ниже может быть в списке аргументов. Этого больше не требуется. (см. ниже). SUBROUTINE sub (i, j, k) REAL, DIMENSION (i, j, k) :: x Размеры для x задаются целыми величинами в вызове программы. Наконец "массив с неявным образом", где память определена в вызове процедуры и для которой даны только тип, ранг и имя. SUBROUTINE sub(a) REAL, DIMENSION (:,:,:) :: a Заметим, что в одном из примеров компилятор на Alfa не передал образ в подпрограмму. з Неявный массив образов (форм) Формальные массивы могут взять форму своего образа (своей формы) из соответствующих фактических параметров (см. замечание выше). з Автоматические массивы Массивы в процедуре имеют размеры, определяемые значениями переменных.
! Пример использования автоматических и неявных образов массивов program main integer :: dim=8 real :: a(4)=(/44.3,77.5,88.21,14.35/) call sub1(a,dim) end program subroutine sub1(x,dim1)
integer dim1 real x(:), b(dim1) ! Объявляет 'x' с тем же самым образом как у фактического аргумента 'a' . . ! Объявляет 'b' с 'dim1' элементами. . end subroutine sub1 з Секция (вырезка) массива Вы можете указать часть массива. Допустим, массив A специфицирован следующим образом REAL, DIMENSION(-4:0, 7) :: A Тогда A(-3, :) указывает второй ряд матрицы, тогда как A(0:-4:-2, 1:7:2) указывает (в обратном порядке) каждый второй элемент в каждой второй колонке. Так же как переменные могут образовывать массивы, так и константы могут образовывать массивы . Вырезки позволяют пользователю получить большее управление массивом путем использования тройки индексов и векторных индексов.. з Конструкция WHERE Конструкция позволяет задавать условия выполнения действий над массивами. В следующем примере мы хотим защититься от отрицательных элементов X. Это задано следующей конструкцией WHERE ( x = 0.0 ) z = 4.0*y*sgrt(x) ELSEWHERE z = 0.0 END WHERE Заметьте, что ELSEWHERE записано одним словом! Сравните с функцией SUM (конец следующей секции.
Сумма положительных значений членов массива записана и так
SUM ( X, MASK = X .GT. 0.0) Такой оператор не может быть использован для того, чтобы избежать деления на ноль в случае суммирования 1/X, что есть слово-маска для определения, какие номера включены в суммирование, и либо ни одно из двух определенное значение не может быть вычислено или нет. Но в последнем случае Вы можете использовать конструкцию WHERE. Присваивание маскированного массива позволяет пользователю сделать присваивание , базирующееся на маске по всему массиву.
! Пример использования распределяемого массива и конструкции where. program main integer number_of_students, number_of_tests ! Объявление массива 'scores' и 'letter_grade' как распределяемых allocatable и 2 мерные. integer, allocatable, dimension(:,:) :: scores character(len=1), allocatable, dimension(:,:) :: letter_grade open(unit=1,file='grades',form='formatted',access='sequential') read(1,10) number_of_students, number_of_tests ! Распределение памяти для массивов. allocate (scores(number_of_students,number_of_tests)) allocate (letter_grade(number_of_students,number_of_tests)) read(1,10) ((scores(i,j),i=1,number_of_students), j=1,number_of_tests) close(1) ! Используется конструкция where для присваивания значений массиву 'letter_grade' , ! основанному на значениях массива 'scores'. where(scores >= 90) letter_grade = 'A' where(scores >= 80 .and. scores < 90) letter_grade = 'B' where(scores >= 70 .and. scores < 80) letter_grade = 'C'
where(scores >= 60 .and. scores < 70) letter_grade = 'D' where(scores < 60) letter_grade = 'F' write(*,*) letter_grade deallocate(scores,letter_grade) ! Освобождение памяти, использованной массивами. 10 format(i3,t5,i3) end program з Встроенные
В Fortran 90 включены 75 новых встроенных функций: В другом руководстве сказано, что Fortran 90 включает около 100 встроенных функций и очень много встроенных подпрограмм. Ряд функций позволяет иметь определенными атрибуты и допустимые параметры среды программирования, такие как наибольшее положительное число целое и с плавающей запятой, как доступ к системным часам. Включен генератор случайных чисел. Все встроенные функции и подпрограммы описываются в соответствующем разделе. Функция Inquiry Находит в программе во время выполнения характеристики массива или статус указателя. Находит в компиляторе характеристики типа данного. Функция Transfer Функция TRANSFER рассматривает сущность одного данного так, как если бы оно было типом другого данного. Она позволяет определенную физическую область передать другой области без конверсии типа. Array Intrinsics Различные новые функции уменьшения (преобразования) массива (например, SUM), перемножение векторов и матриц, конструирование массива (SPREAD), преобразование образа, сдвиг, транспонирование (TRANSPOSE), и указание значений максимума и минимума. Функция SPREAD обсуждается более полно в решении примера (11.1). см.Summary.
Границы массива Некоторые встроенные функции достаточны, чтобы определить фактические границы массива по измерениям. DO (i = LBOUND(a,1), UBOUND(a,1)) DO (j = LBOUND (a,2), UBOUND (a,2)) DO (k = LBOUND(a,3),UBOUND (a,3)) где LBOUND дает нижнюю границу размерности и UBOUND дает ее верхнюю границу. з Манипуляции над битовыми* Установка, очистка, тестирование и сдвиг битов в целых данных. Выполняют логические AND, OR, исключающее OR и дополнение. Тип данных "bit" не включен в стандарт, но имеются допустимые варианты битовых операций над целыми согласно более ранним military стандартом MIL-STD 1753. Дополнительно включены битовые, восьмеричные и шестнадцатиричные константы, так же возможность использовать их в операциях ввода/вывода с помощью трех новых спецификаций формата. В операторе DATA вы можете использовать присваивание. B'01010101010101010101010101010101' для битовых, O'01234567' для восьмеричные и Z'ABCDEF' для шестнадцатиричных чисел. з Строковые переменные Величины CHARACTER могут быть расширены до включения пустой строки a = '' и присваивание частично перекрывающихся строк теперь разрешено a(:5) = a(3:7)
Новая встроенная функция TRIM, удаляющая заключительные пробелы, является важным добавлением. Вы можете теперь делать выбирать между апострофом ' и двойной кавычкой " в качестве ограничителя строки. К числу тех же средств относится возможность использования двойной кавычки для представления апострофа внутри строки.,и использования апострофа для представления двойной кавычки внутри строки. -----------------------------------------------------------------------з Модули и процедуры
Модули это коллекции данных, определений типов определений процедур, которые дают большую защищенность и общее замену понятия COMMON. Модули занимают важное место в том, чтобы положить вещи для совместного использования. Этот новый вариант программной единицы может содержать данные, процедуры, определения производных типов и блоки интерфейса (и даже блоки common), все, что может быть включено в единицу scoping с посощью оператора USE. Модуль может также быть использован в скрытом коде процедуры от клиентов . Один и тот же модуль может быть использован во многих программах. з Интерфейсы В соответствии с предложениями Metcalf и Reid (1990, 1992) в Фортран 90 введено требование явного интерфейса. Он выглядит так INTERFACE SUBROUTINE SUB(A) REAL, DIMENSION (:,:,:) :: A END SUBROUTINE SUB END INTERFACE Если Вы забыли INTERFACE или если Вы имеете ошибочный интерфейс, то Вы обычно получаете "ошибку сегментации", это означает, что программная единица может быть отсутствует. Компилятор может быть использован для проверки результатов если характеристики процедур доступны в явном интерфейсе. Тело интерфейса, определенного пользователем, выглядит очень похоже на оператор определения функции и ассоциируется с определениями. Компилятор знает интерфейс с каждой определенной процедурой внутри программной единицы. С интерфейсом компилятор будет проверять характеристики результата функций, с которым ожидаются при вызове и проверке характеристик каждого аргумента с которыми ожидается процедура.
Программисты общих (родовых) процедур могут использовать общие процедуры (процедуры с одним и тем же имененм) с помощью использования интерфейсного блока, чтобы проверить информацию для определения, какую процедуру вызвать. Специальная процедура чтобы быть вызываемой, использующая вид, тип и ранг (категорию) аргументов.
! Пример использования общих процедур module procedure_def ! Опрелить общий интерфейс 'force' для специальных функций ! 'real_force' and 'double_force'. interface force ! Объявляет функции и подставляемые типы аргумента. function real_force(mass, accel) result(force) real force, mass, accel end function real_force function double_force(mass, accel) result(force) double precision force, mass, accel end function double_force end interface end module program main use procedure_def ! Ассоциирует procedure_def с main. real rmass, raccel, rforce double precision dmass, daccel, dforce data rmass/2401.0/, raccel/9.81245/ data dmass/2401.0d0/, daccel/9.81245d0/
! Вызывает функцию 'force'. Компилятор реализует первый ! в 'real_force', и второй в 'double_force'. rforce = force(rmass, raccel) dforce = force(dmass, daccel) write(*,'(1x,1p,e16.9,t25,d16.9)') rforce, dforce end program ! Фактические функции выполняемы, когда сделан вызов 'force'. function real_force(mass, accel) result(force) real force, mass, accel force = mass*accel end function real_force function double_force(mass, accel) result(force) double precision force, mass, accel force = mass*accel end function double_force з Внутренние процедуры Внутренние процедуры делают более легкой организацию кода, который использован только в одном месте и уменьшает число внешних подпрограмм, которые необходимо знать программисту. Программная единица и процедуры модуля могут содержать свои собственные внутренние подпрограммы и функции. Интерфейс этих внутренних процедур известен из содержащую программную единицу. з Рекурсия*
Рекурсия стандартизована в 90. Если процедура должна вызываться рекурсивно, даже косвенно, это должно быть объявлено ключевым словом RECURSIVE . Например,
RECURSIVE FUNCTION factorial (n) RESULT (fac) Должна иметь возвращаемый результат, когда задано имя величины со спецификацией RESULT. з Параметры необязательные и ключевые слова Подпрограммы могут вызываться с параметрами, сопровождаемыми ключевыми словами, можно использовать параметры по умолчанию SUBROUTINE solve (a, b, n) REAL, OPTIONAL, INTENT (IN) :: b Может быть вызвана с помощью оператора CALL solve (n = i, a = x) Где два аргумента заданы с ключевыми словами вместо позиционных и где один из трех имеет значение по умолчанию. Если SOLVE внешняя подпрограмма, то она требует использования блока INTERFACE в вызывающей программе. Как видно из приведенного, необязательные аргументы с ключевым словом добавляются свободно при вызове подпрограммы или функции. В FORTRAN 77, Вы были обязаны указывать каждый аргумент. В Fortran 90, аргументы могут быть необязательными и их порядок произволен. Имена подставляемых аргументов (аргументов с ключевыми словами) те, которые использованы в вызове процедуры для разрешения связей между фактическими и подставляемыми аргументами. Новые встроенные функции позволяют процедуре определить, какие аргументы представлены в списке фактических аргументов. з Ввод
В Фортране 90 оператор NAMELIST может использоваться среди спецификаций. В примере ниже list2 это имя списка, a и b переменные типа real, i переменная типа integer . NAMELIST /list2 / a, i, x : READ (unit, NML = list2) которым нужно передать исходные данные следующего вида, но все переменные не могут быть заданы и он могут быть заданы в любом порядке.
&list2 X = 4.3, A = 1.E20, I = -4 /
-----------------------------------------------------------------------з Другие средства
Стандартная форма исходного текста
Комметарии вводятся с помощью восклицательного знака. Множество операторов на одной строке разделяются с помощью точки с запятой ; з Свободная форма исходного текста
Колонки не имеют никакого особого значения, важны пробелы, продолжение специальный символ в конце строки, комментарии вводятся в любой строке с помощью восклицательного знака. Множество операторов на одной строке разделяются с помощью точки с запятой ; . . Строка продолжения начинается с симоала & (амперсанд). Строки могут иметь более 132 символов, позволяются более длинные имена и более абзацные отступы для удобства чтения. з Длинные имена *
Максимальная длина 31 символ в обеих формах. Символы подчеркивания внутри имени разрешены. з Включение файлов *
Строка INCLUDE стандартизована. INCLUDE может быть использовано для включения из внешнего вида. Указывается полное имя файла, включаемого в фортран-программу. Рекурсия для оператора INCLUDE не разрешена. з Операции отношения *
Операции, подобные .LT. и .GT. могут быть заменены их математическими символами < и >, а также. < >= /=
.GT. .GE. .NE.
Пробел - значимый символ
Пробел в свободной форме записи является значимым символом. Команды, подобные ENDIF и GOTO могут быть записаны как END IF или GO TO, но не EN DIF или GOT O. Чтобы допустить значимые пробелы в старой (фиксированной ) форме исходного кода не будет возможно, в этом случае допустимо написать END в следующем виде E
N
D
з
Комментарий в конце подпрограммы
Как во многих типах алголо-подобных языков слово END может быть составлено с именем подпрограммы или функции, например, END FUNCTION GAMMA. з Fortran 90 в Lahey
Эта система объединяет проект победившего в конкурсе Fortran -компилятора с технологией фирмы Intel для построения высоко оптимизированного кода. Она оптимизирована для 386, 486, Pentium PC и полной реализации стандарта Fortran 90.
Более подробная информация
Если Вы заинтересованы в более глубоком и детальном знании Fortran 90, авторы рекомендуют переход на Fortran 90 Джеймса Кернигана (James Kerrigan). Вы можете купить эту книгу прямо у нас за $27.95 плюс $3.00 пересылка и вручение. REFERENCES Adams, Jeanne C., Walter S. Brainerd, Jeanne T. Martin, Brian T. Smith, and Jerrold L. Wagener. Fortran 90 Handbook. New York: McGraw-Hill, 1992. Baker, Steven. "Modernizing Fortran." Software Development November 1993, International Standards Organization, ISO/IEC 1539: 1991 (E). The International Fortran Standard. Kerrigan, James F. Migrating to Fortran 90. Sebastopol: O'Reilly & Associates, 1993. Metcalf, Michael and John Reid. Fortran 90 Explained. New York: Oxford University Press, 1990. *These features are already contained in Lahey's FORTRAN 77 language sytems, F77L and F77L-EM/32 . Описание Фортрана 90 разбито на разделы: О компиляции с (compilat_rus.html)
языка
Фортран
90 Вложенность конструкций Структура программы
Соглашения о кодировании Порядок операторов Объекты данных Синтаксис программы Main Переменные Формат размещения программы Спецификации или объявления Программные единицы Виды KIND Процедуры Арифметические операторы Родовые единицы Комментарии Модули Символьный тип Ввод-вывод Производные типы данных
Операции отношения
Интерактивный ввод-вывод
Логические выражения
Простой ввод-вывод
Сравнение символов
Форматированный ввод-вывод
Массивы (термины)
Редактирование ввода-вывода
Спецификации массива
Оператор Namelist
Вырезки (Сечения) массива
Списки ввода-вывода
Векторные указатели
Ввод-вывод без продвижения
Память для массивов
Файловый ввод и вывод
Присваивание массивов
Номер устройства
Массивы нулевого размера
Операторы READ and WRITE
Массивы переменных типов
Оператор OPEN
Инициализация массивов
Оператор CLOSE
Оператор WHERE
Оператор INQUIRE
Встроенные функции для массивов
Память для массивов
Условные операторы
Динамические массивы
Операторы управления
Распределяемые массивы
Циклы
Указатели для массивов Еще примеры
Компиляция и выполнение Компиляция После как программа на Fortran 90 спроектирована и ее исходный текст записан в файл (обычно с суффиксом .f90, а для Альфа с расширением .f), то следующим шагом является компиляция, инициализируемая командой f90 программы)
filename.o
filename.f
(для
создания
однопроцессорной
или vf90 filename.o filename.f (для создания многопроцессорной программы) типичный запуск такой vf90 -O0 -o $1.o $1.f -lm Каждая из этих команд вызывает компилятор, программу перевода исходного кода в промежуточный ассемблерный код и далее в машинный (объектный) код. Компилятор проверяет синтаксис операторов в соответствии со стандартом и семантикой операторов. Этот шаг генерирует версию объектного кода, которая сохраняется в другом файле, обычно с тем же именем, но с другим расширением (обычно .o в системе UNIX). Связывание (редактирование связей ) Редактор связей инициализируется в системе Альфа командой fld filename filename.o Простой вариант такой fld -o filename filename.o Он выполняет включение некоторого кода, который требуется, из библиотек или других предваритеьно прокомпилиованных файлов. Он генерирует версию выполняемого кода, которая снова запоминается в файле, расширение которого не создается (в системе UNIX по умолчанию это имя a.out) Для трансляции и загрузки можно создать bat. файл, например, такой vf90b.bat vf90 -O0 -o $1.o $1.f -lm fld -o $1 $1.o Наличие такого файла вызова позволяет запускать компиляцию и редактирование связей командой vf90b.bat filename Выполнение В однопроцессорном варианте инициализируется путем ввода имени выполняемого файла, что приводит к запуску программы. Во время выполнения программа может потерпеть аварию, если происходят ошибки выполнения Как и в при использовании других компиляторов, логические ошибки не могут
быть проверены компилятором и они зависят от программиста, находящего и удаляющего их. Единственный путь состоит в новых и новых тестированиях с данными, для которых известен результат. Нужно рассмотреть все возможные варианты исходных данных. Предварительная забота об этом должна быть осуществлена во время начального проектирования программы. Идентификация ошибок на фазе проектирования дешевле, чем на более поздних стадиях. Для многопроцессорной задачи перед ее запуском должен быть создан паспорт с помощью команды madd. В паспорте задается имя файла, созданного загрузчиком, имя программы в program (его следует заканчивать символом "подчеркивание"), имена каталогов, где размещается абсолютный модуль, имя каталога, где размещаются файлы ввода-вывода. А также запрашиваются сведения о предполагаемом времени решения, числе требуемых процессоров и числе перезапусков задачи по аварии. Все эти сведения вводятся в ответ на запросы системы, которые появляются после ввода команды. madd Затем задача запускается командой run
Примеры Приведем примеры запусков компилятора f90 на Альфа Команда f90 ax.f приводит к компиляции файла ax.f, созданию выполняемого файла a.out. Оптимизацию компилятор проводит по умролчанию по умолчанию (см. опиции компилятора).
Команда f90 -o abc ax.f bx.f cx.f использует флаг -o для именования выполняемого файла именем abc и компилирует файлы ax.f90, bx.f90, и cx.f90 как одну программу. Межпроцедурная оптимизация распространяется на ax, bx, и cx. Создается объектный файл abc.o и выполняемый файл *abc.
Команда
f90 -c ax.f bx.f cx.f использует флаг -c для поддержания связи и изготовления индивидуальных объектных файлов ax.o, bx.o, и cx.o. Межпроцедурная оптимизация не проводится. Команда f90 -c -o abc.o ax.f bx.f cx.f использует флаг -c для поддержания связи и флаг -o для создания единственного объектного файла abc.o. Межпроцедурная оптимизация проводится. Сведения о трансляции с помощью vf90 и запуске многопроцессорных программ смотри в соответствующем разделе.
Соглашения о записи кода В этих заметках все примеры кода написаны в стиле 'typewriter' , то есть PROGRAM hi ! вывод сообщения WRITE(*,*) 'Hello World!' END PROGRAM hi Соглашения о записи кода состоят в том, что • • • • •
Все ключевые слова и имена встроенных процедур (эти команды и функции есть часть стандарта) набираются на верхнем регистре, все остальное на нижнем Чтобы помочь чтению кода тела модуля программы, с отступом печатаются блоки INTERFACE, блоки DO , блоки IF , блоки CASE и т.д. Имя программы, подпрограммы или функции включается в оператор конца END В операторе USE фраза ONLY использована для явного документирования всех объектов, которые доступны из этого модуля В операторе CALL и вызове функции ключевое слово аргумента всегда используется для необязательных аргументов.
Объекты данных Говоря об объектах данных, будем иметь ввиду •Встроенные типы •Литеральные константы •Неявноые типы •Опреления численных и логических
•Определение символьных •Константы (Параметры) •Инициализация Переменные
В разделе объясняется смысл понятия "переменная" и правила задания идентификаторов: составляются из букв, цифр, возможно подчеркивание, большие и малые буквы считаются эквивалентными. Переменные величины хранятся в памяти, идентификатор дает название тому месту в памяти, где значения хранятся, с переменной соотносится значение (число, текст, другие значения), способ представления значений в памяти и размер памяти, требуемый для размещения значения, зависит от типа переменной, тип определяется специальным оператором или по умолчанию (см. далее). В примерах текстов будут использоваться большие буквы для зарезервированных слов и идентификаторов, малые - для объектов пользователя. В качестве примера можно привести следующие значения переменных 7 96.4 3.14159 с именами переменных: daysinweek temperature pi Тип переменных задается спецификацией типа. Имеется несколько форм численных данных, а именно:
Целые Могут иметь только дискретные значения (такие как. -3124, -960, 10, 365, и т.п..)
Вещественные Могут иметь дробную часть (такие как 10.3, -8.45, 0.00002, и т.п..) и обычно имеют больший диапазон возможных значений, чем целые Комплексные числа Имеют вещественную и мнимую части (например, 3-2i, -5+4i, и т.п.).
Целые более точны для дискетных значений и быстрее обрабатываются, но вещественные нужнее для многих вычислений. Комплексные нужны для некоторых научных приложений. Иногда программы на фортране требуют и других типов данных. Отдельные буквы, слова и фразы могут быть представлены символьным типом, тогда как логические значения `true' и `false' представляются логическим типом. Наконец, необходима возможность явно указывать значения величин, которые называют литеральными константами, например 3.14159. Соглашения об именах В программах на Фортране имена переменных должны соответствовать соглашению об именовании. Это соглашение разрешает длину имени от 1 до 31 алфавитно-цифровых символа - сформированных из 26 доступных букв: a...z; и 10 цифр 0...9; и символа подчеркивания _ - при этом первым символом должна быть буква. Заметим, что бльшие и малые буквы считаются неразличимыми и считаются эквивалентными. Таким образом имена name, Name, NaMe и NAME все ссылаются на один и тот же объект. В отличие от некоторых языков программирования, в которых определенные слова зарезервированы и могут использоваться программистом только в определенном смысле и контексте, Fortran не имеет таких ограничений. Тем не менее программист должен следить, когда при именовании переменных делается попытка использовать любые слова, входящие в язык. Правильные имена переменных: x, x1, mass, cost, day_of_the_week
Правильные имена переменных (но не используйте!): real, integer, do, subroutine, program
Неправильные имена переменных : ten.green.bottles, 1x, a thing, two-times, _time
Спецификации или объявления Все переменные, использованные в программе, должны иметь ассоциированные с ними типы данных, такие как REAL, INTEGER или COMPLEX, которые обычно идентифицированы в начале прогаммы. Они называются объявлениями или спецификациями переменных, например: REAL :: temperature, pressure INTEGER :: count, hours, minutes Объявляет 5 переменных, две их которых имеют значения, являющиеся вещественными числами, и три имеют целые значения. Оператор объявления переменных может быть использован для присваивания начальных значений объявленным переменным. Если начальное значение не задано переменной, она не может быть принимать никаких значений до тех пор, пока не будет присвоено с помощью оператора присваивания. REAL :: temperature=96.4 INTEGER :: days=365, months=12, weeks=52 В общей форме объявление переменной: тип [,атрибуты...] :: список переменных где тип один из встроенных типов данных: INTEGER REAL COMPLEX CHARACTER LOGICAL
А атрибут ... необязательный список "ключевых слов", каждое отделяется запятой, ключевые слова используются для определения свойств переменных:
ALLOCATABLE INTENT(...) PARAMETER PUBLIC DIMENSION(...) INTRINSIC POINTER SAVE EXTERNAL OPTIONAL PRIVATE TARGET
CHARACTER и LOGICAL типы данных, обсуждаемые в отдельном разделе. Атрибуты введены как требуемые к ним заметки. Параметры (Parameters) Термин параметр в Фортране вводит в некоторое заблуждение. Он относится к значению, которое будет заменено во время выполнения программы. Например, программист может хотеть значение pi сделать неизменяемым программой. Тогда pi может объявлено: REAL, PARAMETER :: pi=3.141592
REAL специфицирует тип данного; атрибут PARAMETER в дальнейшем определяет переменную pi. Всем параметрам должны быть даны значения в операторе их объявления (в нашем случае 3.141592). Параметры могут быть определены для других типов данных, например:
INTEGER, PARAMETER :: maxvalue=1024 INTEGER, PARAMETER :: repeatcount=1000 Считается ошибкой попытка переопределения значения параметра в ходе выполнения программы.
Неявные объявления Фортран 90 разрешает тип переменных real и integer объявлять неявно без соответсвующего оператора объявления. Это свойство неявного объявления обеспечивает преемственность с более ранними определениями языка Фортран, но может создавать проблему
программирования при неосторожности. Можно отключить это свойство с помощью оператора: IMPLICIT NONE В начале каждой программы. Это заставит программиста объявлять все переменные, которые использованы в программе, чтобы не приводить к ошибкам во время компиляции. Явное объявление типов позволяет вместе с определениями типов задавать начальные значения. При неявном описании начальная буква имени определяет тип целый для имен, начинающихся на буквы I, J, K, L, M и N ; и тип вещественный для имен, начинающихся на буквы от A до H и от O до Z. KIND
Каждый тип данных имеет одно или более значений параметра типа KIND, связанного с ним. Типы данных с различными значениями KIND используют различное число байтов для запоминания информации. Это означает, что числовые типы данных с различными параметрами типом KIND имеют различный диапазон допустимых значений и/или различного уровня числовой точности. Например, компилятор NAG F90 использован для развития этого курса, обеспечившего три значения параметра типа KIND для типа INTEGER (KIND=1, 2 или 3); 3 являлось по умолчанию. Другие компиляторы или компилятор NAG F90 в различных системах могут поддерживать различные значения KIND. Переменные объявлены с желаемой точностью с помощью использования атрибута KIND: тип (KIND = kind_type_value) [, атрибуты...] :: список переменных Например: INTEGER :: a ! по умолчанию KIND=3 INTEGER(KIND=3) :: b ! по умолчанию INTEGER(KIND=1) :: c ! ограниченная точность -127