A reference to a component of a derived-type structure takes the following form: parent [%component [(s-list)]]... %component [(s-list)] parent Is the name of a scalar or array of derived type. The percent sign (%) is called a component selector. component Is the name of a component of the immediately preceding parent or component. s-list Is a list of one or more subscripts. If the list contains subscript triplets or vector subscripts, the reference is to an array section. Each subscript must be a scalar numeric expression with a value that is within the bounds of its dimension. The number of subscripts in any s-list must equal the rank of the immediately preceding parent or component. Each parent or component (except the rightmost) must be of derived type. The parent or one of the components can have nonzero rank (be an array). Any component to the right of a parent or component of nonzero rank must not have the POINTER attribute. The rank of the structure component is the rank of the part (parent or component) with nonzero rank (if any); otherwise, the rank is zero. The type and type parameters (if any) of a structure component are those of the rightmost part name. The structure component must not be referenced or defined before the declaration of the parent object. If the parent object has the INTENT, TARGET, or PARAMETER attribute, the structure component also has the attribute.
1 – Examples
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.