Лекция 8 МОДУЛИ

advertisement
Лекция 8
МОДУЛИ
Если много параметров ?
program prog
...
call sub1(X,Y,Z,X1,...,PAR)
...
call sub2(X,Y,Z,X1,...,PAR)
...
end
subroutine sub1(A,B,C,D,...,ZW)
! код подпрограммы
end subroutine sub1
subroutine sub2(A,B,C,D,...,ZW)
! код подпрограммы
end subroutine sub2
дублируем
параметры
Если много типов ?
program prog
type T0
integer x,y,z
complex cmpl
end type T0
type T1
real x
character symb
type (T0) style
end type T1
call sub3(massiv)
...
end
subroutine
sub3(massiv)
! дублируем
! типы данных T0, T1
end subroutine sub3
subroutine
sub4(massiv)
! дублируем
! типы данных T0, T1
end subroutine sub4
Если много процедур ?
program prog
subroutine sub3(...)
interface
! дублируем
subroutine
! интерфейсы
sub1(...)
call sub1(...)
...
end subroutine sub3
end subroutine sub1
end interface
subroutine sub4(...)
! дублируем
interface
! интерфейсы
subroutine
call sub1(...)
sub2(...)
end subroutine sub4
...
end subroutine sub2
end interface
end
Данные и процедуры вместе
program
sub5
sub1
module
типы, данные
процедуры
sub4
sub2
sub3
Назначение модулей
Данные и процедуры
в одной программной единице.
Обмен данными между процедурами и
головной программой.
Сокрытие типов, данных и процедур,
используемых для промежуточных вычислений.
Раздельное написание программ.
Состав модуля
module имя_модуля
use другие модули
public
private
protected
описание констант,
типов,
модульных переменных
contains
модульные процедуры
end module
MOD - файлы
После компиляции для каждого модуля создается
файл имя_модуля.mod
на который можно сослаться из других программ.
module FLOW
...
end module FLOW
flow.mod
module GRID
...
end module GRID
grid.mod
Additional Include Directories
Оператор use
Позволяет использовать
типы, данные и процедуры модуля
program prog
use mathlib ! используем модуль mathlib
Атрибут only позволяет использовать только
"избранные" данные или процедуры.
program prog
use mathlib, only : dot
! кроме dot,
! все остальные не используются
Оператор use
Во избежание конфликта одинаковых имен
модуля и программной единицы
используем операцию =>.
module math
integer :: A = 1000,B,C
end module
program prog
use math, AM => A
integer A
A = 80
write(*,*) AM, A
end
! 1000
80
Public, private и protected
Организация доступа к элементам модуля.
Public – данные и процедуры
доступны в других программных единицах
(по умолчанию).
Private – данные и процедуры
доступны внутри модуля.
Protected – доступны только значения данных
в других программных единицах
(нельзя изменять данные).
Public, private и protected
module math
integer, public :: A
integer, private :: B
integer, protected :: C
contains
subroutine init()
A = 1000; B = 2000; C = 3000
end subroutine init
end module math
program prog
use math
implicit none
call init()
A = 50
! public-переменная, полный доступ
B = 100
! private-переменная, доступна в модуле
write(*,*) C ! protected-переменная, доступ к значению
С = С+1
! нельзя изменять значение
end
Public, private и protected
Рекомендации по организации доступа.
Public – объявление констант, глобальных
переменных, типов и процедур.
Все промежуточные и служебные переменные,
процедуры и типы следует объявлять как private.
Доступ в головной программе к private данным
производить при помощи public – процедур.
При необходимости использовать значения
private-данных применяем protected.
Перегрузка процедур
Объединение под одним именем
множества разных процедур.
 Процедура вызывается с разным количеством
параметров.
 В вызове процедуры используются параметры
разных типов данных.
interface общее_имя
module procedure имя_1, имя_2 ,..., имя_N
end interface
Следим за однозначностью выбора одной из
объединённых процедур !
Пример перегрузки
module math
interface prod
module procedure umn, scalar, vector
end interface
contains
real function umn(A,B) ! умножение чисел
real A,B
umn = A*B
end function umn
real function scalar(A,B) ! скалярное умножение
real A(3), B(3)
scalar = A(1)*B(1)+A(2)*B(2)+A(3)*B(3)
end function scalar
subroutine vector(A,B,C) ! векторное умножение
real A(3), B(3), C(3)
C(1) = A(2)*B(3)-B(2)*A(3)
C(2) = A(3)*B(1)-A(1)*B(3)
C(3) = A(1)*B(2)-A(2)*B(1)
end subroutine vector
end module math
Пример перегрузки
program prog
use math
real A(3), B(3), C(3)
A = [2.0, -4.0, 5.0]
B = [4.0, -3.0, 0.0]
write(*,*) "Number = ", prod(4.0,5.0)
write(*,*) "Scalar product = ", prod(A,B)
call prod(A,B,C)
write(*,*) "Vector product = ", C
end
Результат работы программы.
Number =
20.00000
Scalar product =
20.00000
Vector product =
15.00000
20.00000
10.00000
Требования для перегрузки
В каждой паре перегружаемых процедур хотя бы один
параметр должен отвечать двум требованиям:
 по своему положению не имеет аналогов по типу;
module MD
interface func
module procedure F1, F2
end interface
contains
real function F1(A,B) ! A
real A, B
...
end function F1
real function F2(C,D) ! С
real C, D
...
end function F2
end module MD
и
B
вещественного типа
и
D
вещественного типа
Требования для перегрузки
 формальный параметр с таким же именем
отсутствует в списке параметров другой процедуры.
module MD ! --- warning
interface func
module procedure F1, F2
end interface
contains
real function F1(A,B)
real A
integer B
...
end function F1
real function F2(B,A)
real A
integer B
...
end function F2
end module MD
module MD
interface func
module procedure F1, F2
end interface
contains
real function F1(A,B)
real A
integer B
...
end function F1
real function F2(C,D)
real D
integer C
...
end function F2
end module MD
О модулях …

Легкое составление, отладка и модификация
программных единиц независимо друг от друга.
 Использующая программа не знает как устроен
модуль, она умеет с ним общаться
при помощи процедур.
 Хороший модуль снаружи лучше чем внутри и его
лучше использовать чем построить.
 Следует избегать создания модулей, работа
которых будет зависеть от предыстории.
Download