Michael Coughlan

Home > Other > Michael Coughlan > Page 18


  UNTIL Letter = "s"

  Notes on PERFORM..UNTIL

  If you use the WITH TEST BEFORE phrase, PERFORM behaves like a while loop and the condition is tested before the loop body is entered. If you use the WITH TEST AFTER phrase, PERFORM behaves like a do..while loop and the condition is tested after the loop body is entered. The WITH TEST BEFORE phrase is the default and so is rarely explicitly stated.

  How PERFORM..UNTIL Works

  Although flowcharts are generally derided as a program-design tool, they are very useful for showing flow of control.

  The flowcharts in Figure 6-4 and Figure 6-5 show how the WITH TEST BEFORE and WITH TEST AFTER variations of PERFORM..UNTIL work.

  Figure 6-4. Pre-test loop

  119

  Chapter 6 ■ Control StruCtureS: IteratIon

  Figure 6-5. Post-test loop

  Note that the terminating condition is checked only at the beginning of each iteration (PERFORM WITH TEST

  BEFORE) or at the end of each iteration (PERFORM WITH TEST AFTER). If the terminating condition is reached in the middle of the iteration, the rest of the loop body is still executed. The terminating condition cannot be checked until all the statements in the loop body have been executed. COBOL has no equivalent of the break command that allows control to break out of a loop without satisfying the terminating condition.

  PERFORM..VARYING

  PERFORM..VARYING (see Figure 6-6) is the final format of the PERFORM verb.

  Figure 6-6. Metalanguage for PERFORM format 4

  120

  Chapter 6 ■ Control StruCtureS: IteratIon

  PERFORM..VARYING is used to implement counting iteration. It is similar to the for construct in languages like Pascal, C, and Java. However, there are some differences:

  • Most languages permit only one counting variable per loop instruction. COBOL allows up to

  three. Why only three? Before ANS 85 COBOL, tables were allowed only a maximum of three

  dimensions, and PERFORM..VARYING was used to process them.

  • Both pre-test and post-test variations of counting iteration are supported.

  • The terminating condition does not have to involve the counting variable. For instance:

  PERFORM CountRecordsInFile

  VARYING RecordCount FROM 1 BY 1 UNTIL EndOfFile

  Notes on PERFORM..VARYING

  The inline version of PERFORM..VARYING cannot take the AFTER phrase. This means only one counter may be used with an inline PERFORM.

  When you use more than one counter, the counter after the VARYING phrase is the most significant, that after the first AFTER phrase is the next most significant, and the last counter is the least significant. Just like the values in an odometer, the least-significant counter must go through all its values and reach its terminating condition before the next-most-significant counter can be incremented.

  The item after the word FROM is the starting value of the counter (initialization). An index item is a special data item. Index items are examined when tables are discussed.

  The item after the word BY is the step value of the counter (increment). It can be negative or positive. If you use a negative step value, the counter should be signed (PIC S99, for instance). When the iteration ends, the counters retain their terminating values.

  The WITH TEST BEFORE phrase is the default and so is rarely specified.

  How PERFORM..VARYING Works

  Figure 6-7 shows the flowchart for PERFORM..VARYING..AFTER. Because there is no WITH TEST phrase, WITH TEST

  BEFORE is assumed. The table shows the number of times the loop body is processed and the value of each counter as displayed in the loop body. The terminating values of the counters are also given.

  121

  Chapter 6 ■ Control StruCtureS: IteratIon

  Figure 6-7. PERFORM..VARYING..AFTER

  Note how the counter Idx2 must go through all its values and reach its terminating value before the Idx1 counter is incremented. An easy way to understand this is to think of it as an odometer. In an odometer, the units counter must go through all its values 0–9 before the tens counter is incremented.

  Many of the example programs in this book provide a gentle preview of language elements to come. Listing 6-3

  previews edited pictures. Examine the description of PrnRepCount provided by its picture, and review the output produced. Can you figure out how the edited picture works? Why do you think it was necessary to move RepCount to PrnRepCount? Why not just use the edited picture with RepCount?

  Listing 6-3. Using PERFORM..VARYING for Counting

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing6-3.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 RepCount PIC 9(4).

  01 PrnRepCount PIC Z,ZZ9.

  01 NumberOfTimes PIC 9(4) VALUE 1000.

  PROCEDURE DIVISION.

  Begin.

  PERFORM VARYING RepCount FROM 0 BY 50

  UNTIL RepCount = NumberOfTimes

  MOVE RepCount TO PrnRepCount

  DISPLAY "counting " PrnRepCount

  END-PERFORM

  MOVE RepCount TO PrnRepCount

  DISPLAY "If I have told you once, "

  DISPLAY "I've told you " PrnRepCount " times."

  STOP RUN.

  122

  Chapter 6 ■ Control StruCtureS: IteratIon

  ■ Answer RepCount can’t be an edited picture because an edited picture contains non-numeric characters (spaces, in this case), and you can’t do computations with non-numeric characters. You have to do the computations with the numeric RepCount and then move it to the edited field PrnRepCount when you want it printed.

  The explanation of the operation of PERFORM..VARYING..AFTER compares the construct to an odometer.

  The program in Listing 6-4 reinforces this idea by using PERFORM..VARYING to emulate an odometer. The program uses both out-of-line and inline versions of PERFORM..VARYING. Notice that when the inline variation is used, you cannot have an AFTER phrase but must instead use nested PERFORMs just as in Java or Pascal. Because the output is voluminous, only the final part is shown here.

  Listing 6-4. Odometer Simulation

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing6-4.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 Counters.

  02 HundredsCount PIC 99 VALUE ZEROS.

  02 TensCount PIC 99 VALUE ZEROS.

  02 UnitsCount PIC 99 VALUE ZEROS.

  01 Odometer.

  02 PrnHundreds PIC 9.

  02 FILLER PIC X VALUE "-".

  02 PrnTens PIC 9.

  02 FILLER PIC X VALUE "-".

  02 PrnUnits PIC 9.

  PROCEDURE DIVISION.

  Begin.

  DISPLAY "Using an out-of-line Perform".

  PERFORM CountMileage

  VARYING HundredsCount FROM 0 BY 1 UNTIL HundredsCount > 9

  AFTER TensCount FROM 0 BY 1 UNTIL TensCount > 9

  AFTER UnitsCount FROM 0 BY 1 UNTIL UnitsCount > 9

  DISPLAY "Now using in-line Perform"

  PERFORM VARYING HundredsCount FROM 0 BY 1 UNTIL HundredsCount > 9

  PERFORM VARYING TensCount FROM 0 BY 1 UNTIL TensCount > 9

  PERFORM VARYING UnitsCount FROM 0 BY 1 UNTIL UnitsCount > 9

  MOVE HundredsCount TO PrnHundreds

  MOVE TensCount TO PrnTens

  MOVE UnitsCount TO PrnUnits

  DISPLAY "In - " Odometer

  END-PERFORM

  END-PERFORM

  END-PERFORM

  123

  Chapter 6 ■ Control StruCtureS: IteratIon

  DISPLAY "End of odometer simulation."

  STOP RUN.

  CountMileage.

  MOVE HundredsCount TO PrnHundreds

  MOVE TensCount TO PrnTens

  MOVE UnitsCount TO PrnUnits

  DISPLAY "Out
- " Odometer.

  You might be wondering why the word FILLER is used in the description of Odometer. In COBOL, instead of

  having to make up dummy names, you can use FILLER when you need to reserve an area of storage but are never going to refer to it by name. For instance, in the data item Odometer, you want to separate the digits with hyphens, so you declare a character of storage for each hyphen and assign it the value -. But you will never refer to this part of Odometer by name. The hyphens only have significance as part of the group item.

  Summary

  This chapter examined the iteration constructs supported by COBOL. You learned the differences between COBOL’s version of pre-test and post-test iteration and those of other languages. I contrasted counting iteration in its PERFORM..VARYING..AFTER implementation, which has both pre-test and post-test variations, with the offerings of other languages. You also explored the ability to create open subroutines in COBOL, and I provided a rationale for using them.

  LaNGUaGe KNOWLeDGe eXerCISe

  unleash your 2B pencil. It is exercise time again.

  In the columns provided, write out what you would expect to be displayed on the computer screen if you ran the program shown in listing 6-5. use the Continue run column to show what happens after the statement DISPLAY

  "STOP RUN should be here". has been executed.

  Listing 6-5. Program to Test Your Knowledge of the PERFORM Verb

  DATA DIVISION.

  Start Run

  Continue Run

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing6-5.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 LoopCount PIC 9 VALUE 1.

  01 LoopCount2 PIC 9 VALUE 1.

  124

  Chapter 6 ■ Control StruCtureS: IteratIon

  PROCEDURE DIVISION.

  Start Run

  Continue Run

  P1.

  DISPLAY "S-P1"

  PERFORM P2

  PERFORM P3

  MOVE 7 TO LoopCount

  PERFORM VARYING LoopCount

  FROM 1 BY 1 UNTIL LoopCount = 2

  DISPLAY "InLine - " LoopCount

  END-PERFORM

  DISPLAY "E-P1".

  DISPLAY "STOP RUN should be here".

  P2.

  DISPLAY "S-P2"

  PERFORM P5 WITH TEST BEFORE VARYING LoopCount

  FROM 1 BY 1 UNTIL LoopCount > 2

  DISPLAY "E-P2".

  P3.

  DISPLAY "S-P3"

  PERFORM P5

  PERFORM P6 3 TIMES

  DISPLAY "E-P3".

  P4.

  DISPLAY "P4-" LoopCount2

  ADD 1 TO LoopCount2.

  P5.

  DISPLAY "S-P5"

  DISPLAY LoopCount "-P5-" LoopCount2

  PERFORM P4 WITH TEST AFTER UNTIL LoopCount2 > 2

  DISPLAY "E-P5".

  P6.

  DISPLAY "P6".

  prOGraMMING eXerCISe 1

  In this programming exercise, you amend the program you wrote for the programming exercise in Chapter 5

  (or amend the answer provided in listing 5-11). that programming exercise required you to create a calculator program, but the program halted after only one calculation.

  amend the program so it runs until the user enters the letter s instead of an operator (+ - / *). the result of running the program is shown in the sample output in example 6-9.

  125

  Chapter 6 ■ Control StruCtureS: IteratIon

  Example 6-9. Sample Run (User Input Shown in Bold)

  Enter an arithmetic operator (+ - * /) (s to end) : *

  Enter a single digit number - 4

  Enter a single digit number - 5

  Result is = 20.00

  Enter an arithmetic operator (+ - * /) (s to end) : +

  Enter a single digit number - 3

  Enter a single digit number - 3

  Result is = 06.00

  Enter an arithmetic operator (+ - * /) (s to end) : -

  Enter a single digit number - 5

  Enter a single digit number - 3

  Result is = -02.00

  Enter an arithmetic operator (+ - * /) (s to end) : /

  Enter a single digit number - 5

  Enter a single digit number - 3

  Result is = 00.60

  Enter an arithmetic operator (+ - * /) (s to end) : s

  End of calculations

  prOGraMMING eXerCISe 2

  Write a program that gets the user’s name and a countdown value from the keyboard and then displays a

  countdown before displaying the name that was entered. use PERFORM..VARYING to create the countdown.

  the program should produce results similar to those shown in example 6-10. For purposes of illustration,

  user input is in bold.

  Example 6-10. Sample Run

  Enter your name :- Mike Ryan

  Enter the count-down start value :- 05

  Getting ready to display your name.

  05

  04

  03

  02

  01

  Your name is Mike Ryan

  126

  Chapter 6 ■ Control StruCtureS: IteratIon

  LaNGUaGe KNOWLeDGe eXerCISe—aNSWer

  DATA DIVISION.

  Start Run

  Continue Run

  IDENTIFICATION DIVISION.

  S-P1

  S-P2

  PROGRAM-ID. Listing6-5.

  S-P2

  S-P5

  AUTHOR. Michael Coughlan.

  S-P5

  1-P5-5

  DATA DIVISION.

  1-P5-1

  P4-5

  WORKING-STORAGE SECTION.

  P4-1

  E-P5

  01 LoopCount PIC 9 VALUE 1.

  P4-2

  S-P5

  01 LoopCount2 PIC 9 VALUE 1.

  E-P5

  2-P5-6

  S-P5

  P4-6

  PROCEDURE DIVISION.

  2-P5-3

  E-P5

  P1.

  P4-3

  E-P2

  DISPLAY "S-P1"

  E-P5

  S-P3

  PERFORM P2

  E-P2

  S-P5

  PERFORM P3

  S-P3

  3-P5-7

  MOVE 7 TO LoopCount

  S-P5

  P4-7

  PERFORM VARYING LoopCount

  3-P5-4

  E-P5

  FROM 1 BY 1 UNTIL LoopCount = 2

  P4-4

  P6

  DISPLAY "InLine - " LoopCount

  E-P5

  P6

  END-PERFORM

  P6

  P6

  DISPLAY "E-P1".

  P6

  E-P3

  DISPLAY "STOP RUN should be here".

  P6

  P4-8

  E-P3

  S-P5

  P2.

  InLine - 1

  3-P5-9

  DISPLAY "S-P2"

  E-P1

  P4-9

  PERFORM P5 WITH TEST BEFORE VARYING LoopCount

  STOP RUN should be here

  E-P5

  FROM 1 BY 1 UNTIL LoopCount > 2

  P6

  DISPLAY "E-P2".

  P3.

  DISPLAY "S-P3"

  PERFORM P5

  PERFORM P6 3 TIMES

  DISPLAY "E-P3".

  P4.

  DISPLAY "P4-" LoopCount2

  ADD 1 TO LoopCount2.

  P5.

  DISPLAY "S-P5"

  DISPLAY LoopCount "-P5-" LoopCount2

  PERFORM P4 WITH TEST AFTER UNTIL LoopCount2 > 2

  DISPLAY "E-P5".

  P6.

  DISPLAY "P6".

  127

  Chapter 6 ■ Control StruCtureS: IteratIon

  prOGraMMING eXerCISe 1—aNSWer

  Listing 6-6. The Full Calculator Program

  IDENTIFICAT
ION DIVISION.

  PROGRAM-ID. Listing6-6.

  AUTHOR. Michael Coughlan.

  *> Continually calculates using two numbers and an operator

  *> Ends when "s" is entered instead of an operator.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 Num1 PIC 9 VALUE ZERO.

  01 Num2 PIC 9 VALUE ZERO.

  01 Result PIC --9.99 VALUE ZEROS.

  01 Operator PIC X VALUE SPACE.

  88 ValidOperator VALUES "*", "+", "-", "/", "s".

  88 EndOfCalculations VALUE "s".

  PROCEDURE DIVISION.

  Begin.

  PERFORM GetValidOperator UNTIL ValidOperator

  PERFORM UNTIL EndOfCalculations OR NOT ValidOperator

  PERFORM GetTwoNumbers

  EVALUATE Operator

  WHEN "+" ADD Num2 TO Num1 GIVING Result

  WHEN "-" SUBTRACT Num2 FROM Num1 GIVING Result

  WHEN "*" MULTIPLY Num1 BY Num2 GIVING Result

  WHEN "/" DIVIDE Num1 BY Num2 GIVING Result ROUNDED

  END-EVALUATE

  DISPLAY "Result is = ", Result

  MOVE SPACE TO Operator

  PERFORM GetValidOperator UNTIL ValidOperator

  END-PERFORM

  DISPLAY "End of calculations"

  STOP RUN.

  GetValidOperator.

  DISPLAY "Enter an arithmetic operator (+ - * /) (s to end) : "

  WITH NO ADVANCING

  ACCEPT Operator.

  GetTwoNumbers.

  DISPLAY "Enter a single digit number - " WITH NO ADVANCING

  ACCEPT Num1

  DISPLAY "Enter a single digit number - " WITH NO ADVANCING

  ACCEPT Num2.

  128

  Chapter 6 ■ Control StruCtureS: IteratIon

  prOGraMMING eXerCISe 2—aNSWer

  Listing 6-7. Uses PERFORM..VARYING to Display a Countdown from XX to 01

  IDENTIFICATION DIVISION.

  PROGRAM-ID. Listing6-7.

  AUTHOR. Michael Coughlan.

  DATA DIVISION.

  WORKING-STORAGE SECTION.

  01 UserName PIC X(20).

  01 StartValue PIC 99 VALUE ZEROS.

  01 Countdown PIC 99 VALUE ZEROS.

  PROCEDURE DIVISION.

  DisplayCountdown.

  DISPLAY "Enter your name :- " WITH NO ADVANCING

  ACCEPT UserName

  DISPLAY "Enter the count-down start value :- " WITH NO ADVANCING

  ACCEPT StartValue

 

‹ Prev