Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Fortran 90. ANSI Standard.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
861.18 Кб
Скачать

Использование модуля

Ниже пример очень простой главной программы для тестирования интервальной арифметики . Он из файла interval.f90 или intv.f90.

USE INTERVAL_ARITHMETICS

IMPLICIT NONE

TYPE (INTERVAL) :: A, B, C, D, E, F

A%LOWER = 6.9

A%UPPER = 7.1

B%LOWER = 10.9

B%UPPER = 11.1

WRITE (*,*) A, B

C = A + B

D = A - B

E = A * B

F = A / B

WRITE (*,*) C, D

WRITE (*,*) E, F

END

 

Запуская эту программу на компьютере Sun с компилятором NAG получили следующий результат на выводе:

 

% f90 interval_arithmetics.f90 interval.f90

interval_arithmetics.f90:

interval.f90:

% a.out

6.9000001 7.0999999 10.8999996 11.1000004

17.7999992 18.2000008 -4.2000003 -3.7999997

75.2099991 78.8100052 0.6216216 0.6513762

% exit

 

Мы компилировали программу компилятором f90, и счетная программа была автоматически названа a.out. Прямо с выше приведенным (первый модуль) компиляция работала с SunSoft и компилятором Digital compilers!

Я

PRIVATE и PUBLIC

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

PRIVATE

PUBLIC :: VAR1

Объявляют все переменные локальными, но VAR1 глобальный. Заметим, что оба понятия (PUBLIC и PRIVATE) могут быть даны как оператор, например

 

INTEGER :: IVAR

PRIVATE :: IVAR

 

Или как атрибут

INTEGER, PRIVATE :: IVAR

Я

Процедуры

Описание всех сторон понятия "процедура" включает следующие разделы

 

Фактические и формальные параметры

Переменные в процедуре

Параметры процедур

Внутренние процедуры

SAVE

Объекты допустимого образа

Внешние процедуры

Локальные объекты

Вид параметра (атрибут INTENT)

Подпрограммы и функции

Соответствие параметров

Ключевые параметры

Subroutine

Правила области действия

Необязательные параметры

Function

Связь с хозяином (Host) - глобальные данные

Процедуры в качестве параметров

 

Блок взаимодействия

Рекурсия

 

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

procedure name [(argument list)]

[specification statements]

[executable statements]

...

[CONTAINS

internal procedures]

END procedure [name]

 

Где вместо procedure может быть одно из слов SUBROUTINE или FUNCTION.

 

Имеется некоторое различие типов процедур:

 •Internal - внутри другой программной единицы

 •External - внешняя (возможно на языках, отличных от Fortran 90)

 •Module - размещаемая внутри модуля.

 

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

 

CALL name [( список параметров )]

 

result = name ( [список параметров] )

 

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

 

Из процедур могут быть созданы их множества. Существуют

 •встроенные (их в Fortran 90 имеется 113),

 •библиотеки, напрмер, NAg fl90 Numerical Library has 300+, BLAS, IMSL, LaPACK, Uniras

 •модули, много свободно распространяемых, см. WWW.

 

Библиотечные процедуры обычно работают быстрее, даже быстрее чем встроенные!

Я  

 

Фактические и формальные параметры

 

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

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

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

 •Пример подпрограммы, которая измененяет значения одного или более своих параметров:

 REAL, DIMENSION(10) :: a, c

. . .

CALL swap( a,c )

 

SUBROUTINE swap( a,b )

REAL, DIMENSION(10) :: a, b, temp

temp = a

a = b

b = temp

END SUBROUTINE swap

 

Подпрограмма swap обменивает содержимое двух массивов типа real. (то есть значения одного массива становятся значениями другого массива)

 

•Пример функции для генерации одного результата, использующего ее параметры (аргументы):

 

REAL :: y,x,c

. . .

y = line( 3.4,x,c )

 

FUNCTION line( m,x,const )

REAL :: line

REAL :: m, x, const

line = m*x + const

END FUNCTION line

 

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

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

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

 Я

Внутренние процедуры

 

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

 

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

 

PROGRAM outer

REAL :: a, b, c

. . .

CALL inner( a )

. . .

CONTAINS

 

SUBROUTINE inner( a ) ! доступна только для outer

REAL :: a ! передается как параметр

REAL :: b=1.0 ! переопределяется

c = a + b ! c соотносится с хозяйской переменной

END SUBROUTINE inner

 

END PROGRAM outer

 

 

Программа outer содержит внутреннюю подпрограмму inner. Заметим, что переменные определены у единицы-хозяина и снова переопределены во внутренней подпрограмме. В примере, не смотря на то, что a, b и c определены в outer:

 

•Значение a передается как параметр, переопределяемая переменная (формальный параметр), также называемой a. Передаваемое значение то же самое, что и программе outer, переменные a в outer и inner это различные объекты

 

•Подобно a, переменная b переопределена в подпрограмме и также другой объект чем объект b в хозяйской программе. Значение переменной b не передается параметром и не соотносится с хозяином

 

•c есть единственный объект, общий для outer и inner, соотносится с хозяином.

 

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

 Я

Внешние процедуры

 

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

 

PROGRAM first

REAL :: x

x = second()

. . .

END PROGRAM first

 

FUNCTION second() ! внешняя

REAL :: second

. . . ! не соотносится с хозяином

END FUNCTION second

 

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

 Я

Подпрограммы и функции

 

Подпрограммы (Subroutine)

 

Рассмотрим следующий пример

 

PROGRAM Thingy

IMPLICIT NONE

. . . . .

CALL OutputFigures(Numbers)

. . . . ..

CONTAINS

SUBROUTINE OutputFigures(Numbers)

REAL, DIMENSION(:), INTENT(IN) :: Numbers

PRINT*, "Здесь фигуры ", Numbers

END SUBROUTINE OutputFigures

END PROGRAM Thingy

 

Подпрограмма просто печатает свой аргумент. Внутренние процедуры могут "видеть" все переменные , объявленные в главной программе (и оператор IMPLICIT NONE ). Если внутренняя процедура объявляет переменную, которая имеет то же имя, что и переменная из главной программы, то это объявление определяет новую переменную внутри процедуры.

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

 

Внутренние процедуры располагаются между операторами CONTAINS и END PROGRAM и имеют следующий синтаксис

SUBROUTINE < имя подпрограммы >[ (< формальные аргументы >) ]

< объявление формальных аргументов >

< объявление локальных объектов >

...

< выполняемые операторы >

END [ SUBROUTINE [< имя подпрограммы > ] ]

 

 (Заметим, что не все HPF-компиляторы реализуют внутренние подпрограммы.)

 

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

  Я

Функции

 Рассмотрим пример,

 PROGRAM Thingy

IMPLICIT NONE

.....

PRINT*, F(a,b)

.....

CONTAINS

REAL FUNCTION F(x,y)

REAL, INTENT(IN) :: x,y

F = SQRT(x*x + y*y)

END FUNCTION F

END PROGRAM Thingy

 

Функции размещены между операторами CONTAINS и END PROGRAM . Они имеют синтаксис:

[< префикс >] FUNCTION < имя функции>( [< форм.арг >])

< объявление форм.арг >

< объявление локальных объектов >

...

< вычисляемые операторы, присваивание результата >

END [ FUNCTION [ < имя функции > ] ]

 

 Допускается объявлять тип функции внутри функции вместо заголовка.

 Я

Переменные в процедуре

 

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

 

Переменные, объявленные внутри процедуры, обычно существуют только во время выполнения процедуры:

• Какая бы процедурa ни была вызвана, переменные, объявленные в процедуре , "созданы" и для них выделено требуемое место в памяти

• Какая бы процедурa ни существовала, по умолчанию по ее завершении переменные, объявленные в процедуре, "уничтожаются" и любая память, которую процедура имела, будет возвращена снова.

 

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

 Я

SAVE

 

Атрибут SAVE заставляет программу помнить значения переменных процедур от одного вызова до следующего вызова. Любые переменные, которым даны начальные значения при их объявлении, имеют атрибут SAVE по умолчанию. Например:

 

FUNCTION func1( a_new )

REAL :: func1

REAL :: a_new

REAL, SAVE :: a_old ! сохраняемая

INTEGER :: counter=0 ! сохраняемая

...

a_old = a_new

counter = counter+1

END FUNCTION func1

 

Когда функция вызвана в первый раз, a_old имеет неопределенное значение пока счетчик counter установлен в 0. Эти переменные модифицированы функцией и сохраняемы, так что в любых последовательных вызовах a_old имеет значение предыдущего аргумента и counter это счетчик числа вызовов func1.

 Я

Локальные объекты

 

В процедуре

SUBROUTINE Madras(i,j)

INTEGER, INTENT(IN) :: i, j

REAL :: a

REAL, DIMENSION(i,j):: x

 

a, и x известны как локальные объекты. Они :

 

•создаются каждый раз, когда процедура вызывается,

•исчезают, когда процедура завершается,

•не сохраняются их значения между вызовами,

•не используется для них память между вызовами.

 

x будет вероятно иметь различный размер и образ в каждом вызове.

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

 Я

Соответствие параметров

 

Вызов процедуры может быть таким:

 

CALL OutputFigures(NumberSet)

 

А ее объявление,

 

SUBROUTINE OutputFigures(Numbers)

 

Здесь NumberSet фактический параметр и он соответствует формальному параметру Numbers.

 В вызове OutputFigures имя Numbers есть иначе называемый NumberSet. Аналогично рассмотрим

 PRINT*, F(a,b)

 и

REAL FUNCTION F(x,y)

  

Фактические параметры a и b соответствуют формальным параметрам x и y.

 Значение формального параметра заменяется значением фактического.

Подробнее см. раздел "Параметры процедур".

 Я

Правила области действия

 

Fortran 90 не является традиционным языком с блочной структурой:

•область действия объекта есть программная единица, где он видим и доступен

•внутренние процедуры могут наследовать существующие в главной единице (совокупности).

•объекты, объявленные в модулях, могут быть видимы в ассоциации-пользователе (через оператор USE ) -- используется для глобальных данных;

 Я

Связь с хозяином (Host) - глобальные данные

 

Рассмотрим,

 

PROGRAM CalculatePay

IMPLICIT NONE

REAL :: Pay, Tax, Delta

INTEGER :: NumberCalcsDone = 0

Pay = ...; Tax = ... ; Delta = ...

CALL PrintPay(Pay,Tax)

Tax = NewTax(Tax,Delta)

....

CONTAINS

SUBROUTINE PrintPay(Pay,Tax)

REAL, INTENT(IN) :: Pay, Tax

REAL :: TaxPaid

TaxPaid = Pay * Tax

PRINT*, TaxPaid

NumberCalcsDone = NumberCalcsDone + 1

END SUBROUTINE PrintPay

 

REAL FUNCTION NewTax(Tax,Delta)

REAL, INTENT(IN) :: Tax, Delta

NewTax = Tax + Delta*Tax

NumberCalcsDone = NumberCalcsDone + 1

END FUNCTION NewTax

 

END PROGRAM CalculatePay

  

Здесь NumberCalcsDone глобальная переменная. Она доступна во всех процедурах главной ассоциации.

 

Рассмотрим еще один пример

 

PROGRAM Proggie

IMPLICIT NONE

REAL :: A, B, C

CALL sub(A)

CONTAINS

SUBROUTINE Sub(D)

REAL :: D ! D формальный (соответствующий для фактического параметра A)

REAL :: C ! локальное C (отлично от С из Proggie)

C = A**3 ! A не может быть заменено

D = D**3 + C ! D может быть заменено B = C ! B из Proggie получает новое значение

END SUBROUTINE Sub

END PROGRAM Proggie

 

В процедуре Sub при выполнении с одной стороны A как параметр будет подставлен вместо D, с другой стороны в операторе

C = A**3

используется значение А из процедуры Proggie, независимо от того, какой фактический параметр использован при вызове Sub.

Есть и другой аспект: А как глобальная величина из процедуры Proggie не может менять значения, но как фактический параметр, соответствующий D, будет перевычислено оператором

D = D**3 + C.

 

C в Sub отдельное от C в Proggie, замена его значения в Sub не приведет к замене значения C в Proggie.

 Я

Блок взаимодействия (Interface Blocks)

 

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

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

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

 

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

 

INTERFACE

Операторы интерфейса

END INTERFACE

 

Интерфейсный блок для процедуры включается в начало вызывающей программной единицы. Операторы интерфейса содержат копию оператора SUBROUTINE (или FUNCTION), все операторы объхявлений для формальных аргумнетов и оператор END SUBROUTINE (или FUNCTION) . Например:

  

PROGRAM count

INTERFACE

SUBROUTINE ties(score, nties)

REAL :: score(50)

INTEGER :: nties

END SUBROUTINE ties

END INTERFACE

REAL, DIMENSION(50):: data

...

CALL ties(data, n)

...

END PROGRAM count

 

SUBROUTINE ties(score, nties)

REAL :: score(50)

INTEGER :: nties

...

END SUBROUTINE ties

 

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

 Я

Параметры процедур

 

Объекты допустимого образа

 

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

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

  

SUBROUTINE sub2(data1, data3, str)

REAL, DIMENSION(:) :: data1

INTEGER, DIMENSION(:,:,:) :: data3

CHARACTER(len=*) :: str

...

 

Формальные параметры data1 и data3 это массивы, которые могут быть объявлены с рангом, но без размера - задан двоеточием ':' , использованным внутри спецификации размера по каждому измерению. Подобным образом, str имеет не явное задание длины и заимствует длину строки фактического параметра. Когда вызывается подпрограмма sub2, все три формальных параметра принимают размер им соответствующих фактических параметров; все три формальных параметра объекты допустимого образа.

 Я

Вид параметра (атрибут INTENT)

 

Хорошим стилем программирования считается использование

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

 •только входным (вызываемым) -- INTENT(IN), означает, что формальный параметр ожидает значение при вызове процедуры, но не изменяется процедурой;

 •выходным (присваиваемым после использования) -- INTENT(OUT), означает, что формальный параметр не имеет значения при вызове процедуры, но значение будет дано прежде, чем процедура будет завершена;

 •и входным и выходным -- INTENT(INOUT) означает, что формальный параметр имеет начальное значение при вызове процедуры, и значение будет изменено процедурой.

 

SUBROUTINE example(arg1,arg2,arg3)

REAL, INTENT(IN) :: arg1

INTEGER, INTENT(OUT) :: arg2

CHARACTER, INTENT(INOUT) :: arg3

REAL :: r

r = arg1*ICHAR(arg3)

arg2 = ANINT(r)

arg3 = CHAR(MOD(127,arg2))

END SUBROUTINE example

 

Другой пример:

 

SUBROUTINE invert(a, inverse, count)

REAL, INTENT(IN) :: a

REAL, INTENT(OUT) :: inverse

INTEGER, INTENT(INOUT) :: count

inverse = 1/a

count = count+1

END SUBROUTINE invert

 

Подпрограмма invert имеет три формальных параметра: а используется в процедуре, но не меняется в ней, имеет атрибут INTENT(IN); inverse вычисляется в процедуре, имеет атрибут INTENT(OUT), и count (счетчик вызовов) увеличивается процедурой и требует атрибута INTENT (INOUT).

 

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

 •позволить хорошему компилятору проверить ошибки кодирования,

•выполнить эффективно компиляцию и оптимизацию.

 

Ключевые параметры

 

Вместо связывания фактических параметров с формальными только с помощью позиции возможно их связать с помощью имени. Это поможет избежать неприятностей при вызове процедуры часто используется и вызывается несколько встроенных процедур Fortran 90. Например:

 

SUBROUTINE sub2(a, b, stat)

INTEGER, INTENT(IN) :: a, b

INTEGER, INTENT(INOUT):: stat

...

END SUBROUTINE sub2

 

Может быть вызвана операторами:

 

 INTEGER :: x=0

...

CALL sub2( a=1, b=2, stat=x )

CALL sub2( 1, stat=x, b=2)

CALL sub2( 1, 2, stat=x )

 

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

 

CALL sub2( 1, b=2, 0 ) ! неверно

CALL sub2( 1, stat=x, 2) ! неверно

 

Когда используются ключевые слова параметров интерфейс между вызывающей программной единицей и процедурой должен быть явным. Заметим также, что параметры с атрибутом INOUT должны быть ассоциированы с переменной и поэтому значение - stat=0 будет неправильным.

 Я

Необязательные параметры

 

Иногда не все параметры требуются при каждом использовании процедуры. Потому некоторые аргументы могут быть специфицированы как необязательные с помощью атрибута OPTIONAL:

 

SUBROUTINE sub1(a, b, c, d)

INTEGER, INTENT(INOUT):: a, b

REAL, INTENT(IN), OPTIONAL :: c, d

...

END SUBROUTINE sub1

 

Здесь a и b требуются всегда, когда вызывается процедура sub1. Параметры c и d не обязательны и sub1 можно вызывать так:

 

CALL sub1( a, b )

CALL sub1( a, b, c, d )

CALL sub1( a, b, c )

 

Заметим, что порядок, в котором появляются аргументы, важен (без использования ключевых слов), так что не возможно вызвать call sub1 с параметром d, но без параметра c.

CALL sub1( a, b, d ) ! неверно

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

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

REAL :: inverse_c

 

IF( PRESENT(c) ) THEN

inverse_c = 0.0

ELSE

inverse_c = 1/c

ENDIF

 

Если необязательный параметр имеется, то PRESENT возвращает значение .TRUE. . В вышеприведенном примере это использовано для ошибки времени выполнения (деление на 0 будет причиной краха программы 'crash').

  Я

Процедуры в качестве параметров

 

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

 

PROGRAM test

INTERFACE

REAL FUNCTION func( x )

REAL, INTENT(IN) ::x

END FUNCTION func

END INTERFACE

...

CALL sub1( a, b, func(2) )

...

END PROGRAM test

 

REAL FUNCTION func( x ) ! внешняя

REAL, INTENT(IN) :: x

func = 1/x

END FUNCTION func

 

Когда вызов sub1 сделан с тремя параметрами a, b и результат функции func(2) - в этом случае возвращаемое значение 1/2. Процедура, которая использована как параметр будет всегда выполняться прежде, чем процедура, в которой оператор вызова появиться. Использование процедуры в качестве параметра требует явного интерфейса.

 

Заметим, что оператор спецификации для функции func идентифицирует результат типа REAL. Это альтернатива объявлению имени функции как переменной:

 

REAL FUNCTION func( x )

REAL, INTENT(IN) :: x

func = 1/x

END FUNCTION func

 

и

 

FUNCTION func( x )

REAL :: func

REAL, INTENT(IN) :: x

func = 1/x

END FUNCTION func

 

эквивалентны.

 Я

Рекурсия

 

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

Объявление рекурсивной функции имеет отличие в синтаксисе. Должно быть использовано ключевое слово RESULT , специфицирующее имя переменной, хранящей значение результата функции (Ключевое слово RESULT необходимо, чтобы использовать имя функции для возвращения результата. Массив значений рекурсивной функции допустим и в то же время ссылка на рекурсивную функцию будет неразличима от ссылки на массив. Имя функции неявно имеет тот же атрибут , что и имя результата.)

 Очевидно, что что рекурсия должна быть объявлена в заголовке:

 

INTEGER RECURSIVE FUNCTION fact(N) RESULT(N_Fact)

или

RECURSIVE INTEGER FUNCTION fact(N) RESULT(N_Fact)

(Целыми INTEGER будут и fact и N_Fact.)

 

или,

RECURSIVE FUNCTION fact(N) RESULT(N_Fact)

INTEGER N_Fact

 

В последнем случае INTEGER N_Fact дает тип величине fact; фактически специфицирует тип fact.

 

Рекурсия может одного из двух типов:

 •Непрямая рекурсия - A вызывает B вызывает A...

 •Прямая рекурсия - A вызывает A вызывает A...

 обе требуют атрибута RECURSIVE для процедуры A.

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

 Пример рекурсивной функции

 

RECURSIVE FUNCTION fact( n ) RESULT(N_Fact)

INTEGER, INTENT(IN) :: n

INTEGER :: N_Fact

IF( n==1 ) THEN

N_Fact = 1

ELSE

N_Fact = n*fact( n-1 )

END IF

END FUNCTION fact

 

Подпрограммы объявляются с помощью заголовка RECURSIVE SUBROUTINE.

 

Пример рекурсивной подпрограммы

  

RECURSIVE SUBROUTINE Factorial(N, Result)

INTEGER, INTENT(IN) :: N

INTEGER, INTENT(INOUT) :: Result

IF (N > 0) THEN

CALL Factorial(N-1,Result)

Result = Result * N

ELSE

Result = 1

END IF

END SUBROUTINE Factorial

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]