[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [volume] [parte]


Capitolo 578.   Divisione «PROCEDURE DIVISION»

La divisione PROCEDURE DIVISION costituisce la quarta e ultima parte di un programma sorgente COBOL. La divisione si può suddividere in paragrafi, oppure in sezioni contenenti eventualmente dei paragrafi. All'interno delle sezioni o dei paragrafi, si inseriscono le istruzioni che descrivono la procedura del programma.

Le istruzioni sono inserite a gruppi, terminanti con un punto fermo, seguito da uno spazio; le istruzioni singole, che non costituiscono un gruppo autonomo, possono essere separate graficamente attraverso dei separatori (la virgola, il punto e virgola, la parola THEN).

Alcune istruzioni, quando non costituiscono un gruppo autonomo, possono collocarsi solo alla fine del gruppo. Si tratta precisamente di GO TO e di STOP RUN.

La divisione può articolarsi in tre modi diversi; quello che si vede descritto nello schema segue è il più semplice, perché non fa uso delle sezioni:

[PROCEDURE DIVISION.
 ¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯
{paragraph-name.
     [sentence]...}...

Se si usano le sezioni, i paragrafi devono essere contenuti tutti all'interno di sezioni:

[PROCEDURE DIVISION.
 ¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯
/ section-name SECTION [segment-number]. \
|              ¯¯¯¯¯¯¯                   |
< {paragraph-name.                       >...
|      [sentence]...}...                 |
\                                        /

Eventualmente ci può essere un gruppo iniziale di sezioni speciali; in tal caso, è obbligatorio suddividere il resto del programma in sezioni:

[PROCEDURE DIVISION.
 ¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯
 DECLARATIVES.
 ¯¯¯¯¯¯¯¯¯¯¯¯
 / section-name SECTION [segment-number]. \
 |              ¯¯¯¯¯¯¯                   |
 |     USE statement                      |
 <     ¯¯¯                                >...
 | {paragraph-name.                       |
 |      [sentence]...}...                 |
 \                                        /
 END DECLARATIVES.
 ¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯
/ section-name SECTION [segment-number]. \
|              ¯¯¯¯¯¯¯                   |
< {paragraph-name.                       >...
|      [sentence]...}...                 |
\                                        /

Il primo gruppo di istruzioni a essere eseguito è quello che si trova nel primo paragrafo della prima sezione; escludendo quelli inseriti in un blocco DECLARATIVES. In condizioni normali, la sequenza dei gruppi di istruzioni eseguiti prosegue con quelli successivi, salvo quando si incontrano istruzioni speciali che richiedono esplicitamente di modificare questo tipo di flusso.

578.1   Gruppo di sezioni «DECLARATIVES»

Quando all'inizio della divisione PROCEDURE DIVISION appare la parola chiave DECLARATIVES, che inizia dall'area A del modulo di programmazione, le sezioni dichiarate fino alla riga dove appare END DECLARATIVES (sempre a partire dall'area A), non vengono eseguite normalmente, ma solo al verificarsi di certe condizioni.

 DECLARATIVES.
 ¯¯¯¯¯¯¯¯¯¯¯¯
 / section-name SECTION [segment-number]. \
 |              ¯¯¯¯¯¯¯                   |
 |     USE statement                      |
 <     ¯¯¯                                >...
 | {paragraph-name.                       |
 |      [sentence]...}...                 |
 \                                        /
 END DECLARATIVES.
 ¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯

Ogni sezione di questo gruppo speciale, inizia con una o più istruzioni USE, prima di procedere con dei paragrafi contenenti altre istruzioni. L'istruzione USE serve ad abbinare l'esecuzione della sezione (a partire dal primo dei suoi paragrafi), a condizione che si verifichi una certa condizione:

                                              / {file-name}... \
                                              |                |
                   /           \              | INPUT          |
                   | EXCEPTION |              | ¯¯¯¯¯          |
USE AFTER STANDARD < ¯¯¯¯¯¯¯¯¯ > PROCEDURE ON < OUTPUT         >
¯¯¯ ¯¯¯¯¯          | ERROR     | ¯¯¯¯¯¯¯¯¯    | ¯¯¯¯¯¯         |
                   \ ¯¯¯¯¯     /              | I-O            |
                                              | ¯¯¯            |
                                              \ EXTEND         /
                                                ¯¯¯¯¯¯

Tenendo conto che le parole chiave EXCEPTION e ERROR del modello sono equivalenti, si intende che questa istruzione serve ad attivare la sezione che la contiene se si verifica una condizione di errore, che non sia stato gestito diversamente all'interno del programma, riguardante: un certo file (file-name), un file qualunque aperto in lettura (INPUT), scrittura (OUTPUT), lettura e scrittura (I-O) o in estensione (EXTEND).

Viene mostrato l'esempio di un piccolo programma completo, che ha lo scopo di leggere un file (input.txt) e di mostrarne il contenuto sullo schermo:

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID.   TEST-DECLARATIVES.
000300 AUTHOR.       DANIELE GIACOMINI.
000400 DATE-WRITTEN. 2005-02-26.
000500*
000600 ENVIRONMENT DIVISION.
000700*
000800 INPUT-OUTPUT SECTION.
000900*
001000 FILE-CONTROL.
001100*
001200     SELECT FILE-DA-LEGGERE ASSIGN TO "input.txt"
001300                            ORGANIZATION IS LINE SEQUENTIAL
001400                            FILE STATUS IS STATO-FILE-DA-LEGGERE.
001500*
001600 DATA DIVISION.
001700*
001800 FILE SECTION.
001900*
002000 FD  FILE-DA-LEGGERE.
002100 01  RECORD-DA-LEGGERE            PIC X(79).
002200*
002300 WORKING-STORAGE SECTION.
002400 77  STATO-FILE-DA-LEGGERE        PIC XX.
002500*
002600 PROCEDURE DIVISION.
002700*
002800 DECLARATIVES.
002900 FILE-ACCESS-ERROR SECTION.
003000     USE AFTER STANDARD ERROR PROCEDURE ON INPUT.
003100 FILE-ACCESS-ERROR-RECOVERY.
003200     DISPLAY "FILE ACCESS ERROR: ", STATO-FILE-DA-LEGGERE.
003300     STOP RUN.
003400 END DECLARATIVES.
003500*
003550 MAIN-PROCEDURE SECTION.
003600 MAIN.
003700     OPEN INPUT FILE-DA-LEGGERE.
003800     PERFORM LETTURA UNTIL 0 = 1.
003900     CLOSE FILE-DA-LEGGERE.
004000*
004100     STOP RUN.
004200*
004300 LETTURA.
004400     READ FILE-DA-LEGGERE.
004500     DISPLAY RECORD-DA-LEGGERE.
004600*

Si può osservare nel programma che il ciclo di lettura non termina mai, perché la condizione 0 = 1 non si può avverare. Così facendo, dato che la lettura non prevede alcun controllo del superamento della fine del file, si verifica un errore che viene preso in considerazione dalla sezione FILE-ACCESS-ERROR.

Compilando il programma con OpenCOBOL, l'avvio dell'eseguibile che si ottiene genera un risultato simile a quello seguente:

aaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbb
ccccccccccccccccccc
FILE ACCESS ERROR: 10

In pratica, alla fine del file termina la visualizzazione del suo contenuto e si ottiene un messaggio di errore, come organizzato nella sezione FILE-ACCESS-ERROR.

578.2   Sezioni e segmenti

Le sezioni della divisione PROCEDURE DIVISION, oltre al nome possono indicare un numero di segmento, che può andare da zero a 99.

section-name SECTION [segment-number].

Il numero di segmento serve a raggruppare tutte le sezioni con lo stesso numero in uno stesso segmento, allo scopo di sapere, quale parte del programma deve rimanere simultaneamente nella memoria centrale durante il funzionamento.

Si dividono precisamente due tipi di segmenti: quelli fissi, con numeri da 00 a 49, e quelli indipendenti, da 50 a 99. I segmenti numerati fino al numero 49 devono rimanere sempre in memoria, mentre gli altri devono esserci solo per il tempo necessario al loro funzionamento. Per questa ragione, le sezioni dichiarate nella zona DECLARATIVES, possono essere associate soltanto a segmenti fissi (da 00 a 49).

Naturalmente, questa possibilità di segmentare il programma dipende dal compilatore, che potrebbe limitarsi semplicemente a ignorare il numero di segmento.

578.3   Gruppi di istruzioni e istruzioni condizionali

Un gruppo di istruzioni si evidenzia per la presenza del punto fermo conclusivo (seguito da uno spazio). Le istruzioni che non costituiscono gruppi singoli possono essere separate, oltre che con lo spazio, con la virgola, il punto e virgola, e con la parola THEN.

Le istruzioni condizionali sono quelle che alterano la sequenza normale dell'esecuzione delle istruzioni, sulla base della verifica di una condizione. L'istruzione condizionale tipica è IF, ma molte altre istruzioni prevedono delle parole opzionali per descrivere un'azione da compiere al verificarsi di una certa condizione.

                /                    \  .--      /                    \ --.
                | { statement-1 }... |  |        | { statement-2 }... |   |
IF condition-1  <                    >  |  ELSE  <                    >   |
¯¯              | NEXT SENTENCE      |  |  ¯¯¯¯  | NEXT SENTENCE      |   |
                \ ¯¯¯¯ ¯¯¯¯¯¯¯¯      /  `--      \ ¯¯¯¯ ¯¯¯¯¯¯¯¯      / --'

Quello che si vede sopra è lo schema sintattico dell'istruzione IF, che incorpora a sua volta altre istruzioni. Naturalmente, le istruzioni incorporate possono contenere altre istruzioni condizionali annidate; in ogni caso, non è possibile suddividere una struttura del genere in gruppi di istruzioni più piccoli, pertanto il punto fermo finale può apparire solo alla fine della struttura più esterna.

000000 IF ALTEZZA IS GREATER THAN 190
000000   THEN
000000       DISPLAY "LA PERSONA E` MOLTO ALTA!",
000000       PERFORM PERSONA-MOLTO-ALTA;
000000   ELSE
000000       IF ALTEZZA IS GREATER THAN 170
000000         THEN
000000             DISPLAY "LA PERSONA E` ABBASTANZA ALTA.",
000000             PERFORM PERSONA-ALTA;
000000         ELSE
000000             DISPLAY "LA PERSONA HA UN'ALTEZZA MEDIA O BASSA".

L'esempio mostra un'istruzione IF annidata, dove sono stati usati i vari separatori disponibili, per facilitare la lettura: la parola THEN non fa parte dell'istruzione, ma introduce qui le istruzioni da eseguire nel caso la condizione si avveri; la virgola viene usata per terminare le istruzioni singole, mentre il punto e virgola si usa per concludere quelle istruzioni dopo le quali si passa all'alternativa (introdotta dalla parola chiave ELSE).

Il punto fermo finale è molto importante, perché rappresenta l'unico modo per stabilire dove finisca tutta la struttura, dal momento che nel linguaggio non è previsto l'uso di parole come «end if».

578.4   Sezioni, paragrafi e qualificazione

Quando la parte procedurale del programma si suddivide in sezioni, i nomi dei paragrafi devono essere univoci soltanto nell'ambito della sezione in cui vengono dichiarati.

Quando si deve fare riferimento al nome di un paragrafo che non è unico nel programma, si deve usare la qualificazione per distinguere a quale sezione si sta facendo riferimento; eccezionalmente, se si tratta della sezione in cui ci si trova già, la qualificazione è implicita.

La qualificazione si ottiene aggiungendo la parola OF, oppure IN, seguita dal nome della sezione.

               /    \
               | IN |
paragraph-name < ¯¯ > section-name
               | OF |
               \ ¯¯ /

578.5   Espressioni aritmetiche

L'espressione aritmetica è ciò che si traduce in un valore numerico, eventualmente attraverso l'uso di operatori. Gli operatori aritmetici disponibili nel linguaggio COBOL sono molto pochi, limitando le possibilità alle quattro operazioni.

È importante osservare che gli operatori aritmetici, tranne nel caso delle parentesi, vanno separati dai loro argomenti; diversamente, il segno - verrebbe confuso come carattere che compone una parola. Per esempio, A - B è un'espressione che rappresenta una sottrazione, mentre A-B è una parola.

Tabella 578.12. Espressioni aritmetiche.

Espressione Descrizione
+ x
Non modifica il segno di x.
- x
Inverte il segno di x.
x + y
Somma i due operandi.
x - y
Sottrae da x il valore di y.
x * y
Moltiplica i due operandi.
x / y
Divide il primo operando per il secondo.
( ... )
Cambia la precedenza stabilendo che quanto contenuto tra parentesi va calcolato prima di ciò che si trova all'esterno.

L'ordine di precedenza nelle espressioni aritmetiche è quello consueto: prima gli operatori unari, che si applicano a un operando singolo, poi la moltiplicazione e la divisione, quindi la somma e la sottrazione.

578.6   Espressioni condizionali

Nel linguaggio COBOL si distinguono diversi tipi di espressioni condizionali elementari, che vengono descritte nelle sezioni successive. Le espressioni elementari, a loro volta, si possono combinare in espressioni composte, con l'uso di operatori booleani ed eventualmente con l'aiuto di parentesi tonde per modificare l'ordine di valutazione.

578.6.1   Condizioni di relazione

Le condizioni di relazione stabiliscono un confronto tra due valori, che possono essere rappresentati da variabili, costanti o da espressioni aritmetiche. Segue lo schema sintattico:

                        / IS [NOT] GREATER THAN \
                        |     ¯¯¯  ¯¯¯¯¯¯¯      |
                        | IS [NOT] LESS THAN    |
/ identifier-1       \  |     ¯¯¯  ¯¯¯¯         |  / identifier-2       \
|                    |  | IS [NOT] EQUAL TO     |  |                    |
< literal-1          >  <     ¯¯¯  ¯¯¯¯¯        >  < literal-2          >
|                    |  | IS [NOT] >            |  |                    |
\ arith-expression-1 /  |     ¯¯¯  ¯            |  \ arith-expression-2 /
                        | IS [NOT] <            |
                        |     ¯¯¯  ¯            |
                        \ IS [NOT] =            /
                              ¯¯¯  ¯

Tabella 578.14. Significato degli operatori di relazione.

Operatore Descrizione
IS [NOT] GREATER THEN
    ¯¯¯  ¯¯¯¯¯¯¯
maggiore di, non maggiore di
IS [NOT] >
    ¯¯¯  ¯
maggiore di, non maggiore di
IS [NOT] LESS THEN
    ¯¯¯  ¯¯¯¯
minore di, non minore di
IS [NOT] <
    ¯¯¯  ¯
minore di, non minore di
IS [NOT] EQUAL TO
    ¯¯¯  ¯¯¯¯¯
uguale a, diverso da
IS [NOT] =
    ¯¯¯  ¯
uguale a, diverso da
IS GREATER THAN OR EQUAL TO
   -------      --------
maggiore o uguale a
IS >=
   --
maggiore o uguale a
IS LESS THAN OR EQUAL TO
   ----      --------
minore o uguale a
IS <=
   --
minore o uguale a

Quando gli operandi sono entrambi numerici, indipendentemente dal fatto che la loro rappresentazione sia in forma di «indice» (INDEX), compatta (COMPUTATIONAL) o in forma di byte (DISPLAY), il confronto si basa sul valore numerico che esprimono, tenendo conto del segno, se c'è, considerando positivi i valori senza segno.

Quando si confrontano operandi alfanumerici, o quando anche uno solo è di tipo alfanumerico, il confronto avviene in modo lessicografico (in base all'ordinamento previsto dalla codifica adottata).

578.6.2   Condizioni di classe

La condizione di classe serve a stabilire se l'operando a cui si applica è numerico o alfabetico. È numerico un operando che è composto soltanto di cifre da 0 a 9, con il segno eventuale; è alfabetico un operando composto soltanto dal lettere alfabetiche ed eventualmente da spazi.

La condizione di classe si utilizza solo per verificare il contenuto di variabili che sono state dichiarate con una rappresentazione in byte (USAGE IS DISPLAY).

Segue lo schema sintattico per esprimere la condizione di classe:

                     /            \
                     | NUMERIC    |
identifier IS [NOT]  < ¯¯¯¯¯¯¯    >
               ¯¯¯   | ALPHABETIC |
                     \ ¯¯¯¯¯¯¯¯¯¯ /

Naturalmente, se si usa la parola chiave NOT, si intende invertire il significato della condizione.

578.6.3   Nomi di condizione

I nomi di condizione, che si dichiarano nella divisione DATA DIVISION con il numero di livello 88, servono a descrivere il confronto della variabile a cui si riferiscono con i valori che rappresentano.

Supponendo di avere dichiarato il nome di condizione PARI nel modo seguente:

000000     02  CODICE           PIC 9.
000000         88  PARI         0, 2, 4, 6, 8.
000000         88  DISPARI      1, 3, 5, 7, 9.
000000         88  BASSO        0 THRU 4.
000000         88  ALTO         5 THRU 9.

Nella divisione PROCEDURE DIVISION potrebbero apparire righe come quelle successive, per verificare che la variabile CODICE contenga un valore pari:

000000     IF PARI
000000     THEN
000000         PERFORM ...;
000000     ELSE
000000         ...

578.6.4   Condizioni di segno

La condizione di segno permette di stabilire se un'espressione aritmetica (e può essere anche solo una costante o una variabile numerica) è positiva, negativa o se vale esattamente zero:

                                /  POSITIVE  \ 
                                |  ¯¯¯¯¯¯¯¯  |
arithmetic-expression IS [NOT]  <  NEGATIVE  >
                          ¯¯¯   |  ¯¯¯¯¯¯¯¯  |
                                \  ZERO      /
                                   ¯¯¯¯

578.6.5   Condizioni composte e negate

Attraverso gli operatori booleani comuni, si possono definire delle condizioni composte, oppure negate. Si utilizzano le parole chiave AND, OR e NOT per esprimere gli operatori booleani noti con lo stesso nome. Con l'ausilio delle parentesi tonde si possono modificare le precedenze nella valutazione delle espressioni.

Il linguaggio COBOL prevede una forma abbreviata per esprimere delle condizioni di relazione composte. Si osservi l'espressione seguente:

A > B OR A > C OR A < D

Questa potrebbe essere abbreviata così:

A > B OR > C OR < D

Tuttavia, si comprende che l'abbreviazione comporta maggiore difficoltà interpretativa nella lettura umana del programma sorgente.

578.7   Avverbi comuni

Per «avverbi comuni» qui si intendono delle parole chiave che possono far parte di varie istruzioni, fornendo però lo stesso tipo di funzionalità.

Tabella 578.19. Alcuni avverbi comuni.

Avverbio Descrizione
ROUNDED
Quando una variabile deve ricevere il risultato di un'espressione aritmetica e non ha la possibilità di rappresentare in modo esatto i decimali, con l'uso dell'avverbio ROUNDED si chiede di assegnare un valore arrotondato nella cifra meno significativa.
SIZE ERROR
Quando una variabile deve ricevere il risultato di un'espressione aritmetica e non ha la possibilità di rappresentare alcune cifre più significative, si verifica un errore, che può essere espresso dalla condizione SIZE ERROR. La verifica di questa condizione implica l'indicazione di un'istruzione da eseguire se si verifica questo tipo di errore.
CORRESPONDING
Alcune istruzioni prevedono l'uso dell'avverbio CORRESPONDING per fare riferimento a variabili strutturate che contengono campi con lo stesso nome, pur non avendo la stessa struttura. Generalmente si usa per assegnare un gruppo di variabili a un altro gruppo, con lo stesso nome, in un'altra struttura.

Appunti di informatica libera 2007.02 --- Copyright © 2000-2007 Daniele Giacomini -- <daniele (ad) swlibero·org>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome divisione_171_procedure_division_187.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico]

Valid ISO-HTML!

CSS validator!