Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

О. В. Бартеньев. Современный ФОРТРАН

real, public :: a = 3.0, b = 4.0

 

 

public :: length

! Подпрограмма square доступна

private :: square

contains

! только в модуле pupr

real function length(x, y)

 

 

real, intent(inout) :: x, y

 

 

call square(x, y)

 

 

length = sqrt(x + y)

 

 

end function

 

 

subroutine square(x1, y1)

 

 

real, intent(inout) :: x1, y1

 

 

x1 = x1 * x1

 

 

y1 = y1 * y1

 

 

end subroutine

 

 

end module pupr

 

 

program gopu

 

 

use pupr

 

 

print *, length(ep%x, ep%y)

!

5.000000

print *, length(a, b)

!

5.000000

end

 

 

8.10. Операторы заголовка процедур

Полный синтаксис оператора заголовка подпрограммы:

 

[RECURSIVE] SUBROUTINE имя подпрограммы

&

[([список формальных параметров])]

 

Общий вид оператора заголовка функции:

 

[type] [RECURSIVE] FUNCTION имя функции

&

([список формальных параметров]) [RESULT (имя результата)]

8.10.1. Общие характеристики операторов заголовка процедур

Имя процедуры (подпрограммы и функции) может быть глобальным

ивнешним или внутренним в процедуре-носителе. Имя процедуры не может появляться в операторах AUTOMATIC, COMMON, EQUIVALENCE, DATA, INTRINSIC, NAMELIST, SAVE. Имя подпрограммы не может появляться в операторах объявления типа.

Список формальных параметров может содержать имена переменных

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

Процедура может содержать любые операторы, кроме BLOCK DATA

иPROGRAM. До оператора CONTAINS процедура не может содержать

232

8. Программные единицы

операторы FUNCTION и SUBROUTINE. Внутренние процедуры не могут содержать операторы ENTRY и CONTAINS и другую внутреннюю процедуру. Внутренние процедуры размещаются между операторами CONTAINS и END главной программы или процедуры-носителя.

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

Если формальный параметр имеет атрибут OPTIONAL, то при вызове соответствующий фактический параметр может быть опущен. Типы формальных параметров могут быть заданы внутри процедуры как неявно, так и явно (последнее предпочтительнее). Имена формальных параметров не могут появляться в операторах AUTOMATIC, COMMON, DATA, EQUIVALENCE, INTRINSIC, SAVE или STATIC.

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

Полезно явно задавать интерфейс и к внешним процедурам, а в большом числе случаев он просто необходим (разд. 8.11.3).

Если вызываемая процедура находится в динамической библиотеке (DLL), то необходимо задавать ее интерфейс и использовать с ней атрибуты

DLLEXPORT или DLLIMPORT [1].

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

8.10.2. Результирующая переменная функции

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

Имя результирующей переменной задается предложением RESULT или совпадает с именем функции, если это предложение опущено. Задаваемое предложением RESULT имя результата не может совпадать с

именем функции.

Тип результирующей переменной определяет тип функции и может быть задан посредством указания type в заголовке функции.

233

О. В. Бартеньев. Современный ФОРТРАН

type - объявление типа и разновидности типа результирующей переменной (возвращаемого функцией результата). Может быть любого встроенного типа.

type может быть опущен. Тогда тип результирующей переменной может быть задан явно в одном из операторов объявления функции, в операторе IMPLICIT или неявно. Последнее невозможно, если заданы оператор IMPLICIT NONE или директива $DECLARE.

Если в операторе заголовка задан type, то имя результирующей переменной не должно появляться в разделе объявлений функции.

Примеры объявления результирующей переменной:

function imax(a, n)

! Результирующая переменная imax;

integer a(n)

! ее тип INTEGER задан неявно

...

! Исполняемые операторы

logical function flag(a, n)

! Результирующая переменная flag;

integer a(n)

! ее тип LOGICAL задан явно

function flag(a, n)

! Результирующая переменная flag;

logical flag

! ее тип LOGICAL задан явно

function flag(a, n) result(vf)

! Результирующая переменная vf;

logical vf

! ее тип LOGICAL задан явно

Если тип внешней

функции определен без учета правил умолчаний

о типах данных или заданы оператор IMPLICIT NONE или директива $DECLARE, то тип функции либо должен быть объявлен в вызывающей программной единице, либо там должен быть задан интерфейс к этой функции. На модульные и внутренние функции это требование не распространяется, поскольку они и без того имеют явно заданный интерфейс.

Пример:

logical function flag(a, n) result (vf)

...

vf = ... ! Определяем значение результирующей переменной end

program fude

! Объявляем функцию flag в вызывающей программе

logical flag, fl

...

! Тип объявляемой функции определяется типом

fl = flag(a, n)

! результирующей переменной

...

 

end

 

Если результатом функции является переменная производного типа, массив или ссылка, то type опускается и результирующая переменная объявляется в разделе объявлений функции.

234

8. Программные единицы

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

Результирующая переменная может использоваться в выражениях функции, и в результате вычислений она должна получить значение. Последнее значение результирующей переменной используется в выражении, из которого функция вызвана. Результирующая переменная после выполнения функции может быть не определена, если она является ссылкой и вызов функции выполнен не из выражения (разд. 3.11.8). Обычно результирующая переменная получает значение в результате присваивания. Но это необязательно. Например, в случае символьной функции результирующая переменная может быть определена после выполнения оператора (разд. 3.8.7)

WRITE(имя результата, спецификатор формата) выражение

Результирующая переменная может быть скаляром или массивом любого встроенного и производного типа, также она может быть и ссылкой (разд. 3.11.8). Результатом функции не может быть перенимающий размер массив.

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

Пример. Найти сумму последних отрицательных элементов массивов a и b. Поиск последнего отрицательного элемента в массиве выполним в функции finel.

program nel

integer :: a(8) = (/1, -1, 2, -2, 3, -3, 4, -4 /) integer :: b(10) = (/1, 2, 3, 4, 5, -1, -2, -3, -4, -5 /)

integer :: finel

!

Объявляем тип функции

print *, finel(a, 8) + finel(b, 10) !

Вызов функции из выражения

end

!

-9

function finel(c, n)

 

 

integer finel

! Объявляем тип результирующей переменной

integer c(n), i

! Используем массив заданной формы

finel = 0

! Определим результирующую переменную на

do i = n, 1, -1

! случай, если в массиве нет отрицательных

if(c(i) < 0) then

! элементов

finel = c(i)

 

 

return

! Возвратим последний отрицательный элемент

end if

 

 

end do

end function

235