Наложение памяти
INTEGER A(20)
  REAL Y(20)
  EQUIVALENCE(A, Y)

Objects of default character do not need to have the same length. The following example associates character variable D with the last 4 (of the 6) characters of character array F:

  CHARACTER(LEN=4) D
  CHARACTER(LEN=3) F(2)
  EQUIVALENCE(D, F(1)(3:))
(R560) If an equivalence-object is of type default integer, default real, double precision real, 16
default complex, default logical, or numeric sequence type, all of the objects in the equivalence 17
set shall be of these types. 18
C589 (R560) If an equivalence-object is of type default character or character sequence type, all of the 19
objects in the equivalence set shall be of these types. 20
C590 (R560) If an equivalence-object is of a sequence derived type that is not a numeric sequence or 21
character sequence type, all of the objects in the equivalence set shall be of the same type with 22
the same type parameter values. 23
C591 (R560) If an equivalence-object is of an intrinsic type other than default integer, default real, 24
double precision real, default complex, default logical, or default character, all of the objects in 25
the equivalence set shall be of the same type with the same kind type parameter value.

COMMON блок

Все переменные в ФОРТРАНе имеют локальную область видимости. Это означает, что она известна только в модуле (главная программа, подпрограмма), в котором она объявлена. Если в другой подпрограмме есть переменная с тем же именем,  это совсем другая переменная (другая область памяти).

 
                    INTEGER a,b
                    a=5
                    b=7
                    CALL  sub1()
                    PRINT *,a,b                                                           ! напечатает 5,7
                    END
 
                    SUBROUTINE sub1()
                     INTEGER a,b
                     PRINT *,a,b                                                          ! напечатает неизвестно что (в CVF будет 0,0)
                    END
 

Для того, чтобы к одной и той же переменной можно было бы обратиться из разных модулей, в ФОРТРАНе ее надо поместить в  COMMON блок. COMMON блок может иметь имя, которое имеют глобальную область видимости, то есть известно во всех модулях. В программе может быть много COMMON блоков. Они должны иметь разные  имена.

                    Рассмотрим предыдущий пример с применением COMMON:
1                  INTEGER a,b
2                  REAL c
3                  COMMON /cm1/a,b,c
4                  a=5
5                  b=7
6                  CALL  sub1()
7                  PRINT *,a,b                                                           ! напечатает 5,7
8                  END
9
10                SUBROUTINE sub1()
11                 INTEGER a,b               
12                 REAL c
13                 COMMON /cm1/a,b,c
14                 PRINT *,a,b                                                          ! напечатает 5,7
15                END
 

Мы объявили в главной программе COMMON блок с именем cm1и положили в него 3 переменные a,b,c. Далее, в любой подпрограмме можно обратиться к содержимому этого COMMON блока. Для этого достаточно сослаться на него в неисполняемой части модуля (строка 13). При этом, так как глобально известными являются только имена COMMON блоков, в подпрограмме можно использовать имена переменных, включенных в него, отличные от первого описания. Другими словами, следующий вариант подпрограммы sub1 тождественен первоначальному.

10                SUBROUTINE sub1()
11                 INTEGER a1,a2           
12                 REAL ce
13                 COMMON /cm1/a1,a2,ce
14                 PRINT *,a1,b2                                                      ! напечатает 5,7
15                END
 

Можно представить себе COMMON блок как некоторую корзину, в которую в некотором порядке складываются переменные. В другом месте совершенно неважно, как переменные назывались. Важно, в каком порядке они клались туда. Поэтому следующий вариант НЕВЕРЕН:

 
10                SUBROUTINE sub1()
11                 INTEGER a1,a2           
12                 REAL ce
13                 COMMON /cm1/a1,ce,a2
14                 PRINT *,a1,b2                                                      ! напечатает 5,????
15                END

В момент создания cm1в него положили сначала 2 целые переменные, а затем вещественную, а в стр. 13 говорим, что они лежат в другом порядке. В результате значению целой переменной a2 в sub1 соответствует вещественная переменная ce, что неизбежно приведет к ошибке.

Отсюда вытекает правило использования COMMON блоков:

                    Список содержимого COMMON блока при описании в разных модулях  должен совпадать по порядку типов и длин переменных, но совершенно не обязательно по именам.

Есть один прием, который поможет избежать ошибок при использовании COMMON блоков – выносить описание COMMON блоков и всех переменных, включенных в него, в отдельный файл. Этот  файл  потом включается во всех модулях, где нужно.

                    include 'cm1.f90'
                    a=5
                    b=7
                    CALL  sub1()
                    PRINT *,a,b                                                           ! напечатает 5,7
                    END
 
                    SUBROUTINE sub1()
                     include 'cm1.f90'
                     PRINT *,a,b                                                          ! напечатает 5,7
                    END
 
Файл cm1.f90:
                    INTEGER a,b
                    REAL c
                    COMMON /cm1/a,b,c
 

Когда я говорил о COMMON блоке, как о корзине, я не сильно погрешил против истины. Компилятор собирает все переменные, входящие в этот COMMON блок, в одну последовательную область памяти.

Вот, что говориться о COMMON блоках в online documentation to CVF:

Defines one or more contiguous areas, or blocks, of physical storage (called common blocks) that can be accessed by any of the scoping units in an executable program. COMMON statements also define the order in which variables and arrays are stored in each common block, which can prevent misaligned data items.

COMMON [ /[cname]/] var-list [[,] /[cname]/ var-list ] ...
Блоки могут повторяться, дополняясь
COMMON /ralph/ ed, norton, trixie
  COMMON /     / fred, ethel, lucy
  COMMON /ralph/ audrey, meadows
  COMMON /jerry/ mortimer, tom, mickey
  COMMON melvin, purvis

They are equivalent to these COMMON statements:

  COMMON /ralph/ ed, norton, trixie, audrey, meadows
  COMMON         fred, ethel, lucy, melvin, purvis
  COMMON /jerry/ mortimer, tom, mickey
 

Но одна переменная может появиться только в одном COMMON блоке

 

Модуль

В современном фортране существует дополнительный тип программной единицы (как главная программа, подпрограмма и др.), который предпостительнее использовать для организации доступа к общим (для подпрограмм) данным. Это - модуль. Его можно рассматривать как набор (коллекция) объектов (данные, подпрограммы и функции), которые можно сделать доступными в ряде других программных единиц.

Структура модуля:

MODULE <module name>
<USE [other modules]>
IMPLICIT NONE
<Specification Section>
CONTAINS
<module procedure one>
<module procedure two>
: :
<module procedure n >
END MODULE <module name>

Модуль рекомендуется сохранять в отдельном файле.

Для включения содержимого модуля в какую-то программную единицу необходимо использовать оператор USE.

Синтаксис оператора:

USE <module_name>

Пример:

MODULE MyData
integer n
end module MyData

use MyData
implicit none
n=5
call s1()
print *,n
end

subroutine s1()
use MyData
implicit none
print *,n
end

Другой пример:

MODULE commondata
IMPLICIT NONE
SAVE
REAL :: pi=3.14159
INTEGER :: number=10
END MODULE commondata
! ************************************************************
PROGRAM example
USE commondata, ONLY : number, pi
IMPLICIT NONE
PRINT*,number,pi
END PROGRAM example

Оператор SAVE в модуле после IMPLICIT NONE необходим для того, чтобы данные не "забывались" между вызовами.

 

Дополнительно: http://www-solar.mcs.st-and.ac.uk/~steveb/course/notes/set6.pdf

 

Hosted by uCoz