Previous | Contents | Index |
A JUSTIFIED RIGHT clause in the receiving item's data description causes the compiler to reverse its usual data movement conventions. It starts with the rightmost characters of both items and proceeds from right to left. If the sending item is shorter than the receiving item, the compiler fills the remaining leftmost character positions with spaces. If the sending item is longer than the receiving item, truncation occurs on the left. Table 3-4 illustrates various PICTURE character-string situations for the following statement:
MOVE FIELD1 TO FIELD2 |
FIELD1 | FIELD2 | ||
---|---|---|---|
PICTURE Character-String |
Contents | PICTURE Character-String (and JUST-Clause) |
Contents After MOVE |
XX | AB | ||
XXXXX | ABCss | ||
XXX | ABC | XX JUST | BC |
XXXXX JUST | ssABC |
Legend: s = space
If you write a MOVE statement containing more than one receiving item, the compiler moves the same sending item value to each of the receiving items. It has essentially the same effect as a series of separate MOVE statements, all with the same sending item.
The receiving items need have no relationship to each other. The compiler checks the validity of each one independently and performs an independent move operation on each one.
Multiple receiving items on MOVE statements provide a convenient way to set many items equal to the same value, such as during initialization code at the beginning of a section of processing. For example:
MOVE SPACES TO LIST-LINE, EXCEPTION-LINE, NAME-FLD. MOVE ZEROS TO EOL-FLAG, EXCEPT-FLAG, NAME-FLAG. MOVE 1 TO COUNT-1, CHAR-PTR, CURSOR. |
Any item (other than a data item that is not subordinate to an OCCURS clause) of a MOVE statement can be subscripted, and the referenced item can be used to subscript another name in the same statement.
For example, when more than one receiving item is named in the same MOVE statement, the order in which the compiler evaluates the subscripts affects the results of the move. Consider the following examples:
MOVE FIELD1(FIELD2) TO FIELD2 FIELD3. |
In this example, the compiler evaluates FIELD1(FIELD2) only once, before it moves any data to the receiving items. It is as if the single MOVE statement were replaced with the following three statements:
MOVE FIELD1(FIELD2) TO TEMP. MOVE TEMP TO FIELD2. MOVE TEMP TO FIELD3. |
In the following example, the compiler evaluates FIELD3(FIELD2) immediately before moving the data into it, but after moving the data from FIELD1 to FIELD2:
MOVE FIELD1 TO FIELD2 FIELD3(FIELD2). |
Thus, it uses the newly stored value of FIELD2 as the subscript value. It is as if the single MOVE statement were replaced with the following two statements:
MOVE FIELD1 TO FIELD2. MOVE FIELD1 TO FIELD3(FIELD2). |
The compiler considers any MOVE statement that contains a group item
(whether sending or receiving) to be a group move. If an elementary
item contains editing characters or a numeric integer, these attributes
of the receiving item have no effect on the action of a group move.
3.6.6 Using the MOVE CORRESPONDING Statement for Nonnumeric Items
The MOVE CORRESPONDING statement allows you to move multiple items from one group item to another group item, using a single MOVE statement. Refer to the Compaq COBOL Reference Manual for rules concerning the CORRESPONDING phrase. When you use the CORRESPONDING phrase, the compiler performs an independent move operation on each pair of corresponding items from the operands and checks the validity of each. Example 3-2 shows the use of the MOVE CORRESPONDING statement.
Example 3-2 Sample Record Description Using the MOVE CORRESPONDING Statement |
---|
01 A-GROUP. 01 B-GROUP. 02 FIELD1. 02 FIELD1. 03 A PIC X. 03 A PIC X. 03 B PIC 9. 03 C PIC XX. 03 C PIC XX. 03 E PIC XXX. 03 D PIC 99. 03 E PIC XXX. MOVE CORRESPONDING A-GROUP TO B-GROUP. Equivalent MOVE statements: MOVE A OF A-GROUP TO A OF B-GROUP. MOVE C OF A-GROUP TO C OF B-GROUP. MOVE E OF A-GROUP TO E OF B-GROUP. |
You can use reference modification to define a subset of a data item by specifying its leftmost character position and length. Reference modification is valid anywhere an alphanumeric identifier is allowed unless specific rules for a general format prohibit it. The following is an example of reference modification:
WORKING-STORAGE SECTION. 01 ITEMA PIC X(10) VALUE IS "XYZABCDEFG". . . . MOVE ITEMA(4:3) TO... IDENTIFIER VALUE ITEMA (4:3) ABC |
For more information on reference modification rules, refer to the Compaq COBOL Reference Manual.
A table is one or more repetitions of one element, composed of one or more data items, stored in contiguous memory locations.
In this chapter you will find:
You define a table by using an OCCURS clause following a data description entry. The literal integer value you specify in the OCCURS clause determines the number of repetitions, or occurrences, of the data description entry, thus creating a table. Compaq COBOL allows you to define from 1- to 48-dimension tables.
After you have defined a table, you can load it with data. One way to load a table is to use the INITIALIZE statement or the VALUE clause to assign values to the table when you define it (see Figure 4-10).
To access data stored in tables, use subscripted or indexed procedural instructions. In either case, you can directly access a known table element occurrence or search for an occurrence based on some known condition.
You can define either fixed-length tables or variable-length tables,
and they may be single or multidimensional. The following sections
describe how to use the OCCURS clause and its options. For more
information on tables and subscripting, refer to the Compaq COBOL Reference Manual.
4.1.1 Defining Fixed-Length, One-Dimensional Tables
To define fixed-length tables, use Format 1 of the OCCURS clause (refer to the Compaq COBOL Reference Manual). This format is useful when you are storing large amounts of stable or frequently used reference data. Options allow you to define single or multiple keys, or indexes, or both.
A definition of a one-dimensional table is shown in Example 4-1. The integer 2 in the OCCURS 2 TIMES clause determines the number of element repetitions. For the table to have any real meaning, this integer must be equal to or greater than 2.
Example 4-1 One-Dimensional Table |
---|
01 TABLE-A. 05 ITEM-B PIC X OCCURS 2 TIMES. |
The organization of TABLE-A is shown in Figure 4-1.
Figure 4-1 Organization of the One-Dimensional Table
Example 4-1 specifies only a single data item. However, you can specify as many data items as you need in the table. Multiple data items are shown in Example 4-2.
Example 4-2 Multiple Data Items in a One-Dimensional Table |
---|
01 TABLE-A. 05 GROUP-B OCCURS 2 TIMES. 10 ITEMC PIC X. 10 ITEMD PIC X. |
The organization of this table is shown in Figure 4-2.
Figure 4-2 Organization of Multiple Data Items in a One-Dimensional Table
Example 4-1 and Example 4-2 both do not use the KEY IS or INDEXED BY optional phrases. The INDEXED BY phrase implicitly defines an index name. This phrase must be used if any Procedure Division statements contain indexed references to the data name that contains the OCCURS clause. The KEY IS phrase means that repeated data is arranged in ascending or descending order according to the values in the data items that contain the OCCURS clause. (The KEY IS phrase does not cause the data in the table to be placed in ascending or descending order; rather, it allows you to state how you have arranged the data.) For further information about these OCCURS clause options, refer to the Compaq COBOL Reference Manual.
If you use either the SEARCH or the SEARCH ALL statement, you must specify at least one index. The SEARCH ALL statement also requires that you specify at least one key. Specify the search key using the ASCENDING/DESCENDING KEY IS phrase. (See Section 4.3.8 for information about the SEARCH statement and Section 4.3.4 for information about indexing.) When you use the INDEXED BY phrase, the index is internally defined and cannot be defined elsewhere. Example 4-3 defines a table with an ascending search key and an index.
Example 4-3 Defining a Table with an Index and an Ascending Search Key |
---|
01 TABLE-A. 05 ELEMENTB OCCURS 5 TIMES ASCENDING KEY IS ITEMC INDEXED BY INDX1. 10 ITEMC PIC X. 10 ITEMD PIC X. |
The organization of this table is shown in Figure 4-3.
Figure 4-3 Organization of a Table with an Index and an Ascending Search Key
Compaq COBOL allows 48 levels of OCCURS nesting. If you want to define a two-dimensional table, you define another one-dimensional table within each element of the one-dimensional table. To define a three-dimensional table, you define another one-dimensional table within each element of the two-dimensional table, and so on.
A two-dimensional table is shown in Example 4-4.
Example 4-4 Defining a Two-Dimensional Table |
---|
01 2D-TABLE-X. 05 LAYER-Y OCCURS 2 TIMES. 10 LAYER-Z OCCURS 2 TIMES. 15 CELLA PIC X. 15 CELLB PIC X. |
The organization of this two-dimensional table is shown in Figure 4-4.
Figure 4-4 Organization of a Two-Dimensional Table
Example 4-5 shows a three-dimensional table.
Example 4-5 Defining a Three-Dimensional Table |
---|
01 TABLE-A. 05 LAYER-B OCCURS 2 TIMES. 10 ITEMC PIC X. 10 ITEMD PIC X OCCURS 3 TIMES. 10 ITEME OCCURS 2 TIMES. 15 CELLF PIC X. 15 CELLG PIC X OCCURS 3 TIMES. |
The organization of this three-dimensional table is shown in Figure 4-5.
Figure 4-5 Organization of a Three-Dimensional Table
To define a variable-length table, use Format 2 of the OCCURS clause (refer to the Compaq COBOL Reference Manual). Options allow you to define single or multiple keys, or indexes, or both.
Example 4-6 illustrates how to define a variable-length table.
It uses from two to four occurrences depending on the integer value assigned to NUM-ELEM. You specify the table's minimum and maximum size with the OCCURS (minimum size) TO (maximum size) clause. The minimum size value must be equal to or greater than zero and the maximum size value must be greater than the minimum size value. The DEPENDING ON clause is also required when you use the TO clause.
The data-name of an elementary, unsigned integer data item is specified in the DEPENDING ON clause. Its value specifies the current number of occurrences. The data-name in the DEPENDING ON clause must be within the minimum to maximum range.
Unlike fixed-length tables, you can dynamically alter the number of element occurrences in variable-length tables.
By generating the variable-length table in Example 4-6, you are, in effect, saying: "Build a table that can contain at least two occurrences, but no more than four occurrences, and set its present number of occurrences equal to the value specified by NUM-ELEM."
Example 4-6 Defining a Variable-Length Table |
---|
01 NUM-ELEM PIC 9. . . . 01 VAR-LEN-TABLE. 05 TAB-ELEM OCCURS 2 TO 4 TIMES DEPENDING ON NUM-ELEM. 10 A PIC X. 10 B PIC X. |
The compiler maps the table elements into memory, following mapping rules that depend on the use of COMP, COMP-1, COMP-2, POINTER, and INDEX data items in the table element, the presence or absence of the SYNCHRONIZED (SYNC) clause with those data items, and the -align flag (on the Tru64 UNIX operating system) or the /ALIGNMENT qualifier (on the OpenVMS Alpha operating system).
The Compaq COBOL compiler allocates storage for data items within records according to the rules of the Major-Minor Equivalence technique. This technique ensures that identically defined group items have the same structure, even when their subordinate items are aligned. Therefore, group moves always produce predictable results. For more information, refer to the description of record allocation in the Compaq COBOL Reference Manual.
To determine exactly how much space your tables use, specify the -map flag (on Tru64 UNIX), or the /MAP qualifier (on OpenVMS). This gives you an offset map of both the Data Division and the Procedure Division. |
Example 4-7 shows how to describe a sample record in a table.
Example 4-7 Sample Record Description Defining a Table |
---|
01 TABLE-A. 03 GROUP-G PIC X(5) OCCURS 5 TIMES. |
Figure 4-6 shows how the table defined in Example 4-7 is mapped into memory.
Figure 4-6 Memory Map for Sample Record Description Example
Alphanumeric data items require 1 byte of storage per character.
Therefore, each occurrence of GROUP-G occupies 5 bytes. The first byte
of the first element is automatically aligned at the left record
boundary and the first 5 bytes occupy all of word 1 and part of 2. A
memory longword is composed of 4 bytes. Succeeding occurrences of
GROUP-G are assigned to the next 5 adjacent bytes so that TABLE-A is
composed of five 5-byte elements for a total of 25 bytes. Each table
element, after the first, is allowed to start in any byte of a word
with no regard for word boundaries.
4.1.4.1 Using the SYNCHRONIZED Clause
By default, the Compaq COBOL compiler tries to allocate a data item at the next unassigned byte location. However, you can align some data items on a 2-, 4-, or 8-byte boundary by using the SYNCHRONIZED clause. The compiler may then have to skip one or more bytes before assigning a location to the next data item. The skipped bytes, called fill bytes, are gaps between one data item and the next.
The SYNCHRONIZED clause explicitly aligns COMP, COMP-1, COMP-2, POINTER, and INDEX data items on their natural boundaries: one-word COMP items on 2-byte boundaries, longword items on 4-byte boundaries, and quadword items on 8-byte boundaries. Thus the use of SYNC can have a significant effect on the amount of memory required to store tables containing COMP and COMP SYNC data items.
The examples in this section assume compilation without the -align flag (on Tru64 UNIX systems) or the /ALIGNMENT qualifier (on OpenVMS Alpha systems). |
Example 4-8 describes a table containing a COMP SYNC data item. Figure 4-7 illustrates how it is mapped into memory.
Example 4-8 Record Description Containing a COMP SYNC Item |
---|
01 A-TABLE. 03 GROUP-G OCCURS 4 TIMES. 05 ITEM1 PIC X. 05 ITEM2 PIC S9(5) COMP SYNC. |
Figure 4-7 Memory Map for Record Description Containing a COMP SYNC Item
Because a 5-digit COMP SYNC item requires one longword (or 4 bytes) of storage, ITEM2 must start on a longword boundary. This requires the addition of 3 fill bytes after ITEM1, and each GROUP-G occupies 8 bytes. In Example 4-8, A-TABLE requires 32 bytes to store four elements of 8 bytes each.
If, in the previous example, you define ITEM2 as a COMP data item of the same size without the SYNC clause, the storage required will be considerably less. Although ITEM2 will still require one longword of storage, it will be aligned on a byte boundary. No fill bytes will be needed between ITEM1 and ITEM2, and A-TABLE will require a total of 20 bytes.
If you now add a 3-byte alphanumeric item (ITEM3) to Example 4-8 and locate it between ITEM1 and ITEM2 (see Example 4-9), the new item occupies the space formerly occupied by the 3 fill bytes. This adds 3 data bytes without changing the table size, as Figure 4-8 illustrates.
Example 4-9 Adding an Item Without Changing the Table Size |
---|
01 A-TABLE. 03 GROUP-G OCCURS 4 TIMES. 05 ITEM1 PIC X. 05 ITEM3 PIC XXX. 05 ITEM2 PIC 9(5) COMP SYNC. |
Figure 4-8 Memory Map for Example on Adding an Item Without Changing the Table Size
If, however, you place ITEM3 after ITEM2, the additional 3 bytes add their own length plus another fill byte. The additional fill byte is added after the third ITEM3 character to ensure that all occurrences of the table element are mapped in an identical manner. Now, each element requires 12 bytes, and the complete table occupies 48 bytes. This is illustrated by Example 4-10 and Figure 4-9.
Example 4-10 How Adding 3 Bytes Adds 4 Bytes to the Element Length |
---|
01 A-TABLE. 03 GROUP-G OCCURS 4 TIMES. 05 ITEM1 PIC X. 05 ITEM2 PIC 9(5) COMP SYNC. 05 ITEM3 PIC XXX. |
Note that GROUP-G begins on a 4-byte boundary because of the way Compaq COBOL allocates memory.
Figure 4-9 Memory Map for Example on How Adding 3 Bytes Adds 4 Bytes to the Element Length
Previous | Next | Contents | Index |