Название: Квантовая механика - Учеб. пособие. (Краснопевцев Е. А.)

Жанр: Информатика

Просмотров: 1190


2. теоретические сведения

 

Модуль используется для задания глобальных данных и модульных процедур. Он имеет вид:

MODULE имя модуля

   [раздел описаний]

   [CONTAINS

      модульные процедуры]

END [MODULE [имя модуля]].

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

Следующие за оператором CONTAINS модульные процедуры должны завершаться END SUBROUTINE [имя подпрограммы] или END FUNCTION [имя функции]. Модульные процедуры, в свою очередь, после оператора CONTAINS могут содержать внутренние процедуры. Имя модуля, если оно следует за END MODULE, должно совпадать с именем в заголовке модуля.

Объявленные в операторах описания модуля имена доступны:

– в модульных процедурах;

– во внутренних процедурах модуля;

– в использующих модуль программных единицах (если имена не объявлены PRIVATE).

Модульные процедуры доступны:

– в других модульных процедурах модуля;

– в использующей модуль программной единице (если имена не объявлены PRIVATE).

Внутренняя процедура модуля доступна только в содержащей ее модульной процедуре-носителе.

Доступ к модулю в программной единице осуществляется посредством оператора USE, который предваряет раздел объявлений программной единицы. Используя оператор USE, модуль можно включить:

– в головную программу:

– во внешнюю процедуру;

– в другой модуль (при этом необходимо следить, чтобы модуль не ссылался сам на себя ни прямо, ни косвенно через другие модули).

Объектам модуля могут быть даны атрибуты PUBLIC и PRIVATE. Атрибут PUBLIC указывает, что объект модуля может быть доступен в использующих модуль программных единицах. Атрибут PRIVATE указывает, что объект модуля может быть использован только внутри модуля. По умолчанию объекты модуля имеют атрибут PUBLIC.

Формат задания атрибутов PUBLIC, PRIVATE соответствует принятому в FPS формату задания атрибутов.

Модуль testmod содержит модульную процедуру smod и внутреннюю процедуру smod2. С помощью оператора use модуль testmod включен в головную программу  prom и во внешнюю процедуру – подпрограмму osub.

Переменные а и b из раздела описания модуля testmod доступны головной программе prom и внешней процедуре osub. Поэтому изменения переменных а и b в модуле передаются в программные единицы prom и osub. Такой способ обмена данными называется us- ассоциированием.

Также видно, что значение переменной b, объявленной в модуле testmod, известно модульной подпрограмме smod и  внутренней подпрограмме smod2. Такой способ передачи данных называется ассоциированием через носитель. Благодаря ассоциированию через носитель модульная процедура  smod имеет доступ к переменной с, а внутренняя подпрограмма smod2, носителем которой является модульная подпрограмма smod, имеет доступ к локальной переменной с2 подпрограммы smod.

Также в примере головная программа prom, модульная подпрограмма smod, внутренняя подпрограмма smod2 обмениваются данными через параметр d. Такая передача данных называется ассоциированием параметров.

Переменная с с атрибутом private доступна только модульной процедуре smod и ее внутренней процедуре smod2.

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

 

module testmod

integer, save:: a=1, b=1

integer, private:: c=1

contains

  subroutine smod(d)

    integer:: d, c2=1

            d=2; b=1+c

            call smod2(d)

            print *,'smod:',d,b   ! 3 3

    contains

             subroutine smod2(d)

               integer d

               print *,'smod2:', d, b ! 2 2

               d=d+1; b=b+c2

             end subroutine smod2

   end subroutine

 end module testmod

 program prom

use testmod

   print *,'prom_1:',a, b  !  1 1

   call smod(a)

   print *,'prom_2:',a, b  !  3 3

   call osub()

   print *,'prom_3', a, b, с ! 4 4 0.00

 end program prom

 subroutine osub ()

 use testmod

 print *,'osub:', a, b

 a = 4; b = 4

 end

 

Исходный текст модуля может быть размещен в том же файле, в котором размещены использующие его программные единицы. При этом его текст должен предшествовать ссылкам на модуль (см. пример). Можно разместить модуль testmod в отдельном файле. При компиляции этого файла (файл должен быть включен в проект) для модуля будет создан файл, имеющий имя модуля и расширение MOD ( testmod. MOD).

USE-ассоциирование позволяет передавать не только данные, но и статус размещаемых массивов и ссылок.

Примеры:

б) module mod

    integer, pointer:: a(:)

  end module

 

  program tpo

  use mod

  integer, target:: b(5)=5

  a=> b

  call shost()

  print *,'tpo:', a  !  3  3  3

  end program

 

  subroutine shost()

  use mod

  integer, target:: c(3)=3

  print *,'shost:', a ! 5 5 5 5 5

  a=>c

  end subroutine shost

 
а) module wara

   integer n

   integer, allocatable:: work(:,:)

  end module wara

 

  program two

    use wara

call rewo()

work=2

print *, work(5,5)  !  2

call delo(4)

print *, work(5,5)  !  4

  end program two

 

subroutine rewo()

use wara

    print '(1x, a)', 'Enter n'

read (*,*) n

allocate (work(n, 2*n))

  end subroutine rewo

 

  subroutine delo(k)

    use wara

integer k

work(5,5)=k

   end subroutine delo

 

В приведенных примерах размещаемый массив work и массив-ссылка а, описанные в модулях wara и mod, через use-ассоции-рование известны использующим их программным компонентам two, rewo, delo и tpo, shost.

3. Примеры заданий и их программное решение

в языке Фортран

 

Пример 3.1

Даны одномерный массив а из целых чисел и одномерный массив b из вещественных чисел. Найти:

– произведение элементов массива а в процедуре-подпрограм-ме;

– сумму элементов массива b в процедуре-функции;

– найденное в процедуре-подпрограмме произведение удвоить в процедуре-функции и там же распечатать.

   При use-ассоциировании все данные, описанные в модуле ex1(массив а, массив b, переменная p), доступны во всех программных единицах g1, p1, f1.

    g1 – головная программа, p1 – внешняя процедура-подпрограмма,  f1 – внешняя процедура-функция.

При этом вызовы процедур можно осуществлять без параметров.

 
Сделать три варианта задания, поочередно используя use-ассоциирование, ассоциирование через носитель и ассоциирование через параметры.

 

USE – ассоциирование:

module ex1

  integer:: a(5)=(/4,7,1,3,1/), p

  real:: b(3)=(/1.5,9.1,10./)

end module ex1

 

Ассоциирование через носитель:

module ex1

  integer:: a(5)=(/4,7,1,3,1/)

  real:: b(3)=(/1.5,9.1,10./)

 

  contains

    function f1()

      integer dp

      f1= sum(b)

      call p1()

      dp=2*p

      print *,'dp', dp  !  168

     

          contains

          subroutine p1()

          p=product(a)

          print *, p  !  84

          print *,f1  !  20, 600000

         end subroutine p1

     end function f1

end module ex1

 

 
program g1

  use ex1

  call p1()

  print *, p  !  84

  s=f1()

  print *, s  !  20,600000

end

 

subroutine p1()

  use ex1

  p=product(a)

end

 

function f1()

  use ex1

  integer dp

  f1= sum(b)

  call p1()

  dp=2*p

  print *,'dp', dp  !  168

end

Модульной процедуре-функции f1 и внутренней процедуре-подпрограмме p1 доступны массивы a и b, описанные в модуле ex1, также внутренней процедуре-подпрограмме p1 доступна сумма f1 модульной процедуры-функции f1, а процедуре-функции f1 доступно произведение p внутренней процедуры подпрограммы p1 (ассоциирование через носитель).

Переменную p в модуле ex1 можно не объявлять, она доступна функции f1 через носитель.

В головной программе t1 можно вызвать только модульную процедуру-функцию f1, внутренняя же процедура-подпрограмма p1 недоступна головной программе, она доступна только модульной процедуре-носителю f1.

 

Ассоциирование через параметры:

program t1

  use ex1

  s=f1()

end

 

 

 
program t1

   integer:: a(5)=(/4,7,1,3,1/), p

   real:: b(3)=(/1.5,9.1,10./), s

   s=f1(b,a,3,5)

   print *, s  !  20, 600000

   call p1(a,5,p)

   print *, p  !  84

 end

 

 function f1(b,a,n,m)

     Ассоциирование через параметры осуществляется по соответствию формальных и фактических параметров (см. предыдущую лабораторную работу).

 
   integer::  dp, a(m), p

   real f1, b(n)

   f1= sum(b)

   call p1(a, m, p)

   dp=2*p

   print *,'dp', dp  !  168

  end function f1

 

  subroutine p1(a, m, p)

    integer a(m), p

    p=product(a)

  end subroutine p1

 

Пример 3.2.

б) вектор d как размещаемый

массив:

module ex2

 integer, parameter:: m=4, n=3

 integer:: b(m)=(/9,8,4,6/), & c(n)=(/1,5,8/)

 integer, allocatable:: d(:)

endmodule ex2

program g2

 use ex2

   interface

    function f2(b,k)

     integer f2(k),k,b(k)

    end function f2

   end interface

  call p2()

  print *,d  !   1   5

  deallocate(d)

  k=count(mask=mod(b,2)==0)

  allocate(d(k))

  d=f2(b,m)

  print *,d   !    8   4   6

end

subroutine p2()

  use ex2

  integer k, l/1/

  k=count(mask=mod(c,2)/=0)

  allocate(d(k))

  do i=1,n

    if(mod(c(i),2)/=0) then

      d(l)=c(i)

      l=l+1

    endif

  enddo

 end

 function f2(b,k)

   integer f2(k),k,b(k)

   integer l/1/

   do i=1,k

 
Даны два одномерных массива b и с. В процедуре-подпрограмме в динамический вектор d записать элементы массива с, имеющие нечетные значения. В процедуре-функции в динамический вектор d записать элементы массива b, имеющие четные значения.

а) вектор d как массив-ссылка:

module ex2

 integer, parameter:: m = 4, n = 3

 integer:: b(m) = (/ 9, 8, 4, 6 /), &

 c(n)= (/1, 5, 8 /)

 integer, pointer:: d(:)

endmodule ex2

 

program g2

  use ex2

  interface

   function f2( )

     integer, pointer:: f2(:)

    end function f2

   end interface

  call p2( )

  print *, d  !  1   5

  d=>f2( )

  print *, d  !  8   4   6

end

 

subroutine p2( )

  use ex2

  integer k,  l /1/

  k=count(mask=mod(c, 2)/=0)

  allocate(d(k))

  do i=1,n

    if(mod(c(i), 2)/=0) then

      d(l)=c(i)

      l=l+1

    endif

  enddo

 end

 

 if(mod(b(i),2)==0) then

f2(l)=b(i)

       l=l+1

     endif

   enddo

 end

 

 

 

 

 

 
function f2( )

  use ex2

  integer, pointer:: f2(:)

  integer k, l /1/

  k=count(mask=mod(b, 2)==0)

  allocate(f2(k))

  do i=1,m

    if(mod(b(i), 2)==0) then

      f2(l)=b(i)

      l=l+1

    endif

  enddo

 end

 

В случае а) динамический вектор d используется как массив-ссылка, в случае б) динамический вектор d используется как размещаемый массив. В том и другом случае он описан в модуле ex2. Через use-ассоциирование динамический вектор доступен во всех программных единицах, где подключен модуль.

Обмен данными между подпрограммой p2 и головной программой g2 осуществляется через use-ассоциирование, поэтому передача параметров при вызове подпрограммы отсутствует.

Обмен данными между функцией f2 и головной программой g2 в случае а) осуществляется через use-ассоциирование, а в случае б) через параметры (в функцию f2 передается массив b и его размер m, функция f2 при этом описана как массив f2(m)).

В случае а) процедура-функция f2 используется как массив-ссылка, к которому в головной программе подключен массив-ссылка d. В случае б) f2 используется как массивоподобная функция, которая присваивается в головной программе размещаемому массиву d. В том и другом случае требуется в головной программе явно описать интерфейс к функции f2 (см. лабораторную работу № 9).