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

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

При нахождении модуля (включаемого файла) поиск прекращается.

Вслучае неудачи генерируется сообщение об ошибке.

Всреде DS директории для поиска модулей и включаемых файлов можно установить, выполнив цепочку Tools - Options - Show directories for Include files - добавить нужную директорию - OK. Также директории указываются и в результате выполнения цепочки (Project) Build - Settings – Fortran - Preprocessors - занести в поле INCLUDE and USE paths пути к файлам - OK. Путь к файлам завершается слешем. При наличии нескольких путей они разделяются запятыми, например: myfiles/, mylib/. Заданные опции компилятора отображаются в поле Project Options.

8.4. Главная программа

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

[PROGRAM имя программы] [операторы описания] [исполняемые операторы] [CONTAINS

внутренние процедуры]

END [PROGRAM [имя программы]]

Оператор PROGRAM необязательный. Однако же если он присутствует, то должно быть задано и имя программы - любое правильно сформированное имя Фортрана. Если оператор END содержит имя программы, то оно должно совпадать с именем, заданным в операторе

PROGRAM.

Главная программа не может содержать операторы MODULE и BLOCK DATA. Раздел описаний не может содержать операторы и атрибуты OPTIONAL, INTENT, PUBLIC и PRIVATE. Включение атрибута или оператора SAVE не имеет никакого эффекта. Операторы SUBROUTINE, FUNCTION, RETURN и ENTRY не могут появляться среди исполняемых операторов главной программы, но могут размещаться после оператора

CONTAINS.

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

221

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

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

ВФортране могут быть определены два типа процедур: подпрограммы

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

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

подпрограмму.

Структура подпрограммы имеет вид:

заголовок подпрограммы [операторы описания] [исполняемые операторы] [CONTAINS

внутренние процедуры]

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

Аналогично выглядит структура функции:

заголовок функции [операторы описания] [исполняемые операторы] [CONTAINS

внутренние процедуры]

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

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

Оператор CONTAINS в процедуре играет такую же роль, что и в главной программе. Выполнение оператора END приводит к передаче управления в вызывающую программную единицу. Также выход из процедуры осуществляет оператор RETURN.

Заголовок подпрограммы содержит оператор SUBROUTINE, а заголовок функции - оператор FUNCTION. Вызов подпрограммы выполняется оператором

CALL имя подпрограммы([список фактических параметров])

Вызов функции выполняется из выражения, например: result = имя функции([список фактических параметров])

222

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

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

Внутри главной программы, внешней и модульной процедуры можно после оператора CONTAINS задать внутренние процедуры. Они имеют вид:

заголовок подпрограммы [операторы описания] [исполняемые операторы]

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

заголовок функции [операторы описания] [исполняемые операторы] END FUNCTION [имя функции]

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

8.7. Модули

Модуль используется для задания глобальных данных и модульных процедур. Он имеет вид:

MODULE имя модуля [раздел описаний] [CONTAINS

модульные процедуры] END [MODULE [имя модуля]]

Раздел описаний может содержать определения встроенных типов данных, объявления данных, функций и их атрибутов, интерфейсные блоки и namelist-группы. При объявлении данных им могут быть присвоены начальные значения. Операторы объявления данных могут содержать атрибуты ALLOCATABLE, AUNOMATIC, DIMENSION(dim), EXTERNAL, INTENT, INTRINSIC, OPTIONAL, PARAMETER, POINTER, PRIVATE, PUBLIC, SAVE, STATIC, TARGET и VOLATILE (последний атрибут применим только в CVF). Каждый атрибут может быть задан в операторной форме. Также раздел описаний может включать операторы COMMON, DATA, EQUIVALENCE, IMPLICIT, NAMELIST, USE. Раздел описаний не может содержать ни одного выполняемого оператора.

223

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

Следующие за оператором CONTAINS модульные процедуры должны завершаться END SUBROUTINE [имя подпрограммы] или END FUNCTION [имя функции]. Модульные процедуры, в свою очередь, после оператора CONTAINS могут содержать внутренние процедуры. Имя модуля, если оно следует за END MODULE, должно совпадать с именем в заголовке модуля.

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

Объявленные в операторах описания модуля имена доступны:

в модульных процедурах;

во внутренних процедурах модуля;

в использующих модуль программных единицах (если имена не объявлены PRIVATE).

Модульные процедуры доступны:

в других модульных процедурах модуля;

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

PRIVATE).

Внутренняя процедура модуля доступна только в содержащей ее модульной процедуре - носителе.

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

На модуль, используя оператор USE, можно сослаться:

в главной программе;

во внешней процедуре;

в другом модуле.

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

Замечание. Одно из применений модулей - это накопление интерфейсов внешних процедур, в том числе написанных на иных языках программирования. Например, поставляемый с CVF модуль DFCOM содержит интерфейсы, применяемые с объектами ActiveX процедур. Сами же процедуры содержатся в библиотеке dfcom.lib.

Пример: module testmod

!Переменные a, b и c доступны в smod и smod2 и в любой программной единице,

!содержащей ссылку USE TESTMOD

integer, save :: a = 1, b = 1

! Объявленная PRIVATE переменная c

integer, private :: c = 1

contains

! доступна только в модуле TESTMOD

224

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

subroutine smod(d) integer d, c2 /1/ d = 2

b = 1 + c call smod2(d)

print *, 'smod :', d, b

contains

 

subroutine smod2(d)

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

integer d

! только подпрограмме smod

print *, 'smod2 :', d, b

 

d = d + 1

! c2 доступна в smod2 благодаря ассоциированию

b = b + c2

end subroutine smod2

! через носитель

end subroutine smod

 

end module testmod

 

program prom

 

use testmod

! Ссылка на модуль TESTMOD

print *, 'prom_1:', a, b

! a и b доступны в prom и osub благодаря

call smod(a)

! use-ассоциированию

print *, 'prom_2:', a, b

 

call osub( )

 

print *, 'prom_3:', a, b

 

end program prom

 

subroutine osub( )

 

use testmod

 

print *, 'osub :', a, b

 

a = 4

 

b = 4

 

end subroutine osub

 

Результат:

prom_1:

1

1

smod2 :

2

2

smod :

3

3

prom_2:

3

3

osub :

3

3

prom_3:

4

4

Объявленные в модуле TESTMOD переменные a и b являются глобальными в том смысле, что они видны в любом ссылающемся на модуль программном компоненте. Такой способ передачи данных называется use-ассоциированием.

Также значения переменных a, b и с, объявленные в модуле TESTMOD, известны модульной подпрограмме smod и ее внутренней подпрограмме smod2. Такой способ передачи данных называется ассоциированием через носитель. Благодаря ассоциированию через носитель внутренняя

225