Link to home
Start Free TrialLog in
Avatar of Ralphiep
Ralphiep

asked on

When is a flag necessary?

Appended (or more accurately, copied) after the text of this message is a very simple program I have written to accept some input from a screen, perform some simple calculations, and then output three separate comments dependent upon the value of that calculation. After fumbling around for some time I got the program to do what I wanted, but only by setting as a flag, the varible, SETSCR which assumes the value 0 or 1. It seemed that I tried all the different combinations of ACCEPT and DISPLAY, but the only way that I could get the kind of output I needed was by using the flag and inserting into the code a separate looping paragraph. I was thinking that there has to be another, more 'elegant' way.  Is there?

 @OPTIONS MAIN,TEST
 Identification Division.
 Program-Id. ATSTPRG.
 Environment Division.
 Configuration Section.
 Special-Names.
          Crt Status is Keyboard-Status.
*Source-Computer.  IBM-PC.
*Object-Computer.  IBM-PC.
 Data Division.
 Working-Storage Section.
 01   Keyboard-Status.
      03  Accept-Status   Pic 9.
      03  Function-Key    Pic X.
        88 F1-Pressed   Value X"01".
      03  System-Use      Pic X.
 01 SCREENCOM    Pic X(20)      Value Spaces.
 77 SUMFLD    PIC 9(3)     VALUE 0.
 77 FLDA      PIC 99       VALUE 0.
 77 FLDB      PIC 99       VALUE 0.
 77 FLDC      PIC 99      VALUE 0.


 77 SETSCR    PIC 9        VALUE 1.
 Screen Section.
 01 First-Screen
         BLANK SCREEN
         BACKGROUND-COLOR 7
         FOREGROUND-COLOR 0.


     03 FLD1    LINE 10  COLUMN 15  PIC Z(3)  USING FLDA.
     03 FLD2    LINE 10  COLUMN 20  PIC Z(3)  USING FLDB.
     03 FLD3    LINE 10  COLUMN 25  PIC Z(3)  USING FLDC.
     03 FLD4    LINE 14  COLUMN 15  PIC Z(3)  USING SUMFLD.
     03 FLD5    LINE 14  COLUMN 25  PIC X(20) USING SCREENCOM.

 Procedure Division.
 Begin.
     

      Display First-Screen
      Accept First-Screen
      Add FLDA  FLDB  FLDC GIVING SUMFLD
      EVALUATE SUMFLD
     
           WHEN 15 THRU 30  MOVE "HELLO" TO SCREENCOM
           WHEN 31 THRU   51  MOVE "GDBYE" TO SCREENCOM
           WHEN 52 thru 100   MOVE "WHEN" TO SCREENCOM
      END-EVALUATE        
*      IF F1-PRESSED PERFORM BEGIN
*          ELSE CONTINUE
*     DISPLAY FLD5
*     ACCEPT FIRST-SCREEN
*     DISPLAY FIRST-SCREEN
      IF SETSCR = 1 PERFORM DISP-FIRST-SCREEN
      DISPLAY SETSCR
      Stop run.
     
 DISP-FIRST-SCREEN.
      DISPLAY FIRST-SCREEN
      ACCEPT FIRST-SCREEN
      MOVE 0 TO SETSCR
      .    
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

My goodness, COBOL, long time no see.
Are you running windows? The reason that Visual Basic took off in popularity was that it made the construction of an application like this a trivial task.
Im not really sure what options you have in cobol or any old languages ( cant you use if else statements or select case or a switch case as it is known in c++ afaik ) ??

As far as flags they are from what I have come across pretty much like a boolean ie true or false to allow you to determine what to do in certain situations like I made a pool game in vb for a test in my HND and I had to use a flag to determine if player one or player two was playing and obviously once player one had finished playing you would set the flag back to player one etc.
One observation is that you declare the Flag and then later set and reset it. How did you know it was necessary? What it for?
ASKER CERTIFIED SOLUTION
Avatar of JesterToo
JesterToo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Ralphiep
Ralphiep

ASKER

Lynn("JesterToo") ,
       Thanks once again for helping out and simplifying my code by showing how I could get rid of the flag I was using.  Your correction works just fine. It's my fault that I was not explicit about the "deeper" problem that the use of the flage reflected.  This other problem or question is whether there is any way at all of  having a COBOL program accept data from a screen and then display that data by using strictly "inline" coding that is, without some sort of branching (do programmer's still use that word?) mechanism that relies on code like the PERFORM statement that is referenced only through some sort of pointer or label, something that usually indicates the presence of a separately coded section or paragraph.  I suppose in the long run this is not the most pressing of questions but in writing this little program I became curious about the architecture and protocols of COBOL.  Thanks once again for having the patience with my longwindedness.
                                                                    - Ralph
Lynn,
    Please ignore what I just wrote. I read more closely what your comment was and you perfectly addressed my "deeper" question.
                                                      - Ralph
Sure COBOL (like any other programming language) can be coded in a srictly linear fashion using no "performed" routines.  Here is the prodedure division of your prgram coded that way...

Procedure Division.
 Begin.
      Display First-Screen
      Accept First-Screen
      Add FLDA  FLDB  FLDC GIVING SUMFLD
      EVALUATE SUMFLD
          WHEN 15 THRU 30   MOVE "HELLO" TO SCREENCOM
          WHEN 31 THRU 51   MOVE "GDBYE" TO SCREENCOM
          WHEN 52 THRU 100  MOVE "WHEN"  TO SCREENCOM
      END-EVALUATE
      Display First-Screen
      Stop run.

Of course, such a program isn't very useful except for demonstration purposes.  Performed paragraphs are very useful for two purposes... 1) to contain code that needs to be executed from multiple locations within your program and 2) to "encapsulate" or "containerize" code that does some unit of work so it's easier to understand and maintain.  Consider when a program becomes larger, say 500 to 200 lines of code.  You will want (and anyone who later has to understand/maintain your code) to break each of the major pieces of logic out into separate routines with good paragraph names.  Not only is this easier to write the code originally (essentially you can write the main body of the program as if it were an outline) and fill in the details (contents of the paragraphs) later.

Here is a more common version of what you wrote:


77  Finish-Flag        PIC X    Value "N".
88  FINISHED                      Value "Y".

Procedure Division.
 Begin.
      Perform Process-Screen Until Finished
      Stop Run
      .
 Process-Screen.
      Display First-Screen
      Accept First-Screen
      Add FLDA  FLDB  FLDC GIVING SUMFLD
      EVALUATE SUMFLD
          WHEN 15 THRU 30   MOVE "HELLO" TO SCREENCOM
          WHEN 31 THRU 51   MOVE "GDBYE" TO SCREENCOM
          WHEN 52 THRU 100  MOVE "WHEN"  TO SCREENCOM
      END-EVALUATE
      If SCREENCOM = "GDBYE"
         FINISH-FLAG = "Y"
      End-If      
      .

Most versions of COBOL also contain an "inline" version of the perform statement...

    PERFORM VARYING x UNTIL some-condition-is-true
         yada yada yada
         yada yada yada
    END-PERFORM

Here is the same logic as above using inline perform...      

     Begin.
          Perform Until Finished
          Display First-Screen
          Accept First-Screen
          Add FLDA  FLDB  FLDC GIVING SUMFLD
          EVALUATE SUMFLD
              WHEN 15 THRU 30   MOVE "HELLO" TO SCREENCOM
              WHEN 31 THRU 51   MOVE "GDBYE" TO SCREENCOM
              WHEN 52 THRU 100  MOVE "WHEN"  TO SCREENCOM
          END-EVALUATE
          If SCREENCOM = "GDBYE"
             FINISH-FLAG = "Y"
          End-If      
      End-Perform
      Stop Run
      .


This is useful for those times when the code does not need to be executed from multiple locations, is relatively short, and it is desired to keep it very close to where it is being used.

Yes, "branching" is still very much in vogue... it is the heart of any control loop mechanism.  Regardless of whether the programmer actually codes a GO TO statement or not, the compiler generates the internal equivalent for many COBOL verbs.  Years ago Djikstra (sp?) was misunderstood when he wrote a paper about the art of programming and the GO TO statement... he was referring to the overuse of GO TO such that programs contained the statement many times due to careless "design"... a concept called "spaghetti code" in which is very difficult to avoid logic flaws, is difficult (if not impossible) to maintain later (even by the original author).  In some earlier versions of COBOL it was IMPOSSIBLE to write a program of any significance without the use of GO TO statements.  In the very early days of the language the PERFORM statement did not even exist (programmers used lots of ALTER statements to simulate it's behavior).  When it was added to the language it was a huge blessing to COBOL coders everywhere.  Years later, "structured COBOL" came on the scene and added the "END-xxxxx" keywords which enhanced the usability of the language once again.  Prior to that last addition, I've seen authors write code using many flags and perform satements to avoid GO TO statements... the results were extremely ugly and far worse than they would have been if they had simply used a GO TO in 4 or 5 locations in the code.

HTH,
Lynn
Thanks for the grade/points!

Good luck with your COBOL coding.

Lynn