The following example shows a derived-type definition with two
components:
TYPE EMPLOYEE
INTEGER ID
CHARACTER(LEN=40) NAME
END TYPE EMPLOYEE
The following shows how to declare a variable CONTRACT of type
EMPLOYEE:
TYPE(EMPLOYEE) :: CONTRACT
Note that both examples started with the keyword TYPE. The first
(initial) statement of a derived-type definition is called a
derived-type statement, while the statement that declares a
derived-type object is called a TYPE statement.
The following example shows how to reference component ID of parent
structure CONTRACT:
CONTRACT%ID
The following example shows a derived type with a component that is
a previously defined type:
TYPE DOT
REAL X, Y
END TYPE DOT
....
TYPE SCREEN
TYPE(DOT) C, D
END TYPE SCREEN
The following declares a variable of type SCREEN:
TYPE(SCREEN) M
Variable M has components M%C and M%D (both of type DOT); M%C has
components M%C%X and M%C%Y of type REAL.
The following example shows a derived type with a component that is
an array:
TYPE CAR_INFO
INTEGER YEAR
CHARACTER(LEN=15), DIMENSION(10) :: MAKER
CHARACTER(LEN=10) MODEL, BODY_TYPE*8
REAL PRICE
END TYPE
...
TYPE(CAR_INFO) MY_CAR
Note that MODEL has a character length of 10, but BODYTYPE has a
character length of 8. You can assign a value to a component of a
structure; for example:
MY_CAR%YEAR = 1985
The following shows an array structure component:
MY_CAR%MAKER
In the preceding example, if a subscript list (or substring) was
appended to MAKER, the reference would not be to an array structure
component, but to an array element or section.
Consider the following:
TYPE CHARGE
INTEGER PARTS(40)
REAL LABOR
REAL MILEAGE
END TYPE CHARGE
TYPE(CHARGE) MONTH
TYPE(CHARGE) YEAR(12)
Some valid array references for this type follow:
MONTH%PARTS(I) ! An array element
MONTH%PARTS(I:K) ! An array section
YEAR(I)%PARTS ! An array structure component
! (a whole array)
YEAR(J)%PARTS(I) ! An array element
YEAR(J)%PARTS(I:K) ! An array section
YEAR(J:K)%PARTS(I) ! An array section
YEAR%PARTS(I) ! An array section
The following example shows a derived type with a pointer component
that is of the type being defined:
TYPE NUMBER
INTEGER NUM
TYPE(NUMBER), POINTER :: BEFORE_NUM
TYPE(NUMBER), POINTER :: AFTER_NUM
END TYPE
A type such as this can be used to construct linked lists of
objects of type NUMBER.
The following example shows a private type:
TYPE, PRIVATE :: SYMBOL
LOGICAL TEST
CHARACTER(LEN=50) EXPLANATION
END TYPE SYMBOL
This type is private to the module. The module can be used by
another scoping unit, but type SYMBOL is not available.
The following example shows a derived-type definition that is
public with components that are private:
MODULE MATTER
TYPE ELEMENTS
PRIVATE
INTEGER C, D
END TYPE
...
END MODULE MATTER
In this case, components C and D are private to type ELEMENTS, but
type ELEMENTS is not private to MODULE MATTER. Any program unit
that uses the module MATTER can declare variables of type ELEMENTS,
and pass as arguments values of type ELEMENTS.
This design allows you to change components of a type without
affecting other program units that use the module.
If a derived type is needed in more than one program unit, the
definition should be placed in a module and accessed by a USE
statement whenever it is needed, as follows:
MODULE STUDENTS
TYPE STUDENT_RECORD
...
END TYPE
CONTAINS
SUBROUTINE COURSE_GRADE(...)
TYPE(STUDENT_RECORD) NAME
...
END SUBROUTINE
END MODULE STUDENTS
...
PROGRAM SENIOR_CLASS
USE STUDENTS
TYPE(STUDENT_RECORD) ID
...
END PROGRAM
Program SENIOR_CLASS has access to type STUDENT_RECORD, because it
uses module STUDENTS. Module procedure COURSE_GRADE also has
access to type STUDENT_RECORD, because the derived-type definition
appears in its host.