next up previous contents
След.: Массивы Выше: Объекты данных Пред.: Встроенные типы   Содержание


Производные типы

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

TYPE POINT

REAL X,Y

INTEGER:: COLOR = 0

CHARACTER(LEN = 10) COLOUR

END TYPE POINT

Общий синтакис таков:

TYPE [[, атрибуты]::] имя [параметры типа]

описание параметров типа

PRIVATE или SEQUENCE

описание полей

CONTAINS

описание связанных процедур

END TYPE [имя]

Имя типа не должно совпадать с именем встроенного типа (включая DOUBLEPRECISION). Возможные атрибуты: ABSTRACT, PUBLIC, PRIVATE, BIND(C), EXTENDS(имя родительского типа). Первый определяет абстрактный тип, последний -- расширение уже существующего типа. Подробнее об этом в параграфе 15. Атрибуты доступа PUBLIC или PRIVATE уместны при определении типа в модуле и определяют, виден ли тип извне модуля. Скрытые типы используются внутри модуля, но недоступны для программных единиц, использующих модуль. Открытые типы, соответственно, могут использоваться в них. Видимость полей типа никак не связана с видимостью самого типа. Атрибут взаимодействия с языком C рассмотрен в параграфе 14.

Если указано слово SEQUENCE, тип является последовательным. Его поля расположены в памяти последовательно и плотно, без пропусков. Поля могут быть только встроенных и последовательных типов. Связанные с типом процедуры не допускаются.

Скаляр производного типа называется структурой. Назначение типа объекту данных осуществляется указанием слова TYPE и имени в скобках:

TYPE(POINT):: CORNER, CURVE(1000)

Здесь определен один скаляр и массив из тысячи структур.

Два различных определения типа считаются задающими один и тот же тип, если имя типа совпадает, оба типа имеют атрибут SEQUENCE или BIND, не имеют скрытых полей, а параметры типа и поля совпадают по порядку, имени и атрибутам.

Доступ к полям структуры осуществляется посредством символа %

Например, CORNER%X = 0.0 или CORNER % X = 0.0

Возможность вложенности производных типов, включая рекурсивную (тип может содержать размещаемые поля и указатели того же типа) позволяет разрабатывать и использовать структуры данных произвольной сложности: связанные списки, деревья, графы, стеки и т.п. Последними по вложенности полями называются поля встроенного типа, поля, являющиеся указателями либо размещаемыми, а также последние по вложенности поля полей производного типа. Собственными полями производного типа являются его поля, а также собственные поля полей производного типа, не являющихся ни указателями, ни размещаемыми.

Поля объявляются по тем же правилам, что и обычные переменные. Допустимы атрибуты DIMENSION, CODIMENSION, CONTIGUOUOS, POINTER и ALLOCATABLE. Оператор PRIVATE делает объявленные после него поля скрытыми: они видны только из модуля, в котором тип объявлен; есть и одноименный атрибут. По умолчанию все поля открыты. Атрибут PUBLIC делает поля открытыми. Эти атрибуты применимы только в модулях. Если поле не размещаемое и не указатель, его тип должен быть определен (встроенный либо ранее определенный производный).

Связанные с типом процедуры описаны в § 15. Они позволяют определять присваивания и операции выражений и ввода/вывода для производных типов (что является одним из проявлений полиморфизма). Более того, производные типы являются базой для поддержки технологии ООП в Фортране (§ 15).

Производные типы могут иметь параметры разновидности типа, а также иные параметры, аналогичные параметру длины для строк. Если числовые типы (и логический тип) могут иметь разновидность, строковый тип -- разновидность (задающую кодировку) и длину, то производные типы могут иметь сколько угодно таких параметров. Они могут определять разновидности типов полей, длины текстовых полей, границы массивов и т.п. Имена параметров задаются при объявлении типа аналогично аргументам процедур, но при этом указывается, параметр разновидности это (KIND) или параметр «длины» (LEN). Может быть задано значение по умолчанию. Пример [12] типа «матрица»:

TYPE matrix(kind,m,n)

INTEGER, KIND :: kind=KIND(0.0D0) !значение по умолчанию

INTEGER, LEN :: m,n ! нет значений по умолчанию

REAL(kind) :: element(m,n)

END TYPE

Значения параметров типа указываются при объявлении объекта данных этого типа, например

TYPE(matrix(KIND(0.0D0),10,20)) :: a

объявляет матрицу двойной точности размера 10 на 20. Для указателя или размещаемого объекта параметр «длины» может быть двоеточием:

TYPE(matrix(KIND(0.0),:,:)),ALLOCATABLE :: a

Значение определяется при размещении или присваивании указателю.

Формальный аргумент процедуры может иметь в качестве параметра типа символ *, означающий перенимаемый параметр: значение определяется фактическим аргументом.

Возможен доступ по имени параметра (аналогично ключевым аргументам процедур):

TYPE(matrix(kind=KIND(0.0),m=10,n=20)) :: a

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

a%kind, a%m

Этот же синтаксис работает и с встроенными типами:

LOGICAL :: L

WRITE (*,*) L%KIND ! То же, что и KIND(L)

Для создания констант производного типа существует конструктор структур. Он имеет синтаксис

тип(список),

где список состоит из выражений вида [поле=]значение, разделенных запятыми. Нельзя определять поле более одного раза. Если определено поле предка, не следует определять унаследованные поля (про расширение типов см.§ 15). Следует определять неразмещаемые поля, если они не имеют инициализации. Имя поля можно опустить, если опущены все предыдущие имена полей. Важно: выражение имя(...) интерпретируется как вызов функции, если это возможно; как конструктор структуры оно интерпретируется только в том случае, если предыдущая интерпретация невозможна. Можно определить инициализированное и размещаемое поле. Пример[14]:

TYPE(POINT):: P = POINT(1.,2.)



Ilya A. Chernov 2012-12-19
X