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

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

для формальных параметров - процедур (формальных процедур).

8.11.3. Явные и неявные интерфейсы

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

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

Вызовы внешних процедур с неявным интерфейсом допустимы и в современном Фортране. В случае функции при неявном интерфейсе ее тип

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

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

Вслучае внутренней процедуры вызывающая программная единица и ее процедура компилируются как единое целое, поэтому компилятор знает все

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

Модульная процедура вызывается либо в самом модуле, либо из программной единицы, где вызову предшествует оператор USE для этого модуля. Поэтому в обоих случаях компилятор знает все о вызываемой процедуре и, следовательно, ее интерфейс является явным.

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

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

INTERFACE

тело интерфейса

END INTERFACE

Тело интерфейса содержит описание одного и более интерфейсов процедур. Как правило, интерфейс процедуры - это точная копия заголовка

240

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

процедуры, объявлений ее формальных параметров, типа функции в случае процедуры-функции и оператора END процедуры. Однако в интерфейсном блоке:

имена параметров могут отличаться от имен соответствующих формальных параметров процедуры;

могут быть добавлены дополнительные спецификации (например, объявления локальных переменных) за исключением описаний внутренних процедур и операторов DATA и FORMAT;

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

Пример:

subroutine sub1(i1, i2, r1, r2)

 

integer :: i1, i2

 

real :: r1, r2

! В разделе объявлений процедуры атрибут

...

! OPTIONAL может быть опущен. Достаточно того,

end subroutine sub1

! что он задан в интерфейсном блоке

 

program idem

interface ! Интерфейс подпрограммы sub1 subroutine sub1(int1, int2, real1, real2)

integer :: int1, int2

real, optional :: real1, real2 end subroutine sub1

end interface

Также

может

быть задан интерфейс внешних процедур, написанных

на других языках программирования, например на ассемблере или CИ.

Наличие

таких

интерфейсов позволяет создавать разноязычные

приложения [1].

Задание интерфейса означает, что упоминаемые в нем процедуры рассматриваются как внешние. Любая встроенная процедура с таким же именем становится недоступной. Такой же эффект имеет и упоминание имени процедуры в операторе EXTERNAL. Одновременное упоминание имени процедуры в теле интерфейса и операторе EXTERNAL недопустимо.

Интерфейсный блок размещается среди операторов описания. Удобнее всего собрать интерфейсные блоки в одном или нескольких модулях и подключать их по мере необходимости при помощи оператора USE.

Задание явного интерфейса необходимо, если:

процедура имеет необязательные формальные параметры;

результатом процедуры-функции является массив (разд. 4.11);

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

241

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

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

результатом процедуры-функции является ссылка;

процедура является динамической библиотекой. Также интерфейсные блоки употребляются:

при вызове процедуры с ключевыми словами (разд. 8.11.4);

при использовании задаваемого присваивания (разд. 8.12.2);

при использовании задаваемых операций (разд. 8.12.2);

при использовании в вызове родового имени (разд. 8.12);

для доступа к внешним, написанным на других языках процедурам [1].

8.11.4. Ключевые и необязательные параметры

При некоторых вызовах процедуры часть фактических параметров может не использоваться. Примером такой процедуры может послужить встроенная функция SUM(array [, dim] [, mask]) (разд. 4.12.1), имеющая два необязательных параметра dim и mask. В этом случае соответствующие формальные параметры должны быть объявлены с атрибутом OPTIONAL. Как и другие атрибуты, OPTIONAL может быть использован в операторе объявления типа и как самостоятельный оператор.

Пример. Создать функцию npe(array, me, sig), возвращающую:

сумму me первых положительных элементов массива array, если sig > 0;

сумму me первых отрицательных элементов массива array, если sig < 0;

сумму me первых элементов массива array, если sig = 0 или отсутствует;

сумму всех заданных посредством sig-знака элементов массива, если отсутствует параметр me.

program tesop

integer, parameter :: m = 3, n = 10

integer :: a(n) = (/ 1, -1, 2, -2, 3, -3, 4, -4, 5, -5 /)

 

! Необходимо явно задать интерфейс к процедуре

interface

! с необязательными формальными параметрами

integer function npe(array, me, sig)

 

integer, intent(in) :: array(:)

 

 

integer, intent(in), optional :: me, sig

end function npe

 

 

end interface

 

 

print *, npe(a, m, 1)

!

6

print *, npe(a, sig = -1)

!

-15

print *, npe(a)

!

0

end program tesop

 

 

integer function npe(array, me, sig) integer, intent(in) :: array(:)

integer, intent(in), optional :: me, sig integer mval, sval

242

 

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

integer, allocatable :: temp(:)

 

if(.not. present(sig)) then

! Использовать неассоциированный

sval = 0

! необязательный формальный параметр

else

! можно только в качестве аргумента

sval = sig

! функции PRESENT

end if

 

if(present(me)) then

 

mval = me

 

else

 

mval = size(array)

 

end if

 

select case(sval)

! Размер temp может быть меньше mval

case(1:)

allocate(temp(min(mval, count(array > 0))))

temp = pack(array, array > 0)

 

case(:-1)

 

allocate(temp(min(mval, count(array < 0))))

temp = pack(array, array < 0)

 

case(0)

 

allocate(temp(mval))

 

temp = array(1:mval)

 

endselect

 

npe = sum(temp)

! Возвращаемый результат

deallocate(temp)

 

end function npe

 

Синтаксис оператора OPTIONAL: OPTIONAL [::] vname

Синтаксис атрибута OPTIONAL: type-spec, OPTIONAL [, attrs] :: vname

type-spec - спецификация любого типа данных.

vname - разделенные запятыми имена формальных параметров. Атрибут может быть использован только для формальных параметров

процедур. Интерфейс процедуры, содержащей атрибут OPTIONAL, должен быть описан явно. Формальный параметр, имеющий атрибут OPTIONAL, может дополнительно иметь только атрибуты DIMENSION, EXTERNAL, INTENT, POINTER и TARGET.

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

PRESENT(a)

243