Each constant, variable, array, expression, or function reference in a Fortran statement represents typed data. The data type of these items can be inherent in their constructions, implied by convention, or explicitly declared. Each data type has a name, a set of associated values, a way to denote the values, and operations to manipulate and interpret these values. There are two categories of data types: intrinsic and derived. The names of the intrinsic data types are predefined and are always accessible. Derived data types are user-defined data types that are made up of intrinsic or derived data types.
1 – Arrays
An array is a set of scalar elements that have the same type and kind type parameters. Any object that is declared with an array specification is an array. Arrays can be declared with a type declaration statement, a DIMENSION statement, or a COMMON statement. An array can be referenced by element (using subscripts), by section (using a section subscript list), or as a whole. A section subscript list consists of subscripts, subscript triplets, or vector subscripts. At least one subscript in the list must be a subscript triplet or vector subscript. When an array name without any subscripts appears in an intrinsic operation (for example, addition), the operation applies to the whole array (all elements in the array). An array has the following properties: o Data type An array can have any intrinsic or derived type. The data type of an array is either specified in a type declaration statement, or implied by the first letter of its name. All elements of the array have the same type and kind type parameters. If a value assigned to an individual array element is not the same as the type of the array, it is converted to the array's type. o Rank The rank of an array is the number of dimensions in the array. An array can have up to seven dimensions. A rank-one array represents a column of data (a vector), a rank-two array represents a table of data arranged in columns and rows (a matrix), a rank-three array represents a table of data on multiple pages (or planes), and so forth. o Bounds Arrays have a lower and upper bound in each dimension. These bounds determine the range of values that can be used as subscripts for the dimension. The value of either bound can be positive, negative, or zero. The bounds of a dimension are defined in an array specification. o Size The size of an array is the total number of elements in the array (the product of the array's extents). The extent of a dimension is the number of elements in that dimension. It is determined as follows: upper bound - lower bound + 1. If the value of any of an array's extents is zero, the array has a size of zero. o Shape The shape of an array is determined by its rank and extents, and can be represented as a rank-one array (vector) where each element is the extent of the corresponding dimension. Two arrays with the same shape are said to be conformable. A scalar is conformable to an array of any shape. The name and rank of an array are constant and must be specified when the array is declared. The extent of each dimension can be constant, but does not need to be. The extents can vary during program execution if the array is a dummy argument array, an automatic array, an array pointer, or an allocatable array. A whole array is referenced by the array name. Individual elements in a named array are referenced by a scalar subscript or list of scalar subscripts (if there is more than one dimension). A section of a named array is referenced by a section subscript. Consider the following array declaration: INTEGER L(2:11,3) The properties of array L are as follows: Data type: INTEGER Rank: 2 (two dimensions) Bounds: First dimension: 2 to 11 Second dimension: 1 to 3 Size: 30 (the product of the extents: 10 x 3) Shape: 10 by 3 (a vector of the extents (10,3)) The following example shows other valid ways to declare this array: DIMENSION L(2:11,3) INTEGER, DIMENSION(2:11,3) :: L COMMON L(2:11,3) The following example shows references to array elements, array sections, and a whole array: REAL B(10) ! Declares a rank-one array with 10 elements INTEGER C(5,8) ! Declares a rank-two array with 5 elements ! in dimension one and 8 elements in ! dimension two ... B(3) = 5.0 ! Reference to an array element B(2:5) = 1.0 ! Reference to an array section consisting of ! elements: B(2), B(3), B(4), B(5) ... C(4,8) = I ! Reference to an array element C(1:3,3:4) = J ! Reference to an array section consisting of ! elements: C(1,3) C(1,4) ! C(2,3) C(2,4) ! C(3,3) C(3,4) B = 99 ! Reference to a whole array consisting of ! elements: B(1), B(2), B(3), B(4), B(5), ! B(6), B(7), B(8), B(9), and B(10)
1.1 – Declarators
An array specification (or array declarator) declares the shape of an array. It takes the following form: (array-spec) array-spec Is one of the following array specifications: Explicit-shape Assumed-shape Assumed-size Deferred-shape The array specification is appended to the name of the array when the array is declared. The following examples show different forms of array specifications: SUBROUTINE SUB(N, C, D, Z) REAL, DIMENSION(N, 15) :: IARRY ! An explicit-shape array REAL C(:), D(0:) ! An assumed-shape array REAL, POINTER :: B(:,:) ! A deferred-shape array pointer REAL :: Z(N,*) ! An assumed-size array REAL, ALLOCATABLE, DIMENSION(:) :: K ! A deferred-shape ! allocatable array
1.1.1 – Explicit Shape
An explicit-shape array is declared with explicit values for the bounds in each dimension of the array. An explicit-shape specification takes the following form: [lower-bound:] upper-bound [,[lower-bound:] upper-bound ]... The lower bound (if present) and the upper bound are specification expressions that have a positive, negative, or zero value. If necessary, the bound value is converted to integer type. If the lower bound is not specified, it is assumed to be 1. The bounds can be specified as constant or nonconstant expressions, as follows: o If the bounds are constant expressions, the subscript range of the array in a dimension is the set of integer values between and including the lower and upper bounds. If the lower bound is greater than the upper bound, the range is empty, the extent in that dimension is zero, and the array has a size of zero. o If the bounds are nonconstant expressions, the array must be declared in a procedure. The bounds can have different values each time the procedure is executed, since they are determined when the procedure is entered. The bounds are not affected by any redefinition or undefinition of the specification variables that occurs while the procedure is executing. The following explicit-shape arrays can specify nonconstant bounds: - An automatic array (the array is a local variable) - An adjustable array (the array is a dummy argument to a subprogram) The following are examples of explicit-shape specifications: INTEGER I(3:8, -2:5) ! Rank-two array; range of dimension one is ... ! 3 to 8, range of dimension two is -2 to 5 SUBROUTINE SUB(A, B, C) INTEGER :: B, C REAL, DIMENSION(B:C) :: A ! Rank-one array; range is B to C
1.1.1.1 – Automatic Arrays
An automatic array is an explicit-shape array that is a local variable. Automatic arrays are only allowed in function and subroutine subprograms, and are declared in the specification part of the subprogram. At least one bound of an automatic array must be a nonconstant specification expression. The bounds are determined when the subprogram is called. The following example shows automatic arrays: SUBROUTINE SUB1 (A, B) INTEGER A, B, LOWER COMMON /BOUND/ LOWER ... INTEGER AUTO_ARRAY1(B) ... INTEGER AUTO_ARRAY2(LOWER:B) ... INTEGER AUTO_ARRAY3(20, B*A/2) END SUBROUTINE
1.1.1.2 – Adjustable Arrays
An adjustable array is an explicit-shape array that is a dummy argument to a subprogram. At least one bound of an adjustable array must be a nonconstant specification expression. The bounds are determined when the subprogram is called. The array specification can contain integer variables that are either dummy arguments or variables in a common block. When the subprogram is entered, each dummy argument specified in the bounds must be associated with an actual argument. If the specification includes a variable in a common block, it must have a defined value. The array specification is evaluated using the values of the actual arguments, as well as any constants or common block variables that appear in the specification. The size of the adjustable array must be less than or equal to the size of the array that is its corresponding actual argument. To avoid possible errors in subscript evaluation, make sure that the bounds expressions used to declare multidimensional adjustable arrays match the bounds as declared by the caller. In the following example, the function computes the sum of the elements of a rank-two array. Notice how the dummy arguments M and N control the iteration: FUNCTION MY_SUM(A, M, N) DIMENSION A(M, N) SUMX = 0.0 DO J = 1, N DO I = 1, M SUMX = SUMX + A(I, J) END DO END DO MY_SUM = SUMX END FUNCTION The following are examples of calls on SUM: DIMENSION A1(10,35), A2(3,56) SUM1 = MY_SUM(A1,10,35) SUM2 = MY_SUM(A2,3,56)
1.1.2 – Assumed Shape
An assumed-shape array is a dummy argument array that assumes the shape of its associated actual argument array. An assumed-shape specification takes the following form: [lower-bound]: [,[lower-bound]:] ... The lower bound is a specification expression. If the lower bound is not specified, it is assumed to be 1. The rank of the array is the number of colons (:) specified. The value of the upper bound is the extent of the corresponding dimension of the associated actual argument array + lower-bound - 1. The following is an example of an assumed-shape specification: INTERFACE SUBROUTINE SUB(M) INTEGER M(:, 1:, 5:) END SUBROUTINE END INTERFACE INTEGER L(20, 5:25, 10) CALL SUB(L) SUBROUTINE SUB(M) INTEGER M(:, 1:, 5:) END SUBROUTINE Array M has the same extents as array L, but array M has bounds (1:20, 1:21, 5:14). Note that an explicit interface is required when calling a routine that expects an assumed-shape or pointer array.
1.1.3 – Assumed Size
An assumed-size array is a dummy argument array that assumes the size (only) of its associated actual argument array; the rank and extents can differ for the actual and dummy arrays. An assumed-size specification takes the following form: [exp-shape-spec,] [exp-shape-spec,]... [lower-bound:] * The exp-shape-spec is an explicit-shape specification (see DATA ARRAY DECL EXPL in online Help). The lower bound and upper bound are specification expressions that have a positive, negative, or zero value. If necessary, the bound value is converted to integer type. If a lower bound is not specified, it is assumed to be 1. The asterisk (*) represents the upper bound of the last dimension. The rank of the array is the number of explicit-shape specifications plus 1. The size of the array is assumed from the actual argument associated with the assumed-size dummy array as follows: o If the actual argument is an array of type other than default character, the size of the dummy array is the size of the actual array. o If the actual argument is an array element of type other than default character, the size of the dummy array is a + 1 - s, where "s" is the subscript value and "a" is the size of the actual array. o If the actual argument is a default character array, array element, or array element substring, and it begins at character storage unit b of an array with n character storage units, the size of the dummy array is as follows: MAX(INT((n + 1 - b) / y), 0) The "y" is the length of an element of the dummy array. An assumed-size array can only be used as a whole array reference in the following cases: o When it is an actual argument in a procedure reference that does not require the shape o In the intrinsic function LBOUND Because the actual size of an assumed-size array is unknown, an assumed-size array cannot be used as any of the following in an I/O statement: o An array name in the I/O list o A unit identifier for an internal file o A run-time format specifier The following is an example of an assumed-size specification: SUBROUTINE SUB(A, N) REAL A, N DIMENSION A(1:N, *) ...
1.1.4 – Deferred Shape
A deferred-shape array is an array pointer or an allocatable array. The array specification contains a colon (:) for each dimension of the array. No bounds are specified. The bounds (and shape) of allocatable arrays and array pointers are determined when space is allocated for the array during program execution. An array pointer is an array declared with the POINTER attribute. Its bounds and shape are determined when it is associated with a target by pointer assignment, or when the pointer is allocated by execution of an ALLOCATE statement. In pointer assignment, the lower bound of each dimension of the array pointer is the result of the LBOUND intrinsic function applied to the corresponding dimension of the target. The upper bound of each dimension is the result of the UBOUND intrinsic function applied to the corresponding dimension of the target. A pointer dummy argument can be associated only with a pointer actual argument. An actual argument that is a pointer can be associated with a nonpointer dummy argument. A function result can be declared to have the pointer attribute. An allocatable array is declared with the ALLOCATABLE attribute. Its bounds and shape are determined when the array is allocated by execution of an ALLOCATE statement. The following are examples of deferred-shape specifications: REAL, ALLOCATABLE :: A(:,:) ! Allocatable array REAL, POINTER :: C(:), D (:,:,:) ! Array pointers
1.2 – Whole Arrays
A whole array is referenced by the name of the array (without any subscripts). It can be a named constant or a variable. If a whole array appears in a nonexecutable statement, the statement applies to the entire array. For example: INTEGER, DIMENSION(2:11,3) :: L ! Specifies the type and ! dimensions of array L If a whole array appears in an executable statement, the statement applies to all of the elements in the array. For example: L = 10 ! The value 10 is assigned to all the ! elements in array L WRITE *, L ! Prints all the elements in array L
1.3 – Subscripts
Arrays can be referenced by individual elements or by a range of elements (array sections). A subscript list (appended to the array name) indicates which array element or array section is being referenced. In the subscript list for an array section, at least one of the subscripts must be a subscript triplet or vector subscript. VSI Fortran permits intrinsic noninteger expressions for subscripts, but they are converted to integers before use (any fractional parts are truncated).
1.4 – Elements
An array element is one of the scalar data items that make up an array. A subscript list (appended to the array or array component) determines which element is being referred to. A reference to an array element takes the following form: array [(s-list)] array Is the name of an array. s-list Is a list of one or more subscripts. The number of subscripts must equal the rank of the array. Each subscript must be a scalar numeric expression with a value that is within the bounds of its dimension. Each array element inherits the type, kind type parameter, and certain attributes (INTENT, PARAMETER, and TARGET) of the parent array. An array element cannot inherit the POINTER attribute. If an array element is of type character, it can be followed by a substring range in parentheses; for example: ARRAY_D(1,2) (1:3) ! elements are substrings of length 3 However, by convention, such an object is considered to be a substring rather than an array element. The following are some valid array element references for an array declared as REAL B(10,20): B(1,3), B(10,10), and B(5,8). For information on arrays as structure components, see DATA DERIVED COMP in online Help.
1.4.1 – Order of Elements
The elements of an array form a sequence known as the array element order. The position of an element in this sequence is its subscript order value. The elements of an array are stored as a linear sequence of values. A one-dimensional array is stored with its first element in the first storage location and its last element in the last storage location of the sequence. A multidimensional array is stored so that the leftmost subscripts vary most rapidly. This is called the order of subscript progression. In an array section, the subscript order of the elements is their order within the section itself. For example, if an array is declared as B(20), the section B(4:19:4) consists of elements B(4), B(8), B(12), and B(16). The subscript order value of B(4) in the array section is 1; the subscript order value of B(12) in the section is 3.
1.5 – Sections
An array section is a portion of an array that is an array itself. It is an array subobject. A section subscript list (appended to the array or array component) determines which portion is being referred to. A reference to an array section takes the following form: array [(sect-s-list)] [(substring-range)] array Is the name of an array. sect-s-list Is a list of one or more section subscripts (subscripts, subscript triplets, or vector subscripts) indicating a set of elements along a particular dimension. At least one of the items in the section subscript list must be a subscript triplet or vector subscript. Each subscript and subscript triplet must be a scalar numeric expression. Each vector subscript must be a rank-one integer expression. substring-range Is a substring range in the form [expr]:[expr]. Each expression specified must be a scalar numeric expression. The array (or array component) preceding the substring range must be of type character. If no section subscript list is specified, the rank and shape of the array section is the same as the parent array. Otherwise, the rank of the array section is the number of vector subscripts and subscript triplets that appear in the list. Its shape is a rank-one array where each element is the number of integer values in the sequence indicated by the corresponding subscript triplet or vector subscript. If any of these sequences is empty, the array section has a size of zero. The subscript order of the elements of an array section is that of the array object that the array section represents. Each array section inherits the type, kind type parameter, and certain attributes (INTENT, PARAMETER, and TARGET) of the parent array. An array section cannot inherit the POINTER attribute. The following shows valid references to array sections: REAL, DIMENSION(20) :: B ... PRINT *, B(2:20:5) ! the section consists of elements ! B(2), B(7), B(12), and B(17) K = (/3, 1, 4/) B(K) = 0.0 ! section B(K) is a rank-one array with ! shape (3) and size 3. (0.0 is assigned to ! B(1), B(3), and B(4).) Consider the following declaration: CHARACTER(LEN=15) C(10,10) An array section referenced as C(:,:)(1:3) is an array of shape (10,10) whose elements are substrings of length 3 of the corresponding elements of C.
1.5.1 – Triplets
A subscript triplet consists of three parts: the first two parts designate a range of subscript values and the third part designates the increment (stride) between each value. It takes the following form: [subscript-1] : [subscript-2] [:stride] subscript-1 Is a scalar numeric expression representing the first value in the subscript sequence. If omitted, the declared lower bound of the dimension is used. subscript-2 Is a scalar numeric expression representing the last value in the subscript sequence. If omitted, the declared upper bound of the dimension is used. When indicating sections of an assumed-size array, this subscript must be specified. stride Is a scalar numeric expression representing the increment between successive subscripts in the sequence. It must have a nonzero value. If it is omitted, it is assumed to be 1. The stride has the following effects: o If the stride is positive, the subscript range starts with the first subscript and is incremented by the value of the stride, until the largest value less than or equal to the second subscript is attained. For example, if an array has been declared as B(6,3,2), the array section specified as B(2:4,1:2,2) is a rank-two array with shape (3,2) and size 6. It consists of the following six elements: B(2,1,2) B(2,2,2) B(3,1,2) B(3,2,2) B(4,1,2) B(4,2,2) If the first subscript is greater than the second subscript, the range is empty. o If the stride is negative, the subscript range starts with the value of the first subscript and is decremented by the absolute value of the stride, until the smallest value greater than or equal to the second subscript is attained. For example, if an array has been declared as A(15), the array section specified as A(10:3:-2) is a rank-one array with shape (4) and size 4. It consists of the following four elements: A(10) A(8) A(6) A(4) If the second subscript is greater than the first subscript, the range is empty. If a range specified by the stride is empty, the array section has a size of zero. A subscript in a subscript triplet need not be within the declared bounds for that dimension if all values used to select the array elements are within the declared bounds. For example, if an array has been declared as A(15), the array section specified as A(4:16:10) is valid. The section is a rank-one array with shape (2) and size 2. It consists of elements A(4) and A(14). If the subscript triplet does not specify bounds or stride, but only a colon (:), the entire declared range for the dimension is used.
1.5.2 – Vector Subscripts
A vector subscript is a rank-one array of integer values (within the declared bounds for the dimension). It is used to select a sequence of elements from a parent array. The sequence does not have to be in order, and it can contain duplicate values. For example, A is a rank-two array of shape (4,6). B and C are rank-one arrays of shape (2) and (3), respectively, with the following values: B = (/1,4/) C = (/2,1,1/) ! Will result in a many-one ! array section Array section A(3,B) consists of elements A(3,1) and A(3,4). Array section A(C,1) consists of elements A(2,1), A(1,1), and A(1,1). Array section A(B,C) consists of the following elements: A(1,2) A(1,1) A(1,1) A(4,2) A(4,1) A(4,1) An array section with a vector subscript that has two or more elements with the same value is called a many-one array section. A many-one section must not appear on the left of the equals sign in an assignment statement, or as an input item in a READ statement. The following assignments to C also show examples of vector subscripts: INTEGER A(2), B(2), C(2) ... B = (/1,2/) C(B) = A(B) C = A((/1,2/)) An array section with a vector subscript must not be any of the following: o An internal file o An actual argument associated with a dummy array that is defined or redefined (if the INTENT attribute is specified, it must be INTENT(IN)) o The target in a pointer assignment statement If the sequence specified by the vector subscript is empty, the array section has a size of zero.
1.6 – Constructors
An array constructor is a sequence of scalar values that is interpreted as a rank-one array. The array element values are those specified in the sequence. An array constructor takes the following form: (/ac-value-list/) ac-value-list Is a list of one or more expressions or implied-do loops. Each ac-value must have the same type and kind type parameter. An implied-do loop in an array constructor takes the following form: (ac-value-expr, do-variable = expr1, expr2 [,expr3]) ac-value-expr Is a scalar expression evaluated for each value of the d-variable to produce an array element value. do-variable Is the name of a scalar integer variable. Its scope is that of the implied-do loop. expr Is a scalar integer expression. The expr1 and expr2 specify a range of values for the loop; expr3 specifies the stride. The array constructor has the same type as the ac-value-list expressions. If the sequence of values specified by the array constructor is empty (there are no expressions or the implied-do loop produces no values), the rank-one array has a size of zero. The ac-value specifies the following: o If it is a scalar expression, its value specifies an element of the array constructor. o If it is an array expression, the values of the elements of the expression, in array element order, specify the corresponding sequence of elements of the array constructor. o If it is an implied-do loop, it is expanded to form an array constructor value sequence under the control of the DO variable, as in the DO construct. If every expression in an array constructor is a constant expression, the array constructor is a constant expression. If an implied-do loop is contained within another implied-do loop (nested), they cannot have the same DO variable (do-variable). There are three forms for an ac-value, as follows: C1 = (/4,8,7,6/) ! A scalar expression C2 = (/B(I, 1:5), B(I:J, 7:9)/) ! An array expression C3 = (/(I, I=1, 4)/) ! An implied-do loop You can also mix these forms, for example: C4 = (/4, A(1:5), (I, I=1, 4), 7/) To define arrays of more than one dimension, use the RESHAPE intrinsic function. The following are alternative forms for array constructors: o Square brackets (instead of parentheses and slashes) to enclose array constructors; for example, the following two array constructors are equivalent: INTEGER C(4) C = (/4,8,7,6/) C = [4,8,7,6] o A colon-separated triplet (instead of an implied-do loop) to specify a range of values and a stride; for example, the following two array constructors are equivalent: INTEGER D(3) D = (/1:5:2/) ! Triplet form D = (/(I, I=1, 5, 2)/) ! Implied-do loop form The following example shows an array constructor using an implied-do loop: INTEGER ARRAY_C(10) ARRAY_C = (/(I, I=30, 48, 2)/) The values of ARRAYC are the even numbers 30 through 48. The following example shows an array constructor of derived type that uses a structure constructor: TYPE EMPLOYEE INTEGER ID CHARACTER(LEN=30) NAME END TYPE EMPLOYEE TYPE(EMPLOYEE) CC_4T(4) CC_4T = (/EMPLOYEE(2732,"JONES"), EMPLOYEE(0217,"LEE"), & EMPLOYEE(1889,"RYAN"), EMPLOYEE(4339,"EMERSON")/) The following example shows how the RESHAPE intrinsic function is used to create a multidimensional array: E = (/2.3, 4.7, 6.6/) D = RESHAPE(SOURCE = (/3.5,(/2.0,1.0/),E/), SHAPE = (/2,3/)) D is a rank-two array with shape (2,3) containing the following elements: 3.5 1.0 4.7 2.0 2.3 6.6
1.7 – Dynamic Data
Allocatable arrays and pointer targets can be dynamically allocated (created) and deallocated (freed), by using the ALLOCATE and DEALLOCATE statements, respectively. Pointers are associated with targets by pointer assignment or by allocating the target. They can be dynamically disassociated from targets by using the NULLIFY statement.
2 – Constants
A constant is a fixed value. The value of a constant can be a numeric value, a logical value, or a character string. A constant that has a name is a named constant. A named constant can be of any type, including derived type, and it can be array-valued. A named constant has the PARAMETER attribute and is specified in a type declaration statement or PARAMETER statement. A constant that does not have a name is a literal constant. A literal constant must be of intrinsic type and it cannot be array-valued. There are nine types of literal constants: integer, real, complex, binary, octal, hexadecimal, logical, character, and Hollerith. Binary, octal, hexadecimal, and Hollerith constants have no data type; they assume a data type that conforms to the context in which they are used.
2.1 – Binary
You can use this type of constant wherever numeric constants are allowed; it assumes a numeric data type according to its context. A binary constant has one of these forms: B'd[d...]' B"d[d...]" d Is a binary (base 2) digit (0 or 1). You can specify up to 128 binary digits in a binary constant.
2.2 – Character
A character constant is a string of printable ASCII characters enclosed by delimiters. It takes one of the following forms: [k_]'[c...]' [C] [k_]"[c...]" [C] k Is an optional kind type parameter (1 is the default). It must be followed by an underscore. c Is an ASCII character. C Is a C string specifier. If no kind type parameter is specified, the type is default character. The length of the character constant is the number of characters between the delimiters. In the apostrophe format, two consecutive apostrophes represent a single apostrophe. In the quotation mark format, two consecutive quotation marks represent a single quotation mark. The length of a character constant must be in the range 0 to 2000.
2.2.1 – C Strings
String values in the C language are terminated with null characters (CHAR(0)) and can contain nonprintable characters (such as a 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). The following C-style escape sequences 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 character constant contains any other escape sequence, the backslash is ignored. A C string must also be a valid Fortran string. 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 \x"hh" 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.
2.3 – Complex
A complex constant consists of a pair of real or integer constants. The two constants are separated by a comma and enclosed in parentheses. The first constant represents the real part of the number and the second constant represents the imaginary part. VSI Fortran provides three kind type parameters for data of type complex: COMPLEX(KIND=4) (or COMPLEX*8), COMPLEX(KIND=8) (or COMPLEX*16), and COMPLEX(KIND=16). COMPLEX(KIND=8) is DOUBLE COMPLEX. The type specifier for the complex type is COMPLEX; the type specifier for the double complex type is DOUBLE COMPLEX. If a kind type parameter is specified, the complex constant has the kind specified. If no kind type parameter is specified, the kind type of both parts is default real, and the constant is of type default complex. A COMPLEX (COMPLEX(KIND=4) or COMPLEX*8) constant has the form: (c,c) c Is an integer or REAL (REAL(KIND=4) or REAL*4) constant A DOUBLE COMPLEX (COMPLEX(KIND=8) or COMPLEX*16) constant has the form: (c,c) c Is an integer, REAL (REAL(KIND=4) or REAL*4), or DOUBLE PRECISION (REAL(KIND=8) or REAL*8) constant. At least one of the pair must be a DOUBLE PRECISION constant. A COMPLEX(KIND=16) or COMPLEX*32 constant has the form: (c,c) c Is an integer, REAL (REAL(KIND=4) or REAL*4), DOUBLE PRECISION (REAL(KIND=8) or REAL*8), or REAL (KIND=16) (or REAL*16) constant. At least one of the pair must be a a REAL(KIND=16)constant. Note that the comma and parentheses are required.
2.4 – Hexadecimal
You can use this type of constant wherever numeric constants are allowed; it assumes a numeric data type according to its context. A hexadecimal constant has one of these forms: Z'd[d...]' Z"d[d...]" d Is a hexadecimal (base 16) digit in the range 0 - 9, or a letter in the range A - F, or a - f You can specify up to 128 bits in hexadecimal (32 hexadecimal digits) constants. Leading zeros are ignored.
2.5 – Hollerith
A Hollerith constant is a string of printable characters preceded by a character count and the letter H. It is used only in numeric expressions and has the form: nHc[c...] n Is an unsigned, nonzero integer constant stating the number of characters in the string (including tabs and spaces). c Is a printable ASCII character. A Hollerith constant can be a string of 1 to 2000 characters and is stored as a byte string, one character per byte. Hollerith constants have no data type, but assume a numeric data type according to the context in which they are used. They assume data types according to the following rules: o When the constant is used with a binary operator, including the assignment operator, the data type of the constant is the data type of the other operand. o When a specific data type is required, that type is assumed for the constant. o When the constant is used as an actual argument, no data type is assumed. When the length of the constant is less than the length implied by the data type, blanks are appended to the constant on the right. When the length of the constant is greater than the length implied by the data type, the constant is truncated on the right. If any characters other than blank characters are truncated, an error occurs.
2.6 – Integer
An integer constant is a whole number with no decimal point. It can have a leading sign and is interpreted as a decimal number. VSI Fortran provides four kind type parameters for data of type integer: INTEGER(KIND=1) (or INTEGER*1), INTEGER(KIND=2) (or INTEGER*2), INTEGER(KIND=4) (or INTEGER*4), and INTEGER(KIND=8) (or INTEGER*8). The type specifier for the integer type is INTEGER. If a kind type parameter is specified, the integer has the kind specified. If a kind type parameter is not specified, integer constants are interpreted as follows: o If the integer constant is within the default integer kind, the kind is default integer. o If the integer constant is outside the default integer kind, the kind type of the integer constant is the smallest integer kind which holds the constant. Integer constants take the following form: [s]n[n...][_k] s Is a sign; required if negative (-), optional if positive (+). n Is a decimal digit (0 through 9). Any leading zeros are ignored. k Is an optional kind type parameter (1 for INTEGER(KIND=1), 2 for INTEGER(KIND=2), 4 for INTEGER(KIND=4), and 8 for INTEGER(KIND=8)). It must be preceded by an underscore (_). An unsigned constant is assumed to be nonnegative. Integers are expressed in decimal values (base 10) by default. To specify a constant that is not in base 10, use the following syntax: [s][[base] #]nnn... s Is a sign; required if negative (-), optional if positive (+). base Is any constant from 2 through 36. If "base" is omitted but # is specified, the integer is interpreted in base 16. If both "base" and # are omitted, the integer is interpreted in base 10. For bases 11 through 36, the letters A through Z represent numbers greater than 9. For example, for base 36, A represents 10, B represents 11, C represents 12, and so on, through Z, which represents 35. The case of the letters is not significant. For example, the following integers are all assigned a value equal to 3994575 decimal: I = 2#1111001111001111001111 K = #3CF3CF n = +17#2DE110 index = 36#2DM8F You can use integer constants to assign values to data. The integer data types have the following ranges: BYTE Same range as INTEGER*1 INTEGER*1 Signed integers: -128 to 127 (-2**7 to 2**7-1) (1 byte) Unsigned integers: 0 to 255 (2**8-1) INTEGER*2 Signed integers: -32768 to 32767 (2 bytes) (-2**15 to 2**15-1) Unsigned integers: 0 to 65535 (2**16-1) INTEGER*4 Signed integers: -2147483648 to 2147483647 (4 bytes) (-2**31 to 2**31-1) Unsigned integers: 0 to 4294967295 (2**32-1) INTEGER*8 Signed integers: -9223372036854775808 to (8 bytes) 9223372036854775807 (-2**63 to 2**63-1) NOTE1: The value of an integer constant must be within INTEGER(KIND=8) range. NOTE2: The "unsigned" ranges above are allowed for assignment to variables of these types, but the data type is treated as signed in arithmetic operations.
2.7 – Logical
A logical constant represents only the logical values true or false. It takes one of these forms: .TRUE.[_k] .FALSE.[_k] k Is an optional kind type parameter (1 for LOGICAL(KIND=1), 2 for LOGICAL(KIND=2), 4 for LOGICAL(KIND=4), and 8 for LOGICAL(KIND=8)). It must be preceded by an underscore (_). The type specifier for the logical type is LOGICAL. If a kind type parameter is specified, the logical constant has the kind specified. If no kind type parameter is specified, the kind type of the constant is default logical. Note that logical data type ranges correspond to their comparable integer data type ranges. For example, the LOGICAL*2 range is the same as the INTEGER*2 range.
2.8 – Octal
You can use this type of constant wherever numeric constants are allowed; it assumes a numeric data type according to its context. An octal constant has one of these forms: O'd[...d]' O"d[...d]" d Is an octal (base 8) digit in the range 0 - 7. You can specify up to 128 bits in octal (43 octal digits) constants. Leading zeros are ignored.
2.9 – Real
A real constant approximates the value of a mathematical real number. The value of the constant can be positive, zero, or negative. VSI Fortran provides three kind type parameters for data of type real: REAL(KIND=4) (or REAL*4), REAL(KIND=8) (or REAL*8), and REAL(KIND=16) (or REAL*16). REAL(KIND=8) is DOUBLE PRECISION. If DOUBLE PRECISION is used, a kind type parameter must not be specified for the constant. The type specifier for the real (single-precision) type is REAL; the type specifier for the double precision type is DOUBLE PRECISION. If a kind type parameter is specified, the real constant has the kind specified. If a kind type parameter is not specified, the kind is default real. The following is the general form of a real constant with no exponent part: [s]n[n...][_k] A real constant with an exponent part has one of the following forms: [s]n[n...]E[s]nn...[_k] [s]n[n...]D[s]nn... [s]n[n...]Q[s]nn... s Is a sign; required if negative (-), optional if positive (+). n Is a decimal digit (0 through 9). A decimal point must appear if the real constant has no exponent part. k Is an optional kind type parameter (4 for REAL(KIND=4), 8 for REAL(KIND=8), or 16 for REAL(KIND=16)). It must be preceded by an underscore (_). Leading zeros (zeros to the left of the first nonzero digit) are ignored in counting significant digits. For example, in the constant 0.00001234567, all of the nonzero digits, and none of the zeros, are significant. (See the following sections for the number of significant digits each kind type parameter typically has). The exponent represents a power of 10 by which the preceding real or integer constant is to be multiplied (for example, 1.0E6 represents the value 1.0 * 10**6). A real constant with no exponent part is (by default) a single-precision (REAL(KIND=4)) constant. You can change this default behavior by specifying the compiler option /ASSUME=FPCONSTANT. If the real constant has no exponent part, a decimal point must appear in the string (anywhere before the optional kind type parameter). If there is an exponent part, a decimal point is optional in the string preceding the exponent part; the exponent part must not contain a decimal point. The exponent letter E denotes a single-precision real (REAL(KIND=4) or REAL*4) constant, unless the optional kind type parameter specifies otherwise. For example, -9.E2_8 is a double-precision constant (which can also be written as -9.D2). The exponent letter D denotes a double-precision real (REAL(KIND=8) or REAL*8) constant. The exponent letter Q denotes a quad-precision real (REAL(KIND=16) or REAL*16) constant. A minus sign must appear before a negative real constant; a plus sign is optional before a positive constant. Similarly, a minus sign must appear between the exponent letter (E, D, or Q) and a negative exponent, whereas a plus sign is optional between the exponent letter and a positive exponent. If the real constant includes an exponent letter, the exponent field cannot be omitted, but it can be zero. To specify a real constant using both an exponent letter and a kind type parameter, the exponent letter must be E, and the kind type parameter must follow the exponent part.
2.9.1 – DOUBLE_PRECISION
See DATA CONSTANTS REAL REAL_8 in this Help file.
2.9.2 – REAL_4
REAL(KIND=4) or REAL*4 A single-precision REAL constant occupies four bytes of memory. The number of digits is unlimited, but typically only the leftmost seven digits are significant. Either VAX F_floating or IEEE S_floating format is used, depending on the compiler option specified.
2.9.3 – REAL_8
DOUBLE PRECISION (REAL(KIND=8) or REAL*8) A DOUBLE PRECISION constant has more than twice the accuracy of a REAL number, and greater range. A DOUBLE PRECISION constant occupies eight bytes of memory. The number of digits that precede the exponent is unlimited, but typically only the leftmost 15 digits are significant. Either VAX D_floating, G_floating, or IEEE T_floating format is used, depending on the compiler option specified.
2.9.4 – REAL_16
REAL(KIND=16) or REAL*16 A REAL(KIND=16) constant has more than four times the accuracy of a REAL number, and a greater range. A REAL(KIND=16) constant occupies 16 bytes of memory. The number of digits that precede the exponent is unlimited, but typically only the leftmost 33 digits are significant.
2.10 – Type of BOH Constants
Binary, octal, and hexadecimal constants are "typeless" numeric constants. They assume data types based on their usage, according to the following rules: o When the constant is used with a binary operator, including the assignment operator, the data type of the constant is the data type of the other operand. o When a specific data type is required, that type is assumed for the constant. o When the constant is used as an actual argument, if the bit constant is greater than 4 bytes, INTEGER*8 is assumed; otherwise, INTEGER*4 is assumed. o When the constant is used in any other context, an INTEGER*4 data type is assumed (unless a compiler option indicating integer size specifies otherwise). These constants specify up to 16 bytes of data. When the length of the constant is less than the length implied by the data type, the leftmost digits have a value of zero. When the length of the constant is greater than the length implied by the data type, the constant is truncated on the left. An error results if any nonzero digits are truncated.
3 – Derived Types
Like intrinsic data types, a Fortran 95/90 derived data type has a name, a set of associated values, a way to denote the values, and operations to manipulate and interpret these values. The names of the intrinsic data types are predefined, while the names of derived types are defined in derived-type definitions. A derived-type definition specifies the name of the type and the types of its components. A derived type can be 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.
3.1 – Type Definitions
A derived-type definition specifies the name of a user-defined type and the types of its components. It takes the following form: TYPE [[, PRIVATE or PUBLIC] :: ] name [PRIVATE or SEQUENCE]... comp-def [comp-def]... END TYPE [name] 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. comp-def There must be at least one. It takes the following form: type [ [, attr-list] ::] comp [(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-list Is an optional list of component attributes POINTER or DIMENSION. You can specify one or both attributes. If DIMENSION is specified, it can be followed by an array specification. comp 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. 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 objects, =>NULL(). If a name is specified following the END TYPE statement, it must be the same name that follows TYPE in the derived type statement. Within a scoping unit, a derived-type name can only be defined once. 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 entities can have the same derived type in the following cases: o If they are both declared to be of the same derived type, and the derived-type definition can be accessed from the same module, the same scoping unit, or a host scoping unit. o If they are both declared to be of the same derived type, and the derived-type definition can be accessed from the same scoping unit or a host scoping unit. o If they are both declared in a derived-type definition specifying SEQUENCE (they both have sequence type). A sequence type can be defined in each scoping unit that needs to access the type. Each derived-type definition must specify the same name, the keyword SEQUENCE, and have components that agree in order, name, and attributes. (No private components are allowed in a sequence type.) The same PRIVATE or SEQUENCE statements can only appear once in a given derived-type definition. If SEQUENCE is present, all derived types specified in component definitions must be sequence types. The PUBLIC or PRIVATE keywords can only appear if the derived-type definition is in the specification part of a module. The POINTER or DIMENSION attribute can only appear once in a given comp-def. A component is an array if the component definition contains a DIMENSION attribute or an array specification. If the component definition contains an array specification, the array bounds should be specified there; otherwise, they must be specified following the DIMENSION attribute. If an initialization expression ("init_ex") appears for a nonpointer component, the component (in any object of the type) is initially defined with the value determined from the initialization expression. The initialization expression is evaluated in the scoping unit of the type definition. The initialization expression overrides any default initial value specified for the component. Explicit initialization in a type declaration statement overrides default initialization. If POINTER appears in the comp-def, the component is a pointer. 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().
3.2 – 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 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.
3.2.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.
3.3 – Constructors
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 type 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.
3.3.1 – Examples
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"))
4 – Expressions
An expression represents either a data reference or a computation, and is formed from operators, operands, and parentheses. The result of an expression is either a scalar value or an array of scalar values. If the value of an expression is of intrinsic type, it has a kind type parameter. (If the value is of intrinsic type CHARACTER, it also has a length parameter.) If the value of an expression is of derived type, it has no kind type parameter. An operand is a scalar or array. An operator can be either intrinsic or defined. An intrinsic operator is known to the compiler and is always available to any program unit. A defined operator is described explicitly by a user in a function subprogram and is available to each program unit that uses the subprogram. The simplest form of an expression (a primary) can be any of the following: o A constant; for example, 4.2 o A subobject of a constant; for example, 'LMNOP'(2:4) o A variable; for example, VAR1 o A structure constructor; for example, EMPLOYEE(3472, "JOHN DOE") o An array constructor; for example, (/12.0,16.0/) o A function reference; for example, COS(X) o Another expression in parentheses; for example, (I+5) Any variable or function reference used as an operand in an expression must be defined at the time the reference is executed. If the operand is a pointer, it must be associated with a target object that is defined. An integer operand must be defined with an integer value rather than a statement label value. All of the characters in a character data object reference must be defined. When a reference to an array or an array section is made, all of the selected elements must be defined. When a structure is referenced, all of the components must be defined. In an expression that has intrinsic operators with an array as an operand, the operation is performed on each element of the array. In expressions with more than one array operand, the arrays must be conformable (they must have the same shape). The operation is applied to corresponding elements of the arrays, and the result is an array of the same shape (the same rank and extents) as the operands. In an expression that has intrinsic operators with a pointer as an operand, the operation is performed on the value of the target associated with the pointer. For defined operators, operations on arrays and pointers are determined by the procedure defining the operation. A scalar is conformable with any array. If one operand of an expression is an array and another operand is a scalar, it is as if the value of the scalar were replicated to form an array of the same shape as the array operand. The result is an array of the same shape as the array operand. The ranking assigned to each numeric intrinsic data type follows: Data Type Ranking --------- ------- LOGICAL*1 and BYTE lowest LOGICAL*2 . LOGICAL*4 . LOGICAL*8 . INTEGER*1 . INTEGER*2 . INTEGER*4 . INTEGER*8 . REAL (REAL*4) . REAL*16 . DOUBLE PRECISION (REAL*8) . COMPLEX (COMPLEX*8) . DOUBLE COMPLEX (COMPLEX*16) . COMPLEX*32 highest
4.1 – Numeric
Numeric (arithmetic) expressions are formed with numeric operands and numeric operators, and yield a single numeric value. The term numeric includes logical data, because logical data is treated as integer data when used in a numeric context. (.TRUE. is -1; .FALSE. is 0.) The numeric operators are as follows: Operator Description ----------------------- ** exponentiation (evaluated right to left) * multiplication / division + addition - subtraction You can use parentheses to force an order of evaluation.
4.2 – Character
Character expressions consist of character items and character operators. Evaluation of a character expression yields a single value of character data type. A character expression has the form: character operand[//character operand]... The concatenation operator (//) is the only character operator. Concatenation is from left to right.
4.3 – Defined Operations
A defined operation is unary or binary. It is defined by a function subprogram containing a generic interface block with the specifier OPERATOR. A defined operation is not an intrinsic operation. However, you can use a defined operation to extend the meaning of an intrinsic operator. For defined unary operations, the function must contain one argument. For defined binary operations, the function must contain two arguments. Interpretation of the operation is provided by the function that defines the operation. A Fortran 95/90 defined operator can contain up to 31 letters, and is enclosed in periods (.). Its name cannot be the same name as any of the following: o The intrinsic operators .NOT., .AND., .OR., .XOR., .EQV., .NEQV., .EQ., .NE., .GT., .GE., .LT., and .LE. o The logical literal constants .TRUE. or .FALSE.. No two intrinsic operators can follow one another, but an intrinsic or binary operator can be followed by a defined unary operator. The result of a defined operation can have any type. The type of the result (and its value) must be specified by the defining function. The following examples show expressions containing defined operators: .COMPLEMENT. A X .PLUS. Y .PLUS. Z M * .MINUS. N
4.4 – Initialization
An initialization expression must evaluate at compile time to a constant. It is used to specify an initial value for an entity. In an initialization expression, each operation is intrinsic and each operand is one of the following: o A constant or subobject of a constant o An array constructor where each element, and the bounds and strides of each implied-do are expressions whose primaries are initialization expressions o A structure constructor whose components are initialization expressions o An elemental intrinsic function reference of type integer or character, whose arguments are initialization expressions of type integer or character o A reference to one of the following inquiry functions: BIT_SIZE MINEXPONENT DIGITS PRECISION EPSILON RADIX HUGE RANGE ILEN SHAPE KIND SIZE LBOUND TINY LEN UBOUND MAXEXPONENT Each function argument must be one of the following: - An initialization expression - A variable whose kind type parameter and bounds are not assumed or defined by an ALLOCATE statement, pointer assignment, or an expression that is not an initialization expression o A reference to one of the following transformational functions (each argument must be an initialization expression): REPEAT RESHAPE SELECTED_INT_KIND SELECTED_REAL_KIND TRANSFER TRIM o A reference to the transformational function NULL o An implied-do variable within an array constructor where the bounds and strides of the corresponding implied-do are initialization expressions o Another initialization expression enclosed in parentheses Each subscript, section subscript, and substring starting and ending point must be an initialization expression. In an initialization expression, the exponential operator (**) must have a power of type integer. If an initialization expression invokes an inquiry function for a type parameter or an array bound of an object, the type parameter or array bound must be specified in a prior specification statement (or to the left of the inquiry function in the same statement).
4.5 – Logical
Logical expressions can contain one or more logical operators and logical, integer, or relational operands. The following are logical operators: Operator Meaning --------------------------- .AND. Logical conjunction: the expression A .AND. B is true if both A and B are true. .OR. Logical disjunction (inclusive OR): the ex- pression A .OR. B is true if either A, B, or both, are true. .XOR. Same as .NEQV. .NEQV. Logical inequivalence (or exclusive OR): the expression A .NEQV. B is true if either A or B is true, but false if both are true. .EQV. Logical equivalence: the expression A .EQV. B is true if both A and B are true, or both are false. .NOT. Logical negation: the expression .NOT. A is true if A is false and false if A is true.
4.6 – Operator Precedence
The following shows the precedence of all intrinsic and defined operators: Category Operator Precedence --------------------------------------------------- N/A Defined Unary Operators Highest Numeric ** . Numeric * or / . Numeric Unary + or - . Numeric Binary + or - . Character // . Relational .EQ.,.NE.,.LT.,.LE.,.GT.,.GE. . Logical .NOT. . Logical .AND. . Logical .OR. . Logical .XOR., .EQV., .NEQV. . N/A Defined Binary Operators Lowest
4.7 – Relational
Relational expressions consist of two or more expressions whose values are compared to determine whether the relationship stated by the relational operator is satisfied. The expression is reduced to a logical value (true or false). The following are relational operators: Operator Meaning ------------------------------------------ .LT. or < Less than .LE. or <= Less than or equal to .EQ. or == Equal to .NE. or /= Not equal to .GT. or > Greater than .GE. or >= Greater than or equal to NOTE: Expressions of COMPLEX data type can use only .EQ. and .NE. operators.
4.8 – Specification
A specification expression is a restricted expression that is of type integer and has a scalar value. This type of expression appears only in the declaration of array bounds and character lengths. In a restricted expression, each operation is intrinsic and each operand is one of the following: o A constant or subobject of a constant o A variable that is one of the following: - A dummy argument that does not have the OPTIONAL or INTENT (OUT) attribute (or the subobject of such a variable) - In a common block (or the subobject of such a variable) - Made accessible by use or host association (or the subobject of such a variable) o A structure constructor whose components are restricted expressions o An implied-do variable within an array constructor where the bounds and strides of the corresponding implied-do are initialization expressions o A reference to one of the following inquiry functions: BIT_SIZE NWORKERS DIGITS PRECISION EPSILON PROCESSORS_SHAPE HUGE RADIX ILEN RANGE KIND SHAPE LBOUND SIZE LEN SIZEOF MAXEXPONENT TINY MINEXPONENT UBOUND NUMBER_OF_PROCESSORS Each function argument must be one of the following: - A restricted expression - A variable whose properties inquired about are not dependent on the upper bound of the last dimension of an assumed-size array, are not defined by an expression that is a restricted expression, or are not definable by an ALLOCATE or pointer assignment statement. o A reference to any other intrinsic function where each argument is a restricted expression. o A reference to a specification function (see below) where each argument is a restricted expression o An array constructor where each element, and bounds and strides of each implied-do are expressions whose primaries are restricted expressions o Another restricted expression enclosed in parentheses Each subscript, section subscript, and substring starting and ending point must be a restricted expression. Specification functions can be used in specification expressions to indicate the attributes of data objects. A specification function is a pure function. It cannot have a dummy procedure argument or be any of the following: o An intrinsic function o An internal function o A statement function o Defined as RECURSIVE A variable in a specification expression must have its type and type parameters (if any) specified in one of the following ways: o By a previous declaration in the same scoping unit o By the implicit typing rules currently in effect for the scoping unit o By host or use association If a variable in a specification expression is typed by the implicit typing rules, its appearance in any subsequent type declaration statement must confirm the implied type and type parameters. If a specification expression invokes an inquiry function for a type parameter or an array bound of an object, the type parameter or array bound must be specified in a prior specification statement (or to the left of the inquiry function in the same statement).
5 – Intrinsic Types
VSI Fortran provides the following intrinsic data types: o INTEGER (4 kind type parameters) - a whole number o REAL (3 kind type parameters) - a floating point number (a whole number, a decimal fraction, or a combination) o DOUBLE PRECISION - a REAL kind type parameter that has more than twice the degree of accuracy in its representation, and greater range o COMPLEX (3 kind type parameters) - a pair of REAL values representing a complex number (the first part of the number is the real part, the second is the imaginary part) o DOUBLE COMPLEX - a COMPLEX kind type parameter with DOUBLE PRECISION real and imaginary parts o LOGICAL (4 kind type parameters)- a logical value, .TRUE. or .FALSE. o CHARACTER - a sequence of characters o BYTE - a one-byte value equivalent to INTEGER(KIND=1)
5.1 – CHARACTER
A character string is a contiguous sequence of bytes in memory. A character string is specified by two attributes: the address of the first byte of the string and the length of the string in bytes. The length of the string must be in the range 1 through 65535. Hollerith constants are stored internally, one character per byte.
5.2 – COMPLEX
Real and complex numbers are floating-point representations. COMPLEX(KIND=4) (or COMPLEX*8) data is eight contiguous bytes aligned on an arbitrary byte boundary. The low-order four bytes contain REAL(KIND=4) (or REAL*4) data that represents the real part of the complex number. The high-order four bytes contain REAL data that represents the imaginary part of the complex number. For information on the ranges of REAL data, see REAL (within the DATA CONSTANTS section of online Help). DOUBLE COMPLEX (COMPLEX(KIND=8) or COMPLEX*16) data is 16 contiguous bytes aligned on an arbitrary byte boundary. The low-order bytes contain DOUBLE PRECISION data that represents the real part of the complex number. The high-order eight bytes contain DOUBLE PRECISION data that represents the imaginary part of the complex data. For information on the ranges of DOUBLE PRECISION data, see DOUBLE_PRECISION (within the DATA CONSTANTS section of online Help). COMPLEX(KIND=16) (or COMPLEX*32) data is 32 contiguous bytes aligned on an arbitrary byte boundary. The low-order bytes contain REAL(KIND=16) (or REAL*16) data that represents the real part of the complex number. The high-order bytes contain REAL*16 data that represents the imaginary part of the complex number. For information on the ranges of REAL*16 data, see REAL (within the DATA CONSTANTS section of online Help).
5.3 – INTEGER
Integer numbers are whole numbers. For information on the ranges of INTEGER data, see INTEGER (within the DATA CONSTANTS section of online Help). INTEGER*2, INTEGER*4, and INTEGER*8 values are stored in two's complement form. Note that logical data type ranges correspond to their comparable integer data type ranges. For example, in LOGICAL*2 L, the range for L is the same as the range for INTEGER*2 integers.
5.4 – LOGICAL
Logical values start on an arbitrary byte boundary and are stored in one, two, or four contiguous bytes. The low-order bit (bit 0) determines the value. If bit 0 is set, the value is .TRUE.; if bit 0 is clear, the value is .FALSE. The remaining bits are undefined. When a logical value is stored in memory, all of its bits are stored. For example, consider the following: LOGICAL*4 L1, L2, L3 L1 = L2 .AND. L3 This example does a full 32-bit AND of L2 and L3, and stores all 32 resulting bits in L1.
5.5 – REAL
Real and complex numbers are floating-point representations. The exponent for REAL(KIND=4) (or REAL*4) (F_floating) and DOUBLE PRECISION (REAL(KIND=8) or REAL*8) (D_floating) formats is stored in binary excess 128 notation. Binary exponents from -127 to 127 are represented by the binary equivalents of 1 through 255. The exponent for the DOUBLE PRECISION G_floating format and T_floating format is stored in binary excess 1024 notation. The exponent for the REAL*16 format is stored in binary excess 16384 notation. In DOUBLE PRECISION (G_floating) format, binary exponents from -1023 to 1023 are represented by the binary equivalents of 1 through 2047. In REAL*16 format, binary exponents from -16383 to 16383 are represented by the binary equivalents of 1 through 32767. For floating-point format, fractions are represented in sign-magnitude notation, with the binary radix point to the left of the most significant bit for F_floating, D_floating, and G_floating, and to the right of the most significant bit for S_floating and T_floating. Fractions are assumed to be normalized, and therefore the most significant bit is not stored. This bit is assumed to be 1 unless the exponent is 0. in which case the value represented is either zero or is a reserved operand. REAL(KIND=4) (or REAL*4) numbers occupy four contiguous bytes and the precision is approximately one part in 2**23, that is, typically 7 decimal digits. DOUBLE PRECISION (D_floating) numbers occupy eight contiguous bytes and the precision is approximately one part in 2**55, that is, typically 16 decimal digits. DOUBLE PRECISION G_floating numbers occupy eight contiguous bytes and the precision is approximately one part in 2**52, that is, typically 15 decimal digits. REAL*16 (H_floating) numbers occupy sixteen contiguous bytes and the precision is approximately 2**112, that is, typically 33 decimal digits. For more information on real data type ranges, see DATA CONSTANTS REAL and DATA CONSTANTS DOUBLE_PRECISION in this Help file.
6 – Substrings
A character substring is a contiguous segment of a character variable, character array element, or character field reference. It has one of the following forms: v([e1]:[e2]) a(s[,s]...)([e1]:[e2]) v Is a character variable name a Is a character array name s Is a subscript expression e1 Is a numeric expression specifying the leftmost character position of the substring e2 Is a numeric expression specifying the rightmost character position of the substring 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.
7 – Variables
A variable is a data object whose value can be changed at any point in a program. It can be any of the following: o A scalar name A scalar is a single object that has a single value; it can be of any intrinsic or user-defined type. o An array name An array is a collection of scalar elements of any intrinsic or derived type. All elements must be have the same type and kind type parameter. o A subobject designator A subobject is part of an object. The following are subobjects: An array element An array section A structure component A substring For example, B(3) is a subobject (array element) designator for array B. A subobject cannot be a variable if its parent object is a constant. The name of a variable is associated with a single storage location. Variables are classified by data type, as constants are. The data type of a variable indicates the type of data it contains, including its precision, and implies its storage requirements. When data of any type is assigned to a variable, it is converted to the data type of the variable (if necessary). A variable is usually defined in a type declaration statement or DATA statement. But during program execution, events can occur to cause variables to be defined or redefined (such as assignment statements and READ statements), or undefined (such as an I/O error). Scalar variables are assigned data types explicitly in type declaration statements or IMPLICIT statements, or they can have implicit data types.
7.1 – Implicit Typing
By default, all variables with names beginning with I, J, K, L, M, or N are assumed to be integer variables. Variables beginning with any other letter are assumed to be real variables. Names beginning with a dollar sign ($) are implicitly INTEGER. You can override the default data type implied in a name by specifying data type explicitly in either an IMPLICIT statement or a type declaration statement. Note: You cannot change the implicit type of a name beginning with a dollar sign in an IMPLICIT statement.
7.2 – Explicit Typing
Type declaration statements explicitly specify the data type of scalar variables. For example, the following statements associate VAR1 with an 8-byte complex storage location, and VAR2 with an 8-byte double-precision storage location: COMPLEX VAR1 DOUBLE PRECISION VAR2 You can explicitly specify the data type of a scalar variable only once. An explicit data type specification takes precedence over the type specified by an IMPLICIT statement. If no explicit data type specification appears, any variable with a name that begins with the letter in the range specified in the IMPLICIT statement becomes the data type of the variable. Character type declaration statements specify that given variables represent character values with the length specified. For example, the following statements associate the variable names INLINE, NAME, and NUMBER with storage locations containing character data of lengths 72, 12, and 9, respectively: CHARACTER*72 INLINE CHARACTER NAME*12, NUMBER*9 In single subprograms, assumed-length character arguments can be used to process character strings with different lengths. The assumed-length character argument has its length specified with an asterisk, for example: CHARACTER*(*) CHARDUMMY The argument CHARDUMMY assumes the length of the actual argument.