Michael Coughlan
Page 12
Statement
Num1
Num2
Num3
Num4
Num1
Num2
Num3
Num4
ADD Num1 TO Num2
25
30
ADD Num1, Num2 TO Num3, Num4
13
04
05
12
ADD Num1, Num2, Num3 GIVING Num4
04
03
02
01
SUBTRACT Num1 FROM Num2
04
10
55
GIVING Num3
SUBTRACT Num1,Num2 FROM Num3
05
10
55
SUBTRACT Num1, Num2 FROM Num3
05
10
55
20
GIVING Num4
MULTIPLY Num1 BY Num2
10
05
MULTIPLY Num1 BY Num2
10
05
33
GIVING Num3
DIVIDE Num1 INTO Num2
05
64
DIVIDE Num2 BY Num1
05
64
24
88
GIVING Num3 REMAINDER Num4
COMPUTE Num1 = 5 + 10 * 30 / 2
25
71
Chapter 4 ■ proCedure division BasiCs
LaNGUaGe KNOWLeDGe eXerCISeS - aNSWerS
sharpen up the 2B pencil you used to answer the questions in the last chapter, and fill in the after positions for data items that have a before entry:
01 Num1 PIC 99.
01 Num2 PIC 99.
01 Num3 PIC 99.
01 Num4 PIC 99.
Before Values
After Values
Statement
Num1
Num2
Num3
Num4
Num1
Num2
Num3
Num4
ADD Num1 TO Num2
25
30
25
55
ADD Num1, Num2 TO Num3, Num4
13
04
05
12
13
04
22
29
ADD Num1, Num2, Num3 GIVING Num4
04
03
02
01
04
03
02
09
SUBTRACT Num1 FROM Num2
04
10
55
04
10
06
GIVING Num3
SUBTRACT Num1,Num2 FROM Num3
05
10
55
05
10
40
SUBTRACT Num1, Num2 FROM Num3
05
10
55
20
05
10
55
40
GIVING Num4
MULTIPLY Num1 BY Num2
10
05
10
50
MULTIPLY Num1 BY Num2
10
05
33
10
05
50
GIVING Num3
DIVIDE Num1 INTO Num2
05
64
05
12
DIVIDE Num2 BY Num1
05
64
24
88
05
64
12
04
GIVING Num3 REMAINDER Num4
COMPUTE Num1 = 5 + 10 * 30 / 2
25
55
72
Chapter 5
Control Structures: Selection
The last chapter noted that programs that consist only of a sequence of statements are not very useful. To be useful, a program must use selection constructs to execute some statements rather than others and must use iteration constructs to execute certain statements repeatedly.
In this chapter, you examine the selection constructs available to COBOL. In addition to discussing the
IF and EVALUATE statements, this chapter also discusses the condition types recognized by the selection constructs, the creation and use of condition names, the use of the SET verb to manipulate condition names, and the proper naming of condition names.
A number of short example programs are introduced in this chapter. Please keep in mind that these are only used to demonstrate particular language elements. They are not intended as realistic examples.
Selection
In most procedural languages, if and case/switch are the only selection constructs supported. COBOL supports advanced versions of both of these constructs, but it also supports a greater variety of condition types including relation conditions, class conditions, sign conditions, complex conditions, and condition names.
IF Statement
When a program runs, the program statements are executed one after another, in sequence, unless a statement is encountered that alters the order of execution. An IF statement is one of the statement types that can alter the order of execution in a program. It allows you to specify that a block of code is to be executed only if the condition attached to the IF statement is satisfied. The basic metalanguage for the IF statement is given in Figure 5-1.
Figure 5-1. Metalanguage for the IF statement/verb
73
Chapter 5 ■ Control StruCtureS: SeleCtion
The StatementBlock following the THEN executes, if the condition is true. The StatementBlock following the ELSE
(if used) executes, if the condition is false. The StatementBlock(s) can include any valid COBOL statement including further IF constructs. This allows for nested IF statements.
One difference from many other programming languages is that when a condition is evaluated, it evaluates to either true or false. It does not evaluate to 1 or 0.
The explicit scope delimiter END-IF was introduced in ANS 85 COBOL. In the previous versions of COBOL, scope was delimited by means of the period. Although the scope of the IF statement may still be delimited by a period, the END-IF delimiter should always be used because it makes explicit the scope of the IF statement.
There are two problems with using a period as a scope delimiter:
• Periods are hard to see, and this makes it more difficult to understand the code.
• A period delimits all open scopes, and this is a source of many programming errors.
You explore this topic more fully later in the chapter.
Condition Types
The IF statement is not as simple as the metalanguage in Figure 5-1 seems to suggest. The condition that follows the IF is drawn from one of the condition types shown in Table 5-1. If a condition is not a complex condition, then it is regarded as a simple condition. A simple condition may be negated using the NOT keyword. Bracketing a complex condition causes it to be treated as a simple condition.
Table 5-1. Condition Types
Condition Type
Relation
Class
Sign
Complex
Condition names
Relation Conditions
Relation conditions are used to test whether a value is less than, equal to, or greater than another value.
These conditions will be familiar to programmers of other languages. The use of words as shown in the relation condition metalanguage in Figure 5-2 may come as bit of a shock, but for most conditions the more familiar symbols (= < > >= <=) may be used. There is one exception to this: unlike in many other languages, in COBOL
there is no symbol for NOT. You must use the word NOT if you want to express this condition.
74
Chapter 5 ■ Control StruCtureS: SeleCtion
Figure 5-2. Metalanguage f
or relation conditions
Note that the compared values must be type compatible. For instance, it is not valid to compare a string value to a numeric value. Some examples of relation conditions are shown in Example 5-1. Most of these examples are straight forward, but the final example includes an arithmetic expression. In this case, the arithmetic expression is evaluated and then the result is compared with the value in Num1.
Example 5-1. Some Sample Relation Conditions
IF Num1 < 10 THEN
DISPLAY "Num1 < 10"
END-IF
IF Num1 LESS THAN 10
DISPLAY "Num1 < 10"
END-IF
IF Num1 GREATER THAN OR EQUAL TO Num2
MOVE Num1 TO Num2
END-IF
IF Num1 < (Num2 + ( Num3 / 2))
MOVE ZEROS TO Num1
END-IF
Class Conditions
A class condition does not refer to a class in the OO sense. Instead, it refers to the broad category or class (such as numeric, alphabetic, or alphabetic lower or upper) into which a data item may fall (see the metalanguage for class conditions in Figure 5-3). A class condition is used to discover whether the value of data item is a member of one these classes. For instance, a NUMERIC class condition might be used on an alphanumeric (PIC X) or a numeric (PIC 9) data item to see if it contained numeric data. Or an ALPHABETIC-UPPER class condition might be used to discover if a data item contained only capital letters (see Example 5-2).
75
Chapter 5 ■ Control StruCtureS: SeleCtion
Figure 5-3. Metalanguage for class conditions
Example 5-2. Class Condition That Checks Whether the StateName Contains All Capitals
IF StateName IS ALPHABETIC-UPPER
DISPLAY "All the letters in StateName are upper case"
END-IF
Notes on Class Conditions
The target of a class test must be a data item with an explicit or implicit usage of DISPLAY. In the case of numeric tests, data items with a usage of PACKED-DECIMAL may also be tested.
The numeric test may not be used with data items described as alphabetic (PIC A) or with group items when
any of the elementary items specifies a sign. An alphabetic test may not be used with any data items described as numeric (PIC 9).
The UserDefinedClassName is a name that you can assign to a set of characters. You must use the CLASS clause of the SPECIAL-NAMES paragraph, of the CONFIGURATION SECTION, in the ENVIRONMENT DIVISION, to assign a class name to a set of characters. A data item conforms to the UserDefinedClassName if its contents consist entirely of the characters listed in the definition of the UserDefinedClassName (see Listing 5-1 in the next section).
User-Defined Class Names
Whereas ALPHABETIC and NUMERIC are predefined class names that identify a subset of the character set, the UserDefinedClassName in the metalanguage (see Figure 5-3) is a name that you can assign to a defined subset of characters. To define the subset, you must create a CLASS entry in the SPECIAL-NAMES paragraph, of the CONFIGURATION
SECTION, in the ENVIRONMENT DIVISION. The CLASS clause assigns a class name to a defined subset of characters.
In a class condition, a data item conforms to the UserDefinedClassName if its contents consist entirely of the characters listed in the definition of the UserDefinedClassName.
Listing 5-1 is an example program that shows how to define and use a user-defined class name. In this listing, two class names are defined: HexNumber and RealName. HexNumber is used to test that NumIn contains only hex digits (0–9 and A–F). RealName is used to test that NameIn contains only valid characters. RealName was created because you can’t just use the IS ALPHABETIC class condition to test a name—sometimes names, especially Irish names, contain other characters; such as the apostrophe (’). RealName allows you to test that the name entered contains only characters from the set you have defined.
76
Chapter 5 ■ Control StruCtureS: SeleCtion
Listing 5-1. User-Defined Class Names Used with a Class Condition
IDENTIFICATION DIVISION.
PROGRAM-ID. Listing5-1.
AUTHOR. Michael Coughlan.
*> Shows how user defined class names are created and used
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
CLASS HexNumber IS "0" THRU "9", "A" THRU "F"
CLASS RealName IS "A" THRU "Z", "a" THRU "z", "'", SPACE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NumIn PIC X(4).
01 NameIn PIC X(15).
PROCEDURE DIVISION.
Begin.
DISPLAY "Enter a Hex number - " WITH NO ADVANCING
ACCEPT NumIn.
IF NumIn IS HexNumber THEN
DISPLAY NumIn " is a Hex number"
ELSE
DISPLAY NumIn " is not a Hex number"
END-IF
DISPLAY "----------------------------------"
DISPLAY "Enter a name - " WITH NO ADVANCING
ACCEPT NameIn
IF NameIn IS ALPHABETIC
DISPLAY NameIn " is alphabetic"
ELSE
DISPLAY NameIn " is not alphabetic"
END-IF
IF NameIn IS RealName THEN
DISPLAY NameIn " is a real name"
ELSE
DISPLAY NameIn " is not a real name"
END-IF
STOP RUN.
How the Program Works
The program accepts a hex number from the user, tests that it contains only valid hex digits, and then displays the appropriate message. The program then accepts a name from the user, uses a class condition to test whether the contents are alphabetic, and displays the appropriate message. The program next tests that NameIn contains only the allowed characters and displays the appropriate message. To give you a feel for how the program works, I ran it a number of times and captured the output (see the output attached to Listing 5-1).
77
Chapter 5 ■ Control StruCtureS: SeleCtion
Sign Conditions
The sign condition (see the metalanguage in Figure 5-4) is used to discover whether the value of an arithmetic expression is less than, greater than, or equal to zero. Sign conditions are a shorter way of writing certain relation conditions.
Figure 5-4. Metalanguage for sign conditions
In Example 5-3, a sign condition is used to discover whether the result of evaluating an arithmetic expression is a negative value. This example also shows the equivalent relation condition.
Example 5-3. Sign Condition Used to Discover Whether a Result Is Negative
IF (Num2 * 10 / 50) - 10 IS NEGATIVE
DISPLAY "Calculation result is negative"
END-IF
*> the equivalent Relation Condition is
IF (Num2 * 10 / 50) - 10 LESS THAN ZERO
DISPLAY "Calculation result is negative"
END-IF
Complex Conditions
Unlike sign conditions and class conditions, complex conditions (sometimes called compound conditions) should be familiar to programmers of most languages. Even here, however, COBOL has a tweak—in the form of implied subjects—that you may find unusual. The metalanguage for complex conditions is given in Figure 5-5.
Figure 5-5. Metalanguage for complex conditions
Complex conditions are formed by combining two or more simple conditions using the conjunction operator
OR or AND. Any condition (simple, complex, condition name) may be negated by preceding it with the word NOT.
When NOT is applied to a condition, it toggles the true/false evaluation. For instance, if Num1 < 10 is true then NOT Num1 < 10 is false.
Like other conditions in COBOL, a complex condition evaluates to either true or false. A complex condition is an expression. Like arithmetic expressions, a complex condition is evaluated from left to right unless the order of evaluation is changed by precedence rules or by brac
keting.
The precedence rules that apply to complex conditions are given in Table 5-2. To assist your understanding, the equivalent arithmetic precedence rules have been given alongside the condition rules.
78
Chapter 5 ■ Control StruCtureS: SeleCtion
Table 5-2. Precedence Rules
Precedence
Condition Value
Arithmetic Equivalent
1
NOT
**
2
AND
* or /
3
OR
+ or -
Example 5-4. Complex Condition to Detect Whether the Cursor Is Onscreen
*> A complex condition example that detects if the cursor position located at
*> ScrnRow, ScrnCol is on screen (the text screen is 24 lines by 80 columns)
IF (ScrRow > 0 AND ScrRow < 25) AND (ScrCol > 0 AND ScrCol < 81) THEN
DISPLAY "On Screen"
END-IF
Truth Tables
When a complex condition is being evaluated, it is useful to consider the OR and AND truth tables, shown in Table 5-3.
Table 5-3. OR and AND Truth Tables
OR Truth Table
AND Truth Table
Condition
Condition
Result
Condition
Condition
Result
T
T
True
T
T
True
T
F
True
T
F
False
F
T
True
F
T
False
F
F
False
F
F
False
The Effect of Bracketing
Bracketing can make the order of evaluation explicit or can change it. Complex conditions are often difficult to understand, so any aid to clarity is welcome. For that reason, when you have to write a complex condition, you should always use bracketing to make explicit what is intended.
Consider the statement
IF NOT Num1 < 25 OR Num2 = 80 AND Num3 > 264 THEN
DISPLAY "Done"
END-IF
The rules of precedence govern how this IF statement is evaluated. You can leave it like this and hope that future readers will understand it, or you can assist their understanding by using bracketing to make explicit the order of evaluation already governed by those rules.