Object Pascal

Controllo di flusso                 

Si tratta ora di analizzare un semplice insieme di istruzioni che permettono di operare selezioni ed iterazioni.
Iniziamo con le selezioni e incontriamo subito con il costrutto più intuitivo più semplice, ci consente di scegliere di eseguire una certa porzione di codice sulla base di una selezione. Sono coinvolte 3 keywords: if, then ed else. Lo schema di funzionamento è il seguente:

1)
if espressione booleana then
begin
  codice
end


2)
if espressione booleana then
 begin
  codice
 end
else
 begin
  codice
 end

3)
if espressione booleana then
 begin
  codice
 end
else if espressione booleana
 begin
  codice
 end
else if espressione booleana
 begin
  codice
 end
else
 begin
  codice
 end

ovviamente con "espressione booleana" si intende una scrittura che restituisca true o false come risultato mentre va ancora specificato che le ramificazioni introdotte da "else if" possono essere numerose a piacere, anche se è meglio non esagerare per evitare di avere problemi di leggibilità e manutenubilità del programma.


  Esempio 6.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
program Project1;
var
x : Integer;
begin
  Write('Inserisci un numero: ');
  Readln(x);
  if x mod 2 = 0 then
  begin
    writeln('Numero pari');
  end
else
 writeln('Numero dispari');
Readln();
end.

L'esempio dovrebbe essere abbastanza chiaro, la riga 7 introduce il nostro if accompagnato dalla sua espressione booleana (x mod 2 = 0). Come intuibile dall'esempio stesso, riga 12, la coppia di delimitazione begin / end, può essere omessa se abbiamo una sola istruzione che compone il codice sotteso da if o else. Sempre a logica si intuisce che, nei casi 2 e 3  della definizione, l'"else" finale serve da rastrello per comprendere tutti i casi che non rientrano nei rami precedenti. Alcune vecchie versioni di Pascal per questo caso particolare usanvano la keyword "otherwise". Vediamo un altro esempio più completo che illustrerà un altro concetto:

  Esempio 6.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
program Project1;
var x1 : Integer;
begin
  Write('Inserisci i numeri 1 o 2 o 3: ');
  Readln(x1);
  if x1 = 1 then begin
    Writeln('Bene, hai inserito il numero 1');
  end
  else if x1 = 2 then begin
    Writeln('Bene, hai inserito il numero 2');
  end
  else if x1 = 3 then begin
    Writeln('Bene, hai inserito il numero 3');
  end
  else
  begin
    Writeln('Ho detto 1 o 2 o 3!!');
  end;
Readln();
end.

Vale la pena porre l'accento sul fatto che alle righe 8, 11 e 14 l'istruzione end non è seguita dal ; cosa che invece accade alla 18. Questo evidentemente perchè alla 18 viene indicata la fine del blocco che inizia alla 6 mentre alla 8, 11 e alla 14 siamo ancora all'interno del blocco stesso. Il compilatore in questo senso vi aiuta segnalandovi ciò che non va.
Come  ho accennato è meglio non esagerare nell'uso di ramificazioni iontrodotte da if - else, per i motivi anzi detti. Possono tutavia capitare situazioni per le quali si rende necessaria la selezione in un insieme più alto di valori; in questo caso è possibile usare il costrutto seguente che prevede le keywords caseof - else - end con la seguente sintassi:

case variabile of
valore1 : codice
valore2 : codice
....
valoren : codice
else
codice

end;

da notare in fondo quel 'end' che chiude il blocco relativo all'istruzione case. Vediamo l'esempio precedente ampliato, che ben si adatta ad illustrare come funziona questa elegante istruzione:

  Esempio 6.3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
program Project1;
var x1 : Integer;
begin
  Write('Inserisci un nemro da 1 a 5: ');
  Readln(x1);
  case x1 of
    1: Writeln('OK - 1');
    2: Writeln('Ok - 2');
    3: Writeln('OK - 3');
    4: Writeln('OK - 4');
    5: begin
      Writeln('Bravo');
      Writeln('Hai inserito il valore massimo');
       end;
    else
    Writeln('Cosa non ti risulta chiaro sui valori da immettere?');
  end;
  Readln();
end. 

il ramo che inizia quando si seleziona il numero 5 ci fa vedere come si può fare se ci sono più istruzioni, banalmente si usa la solita coppia begin - end.
E ' possibile comprendere più valori in uno stesso ramo? Ovviamente si:

case x of
1..10 :


comprende tutti valori da 1 a 10

case x of
1, 2, 5, 8, 123
:

viene selezionato se x assume i valori nella sequenza indicata.

Terminate le istruzioni di selezione vediamo ora come effettuare le iterazioni, ovvero come ripetere un certo blocco di istruzioni per un numero da noi scelto di cicli.
La prima istruzione che incontriamo è il classico for che ha la seguente sintassi, nella sua forma più semplice:

for variabile := valoreinizale to valorefinale do
begin
codice
end;

ed ecco l'esempio:


  Esempio 6.4
1
2
3
4
5
6
7
program Project1;
var x1 : Integer;
begin
  for x1 := 0 to 10 do
  writeln('x1 = ',x1);
readln()
end. 

Notiamo che il semplice esempio 6.4 ci dice anche che, come al solito, in presenza di una sola istruzione si può omettere la coppia begin - end. L'output vi mostrera che gli etremi dell'intervallo in cui si muove la variabile x1 sono compresi.  Se volete andare a ritroso non c'è problema, basta usare downto invece di to:

for x1 := 10 downto 0 do
....

Diversamente da altri linguaggi il ciclo che inizia con for non prevede la possibilità di usare un passo diverso da 1 per cui, in situazioni in cui questo procedimento sia necessario, bisognerà ricorrere al ciclo introdotto dalla kwyword while che vediamo adesso.

while espressione booleana do
begin
codice
end;


  Esempio 6.5
1
2
3
4
5
6
7
8
9
10
program Project1;
var x1 : Integer = 0;
begin
  while x1 < 10 do
  begin
    writeln('x1 = ', x1);
    x1 := x1 + 1;
  end;
readln();
end.

Il loop inizia alla riga 4 proponendo l'espressione booleana x < 10. In questo caso è vera se così non fosse il blocco che inizia col while viene saltato integralmente. All'interno è necessario che vi sia una qualche istruzione che, prima o poi renda false l'espressione booleana altrimenti si ha un loop infinito. In questo esempio abbiamo quanto serve alla riga 7 che incrementando x1 prima o poi renderà falsa l'espressione alla riga 4. Provate a rimuovere la riga 7 ed avrete una infinita sequenza di valori 0. A questo proposito vediamo di risolvere il problema precedente di simulare un for con passo diverso da 1: basta, riferendoci all'esempio 6.5, trasformare la riga 7 come segue:

x1 := x1 + 3;

per avere passo 3... ecc...

L'ultima istruzione è caratterizzata dalle keyword repeat e until.

repeat
codice
until espressione booleana


questo significa che verrà eseguita una certa parte di codice finchè è vera la condzione indicata nella espressione booleana non viene realizzata ovvero si procede finchè l'espressione restituisce false e si blocca l'esecuzione quando si ottiene true. Come accade per il while è necessario che all'interno ci sia qualche istruzione possa rendere realizzabile la condizione di uscita.

  Esempio 6.6
1
2
3
4
5
6
7
8
9
program Project1;
var x1 : Integer = 0;
begin
  repeat
  writeln('x1 = ', x1);
  x1 := x1 + 1;
  until x1 > 10;
readln();
end.

Come potrete notare non è necessario mettere la solita coppia begin - end per racchiudere più istruzioni. E' altresì necessario il ; prima di until. Inoltre, grossa differenza rispetto al loop introdotto con il while, abbiamo la certezza che il codice all'iterno del repeat - until, sarà eseguito almeno una volta, come è facile verificare. Infatti la condizione di uscita viene testata dopo che almeno una volta saremo passati all'interno del repaet.

Concludiamo questo lungo ma concettualmente semplice paragrafo presentano le due parole che permettono di alterare il corso di una iterazione, ovvero break e continue.
La prima esce completamente da un loop e reestituisce il controllo al livello più alto possibile.

  Esempio 6.7
1
2
3
4
5
6
7
8
9
10
11
program Project1;
var x1 : Integer = 0;
begin
  while x1 < 10 do
  begin
    writeln('x1 = ', x1);
    x1 := x1 + 1;
    if x1 = 5 then break
  end;
  readln();
end. 

Qui l'esecuzione si ferma al nuimero 4 in quanto l'istruzione alla righa 8 causa la uscita dal ciclo iniziato aslla riga 4.

Continue invece salta l'esecuzione di un ciclo, o meglio la parte di codice che viene dopo di esso, e retituisce il controlo all'iterazione successiva..

  Esempio 6.8
1
2
3
4
5
6
7
8
9
10
11
program Project1;
var x1 : Integer = 0;
begin
  while x1 < 10 do
  begin
    x1 := x1 + 1;
    if x1 = 5 then continue;
    writeln(x1)
  end;
readln();
end.

Qui invece viene saltata la stampa del numero 5 a causa del continue definito alla 7