190 likes | 306 Views
Лекция 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.
E N D
Лекция 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) ! код подпрограммы endsubroutine sub1 subroutine sub2(A,B,C,D,...,ZW) ! код подпрограммы endsubroutine sub2 дублируем параметры
Если много типов ? programprog type T0 integerx,y,z complexcmpl endtype T0 type T1 real x charactersymb type (T0) style endtype T1 callsub3(massiv) ... end subroutine sub3(massiv) ! дублируем ! типы данных T0, T1 endsubroutine sub3 subroutine sub4(massiv) ! дублируем ! типы данных T0, T1 endsubroutinesub4
Если много процедур ? program prog interface subroutinesub1(...) ... endsubroutinesub1 endinterface interface subroutinesub2(...) ... endsubroutinesub2 endinterface end subroutine sub3(...) ! дублируем ! интерфейсы call sub1(...) endsubroutine sub3 subroutine sub4(...) ! дублируем ! интерфейсы call sub1(...) endsubroutine sub4
Данные и процедуры вместе program sub5 sub1 module типы, данные процедуры sub4 sub2 sub3
Назначение модулей Данные и процедуры в одной программной единице. Обмен данными между процедурами и головной программой. Сокрытие типов, данных и процедур, используемых для промежуточных вычислений. Раздельное написание программ.
Состав модуля moduleимя_модуля useдругие модули public private protected описаниеконстант, типов, модульных переменных contains модульные процедуры end module
MOD - файлы После компиляции для каждого модуля создается файл имя_модуля.mod на который можно сослаться из других программ. • moduleFLOW • ... • end module FLOW • moduleGRID • ... • end module GRID flow.mod grid.mod Additional Include Directories
Оператор use • Позволяет использовать • типы, данные и процедуры модуля • programprog • usemathlib! используем модуль mathlib • Атрибут only позволяет использовать только "избранные" данные или процедуры. • programprog • usemathlib, only : dot • ! кроме dot, • ! все остальные не используются
Оператор use Во избежание конфликта одинаковых имен модуля и программной единицы используем операцию =>. module math integer :: A = 1000,B,C end module programprog use math, AM=>A integer A A = 80 write(*,*) AM, A! 1000 80 end
Public, private и protected Организация доступа к элементам модуля. Public–данные и процедуры доступны в других программных единицах (по умолчанию). Private–данные и процедуры доступны внутри модуля. Protected– доступны только значения данных в других программных единицах (нельзя изменять данные).
Public, private и protected module math integer, public :: A integer, private :: B integer, protected :: C contains subroutineinit() A = 1000; B = 2000; C = 3000 end subroutineinit end module math programprog use math implicit none callinit() A = 50 ! public-переменная, полный доступ B = 100 ! private-переменная, доступна в модуле write(*,*) C ! protected-переменная, доступ к значению С=С+1 ! нельзя изменять значение end
Public, private и protected Рекомендации по организации доступа. Public– объявление констант, глобальных переменных, типов и процедур. Все промежуточные и служебные переменные, процедуры и типы следует объявлять как private. Доступ в головной программе к privateданным производить при помощи public– процедур. При необходимости использовать значения private-данных применяем protected.
Перегрузка процедур Объединение под одним именем множества разных процедур. Процедура вызывается с разным количеством параметров. В вызове процедуры используются параметры разных типов данных. interfaceобщее_имя moduleprocedureимя_1, имя_2 ,..., имя_N endinterface Следим за однозначностью выбора одной из объединённых процедур !
Пример перегрузки module math interface prod moduleprocedure umn, scalar, vector end interface contains realfunctionumn(A,B) ! умножениечисел real A,B umn = A*B end functionumn realfunction 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 modulemath
Пример перегрузки programprog 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 interfacefunc moduleprocedure F1, F2 end interface contains realfunction F1(A,B) ! A и B вещественного типа real A, B ... end function F1 realfunction F2(C,D) ! С и D вещественного типа real C, D ... end function F2 end moduleMD
Требования для перегрузки формальный параметр с таким же именем отсутствует в списке параметров другой процедуры. module MD ! --- warning interfacefunc moduleprocedure F1, F2 end interface contains realfunction F1(A,B) real A integer B ... end function F1 realfunction F2(B,A) real A integer B ... end function F2 end moduleMD module MD interfacefunc moduleprocedure F1, F2 end interface contains realfunction F1(A,B) real A integer B ... end function F1 realfunction F2(C,D) real D integer C ... end function F2 endmodule MD
О модулях … Легкое составление, отладка и модификация программных единиц независимо друг от друга. Использующая программа не знает как устроен модуль, она умеет с ним общаться при помощи процедур. Хороший модуль снаружи лучше чем внутри и его лучше использовать чем построить. Следует избегать создания модулей, работа которых будет зависеть от предыстории.