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

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

подпрограмма smod2, носителем которой является модульная подпрограмма smod, имеет доступ к локальной переменной c2 подпрограммы smod.

Кроме того, в примере главная программа prom, модульная подпрограмма smod, внутренняя подпрограмма smod2 обмениваются данными через параметр d. Такая передача данных называется ассоциированием параметров.

Рассмотренное use-ассоциирование позволяет передавать не только данные, но и статус размещаемых массивов (разд. 4.8.2) и ссылок. Например:

module mod

integer, pointer :: a(:)

end module

 

 

 

 

 

 

program tpo

 

 

 

 

 

 

use mod

 

 

 

 

 

 

integer, parameter :: m = 4, n = 5

 

 

 

 

 

 

integer, target :: b(5) = 5

! Прикрепляем ссылку к адресату b

a => b

call shost( )

! Статус ссылки будет известен в shost

print *, a

!

3

3

3

 

 

end program

 

 

 

 

 

 

subroutine shost( )

 

 

 

 

 

 

use mod

 

 

 

 

 

 

integer, target :: c(3) = 3

 

 

 

 

 

 

print *, associated(a)

! T

 

 

 

 

 

print *, a

!

5

5

5

5

5

a => c

 

 

 

 

 

 

end subroutine shost

 

 

 

 

 

 

Исходный текст модуля может быть размещен в том же файле, в котором размещены и использующие его программные единицы. При этом его текст должен предшествовать ссылкам на модуль. Можно разместить модуль в отдельном файле, например модуль TESTMOD (один или вместе с другими модулями) может быть размещен в файле mofil.f90. При компиляции этого файла (файл должен быть включен в проект) для каждого его модуля будет создан файл, имеющий имя модуля и расширение MOD. Так, для модуля TESTMOD будет создан файл testmod.mod. При работе с откомпилированными файлами модулей присутствие исходных текстов модулей в проекте необязательно, но компилятору должны быть известны пути к откомпилированным файлам или к содержащим эти файлы библиотекам.

8.8. Оператор USE

Доступ к модулю выполняется посредством использования оператора USE. Если, например, задан оператор

226

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

USE TESTMOD

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

В то же время оператор USE позволяет:

ограничить доступ к объектам модуля за счет применения параметра

ONLY;

использовать в программной единице для объектов модуля другие имена. Например, на модуль TESTMOD (разд. 8.7) можно сослаться так:

use testmod, only : a, smod

или так:

program prom

use testmod, va => a, prosub => smod print *, 'prom_1:', va, b

call prosub(va) call osub( )

end program prom

В первом случае в использующей модуль TESTMOD программной единице будут видны только переменная a модуля и его подпрограмма smod. Во втором случае в результате переименования переменная a модуля TESTMOD будет доступна в prom под именем va, а модульная подпрограмма smod - под именем prosub. Глобальная переменная b модуля будет доступна под ее собственным именем. Механизм взаимодействия модуля и использующей его программной единицы, разумеется, сохранится.

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

Дадим теперь общее представление двух форм оператора USE: USE имя модуля [, список переименований]

USE имя модуля, ONLY: [only-список]

Список переименований содержит переименования глобальных объектов модуля. Каждый элемент списка имеет вид

227

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

local-name => use-name

и означает, что объект модуля c именем use-name будет доступен в использующей модуль программной единице под именем local-name. В общем случае можно для одного use-name использовать несколько разных local-name, например:

use testmod, prosub => smod, prosub2 => smod

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

module mymod

type point ! Объявляем в модуле производный тип данных point real(4) :: x, y, z

end type point

end module mymod

program t2

! Теперь тип данных point доступен в t2

use mymod

type(point) :: pt

! Объявляем переменную pt типа point

pt = point(1.0, 2.0, 3.0)

! Даем переменную pt типа point начальные значения

print *, pt

!

1.000000

2.000000

3.000000

end program t2

 

 

 

 

Также only-список может включать элемент вида

[local name =>] use-name

Находящиеся в only-списке объекты модуля не могут иметь атрибут PRIVATE. Если опция ONLY задана, то в использующей модуль программной единице доступны только размещенные в only-списке объекты модуля.

Программная единица может содержать более одного оператора USE для любого модуля, например:

use testmod, only : va => a, b

use testmod, only : prosub => smod

В этом случае only-списки сцепляются в один only-список. Если же хотя бы один оператор USE использован без опции ONLY, то использующей модуль программной единице будут доступны все глобальные объекты модуля, а присутствующие переименования в списках переименований и only-списках сцепляются в единый список переименований.

Пример:

module mymod real :: a = 5.0

end module mymod

228

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

program t3

use mymod, a2 =>a

! Теперь переменная а модуля MYMOD доступна в t3 под именем и a2 print *, a, a2 ! 0.000000 5.000000

! Переменную a можно использовать в t3 как локальную end program t3

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

module mymod

real :: a = 5.0

 

contains

 

subroutine b(d)

 

real d

 

d = 4.5

 

end subroutine b

 

end module mymod

 

program t4

 

use mymod

! Глобальное имя b уже использовано в MYMOD

b = 1.2

end program t4

! как имя подпрограммы

вызовет ошибку компиляции: Error: This name has already been used as an external subroutine name. [B] b = 1.2. Если же в t4 добавить объявление

real(4) b

то дополнительно возникнет ошибка: Error: The attributes of this name conflict with those made accessible by a USE statement. [B] real(4) b.

Избежать ошибки можно, во-первых, удалив из t4 ссылку use mymod, вовторых, выполнив переименование, например use mymod, b2 => b, и, в-третьих, изменив имя локальной переменной b главной программы t4, например на b3.

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

module a real s, t

...

end module a

module b

use a, bs => s

229