Arrays

Arrays are data structures that are used to simplify coding and improve processing efficiency. It is a linear data structure and is a collection of individual data items of the same type.

Data items of a table array are internally sorted. 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. The primary uses of arrays are to define:

  • Defining a series of input or output fields, each with the same format.
  • Defining a series of totals in WORKING-STORAGE to which amounts are added; after all data is accumulated, the totals can be printed.
  • Defining a  table  in WORKING-STORAGE to be accessed by each input record. With table we use the contents of some input field to “look up” the required data in the table.

The table is declared in the Data Division. Occurs clause is used to define a table. Occurs clause indicates the repetition of the data-name definition. It can be used only with level numbers starting from 02 to 49. Do not use occurs clause with Redefines. COBOL also supports the Multi-Level table. To create a multi-level table we have a give an OCCURS clause within another OCCURS clause. Such tables can be 2-Dimensional or 3-Dimensional in size.

Two-dimension Arrays

If the repeated information is a group of fields the description of the table may look like this:

01 ITEM-RECORD.
   03 ITEM-INFO OCCURS 100 TIMES.
      05 ITEM-CODE PIC S9(7) COMP-3.
      05 ITEM-DESCRIPTION PIC X(24).
      05 ITEM-PRICE PIC S9(3) V99 COMP-3.

Three-dimension Arrays

01 STORE-RECORD.
   03 STORE-INFO OCCURS 1000 TIMES.
      05 STORE-NO PIC S9 (5) COMP-3.
      05 STORE-STUFF PIC X.
      05 STORE-SALES PIC S9 (5) V99 COMP-3 OCCURS 12 TIMES.

This definition provides for a store number and suffix followed by 12 monthly sales figures. The whole group repeated 1000 times.

In this case, two subscripts need to be defined in Working-Storage

01 PROGRAM-SUBSCRIPTS.
   03 ST-SUBSCRIPT PIC S9 (9) COMP VALUE +1.
   03 ST-SALES-SUB PIC S9 (9) COMP VALUE +1.

An OCCURS clause is defined in the DATA DIVISION to indicate the repeated occurrence of items in an array that have the same format.

A subscript ([1] data-name with numeric, integer value or [2] a numeric literal with an integer value) is used in the PROCEDURE DIVISION to indicate which specific item within the array we wish to access.

Loading Arrays

VALUE clauses cannot be used in table definitions so a table must be loaded with information during the run of the program. This will generally be done by using the PERFORM …. VARYING …. statement.

For Example, The Store Table described above may be loaded from the records on the Master Store File. The file would be read, one record at a time, and entries made in the table for each store:

. . . . .
READ MASTER-STORE-FILE
AT END
MOVE 'Y' TO ST-EOF.
PERFORM LOAD-STORE-TABLE VARYING ST-SUBSCRIPT
FROM 1 BY 1
UNTIL END-OF-STORES
OR ST-SUBSCRIPT > 1000.
. . . . .
. . . . .
LOAD-STORE-TABLE.
MOVE MSF-ST-NO TO STORE-NO (ST-SUBSCRIPT).
MOVE MSF-ST-SUFF TO STORE-SUFF (ST-SUBSCRIPT).
PERFORM LOAD-SALES VARYING ST-SALES-SUB
FROM 1 BY1
UNTIL ST-SALES-SUB > 12
READ MASTER-STORE-FILE
AT END
MOVE 'Y' TO ST-EOF
LOAD-SALES.
MOVE ST-SALES-SUB TO MSF-SALES-SUB.
MOVE MSF-SALES (MSF-SALES-SUB)
TO STORE-SALES (ST-SUBSCRIPT, ST-SALES-SUB).

You can see from this example that the Store Table has 2 subscripts, which must be defined in Working-Storage: one to reference the different stores (ST-SUBSCRIPT) and one to access the monthly sales for the store (ST-SALES-SUB).

The Master Store File record description would also contain a table definition for the 12 occurrences of the monthly sales figure. These sales figures are referenced via the subscript called MSF-SALES-SUB.

INITIALIZE Arrays – General Format

INITIALIZE identifier-1 REPLACING data-type BY identifier-2

The INITIALIZE statement offers an alternative to the MOVE statement in initializing data items to fixed values. The following examples illustrate the simple form of INITIALIZE:

05 RECORD-COUNTER PIC 9 (5)
INITIALIZE RECORD-COUNTER.

In this example, the data item, RECORD-COUNTER, is defined as numeric. The INITIALIZE statement causes it to be set to zero.

The subject of an INITIALIZE statement can also be data items defined as alphanumeric, alphabetic, alphanumeric edited, or numeric edited. The following example illustrates this point:

01 GROUP-ITEM.
   03 FIELD-1 PIC X (4).
   03 FIELD-2 PIC A (3).
   03 FIELD-3 PIC BBBXX.
   03 FIELD-4 PIC Z9.99.
   03 FILED-5 PIC S9 (5) V99 COMP-3.
   03 FIELD-6 PIC S9 (4) COMP.

INITIALIZE FIELD-1 FIELD-2 FIELD-3 FIELD-4 FIELD-5 FIELD-6.


In this example, FIELD-1 FIELD-2 and FIELD-3 are initialized to SPACES, while FIELD-4 FIELD-5 and FIELD-6 are set to zero. The INITIALIZE statement also works to initialize a group item. For example, the following INITIALIZE statement will have the same effect as the one on the above:

INITIALIZE GROUP-ITEM.

Unless you specify otherwise, alphanumeric, alphabetic, and alphanumeric edited items are initialized to SPACES. Numeric and numeric edited fields are initialized to zero.

INITIALIZE Arrays – Replacing option

The REPLACING option for the INITIALIZE statement lets you initialize data items to values other than SPACES or zeros. For example, the following statement initializes a counter to 1:

05 PAGE-COUNT PIC 99.
 INITIALIZE PAGE-COUNT REPLACING NUMERIC DATA BY 1.

This option is also available on group items and tables.

Initializing fixed-length Arrays
For example,

01 A-TABLE.
   03 TABLE-INFO OCCURS 5 TIMES.
      05 TABLE-NAME PIC X (20).
      05 TABLE-NUMBER PIC 9 (5).
      . . . . . . . . .
  INITIALIZE A-TABLE.

Restrictions on the use of INITIALIZE

  • INITIALIZE cannot be used to change the value of an index data item.
  • You cannot use INITIALIZE to initialize a variable-length table.
  • If you initialize a group item, subordinate FILLER items will not be initialized. Therefore, INITIALIZE is not appropriate for initializing a print line to SPACES.

Variable Length or Dynamic Arrays: Not all tables have a set number of occurrences. Consider a file that contains a weekly sales total for a store. At the beginning of the financial year, there are only a few sales totals while towards the end of the year there may be up to 52. Rather than waste space on a disk or tape, the file could be designed in such a way that the record would “grow” each week, i.e. The record description would contain the following –

02 ST-WEEK-COUNT PIC S9(4) COMP.
02 ST-WEEKLY-SALES PIC S9(5)V99 COMP-3 OCCURS 52 TIMES
                             DEPENDING ON ST-WEEK-COUNT.

When the record is output to the new file only the number of occurrences specified in the count of weeks (ST-WEEK-COUNT) will be written to disk/tape. It is the programmer’s responsibility to ensure that the number of weeks is increased by one during the program so that the length of the record “grows”.

Indexes are processed more efficiently than subscripts. A subscript is a field that refers to the number of the table entry we want to reference. An index refers to displacement. 

SUBSCRIPTS

What actually happens when a subscript is used in the COBOL program?
1) The value in the subscript field is multiplied by the length of the recurring group in the table.
2) The length of one group is subtracted from the total to give the displacement along with the table of the start of the recurring group to be accessed.

For example, The recurring group in the Store File sales table described above contains the following:
Store Number 3 bytes
Store Suffix 1 byte
12 sales figure 12 x 4 bytes
The total length of 52 bytes
To refer to the 6th store in the table the number 6 is in the subscript field.
6 x 52 = 312
312 – 52 = 260
260 bytes along the table is the start of the 6th occurrence.
Note that the subscript is used while it contains 0 the calculation will result in a value of -52 which will cause the program (in this case) to access the data held in a position in the Working-Storage 52 bytes before the start of the table.
Similarly, if the value in the subscript is greater than the number of occurrences in the table then the program will obtain its information from an area of computer memory which may be
Working-Storage, machine code of the program or the program Save Area where the register contents are stored. This may result in an 0C4 abend.

INDEXING

Indexing can be used instead of subscripting to deal with table handling. It is faster than subscripting if used correctly as it saves time by not having to recalculate the displacement of a group occurrence each time it is used.
To assign an index to a table use the OCCURS….INDEXED BY….clause.

For example:
02 INV-STOCK-NUMBER PIC S9(7) COMP-3 OCCURS 100 TIMES
INDEXED BY INV-INDEX.

INV-INDEX is the name given to the index field. The field does not have to be defined in Working-Storage as it will be set up by the COBOL Compiler in the Memory Map TGT. The indexes are stored, in the order that they are defined in the program, under the name INDEX CELLS. Each index field is a 4-byte binary field. Within the COBOL program, only the following instructions can alter the contents of an index field –
SET, PERFORM, SEARCH.
The IF statement can be used to interrogate the contents of the index only.
Examples: To alter the occurrence number use the SET instruction –
SET INV-INDEX UP BY 1 (Move along the table 1 occurrence)
SET INV-INDEX DOWN BY 1 (Move back along with the table entry)
SET INV-INDEX TO 5 (Access the 5th entry in the table)

To process a table in a loop -
PERFORM TABLE-PROCESS VARYING INV-INDEX FROM 1 BY 1 
         UNTIL INV-INDEX > 100

Subscripts can be used to reference a number of different tables as they only hold the occurrence number and the program calculates the displacement along with the table each time a subscript is used. Indices, however, may only be used for the table with which they are identified in the Data Division or for a table that has recurring groups of exactly the same length. The reason for this is the way that indices are used by the program. The value held in the index is not an occurrence number but the displacement along with the table of the start of the required occurrence.

For example:
SET INV-INDEX TO 5

Using the ITEM-RECORD table, this instruction will result in the following calculation:
5 x 4 = 20, 20 – 4 = 16 the value 16 is stored in the index.
SET INV-INDEX UP BY 1.
This causes the value of one occurrence’s length to be added to the contents of the index field, thus: 16 + 4 = 20, the value 20 is stored in the index.
NB: A value of 0 in the index field points to the first entry in the table as this has a zero displacement from the beginning of the table.

Using SEARCH in ARRAY processing

SEARCH identifier-1
	[ AT END imperative-statement1]
  WHEN condition1 ]
	imperative-statement2		. . . . . 
	CONTINUE
[END-SEARCH]

The identifier used with the SEARCH verb is the table entry name specified on the OCCURS level, not on the 01 levels. 

The WHEN clause indicates what action is to be taken when the condition specified is actually met

With the SEARCH statement, the AT END clause specifies what should be done if the table has been completely searched and no matched is found. It is strongly recommended that always use this optional clause, without it, the “no-match” condition will simply cause the program to continue with the next sentence.

THE INDEXED BY clause and the SEARCH Statement.

When using a SEARCH statement, table entries must be specified with an index rather than a subscript. An index is similar to a subscript but it is defined along with the table entries as part of the OCCURS description.

 01 SALES-TAX-TABLE
    05 TABLE-ENTRIES OCCURS 1000 TIMES INDEXED BY X1
       10 WS-ZIPCODE    PIC 9(5).
       10 WS-TAX-RATE   PIC V999.

The SEARCH statement will perform a table look-up, TABLE-ENTRIES, the identifier used with the OCCURS and INDEXED BY clauses, is the item designated with the SEARCH as well. 01 SALES-TAX-TABLE will not be used with the SEARCH. 

The table will be searched and the index automatically incremented until the condition specified is satisfied or until AT END is met. The AT END indicates that the table has been completely searched without the condition being met; that is, no match has been found between an input field (search argument) and a table entry (table argument).

A SEARCH statement does not automatically initialize the index at 1 because sometimes we want to begin searching a table at some point other than the beginning. Initializing an index at 1 must be performed by a SET statement prior to the SEARCH if we want to begin each table look-up with the first entry. 

Example: Print the average temperature for the entire week.

01 TEMPERATURE-ARRAY.
   05 DAY-IN-WEEK OCCURS 7 TIMES.
      10 HOURS OCCURS 24 TIMES  PIC S9(3).

800-AVERAGE-RTN.
MOVE 0 TO TOTAL.
PERFORM VARYING DAY-SUB FROM 1 BY 1 UNTIL DAY-SUB > 7
  PERFORM VARYING HOUR-SUB FROM 1 BY 1 UNTIL HOUR-SUB > 24
     ADD TEMP (DAY-SUB , HOUR –SUB ) TO TOTAL
  END-PERFORM
END-PERFORM.
COMPUTE WEEKLY-AVERAGE= TOTAL/168
WRITE PRINT-REC FROM OUT-REC AFTER ADVANCING 2 LINES.

OR using PERFORM . . . VARYING WITH THE AFTER OPTION

01 TEMPERATURE-ARRAY.
   05 DAY-IN-WEEK OCCURS 7 TIMES.
      10 HOURS OCCURS 24 TIMES  PIC S9(3).

600-AVERAGE-RTN.
MOVE 0 TO TOTAL.
PERFORM 700-LOOP1 VARYING DAY-SUB FROM 1 BY 1 
                  UNTIL DAY-SUB > 7 
   AFTER HOUR-SUB FROM 1 BY 1 UNTIL HOUR-SUB > 24
COMPUTE WEEKLY-AVERAGE= TOTAL/168
WRITE PRINT-REC FROM OUT-REC AFTER ADVANCING 2 LINES.

700-LOOP1.
ADD TEMP (DAY-SUB , HOUR –SUB ) TO TOTAL.

This format is particularly useful for processing multiple-level arrays and tables. The PERFORM . . VARYING varies the major subscript, and the AFTER clause varies the minor subscript. Note, however, that for many compilers the AFTER clause requires a procedure-name1 following the word PERFORM.

COBOL Blog: Click Here IBM Reference:Click Here

Scroll to Top