Ciclo for in Object Pascal

Concetti Chiave
  • Il ciclo for in Object Pascal consente di eseguire un blocco di codice un numero specifico di volte.
  • La sintassi di base del ciclo for è:
    for variabile := valore_iniziale to valore_finale do
        istruzione;
    
  • Se il corpo del ciclo contiene più istruzioni, queste devono essere racchiuse tra begin e end.
  • Il contatore del ciclo deve essere di un tipo ordinale (come Integer, Char, o un tipo enumerato).
  • Ogni ciclo for può avere un unico contatore.
  • Il contatore del ciclo viene sempre incrementato di uno ad ogni iterazione (non è possibile specificare un incremento diverso).
  • In Object Pascal il ciclo for è molto semplice ma più restrittivo rispetto ad altri linguaggi di programmazione.

Ciclo for

L'istruzione for in Object Pascal è un'istruzione di ciclo che consente di eseguire ripetutamente un blocco di codice per un numero specifico di volte. A differenza di altri linguaggi di programmazione, come C, C++, Java e JavaScript, che offrono una sintassi più flessibile per i cicli for, Object Pascal adotta un approccio più semplice e diretto.

Il ciclo for in Object Pascal, infatti, è strettamente basato su un contatore, che può essere aumentato o diminuito ogni volta che il ciclo viene eseguito.

La sintassi di base per un ciclo for in Object Pascal è la seguente:

for variabile := valore_iniziale to valore_finale do
    istruzione;

Dove variabile è una variabile di tipo ordinale (come Integer, Char, o un tipo enumerato), valore_iniziale è il valore da cui iniziare il conteggio, e valore_finale è il valore a cui terminare il conteggio. La parola chiave to indica che la variabile del ciclo verrà incrementata di uno ad ogni iterazione.

Il corpo del ciclo, ovvero l'istruzione o il blocco di istruzioni che verranno eseguite ad ogni iterazione, segue la parola chiave do. Se il corpo del ciclo consiste in una singola istruzione, non è necessario racchiuderlo tra begin e end. Tuttavia, se si desidera eseguire più istruzioni all'interno del ciclo, è necessario utilizzare un blocco di istruzioni racchiuso tra begin e end:

for variabile := valore_iniziale to valore_finale do
begin
    istruzione1;
    istruzione2;
    { ... altre istruzioni ... }
end;

Chiariamo il tutto con un esempio pratico. Supponiamo di voler calcolare la somma dei numeri da 1 a 10. Ecco come si potrebbe scrivere questo codice in Object Pascal:

program SommaInteri;

var
    Total, I: Integer;
begin
    Total := 0;
    for I := 1 to 10 do
        Total := Total + I;
    Writeln('La somma dei numeri da 1 a 10 è: ', Total);
end.

In questo caso l'output sarà:

La somma dei numeri da 1 a 10 è: 55

Ricapitolando, quindi:

Definizione

Ciclo for in Object Pascal

In Object Pascal, il ciclo for consente di eseguire un blocco di codice un numero specifico di volte, utilizzando una variabile contatore che ad ogni iterazione viene incrementata di 1.

La sintassi di base è:

for variabile := valore_iniziale to valore_finale do
    istruzione;

Se il corpo del ciclo contiene più istruzioni, queste devono essere racchiuse tra begin e end:

for variabile := valore_iniziale to valore_finale do
begin
    istruzione1;
    istruzione2;
    { ... altre istruzioni ... }
end;

Restrizioni del ciclo for

Il ciclo for in Pascal è meno flessibile che in altri linguaggi (non è possibile specificare un incremento diverso da uno), ma è semplice e facile da comprendere.

Infatti, lo stesso ciclo dell'esempio di sopra, scritto in C, C++, Java o JavaScript, potrebbe essere simile a questo:

int total = 0;
for (int i = 1; i <= 10; i++) {
    total = total + i;
}

In questi linguaggi, l'incremento è un'espressione che può specificare qualsiasi tipo di sequenza, il che può portare a codice che molti considererebbero illeggibile, come il seguente:

int total = 0;
for (int i = 10; i > 0; total += i--) {
    // corpo del ciclo ...
}

In Object Pascal, tuttavia, è possibile utilizzare solo un incremento di un singolo passo. Se si vuole testare una condizione più complessa, o se si vuole fornire un contatore personalizzato, sarà necessario utilizzare un'istruzione while o repeat, invece di un ciclo for.

Definizione

Restrizioni del ciclo for in Object Pascal

  1. Il contatore del ciclo deve essere di un tipo ordinale (come Integer, Char, o un tipo enumerato).
  2. Ogni ciclo for può avere un unico contatore.
  3. Il contatore del ciclo viene sempre incrementato di uno ad ogni iterazione (non è possibile specificare un incremento diverso).

Variabile di ciclo inline

Un altro modo per scrivere un ciclo for è dichiarare la variabile contatore del ciclo all'interno della dichiarazione (con una sintassi che ricorda in qualche modo i cicli for in C e nei linguaggi derivati):

for var I: Integer := 1 to 10 do
    Total := Total + I;

In questo caso, la variabile I è dichiarata direttamente nella dichiarazione del ciclo for, e il suo ambito è limitato al ciclo stesso. Non abbiamo dovuto dichiarare I nella sezione var del programma.

Inoltre, è anche possibile sfruttare l'inferenza di tipo e omettere la specifica del tipo. Per cui, il programma completo sopra diventa:

program SommaInteri;

var
    Total: Integer;
begin
    Total := 0;
    for var I := 1 to 10 do
        Total := Total + I;
    Writeln('La somma dei numeri da 1 a 10 è: ', Total);
end.

Un vantaggio nell'utilizzare un contatore di ciclo inline è che l'ambito di quella variabile sarà limitato al ciclo: utilizzarla dopo l'istruzione for causerà un errore, mentre in generale si ottiene solo un avviso quando si usa il contatore del ciclo fuori dal ciclo.

Definizione

Variabile di ciclo inline

Nel ciclo for, è possibile dichiarare la variabile contatore direttamente nella dichiarazione del ciclo, limitandone l'ambito al ciclo stesso.

La sintassi è:

for var variabile: tipo := valore_iniziale to valore_finale do
    istruzione;

Dove variabile è la variabile contatore, tipo è il suo tipo (opzionale se si sfrutta l'inferenza di tipo), valore_iniziale è il valore da cui iniziare il conteggio, e valore_finale è il valore a cui terminare il conteggio.

Una delle domande che sorge spontanea quando si lavora con i cicli for è cosa succede al contatore del ciclo dopo il termine del ciclo stesso.

In breve, il valore risulta non specificato e il compilatore emetterà un avviso se si tenta di utilizzare il contatore del ciclo for dopo che il ciclo è terminato.

Ad esempio, nel programma seguente:

program TestContatoreFor;

var
    Total, I: Integer;
begin
    Total := 0;
    for I := 1 to 10 do
        Total := Total + I;
    Writeln('La somma dei numeri da 1 a 10 è: ', Total);
    Writeln('Valore di I dopo il ciclo: ', I); // Avviso
end.

Il compilatore emetterà un avviso simile a questo:

Warning: Variable 'I' is used before being initialized

Un vantaggio nell'utilizzare una variabile inline per il contatore del ciclo è che la variabile è definita solo all'interno del ciclo stesso e non sarà accessibile dopo la sua istruzione end, risultando in un errore del compilatore (che fornisce una protezione più forte):

program TestContatoreForInline;

var
    Total: Integer;
begin
    Total := 0;
    for var I: Integer := 1 to 10 do
        Total := Total + I;
    Writeln('La somma dei numeri da 1 a 10 è: ', Total);
    Writeln('Valore di I dopo il ciclo: ', I); // Errore
end.

Il compilatore emetterà un errore simile a questo:

Error: Undeclared identifier: 'I'

Ciclo for con decremento

Abbiamo detto che il ciclo for in Object Pascal può essere utilizzato solo con un incremento di uno. Tuttavia, è possibile utilizzare la parola chiave downto invece di to per creare un ciclo che decrementa il contatore di uno ad ogni iterazione. Ecco un esempio che calcola la somma dei numeri da 10 a 1, ossia effettua lo stesso calcolo dell'esempio precedente, ma in ordine inverso:

program SommaInteri2;

var
    Total, I: Integer;
begin
    Total := 0;
    for I := 10 downto 1 do
        Total := Total + I;
    Writeln('La somma dei numeri da 10 a 1 è: ', Total);
end.

Questo è l'unico caso in cui si può specificare uno step differente da uno, ma solo perché il passo è implicitamente -1 (decremento di uno).

Definizione

Ciclo for con decremento

La sintassi per un ciclo for che decrementa il contatore è:

for variabile := valore_iniziale downto valore_finale do
    istruzione;

Dove variabile è una variabile di tipo ordinale, valore_iniziale è il valore da cui iniziare il conteggio, e valore_finale è il valore a cui terminare il conteggio. La parola chiave downto indica che la variabile del ciclo verrà decrementata di uno ad ogni iterazione.

Ovviamente, se il valore iniziale è minore del valore finale in un ciclo for ... downto, il corpo del ciclo non verrà eseguito affatto.

Ciclo for con tipi non numerici

In Object Pascal il contatore di un ciclo for non deve essere necessariamente un numero. Può essere un valore di qualsiasi tipo ordinale, come un carattere o un tipo enumerato. Questo aiuta a scrivere codice più leggibile.

Ad esempio, ecco un programma che stampa tutte le lettere dell'alfabeto inglese, utilizzando un ciclo for con un contatore di tipo Char:

program Alfabeto;

var
    C: Char;
begin
    Writeln('Lettere dell''alfabeto inglese:');
    for C := 'A' to 'Z' do
        Write(C, ' ');
    Writeln;
end.

Questo codice mostra tutte le lettere dell'alfabeto inglese, ciascuna separata da uno spazio. Abbiamo adoperato la funzione Write invece di Writeln per evitare di andare a capo dopo ogni lettera. Inoltre, il contatore del ciclo C è di tipo Char, che comunque è un tipo ordinale in Object Pascal.

Potendo adoperare un tipo ordinale qualunque, in un ciclo for possiamo anche utilizzare un tipo enumerato personalizzato.

Ad esempio, supponiamo di avere un tipo enumerato che rappresenta i giorni della settimana:

TDay = (Lun, Mar, Mer, Gio, Ven, Sab, Dom);

Possiamo scrivere un ciclo for che itera su tutti i giorni della settimana come segue:

program GiorniSettimana;

type
    TDay = (Lun, Mar, Mer, Gio, Ven, Sab, Dom);
var
    ADay: TDay;
begin
    for ADay := Lun to Dom do
        { Stampa il numero del giorno della settimana (0 per Lun, 1 per Mar, ecc.) }
        Writeln(Ord(ADay));
end.

Quest'ultimo ciclo itera su tutti gli elementi del tipo di dati.

Quando lavoriamo con gli enumerati possiamo utilizzare una tecnica migliore per operare esplicitamente su ogni elemento del tipo (rendendolo più flessibile ai cambiamenti nella definizione) piuttosto che indicare specificamente il primo e l'ultimo elemento, scrivendo:

for ADay := Low(TDay) to High(TDay) do

In modo simile, è abbastanza comune scrivere cicli for per tutti gli elementi di una struttura dati, come una stringa. Ad esempio, possiamo scrivere un ciclo for che itera su tutti i caratteri di una stringa e li converte in maiuscolo:

program Maiuscole;

var
    S: string;
    I: Integer;
begin
    Write('Inserisci una stringa: ');
    Readln(S);
    for I := Low(S) to High(S) do
        S[I] := UpCase(S[I]);
    Writeln('Stringa in maiuscolo: ', S);
end.

Esiste, tuttavia, un'altra forma di ciclo for, chiamata ciclo for-in, che consente di iterare direttamente su ogni elemento di una struttura dati senza dover specificare esplicitamente gli indici. Analizzeremo questo tipo di ciclo più avanti nelle prossime lezioni.

Nota

Limiti delle stringhe e cicli for

Nell'esempio di sopra abbiamo adoperato le funzioni Low e High per ottenere i limiti inferiore e superiore della stringa.

Tuttavia, il modo in cui il compilatore tratta la lettura diretta dei dati stringa utilizzando gli operatori [] e determina i limiti inferiore e superiore di una stringa è un argomento piuttosto complesso in Object Pascal, anche se i valori predefiniti sono ora gli stessi per tutte le piattaforme. Analizzeremo in dettaglio questo argomento nelle lezioni sulle stringhe.

Per strutture dati che utilizzano indicizzazione basata su zero, è naturale voler iterare dall'indice zero a fino a quello prima della dimensione o lunghezza della struttura dati.

Modi comuni di scrivere questo codice sono:

for I := 0 to Count - 1 do
    { ... }

for I := 0 to Pred(Count) do
    { ... }