
- •Lesson 5 Структура программы
- •Главная программа
- •Внешние процедуры
- •Процедуры-функции
- •Пример функции
- •Процедуры-подпрограммы
- •Пример подпрограммы
- •Параметры процедур
- •Implicit none
- •Массив как параметр процедуры
- •Интерфейсы
- •Interface
- •Interface
- •Внутренние процедуры
- •Implicit none
- •Встроенные функции
- •Пример присоединения объектов модуля.
- •Implicit none
- •Implicit none
- •Implicit none
Процедуры-подпрограммы
Процедура-подпрограмма отличается от процедуры-функции тем, что она не имеет возвращаемого значения. Результаты ее работы передаются вызываемой программе через формальные параметры, либо через глобальные переменные.
Структура подпрограммы имеет вид:
subroutine Имя подпрограммы (список формальных параметров)
[Операторы описания]
[Исполняемые операторы]
[contains
внутренние процедуры]
end[subroutine [имя подпрограммы]]
В списке формальных параметров подпрограммы перечислены входныеивыходныепараметры. Используя входные параметры, процедура вычисляет значения выходных параметров и возвращает управление в вызывающую программную единицу.
Оператор subroutine называется заголовком подпрограммы. Тип подпрограммы не существует, так как у нее нет возвращаемого значения. В заголовке указывается уникальное имя подпрограммы, составленное по правилам Фортрана, и список формальных параметров в круглых скобках.
Так же, как и в функции, среди операторов описаниядолжны присутствовать описания формальных параметров подпрограммы и внутренних (локальных) переменных и массивов.
Если в операторе endуказано имя подпрограммы, оно должно совпадать с именем в заголовке подпрограммы.
Обращение к подпрограммеосуществляется операторомcall, имеющим вид:
call имя подпрограммы[(список фактических параметров)]
Пример подпрограммы
Написать подпрограмму, меняющую местами первую и последнюю строки вещественной матрицы.
subroutine Transform(Matrix, cRows, cCols) ! заголовок
! операторы описания:
implicit none ! оператор должен быть в каждой программной единице
! формальные параметры
integer,intent(in)::cRows, cCols! протяженности по измерениям
! матрица
real, dimension(1:cRows, 1:cCols), intent(in)::Matrix
! локальный временный массив для одной строки:
real, dimension(1:cCols):: Temp
! исполняемыеоператоры:
cRows = size(Matrix,1) ! количество строк матрицы
Temp = Matrix(1, :) ! первая строка матрицы
Matrix(1, :) = Matrix(cRows, :) ! последняя строка на место первой
Matrix(cRows, :) = Temp ! первая строка на место последней
end subroutine Transform
В главной программе:
integer, parameter:: cR = 6, cCol = 8
real, dimension(1:cR, 1:cCol) :: Array
. . .
call Transform(Array, cR, cCol)
В подпрограмме используется временный локальный массив Temp, длина которого равна длине строки матрицы (cCols). Память для этого массива выделяется динамически при выполнении подпрограммы, операторыallocatableиallocateне требуются.
Параметры процедур
Рассмотрим подробнее способ передачи данных между вызывающей программной единицей и процедурой через параметры. В этом случае в заголовке процедуры указывается список формальных параметров. Формальными параметрами могут быть переменные и массивы, а также имена функций.
В операторах вызова процедуры указывается списокфактических параметров. В отличие от формальных параметров,фактическими параметрамимогут быть:
переменные;
массивы;
имена функций;
элементы массивов;
секции массивов;
константы – только входные параметры;
выражения – только входные параметры.
Каждый параметр процедуры имеет следующие основные характеристики:
тип;
ранг – размерность или количество измерений; ранг переменной равен 0;
назначение параметра – входной, выходной или универсальный (изменяемый).
Назначениеформального параметра определяет атрибутintent.
Пример.
subroutine Transform(N, Pin, Result) ! заголовок
! операторы описания:
implicit none ! оператор должен быть в каждой программной единице
integer, intent(in) :: N ! входной параметр
real, intent(out) :: Pin !выходнойпараметр
! Result – изменяемыйпараметр – одномерный массив:
real, dimension(:), intent(inout) :: Result
Атрибут intent(in)в описании параметра определяет параметр как входной: такой параметр не должен изменяться во время работы подпрограммы.
Атрибут intent(out)определяет параметр как выходной, то есть параметрдолженбыть переопределен в процедуре, поэтому при входе в подпрограмму он переходит в состояние неопределенности. Соответствующийфактическийпараметр не может быть константой или выражением.
Универсальные параметры описываются с атрибутом intent(inout). Предполагается, что значение универсального параметра может быть переопределено, поэтому соответствующийфактическийпараметр не может быть константой или выражением.
Для корректной связи вызывающей и вызываемой программных единиц фактические параметры должны согласовываться с формальными параметрами по количеству, и попарно в порядке следования – по типу, рангу, назначению.
Совпадение имен формального и фактического параметров не требуется.
Пример соответствия фактических и формальных параметров:
В функции вычислить среднее арифметическое значение Nпоследних элементов одномерного вещественного массива. В главной программеприменить функцию к строкам матрицы из 10 строк и 7 столбцов, считая количество элементов для усредненияN= 5. Результаты записать в одномерный массив.
real function Average(Array, Len, N)
! заголовок функции; возвращаемое значение вещественного типа
! операторы описания:
implicit none ! оператор должен быть в каждой программной единице
! формальные параметры
integer, intent(in) :: Len ! длина одномерного массива
integer, intent(in) :: N ! кол-во последних элементов
integer :: i ! локальная переменная
real :: summa ! локальная переменная
real, dimension(1:Len), intent(in) :: Array ! массив
! исполняемые операторы:
summa = 0
do i = Len-N+1, Len
summa = summa + Array(i)
enddo
Average = summa/N ! возвращаемое значение
end function Average
В главной программе:
program Main
! операторы описания: