Программирование больших вычислительных задач на современном Фортране с использованием компиляторов Intel

Модули

Показывать лекцию целиком

Презентацию к лекции Вы можете скачать здесь.

Если много параметров?

Если много типов?

Если много процедур?

Данные и процедуры вместе

Назначение модулей

  • Данные и процедуры в одной программной единице.
  • Обмен данными между процедурами и головной программой.
  • Сокрытие типов, данных и процедур, используемых для промежуточных вычислений.
  • Раздельное написание программ.
  • Состав модуля

    module имя_модуля
      use другие модули
    
      public
      private
      protected
         описание констант,
                  типов, 
                  модульных переменных
    
    contains
        модульные процедуры	
    
    end module
        

    Оператор use

    Позволяет использовать типы, данные и процедуры модуля

    program prog
      use mathlib ! используем модуль mathlib
        

    Атрибут only позволяет использовать только "избранные" данные или процедуры.

    program prog
      use mathlib, only : dot
      ! кроме dot, 
      ! все остальные не используются
        

    Во избежание конфликта одинаковых имен модуля и программной единицы используем операцию =>.

    module math
      integer :: A = 1000,B,C
    end module
    
    program prog
      use math, AM => A
      integer A
      A = 80
      write(*,*) AM, A    ! 1000   80
    end
        

    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.
    Доступ в головной программе к 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  и  B  вещественного типа
        real A, B
          ...
      end function F1
      real function F2(C,D) ! С  и  D  вещественного типа
        real C, D
          ...
       end function F2
    end module MD
              
  • формальный параметр с таким же именем отсутствует в списке параметров другой процедуры.
    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
                  
  • О модулях…

  • Легкое составление, отладка и модификация программных единиц независимо друг от друга.
  • Использующая программа не знает как устроен модуль, она умеет с ним общаться при помощи процедур.
  • Хороший модуль снаружи лучше чем внутри и его лучше использовать чем построить.
  • Следует избегать создания модулей, работа которых будет зависеть от предыстории.
  • Вернуться к учебному плану