
- •Lesson 5 Структура программы
- •Главная программа
- •Внешние процедуры
- •Процедуры-функции
- •Пример функции
- •Процедуры-подпрограммы
- •Пример подпрограммы
- •Параметры процедур
- •Implicit none
- •Массив как параметр процедуры
- •Интерфейсы
- •Interface
- •Interface
- •Внутренние процедуры
- •Implicit none
- •Встроенные функции
- •Пример присоединения объектов модуля.
- •Implicit none
- •Implicit none
- •Implicit none
Implicit none
real, dimension(1:10, 1:7) :: Array ! исходная матрица
real, dimension(1:10) :: Result ! результирующий массив
! локальные переменные
integer :: N=5 ! количество элементов для усреднения
integer :: i
real Average
! исполняемыеоператоры:
do i = 1, 10 !цикл по строкам матрицы
Result(i) = Average(Array(i, :), 7, N)
enddo
end program Main
Здесь в качестве фактического параметра функции – одномерного массива – используется секция двумерного массива (строка с номером i)
Массив как параметр процедуры
При описании массива – формальногопараметра – можно не включать протяженности массива по измерениям в список параметров. Форма массива в этом случае перенимается у соответствующегофактическогопараметра. Определить в программе форму или размер массива можно, обратившись к функциям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процедуры
endinterface
Интерфейсный блок может содержать описания нескольких процедур. Он размещается в вызывающей программе среди операторов описания; после этого интерфейсы процедур, содержащихся в нем, становятся явными.
При наличии интерфейса процедуры ошибки обращения к ней обнаруживаются уже на этапе компиляции.
Пример. Написать подпрограмму, определяющую, есть ли в вещественной матрице положительные элементы, и, если есть, вычисляющую их среднее арифметическое и среднее геометрическое значения. В главную программу включить интерфейс подпрограммы.
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 ! средние значения
! интерфейс подпрограммы