Monday, March 7, 2011

COBOL Arrays or Tables

Single dimensional arrays:
Arrays are data structures that are used to simplify coding and improve processing efficiency. The primary uses of arrays are to define:
·         a series of similarly formatted input or output record fields in the FILE SECTION
·         a group of accumulators in WORKING-STORAGE for different categories of totals
·         a table in WORKING-STORAGE that is searched to obtain a value related to a particular search criteria
An array can contain any number of data items of identical type and size. Each data item in the array is referenced by the name of the array and its position in the array given by a subscript or index contained in parentheses following the array name.
Declaring an Array
Arrays, as all COBOL data items, must be declared in the DATA DIVISION, but are distinguished from "scalar" (unsubscripted) data items by use of the OCCURS clause in their data definition. Arrays may be declared for elementary or group data items at levels 02-49.
Arrays of Elementary Data Items
To declare an array of elementary data-items, use the clause
OCCURS int_num TIMES
in the data-item definition. 'int_num' is any positive integer specifying the number of elements in the array:
01  DAILY-TEMP.
    05  TEMP OCCURS 24 TIMES       PIC 999.
This example declares an array named TEMP that contains 24 elementary data items, each of PIC 999, and referenced as TEMP (1), ... TEMP (24). DAILY-TEMP is not itself an array, but a group data item 72 characters long: 24 x 3. Any 02-49 level data definition can contain an OCCURS clause.
Arrays of Group Data Items
An array can also be specified to consist of group data items:
01  ACCUMULATORS.
    05  MONTH-TOTALS OCCURS 12 TIMES.
        10  M-TEMP     PIC 9(06).
        10  M-COUNT    PIC 9(02).
        10  M-HIGH     PIC 9(03).
        10  M-LOW      PIC 9(03).
Here the array MONTH-TOTALS consists of twelve identically formatted occurrences of a group data item, each 14 characters long, each of which contains four elementary data items. An alternative construct of arrays of only elementary data items is:
01  ACCUMULATORS.
    05  M-TEMP OCCURS 12 TIMES     PIC 9(06).
    05  M-COUNT OCCURS 12 TIMES    PIC 9(02).
    05  M-HIGH OCCURS 12 TIMES     PIC 9(03).
    05  M-LOW OCCURS 12 TIMES      PIC 9(03).
Accessing Elements of an Array with Subscripts
Individual array elements can be used as any other COBOL variable in an expression by referencing the array name and the element's position in the array with a subscript. The subscript can be an integer numeric literal, an integer numeric data item or (in COBOL-85) an expression.
Literal Subscripts
To reference an array element, you must specify its position in the array with a subscript contained in parentheses following the array name and separated from it by a single space:
MOVE ZERO TO TEMP (2).
The above statement assigns the value 0 to the second element of the array TEMP. Note: many compilers (including RM/COBOL-85) do not require the space after the array name.
In an array of group data items, an elementary data item is referenced by its own name, and subscripted to indicate its group item's position in the array:
MOVE ZERO TO M-COUNT (6).
In either case, the subscript must be valid for the array: >= 1 and <= the highest numbered element in the array).
Data-item (Variable) Subscripts
An integer numeric data item can be used as a subscript, as long as its value, when evaluated, is valid for that array. This is especially useful with the iteration structure:
MOVE 1 TO J.
PERFORM UNTIL J > 24
    MOVE ZERO TO TEMP (J)
    ADD 1 TO J
END-PERFORM.
-or-
PERFORM VARYING J FROM 1 BY 1 UNTIL J > 24
    MOVE ZERO TO TEMP (J)
END-PERFORM.
Data items used as subscripts must be declared in the DATA DIVISION as numeric integers, of a size sufficient to address the highest element of the array. That is, if an array is dimensioned to contain 100 elements (OCCURS 100 TIMES), the subscript(s) used to access the array must be
declared of at least size PIC 999.
Expressions as Subscripts
In COBOL-85, a subscript may be an expression, which is evaluated during execution (and truncated to an integer value) to determine what array element is referenced. For example:
ADD 1 TO M-COUNT (J + 2).
Accessing Elements of an Array with an Index
Array elements can also be accessed by using an index -- an internal "pointer" established for the array by use of the INDEXED BY clause when the array is defined:
01  DAILY-TEMP.
    05  TEMP   OCCURS 24 TIMES
               INDEXED BY XTEMP    PIC 999.
XTEMP is not a COBOL data-item; it is not defined elsewhere in the DATA DIVISION. Its only use in the program is to serve as an index to the array TEMP. It can be used as a normal data item subscript when referencing an element of an array:
ADD TEMP (XTEMP) TO TEMP-TOTAL.
Since an index is not a numeric data item, it can't be used in an arithmetic expression, MOVEd or printed. It can, however, be tested as a condition in an IF statement, and used as the loop control variable in a PERFORM VARYING loop:
PERFORM VARYING XTEMP FROM 1 BY 1 UNTIL XTEMP > 24
    ADD TEMP (XTEMP) TO TEMP-TOTAL
END-PERFORM.
An index may only be modified directly by using the SET statement:
SET index_name { TO | UP BY | DOWN BY } int_num
Processing a large array is faster using indexes than subscripts, so indexes are often used when large internal tables need to be searched.
Assigning Values to Elements of an Array
An array element can be assigned a value with a READ or MOVE statement, as the result of an arithmetic operation (i.e.: ADD ... GIVING ...), or by use of the REDEFINES clause in the DATA DIVISION.
Reading Values into an Array
Assume TEMP-FILE is a sequential file whose records consist of a date
and 24 hourly temperature readings for that date, in this format:
TEMP-REC
+----+----+----+------+------+-   -+------+
| MO | DA | YR | 1am  | 2am  | ... | 12pm |
+----+----+----+------+------+-   -+------+
 1  2 3  4 5  6 7    9 10  12       76  78
An appropriate FD for this file could be written as:
FD  TEMP-FILE.
01  TEMP-REC.
    05  TDATE.
        10  TMONTH                  PIC 99.
        10  TDAY                    PIC 99.
        10  TYEAR                   PIC 99.
    05  TEMP-DATA.
        10  TEMP  OCCURS 24 TIMES   PIC 999.
Each time the command READ TEMP-FILE ... is executed, the next record is read into the input buffer area defined as TEMP-REC. As a result, the values in record positions 7-78 are then available as TEMP (1) ... TEMP (24). The next READ will overlay any previous values.
Moving Values into an Array
Individual array elements can be assigned values as the target of a MOVE statement. Arrays are often initialized by moving appropriate values to the array elements as part of a PERFORM loop:
PERFORM VARYING J FROM 1 BY 1 UNTIL J > 12
    MOVE 0    TO M-TEMP (J)
                 M-COUNT (J)
    MOVE 999  TO M-LOW (J)
    MOVE 0    TO M-HIGH (J)
END-PERFORM.
This in-line PERFORM initializes elements in the group item array MONTH-TOTALS (see data definition above).
Array Elements as Targets of an Arithmetic Operation
Elementary data items of an array can be used as an operand or target of an arithmetic operation:
ADD DAILY-AVG TO M-TEMP (TMONTH)
The variable subscript TMONTH is evaluated to establish what array element is being referenced, and the value of the variable DAILY-AVG is added to its current value.
Initializing an Array in the DATA Division
The VALUE clause is used to initialize a data-item in WORKING-STORAGE, but COBOL-74 does not permit its use in a definition containing an OCCURS clause. A data-item with a VALUE clause must be defined and the space it occupies, and then REDEFINED as an array:
01  MONTH-NAMES.
    05  MONTH-NAME-DATA        PIC X(36) VALUE
            'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.
    05  M-NAME REDEFINES MONTH-NAME-DATA
            OCCURS 12 TIMES    PIC X(03).
Here the alphanumeric variable MONTH-NAME-DATA is defined as an elementary data item and assigned an initial value (the three digit month name abbreviations). The space it occupies is then REDEFINED as the array M-NAME. Thus M-NAME (2) = FEB, etc.
COBOL-85 permits both VALUE and OCCURS clauses in the same definition, so the REDEFINES entry may be eliminated:
01  MONTH-NAMES   VALUE
        'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.
    05  M-NAME   OCCURS 12 TIMES   PIC X(03).
Assigning values to arrays in WORKING-STORAGE is often used to initialize an internal table of constants.

No comments: