Массив как параметр процедуры
При описании массива – формального параметра – можно не включать протяженности массива по измерениям в список параметров. Форма массива в этом случае перенимается у соответствующего фактического параметра. Определить в программе форму или размер массива можно, обратившись к функциям shape или size.
Пример Перепишем функцию, рассмотренную выше, находящую в вещественной матрице элемент с максимальным абсолютным значением.
real function Max_Abs(Array)
! заголовок функции; возвращаемое значение вещественного типа
! для матрицы не указаны протяженности по измерениям
! операторы описания:
implicit none! оператор должен быть в каждой программной единице
! формальный параметр – массив (указаны тип и ранг)
real, dimension(:,:), intent(in):: Array
! локальные переменные
integer:: cRows, cCols ! протяженности по измерениям
integer :: i, j ! переменные циклов
integer :: NumI, NumJ ! координаты элемента матрицы
! исполняемые операторы:
! протяженности по измерениям
cRows = size(Array, 1) ! количество строк
cCols = size(Array, 2) ! количество столбцов
! максимальным по модулю считаем Array(1,1)
NumI = 1; NumJ = 1
do i = 1, cRows
do j = 1, cColumns
If (abs(Array(i,j)) > abs(Array(NumI,NumJ))) then
NumI = i; NumJ = j
Endif
Enddo
Enddo
Max_Abs = Array(NumI,NumJ) ! возвращаемое значение
end function Max_Abs
В главной программе:
implicit none! оператор должен быть в каждой программной единице
integer, parameter:: cR = 6, cCol = 8
real, dimension(1:cR, 1:cCol) :: Array
real:: Max_Abs ! описание типа возвращаемого значения функции
. . .
! фактический параметр функции Max_Abs – матрица
write(*,*)Max_Abs(Array)
Интерфейсы
Для организации вызова любой процедуры необходимо и достаточно знать ее интерфейс: заголовок, список формальных параметров и их описание.
Внешние процедуры являются независимыми программными единицами. У компилятора нет сведений об их параметрах, то есть их интерфейс является неявным. Поэтому на этапе компиляции невозможно выполнить проверку на соответствие между фактическими и формальными параметрами.
Сделать неявный интерфейс явным можно, описав его в интерфейсном блоке:
Interface
заголовок процедуры
описание формальных параметров
оператор end процедуры
End interface
Интерфейсный блок может содержать описания нескольких процедур. Он размещается в вызывающей программе среди операторов описания; после этого интерфейсы процедур, содержащихся в нем, становятся явными.
При наличии интерфейса процедуры ошибки обращения к ней обнаруживаются уже на этапе компиляции.
Пример. Написать подпрограмму, определяющую, есть ли в вещественной матрице положительные элементы, и, если есть, вычисляющую их среднее арифметическое и среднее геометрическое значения. В главную программу включить интерфейс подпрограммы.
subroutine Primer(Matrix, Yes, Ar, Geom) ! заголовок
! операторы описания:
implicit none! оператор должен быть в каждой программной единице
! формальные параметры
real, dimension(:,:), intent(in) :: Matrix ! матрица
logical, intent(out) :: Yes ! признак – есть эл-ты >0
real, intent(out) :: Ar, Geom ! средние значения
! локальные переменные и массив
integer:: i, j ! переменные циклов
real:: Summa, Prod ! сумма и произведение эл-тов матрицы
integer:: cPos ! количество положительных эл-тов матрицы
integer, dimension(1:2):: Shape_Matr ! форма массива Matrix
! исполняемые операторы:
Shape_Matr= shape(Matrix) ! форма массива Matrix
Summa = 0; Prod = 1; cPos = 0
do i = 1, Shape_Matr(1) ! цикл по строкам
do j = 1, Shape_Matr(2) ! цикл по столбцам
if(Matrix(i, j) > 0) then ! подсчет суммы и произведения
cPos = cPos + 1
Summa = Summa + Matrix(i, j)
Prod = Prod * Matrix(i, j)
Endif
Enddo
Enddo
Yes = cPos>0 ! признак наличия положительных элементов
If (Yes) then
Ar = Summa / cPos
Geom = Prod ** (1./cPos)
Endif
end subroutine Primer
В главной программе:
implicit none! оператор должен быть в каждой программной единице
integer, parameter:: cR = 6, cCol = 8
real, dimension(1:cR, 1:cCol) :: Array
! локальные переменные
logical:: YesPlus ! признак – есть эл-ты >0
real :: Ar, Geom ! средние значения
! интерфейс подпрограммы
Interface
subroutine Primer(Matrix, Yes, Ar, Geom) ! заголовок процедуры
implicit none! оператор должен быть в каждой программной единице
! формальные параметры
real, dimension(:,:), intent(in) :: Matrix ! матрица
logical, intent(out) :: Yes ! признак – есть эл-ты >0
real, intent(out) :: Ar, Geom ! средние значения
end subroutine Primer
End interface
! исполняемые операторы:
. . .
call Primer(Array, YesPlus, Ar, Geom)
If (YesPlus) then
. . . ! печать результатов
Endif
End
В этом примере при описании массива – формального параметра – указаны только его тип и ранг; протяженности массива по измерениям не включены в список параметров. Форма массива перенимается у соответствующего фактического параметра. В этом случае присутствие интерфейса процедуры в вызывающей программе обязательно.
Среди исполняемых операторов подпрограммы с помощью функции shape определяется форма массива-параметра – одномерный массив Shape_Matr. Протяженности массива по измерениям равны Shape_Matr(1) (количество строк матрицы) и Shape_Matr(2) (количество ее столбцов).
Дата добавления: 2017-09-19; просмотров: 447;