[an error occurred while processing this directive]
HP OpenVMS Systems Documentation |
HP Fortran for OpenVMS
|
Previous | Contents | Index |
String values in the C language are terminated with null characters (CHAR(0)) and can contain nonprintable characters (such as backspace).
Nonprintable characters are specified by escape sequences. An escape sequence is denoted by using the backslash (\) as an escape character, followed by a single character indicating the nonprintable character desired.
This type of string is specified by using a standard string constant followed by the character C. The standard string constant is then interpreted as a C-language constant. Backslashes are treated as escapes, and a null character is automatically appended to the end of the string (even if the string already ends in a null character).
Table 3-1 shows the escape sequences that are allowed in character constants.
Escape Sequence | Represents |
---|---|
\a or \A | A bell |
\b or \B | A backspace |
\f or \F | A formfeed |
\n or \N | A new line |
\r or \R | A carriage return |
\t or \T | A horizontal tab |
\v or \V | A vertical tab |
\x hh or \X hh | A hexadecimal bit pattern |
\ ooo | An octal bit pattern |
\0 | A null character |
\\ | A backslash (\) |
If a string contains an escape sequence that isn't in this table, the backslash is ignored.
A C string must also be a valid Fortran character constant. If the string is delimited by apostrophes, apostrophes in the string itself must be represented by two consecutive apostrophes ( '' ).
For example, the escape sequence \'string causes a compiler error because Fortran interprets the apostrophe as the end of the string. The correct form is \''string .
If the string is delimited by quotation marks, quotation marks in the string itself must be represented by two consecutive quotation marks ("").
The sequences \ooo and \xhh allow any ASCII character to be given as a one- to three-digit octal or a one- to two-digit hexadecimal character code. Each octal digit must be in the range 0 to 7, and each hexadecimal digit must be in the range 0 to F. For example, the C strings '\010'C and '\x08'C both represent a backspace character followed by a null character.
The C string '\\abcd'C is equivalent to the string '\abcd' with a null character appended. The string ''C represents the ASCII null character.
A character substring is a contiguous segment of a character string. It takes one of the following forms:
|
v
Is a character scalar constant, or the name of a character scalar variable or character structure component.e1
Is a scalar integer (or other numeric) expression specifying the leftmost character position of the substring; the starting point.e2
Is a scalar integer (or other numeric) expression specifying the rightmost character position of the substring; the ending point.a
Is the name of a character array.s
Is a subscript expression.
Both e1 and e2 must be within the range 1,2, ..., len, where len is the length of the parent character string. If e1 exceeds e2, the substring has length zero.
Character positions within the parent character string are numbered
from left to right, beginning at 1.
If the value of the numeric expression e1 or e2 is
not of type integer, it is converted to an integer before use (any
fractional parts are truncated).
If e1 is omitted, the default is 1. If e2 is omitted, the default is len. For example, NAMES(1,3)(:7) specifies the substring starting with the first character position and ending with the seventh character position of the character array element NAMES(1,3).
Consider the following example:
CHARACTER*8 C, LABEL LABEL = 'XVERSUSY' C = LABEL(2:7) |
LABEL(2:7) specifies the substring starting with the second character position and ending with the seventh character position of the character variable assigned to LABEL, so C has the value ' VERSUS ' .
Consider the following example:
TYPE ORGANIZATION INTEGER ID CHARACTER*35 NAME END TYPE ORGANIZATION TYPE(ORGANIZATION) DIRECTOR CHARACTER*25 BRANCH, STATE(50) |
The following are valid substrings based on this example:
BRANCH(3:15) ! parent string is a scalar variable STATE(20) (1:3) ! parent string is an array element DIRECTOR%NAME ! parent string is a structure component |
Consider the following example:
CHARACTER(*), PARAMETER :: MY_BRANCH = "CHAPTER 204" CHARACTER(3) BRANCH_CHAP BRANCH_CHAP = MY_BRANCH(9:11) ! parent string is a character constant |
BRANCH_CHAP is a character string of length 3 that has the value ' 204 ' .
You can create derived data types from intrinsic data types or previously defined derived types.
A derived type is resolved into "ultimate" components that are either of intrinsic type or are pointers.
The set of values for a specific derived type consists of all possible sequences of component values permitted by the definition of that derived type. Structure constructors are used to specify values of derived types.
Nonintrinsic assignment for derived-type entities must be defined by a subroutine with an ASSIGNMENT interface. Any operation on derived-type entities must be defined by a function with an OPERATOR interface. Arguments and function values can be of any intrinsic or derived type.
A derived-type definition specifies the name of a user-defined type and the types of its components. It takes the following form:
|
access
Is the PRIVATE or PUBLIC keyword. The keyword can only be specified if the derived-type definition is in the specification part of a module.name
Is the name of the derived type. It must not be the same as the name of any intrinsic type, or the same as the name of a derived type that can be accessed from a module.component-definition
Is one or more type declaration statements defining the component of derived type.The first component definition can be preceded by an optional PRIVATE or SEQUENCE statement. (Only one PRIVATE or SEQUENCE statement can appear in a given derived-type definition.)
PRIVATE specifies that the components are accessible only within the defining module, even if the derived type itself is public.
SEQUENCE causes the components of the derived type to be stored in the same sequence they are listed in the type definition. If SEQUENCE is specified, all derived types specified in component definitions must be sequence types.
A component definition takes the following form:
type [ [, attr] ::] component [(a-spec)] [ *char-len] [init-ex]
type
Is a type specifier. It can be an intrinsic type or a previously defined derived type. (If the POINTER attribute follows this specifier, the type can also be any accessible derived type, including the type being defined.)attr
Is an optional POINTER attribute for a pointer component, or an optional DIMENSION attribute for an array component. You can specify one or both attributes. If DIMENSION is specified, it can be followed by an array specification.The POINTER or DIMENSION attribute can only appear once in a given component-definition.
component
Is the name of the component being defined.a-spec
Is an optional array specification, enclosed in parentheses. If POINTER is specified, the array is deferred shape; otherwise, it is explicit shape. In an explicit-shape specification, each bound must be a constant scalar integer expression. For more information on array specifications, see Section 5.1.4.If the array bounds are not specified here, they must be specified following the DIMENSION attribute.
char-len
Is an optional scalar integer literal constant; it must be preceded by an asterisk (*). This parameter can only be specified if the component is of type CHARACTER.init-ex
Is an initialization expression or, for pointer components, =>NULL(). This is a Fortran 95 feature.If init-ex is specified, a double colon must appear in the component definition. The equals assignment symbol (=) can only be specified for nonpointer components.
The initialization expression is evaluated in the scoping unit of the type definition.
If a name is specified following the END TYPE statement, it must be the same name that follows TYPE in the derived type statement.
A derived type can be defined only once in a scoping unit. If the same derived-type name appears in a derived-type definition in another scoping unit, it is treated independently.
A component name has the scope of the derived-type definition only. Therefore, the same name can be used in another derived-type definition in the same scoping unit.
Two data entities have the same type if they are both declared to be of the same derived type (the derived-type definition can be accessed from a module or a host scoping unit).
If the entities are in different scoping units, they can also have the same derived type if they are declared with reference to different derived-type definitions, and if both derived-type definitions have all of the following:
Default initialization occurs if initialization appears in a derived-type component definition. (This is a Fortran 95 feature.)
The specified initialization of the component will apply even if the definition is PRIVATE.
Default initialization applies to dummy arguments with INTENT(OUT). It does not imply the derived-type component has the SAVE attribute.
Explicit initialization in a type declaration statement overrides default initialization.
To specify default initialization of an array component, use a constant expression that includes one of the following:
Pointers can have an association status of associated, disassociated, or undefined. If no default initialization status is specified, the status of the pointer is undefined. To specify disassociated status for a pointer component, use =>NULL().
You do not have to specify initialization for each component of a derived type. For example:
TYPE REPORT CHARACTER (LEN=20) REPORT_NAME INTEGER DAY CHARACTER (LEN=3) MONTH INTEGER :: YEAR = 1995 ! Only component with default END TYPE REPORT ! initialization |
Consider the following:
TYPE (REPORT), PARAMETER :: NOV_REPORT = REPORT ("Sales", 15, "NOV", 1996) |
In this case, the explicit initialization in the type declaration statement overrides the YEAR component of NOV_REPORT.
The default initial value of a component can also be overridden by default initialization specified in the type definition. For example:
TYPE MGR_REPORT TYPE (REPORT) :: STATUS = NOV_REPORT INTEGER NUM END TYPE MGR_REPORT TYPE (MGR_REPORT) STARTUP |
In this case, the STATUS component of STARTUP gets its initial value
from NOV_REPORT, overriding the initialization for the YEAR component.
3.3.3 Structure Components
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 integer (or other 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.
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 CONTRACT to be 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 BODY_TYPE 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:
MY_CAR%MAKER(2) (4:10) |
In this case, the component is substring 4 to 10 of the second element of array MAKER.
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 :: START_NUM => NULL() TYPE(NUMBER), POINTER :: NEXT_NUM => NULL() END TYPE |
A type such as this can be used to construct linked lists of objects of type NUMBER. Note that the pointers are given the default initialization status of disassociated.
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.
A structure constructor lets you specify scalar values of a derived type. It takes the following form:
d-name (expr-list) |
d-name
Is the name of the derived type.expr-list
Is a list of expressions specifying component values. The values must agree in number and order with the components of the derived type. If necessary, values are converted (according to the rules of assignment), to agree with their corresponding components in type and kind parameters.
A structure constructor must not appear before its derived type is defined.
If a component of the derived type is an array, the shape in the expression list must conform to the shape of the component array.
If a component of the derived type is a pointer, the value in the expression list must evaluate to an object that would be a valid target in a pointer assignment statement. (A constant is not a valid target in a pointer assignment statement.)
If all the values in a structure constructor are constant expressions, the constructor is a derived-type constant expression.
Consider the following derived-type definition:
TYPE EMPLOYEE INTEGER ID CHARACTER(LEN=40) NAME END TYPE EMPLOYEE |
This can be used to produce the following structure constructor:
EMPLOYEE(3472, "John Doe") |
The following example shows a type with a component of derived type:
TYPE ITEM REAL COST CHARACTER(LEN=30) SUPPLIER CHARACTER(LEN=20) ITEM_NAME END TYPE ITEM TYPE PRODUCE REAL MARKUP TYPE(ITEM) FRUIT END TYPE PRODUCE |
In this case, you must use an embedded structure constructor to specify the values of that component; for example:
PRODUCE(.70, ITEM (.25, "Daniels", "apple")) |
On pointer assignment, see Section 4.2.3.
Previous | Next | Contents | Index |