Libero

Programmare in Pascal

 

Obiettivi operativi

          Realizzare programmi

          Inviare dati al video

          Accettare valori da tastiera

          Usare variabili e costanti di tipo integer

          Invocare funzioni e procedure predefmite

Obiettivi cognitivi

          La struttura dei programmi

          Tipi, variabili e costanti

          Dichiarazioni

          Il tipo integer

          Assegnamenti ed espressioni

 

 

2.1   Struttura dei programmi

 

Iniziamo lo studio del Pascal osservando il listato 2.1, in cui possono già essere evidenziate alcune delle caratteristiche comuni alla struttura di ogni programma.

La parola chiave program, che apre l'intestazione, è seguita dal nome che abbiamo assegnato al programma, nel caso in esame paese. Il punto e virgola chiude l'intestazione.

Il corpo del programma è compreso tra la parola chiave begin e la parola chiave end seguita da un punto ed è composto da una serie di istruzioni write che verranno eseguite sequenzialmente.

program paese ;

 

 begin

    write('Tre') ;

    write(' casettine')

    write(' dai');

    write(' tetti');

    write(' aguzzi');

 end.

 

 

NOTA INFORMATIVA

Nei linguaggi di programmazione con parola chiave o riservata si intende una parola a cui il compilatore attribuisce un'interpretazione univoca e determinata riservandola a un uso specifico. Tali parole non devono quindi essere utilizzate dal programmatore in modi e con scopi diversi da quelli previsti. Rimandiamo all'appendice A per un elenco completo delle parole chiave del Turbo Pascal 7.0.

 

 

Ogni istruzione write permette la stampa su video di ciò che è racchiuso fra parentesi tonde e apici. Per esempio

 

Write('Tre’);

 

Visualizza

 

Tre

 

Ogni istruzione deve essere seguita obbligatoriamente dal carattere di punto e virgola; fa eccezione l'ultima istruzione, quella che precede l'end finale, in cui il punto e virgola è opzionale. La struttura di un programma Pascal così come l'abbiamo finora descritta è:

 

Casella di testo: program nome_programma; 

begin
   istruzionel;
   istruzione2;
   istruzione3;
                                               
   istruzioneN 
end.

Le istruzioni vengono eseguite una dopo l'altra nella sequenza in cui si presentano. Il programma del listato 2.1 è composto da istruzioni write e la sua esecuzione visualizzerà la frase

 

Tre casettine dai tetti aguzzi

 

Nell'esecuzione delle istruzioni il Pascal non distingue fra lettere maiuscole e minuscole; possiamo dunque scrivere write anche come WRITE, Write o wRiTE.

Le write successive alla prima iniziano a scrivere a partire dalla posizione del video che segue quella occupata dall'ultimo carattere visualizzato dalla write immediatamente precedente. Abbiamo perciò inserito all'interno degli apici uno spazio bianco iniziale; se non lo avessimo fatto avremmo ottenuto:

 

Trecasettinedaitettìaguzzi

 

Infatti anche lo spazio è un carattere come gli altri e, se vogliamo visualizzarlo, dobbiamo esplicitamente inserirlo nella giusta posizione. Se desideriamo che ogni parola della frase sia scritta su una riga separata, dobbiamo utilizzare l'istruzione writeln. Sostituendo nel listato 2.1 ogni write con una writeln otteniamo la seguente visualizzazione:

 

program paese_tranguillo;

begin

   write('Tre');

   write(' cassettine');

   write (' dall1 'aria') ;

   wrìte('   tranquilla'};

end

 
 

 


Un

programma

con

apostrofo

 

.

 

 

 

Tre

 

casettine

dai

tetti

aguzzi

 

Dalla seconda riga in poi il primo carattere visualizzato è uno spazio, se vogliamo toglierlo dobbiamo cancellarlo dalla parte compresa tra apici delle writeln corrispondenti. Se nel testo che desideriamo visualizzare sullo schermo compare un apostrofo, come in:

Tre casettine dall'aria tranquilla

dobbiamo usare un doppio apostrofo come nella terza write del listato 2.2

 

2.2 Variabili e assegnamenti

Supponiamo di voler calcolare l'area di un rettangolo di base 3 e altezza 7; com'è noto, l'area cercata è data dal prodotto 3x7. Osserviamo il listato 2.3 il programma che risolve il problema.

 

{ Calcolo area rettangolo }

program rettangolo;

var

base : integer;

altezza: integer;

area : integer;

 begin

 base := 3;

    altezza := 7;

    area := base*altezza;

write(area);

 end.

 

 
Listato 2.3

Calcolo

dell'area di

un rettangolo

 

 

 

 

 

 

 

 

 

 

 

 

Per rendere evidente la funzione espletata dal programma abbiamo inserito un commento:

 

{   Calcolo  area   rettangolo   }

 

I commenti devono essere inseriti tra parentesi graffe e possono estendersi su più righe e apparire in qualsiasi parte del programma. Tutto ciò che è racchiuso fra parentesi graffe non viene preso in considerazione e non ha alcuna influenza sul funzionamento del programma. In alternativa possiamo far precedere i commenti dalla sequenza di caratteri ( * e farli seguire dalla sequenza * ) ; dunque avremmo anche potuto scrivere:

 

(*   Calcolo  area   rettangolo   *)

 

Dopo la parola chiave var e prima di begin sono presenti le dichiarazioni delle variabili intere necessarie:

 

var

 base : integer;

 altezza: integer;

 area: integer;

 

Ogni singola dichiarazione è costituita da un identificatore di variabile seguito da due punti e dalla parola chiave integer, che specifica che la variabile è di tipo intero, base, altezza e area sono dunque identificatori di variabili di tipo integer.

Anche le dichiarazioni devono terminare con un punto e virgola. Nel nostro esempio alla dichiarazione del tipo della variabile corrisponde inoltre la sua definizione, la quale fa sì che alla variabile venga riservato uno spazio nella memoria centrale dell'elaboratore:

 

 

 

 

 

 

 
base                            altezza                             area

 

II nome di una variabile la identifica, il suo tipo ne definisce la dimensione e l'insieme delle operazioni che vi si possono effettuare. Il Turbo Pascal riserva per gli integer uno spazio di due byte, il che consente di poter lavorare su interi che vanno da -32768 a +32767.

 

NOTA INFORMATIVA

La memoria degli elaboratori elettronici è organizzata in byte. Ogni byte è composto da otto bit. Un bit può avere il valore zero o uno. Nel sistema binario che utilizza solo le cifre O e 1, con 2 byte (16 bit) sono rappresentabili valori compresi tra -215 (-32768) e +215- 1 (432767), quindi in totale 216 valori, considerando lo zero.

Tra le varie operazioni permesse fra integer che danno come risultato un integer vi sono somma, sottrazione e prodotto, che corrispondono rispettivamente agli operatori +, -, *.

L'istruzione

 

base   :=  3;

 

assegna alla variabile base il valore 3, cioè inserisce il valore (3) che segue l'operatore : = nello spazio di memoria riservato alla variabile (base). Effetto analogo avrà altezza := 7. L'assegnamento è dunque realizzato mediante l'operatore : =. Nella macchina i valori saranno memorizzati in notazione binaria, ma per comodità li riportiamo in formato decimale:

                                   Base                            Altezza             Area

3

 

7

 

 

 
 

 

 


L'istruzione:

 

area   := base*altezza;

 

assegna alla variabile area il prodotto dei valori di base e altezza:

                        Base                                        Altezza       Area

21

 

7

 

3

 
 

 

 

L'ultima istruzione

 

write(area);

 

visualizza 21, il valore della variabile area.

La struttura dei programmi Pascal prevede che le variabili siano dichiarate dopo la parola chiave var e prima di begin:

 

program nome_programma;

var

  dichiarazioni_di_variabili;

begin

  istruzione1;

  istruzione2;

  istruzioneS;

  istruzioneN

end.

 

 

 

Nelle dichiarazioni gli identificatori delle variabili dello stesso tipo possono essere scritti in sequenza:

base, altezza, area: integer;

 

Gli identificatori della lista possono essere in numero qualsiasi e devono essere separati da virgola e seguiti da due punti e dalla dichiarazione del tipo. Un punto e virgola chiude come al solito la dichiarazione:

 

lista_di_identificatori: tipo;

 

Allo scopo di rendere più chiaro l'effetto ottenuto dal programma dell'esempio precedente, si possono visualizzare anche i valori delle variabili base e altezza.

 

writeln(base); writeln(altezza); write(area);

 

In ogni write o writeln, tra parentesi tonde, si è inserito il nome della variabile da visualizzare, così da ottenere:

3

7

21

Se si vuole far precedere la visualizzazione dei valori da una descrizione, è sufficiente inserirla tra apici seguiti da una virgola, prima del nome della variabile.

 

write (‘Base:    ', base);

write ('  Altezza: ', altezza);

write('  Area: ', area);

 

Quello che si ottiene in esecuzione è

 

Base:   3       Altezza:   7       Area:   21

 

Una seconda versione del programma per il calcolo dell'area del rettangolo è quella del listato 2.4, la cui esecuzione avrà il seguente effetto:

 

Base: 3

Altezza: 7

Area: 21

 

Mentre integer è una parola chiave del Pascal e fa parte integrante del linguaggio, rettangolo, base, altezza e area sono identificatori scelti a nostra discrezione.

Esistono comunque alcune regole da rispettare nella costruzione degli identificatori: devono iniziare con una lettera o con un carattere di sottolineatura (_) e possono contenere solo lettere non accentate, cifre e_. Le lettere maiuscole vengono considerate equivalenti alle rispettive minuscole.

 

 

 

 

 

 

 

{ Calcolo area rettangolo }

program rettangolo2;

var

 base, altezza, area : integer;

begin

   base := 3;

   altezza := 7;

   area := base*altezza;

       writeln('Base : ' , base);  

   writeln('Altezza:', altezza);  

   writeln('Area: ', area);

end.

 

 
Listato 2.4

Calcolo

dell'area di

un rettangolo

(seconda

versione)

 

 

 

 

 

 

 

Esempi d'identificatori validi sono: nome1, cognome2, cognome_nome, volume, età, a, x; al contrario non sono corretti: 12nome, cognome-nome, vero?, padre&figli, età. Si noti che volume, VOLUME e voLume fanno riferimento allo stesso identificatore. Oltre a rispettare le regole precedentemente enunciate, un identificatore non può essere una parola chiave del linguaggio, né può essere uguale a uno degli identificatori definiti precedentemente. Anche il nome del programma, quello che segue la parola chiaveprogram, è un identificatore e non può quindi essere in conflitto con un nome di variabile.

Nel programma per il calcolo dell'area del rettangolo, si sarebbe ottenuto lo stesso risultato utilizzando nomi generici quali prova, x, y e z. Inoltre la forma grafica data al programma è del tutto opzionale: una volta rispettata la sequenzialità e la sintassi, la scrittura del codice è libera. In particolare più istruzioni possono essere scritte sulla stessa riga:

 

program prova;

var x, y, z: integer;begin x := 3; y := 7

z:=x*y; writeln('Base:’,x) end.;

 writeln ('Altezza :',   y);   writeln('Area:)

 

Indubbiamente questo programma è notevolmente meno leggibile del precedente. Lo stile grafico facilita enormemente il riconoscimento delle varie parti del programma e consente una diminuzione di tempo nelle modifiche, negli ampliamenti e nella correzione degli errori. Non importa quale stile decidiate di utilizzare, l'importante è che lo seguiate con coerenza senza, d'altra parte, incorrere in un'eccessiva rigidità. In generale è bene dare a ogni variabile un nome significativo, in modo che, quando si deve intervenire a distanza di tempo sullo stesso programma, si possa facilmente ricostruire l'uso che se ne è fatto.

 

 

 

2.3 Costanti

 Nel programma visto nel paragrafo precedente i valori di base e altezza sono costanti, dato che non variano durante l'esecuzione del programma. Evidentemente, avremmo potuto scrivere direttamente:

 

area   :=  3*7;

 

Quando un certo valore non viene modificato nel corso del programma è opportuno, soprattutto se è utilizzato in modo ricorrente, rimpiazzarlo con un nome simbolico. Per farlo dobbiamo definire prima di begin e dopo la parola chiave const un identificatore di costante e fargli corrispondere il valore desiderato.

const

   BASE  =   3;

 

Grazie a questa direttiva potremo utilizzare all'interno del programma l'identificatore BASE al posto del valore intero 3.

La stessa definizione di costante implica che il suo valore non può essere modificato: BASE può essere utilizzata in un'espressione a patto che su di essa non venga mai effettuato un assegnamento.

Vediamo nel listato 2.5 come viene modificato il programma del paragrafo precedente utilizzando alcune costanti.

Il nome di una costante può essere qualsiasi identificatore valido in Pascal. Per maggiore chiarezza abbiamo scelto di evidenziare visivamente le costanti scrivendole con caratteri maiuscoli.

Invece dì utilizzare direttamente i valori è auspicabile far uso degli identificatori di costante che, essendo descrittivi, migliorano la leggibilità

 

 

 

{ Calcolo area rettangolo, utilizzando costanti }

program rettangole3;

const

  BASE = 3;

  ALTEZZA = 7;

var

  area: integer;

begin

  area := BASE*ALTEZZA;

  writeln('Base : ',    BASE);

  writeln('Altezza:     ', ALTEZZA);

  writeln('Area: ',     area);

end.

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


dei programmi. Inoltre, dovendo cambiare un determinato valore se questo è stato definito come costante è sufficiente modificare il solo valore attribuitogli al momento della dichiarazione; se, al contrario, il valore non è stato definito come costante occorrerà cercare e modificare tutte le sue Decorrenze all'interno del testo, con notevole perdita di tempo in listati di una certa lungezza.

Per esempio, per fare in modo che il programma del listato 2.5 calcoli l'area del rettangolo con base 102 e altezza 34, è sufficiente modificare gli assegnamenti effettuati in fase di definizione delle costanti BASE e ALTEZZA:

 

const

  BASE = 102;

  ALTEZZA = 34;

 

In sintesi, l'uso delle costanti migliora due parametri classici di valutazione dei programmi: flessibilità e facilità di manutenzione. Nel Turbo Pascal le dichiarazioni di costanti e variabili possono apparire in un ordine qualsiasi, fermo restando che devono seguire l'intestazione del programma e precedere il begin del corpo del programma. Questa regola rimane valida anche per le dichiarazioni che studieremo in seguito, come le dichiarazione di tipo definito dall'utente, di funzione e di procedura le quali tutte insieme vanno a formare la parte dichiarativa.

 

program nome_programma;

parte_dichiarativa

begin

  istruzionel;

  istruzione2;

  istruzioneS;

  ìstruzioneN;

end.

 

2.4  Immissione ed emissione di dati

I programmi che abbiamo scritto non calcolano l'area di un qualsiasi rettangolo ma soltanto di quello che ha per base 3 e per altezza 7, supponiamo centimetri.

Per esempio, per trovare l'area di un rettangolo di base 57 e altezza 20 si deve intervenire nella parte dichiarativa del programma riportato nel listato 2.5 scrivendo:

 

const

BASE = 57;

ALTEZZA =20;

 

oppure nel corpo del listato 2.4, dove al posto delle costanti si sono utilizzate delle variabili, si deve scrivere:

 

base := 57;  

altezza := 20;

 

Dopo aver effettuato nuovamente la compilazione, la successiva esecuzione restituirà 1140, cioè l'area del rettangolo in centimetri quadri. Come si comprende anche da questo semplice esempio, la procedura di modifica del programma è estremamente laboriosa. Per rendere il programma di applicazione più generale si deve permettere a chi lo sta utilizzando di immettere i valori della base e dell'altezza: in questo modo l'algoritmo calcolerà l'area di un qualsiasi rettangolo. L'esecuzione dell'istruzione:

read(base);

fa sì che il sistema attenda l'immissione di un dato da parte dell'utente. Durante l'esecuzione di un programma può essere richiesta all'utente l'immissione di più informazioni. Perciò è opportuno visualizzare frasi esplicative; a tale scopo facciamo precedere le istruzioni read da appropriate istruzioni  write:

 

write('Valore base: ');

read (base);

 

L'argomento di write è semplicemente una frase da visualizzare, quindi deve essere racchiuso tra apici. Non è neppure necessario richiedere un salto a riga nuova mediante una writeln, in quanto l'immissione può avvenire sulla stessa riga. Quello che apparirà all'utente in fase di esecuzione del programma sarà:

 

Valore base :

 

In questo istante l'istruzione read attende l'immissione di un valore, se l'utente digiterà 15 seguito da INVIO:

Valore  base:   15<INVIO>

Questo dato verrà assegnato alla variabile base:

        base

15

 
 

 

 

 


L'istruzione read   può leggere più valori in ingresso. Per esempio

 

read(base, altezza);

 

aspetta due valori in ingresso e li assegna rispettivamente alle variabili base e altezza.

Nel nostro caso dovremmo coerentemente modificare il commento che apparirà sul video:

 

write('Valori di base e altezza: ');

read(base, altezza);

 

L'utente vedrà apparire sul video il messaggio dell'istruzione write e dovrà inserire i valori separati da almeno uno spazio:

 

Valori di base e altezza: 10 13

 

Nel caso di valori numerici non ha importanza se vengono digitati uno o più spazi prima o dopo i valori in ingresso.

L'istruzione readln agisce in modo simile a read; ma, a differenza di questa, alla fine della lettura delle variabili effettua un salto a riga nuova. Inoltre readln, seguita direttamente dal punto e virgola, può essere utilizzata per provocare un'attesa indefinita durante l'esecuzione del programma:

 

write('Premere Invio per continuare...');

Casella di testo: Quando l'utente premerà il tasto di INVIO verranno eseguite le successive istruzioni del programma.
Modifichiamo ora il programma per il calcolo dell'area del rettangolo consentendo l'immissione dei dati durante l'esecuzione, come nel listato 2.6.
readln;

{ Calcolo area rettangolo }

program rettangolo4;

var

  base, altezza, area: integer;

begin

  writeln;

  writeln;

  writeln('AREA RETTANGOLO');

  writeln;

  write('Valore base : ');

  readln(base);

  write('  Valore altezza: ');

  readln(altezza);

  area := base*altezza;

  writeln;

  writeln('Base : ', base);

  writeln('Altezza: ', altezza);

  writeln('Area: ', area);

readln;

 end.

 

 
 


 

Listato 2.6

Calcolo

dell'area di

un rettangolo

(quarta

versione)

 

 

 

 

 

 

 

 

 

 

 

Vediamo l'esecuzione del programma nell'ipotesi che l'utente inserisca i valori 10 e 13:

 

AREA RETTANGOLO

Valore base: 10

Valore altezza: 13

Base: 10

Altezza: 13

Area: 130

 

Per lasciare una riga vuota si deve utilizzare l'istruzione writeln seguita direttamente dal punto e virgola:

 

writeln('AREA RETTANGOLO');

writeln;

 

La prima istruzione writeln fa andare il cursore a riga nuova dopo la visualizzazione di AREA RETTANGOLO, la seconda, senza argomenti, lo fa scorrere di un'ulteriore riga.

Si possono stampare più variabili con una sola write o writeln, indicando gli identificatori separati da una virgola. L'istruzione

 

writeln(base, altezza, area);

 

inserita alla fine del programma precedente, visualizzerebbe, se i dati immessi dall'utente fossero ancora 10 e 13:

 

1013130

 

Per far in modo che i valori vengano separati da spazi dobbiamo esplicitamente inserirli all'interno di apici:

 

writeln(base,’ ‘,altezza,’ ‘,area);

 

E comunque consigliabile inserire commenti che descrivano ciò che viene visualizzato:

 

writeln('Base: ', base,'  Altezza: ', altezza, '  Area: ', area);

 

genererà:

 

Base: 10  Altezza: 13  Area: 130

 

Si tratta dunque di inserire i vari messaggi che devono apparire sul video tra apici, prima o dopo gli oggetti da visualizzare. È possibile inserire espressioni aritmetiche nella write al posto delle variabili:

 

writeln('Area:    ',   10*13);

 

L'istruzione stamperà 130, cioè il risultato dell'espressione.

 

 

 

 

L'operatore div (divisione intera)

 

x  div  y

 

 restituisce il risultato della divisione intera tra x e y. Per esempio:

 

11   div   4

 

è uguale a 2; viene cioè effettuato il troncamento del risultato alla parte

intera mentre la parte decimale viene perduta. L'operatore mod (modulo)

 

x mod y

 

 

consente di ottenere il resto della divisione intera x div y. Per esempio:

 

34  mod  5;

 

ha valore 4 (resto di 34 diviso 5). Si noti che per ogni x vale la formula:

 

x   =  x  div  y  *   y  +  x  mod   y

 

All'interno delle espressioni aritmetiche la priorità degli operatori segue le regole dell'algebra. Le operazioni di negazione sono eseguite per prime, poi vengono eseguite le moltiplicazioni e le divisioni, infine le somme e le sottrazioni. Se due operatori sono gerarchicamente allo stesso livello, per esempio * e div, quello più a sinistra sarà considerato per primo (vedi figura 2.1).

Il risultato di un'espressione intera può essere assegnato a una variabile intera, come abbiamo già visto nel programma per il calcolo dell'area di un rettangolo:

 

area   :=  base*altezza;

 

In un'istruzione di assegnamento

 

y   :=  z  +  3*x

 

prima viene valutata completamente la parte a destra dell'assegnamento e poi il risultato viene attribuito alla variabile y.

La priorità degli operatori può essere alterata mediante parentesi tonde; in questo caso vengono valutate per prime le operazioni contenute nelle parentesi tonde più interne. Osserviamo per esempio il seguente assegnamento:

 

x   :=  a   +  b   -    15   +   4    *   c;

 

nell'ipotesi che le variabili intere a, b e e abbiano rispettivamente valore 7, 3 e 5, a x viene assegnato il valore 15. L'inclusione tra parentesi dell'espressione 15 + 4

 

x   :=  a   +  b   -    (15   +   4)    *   c;

 

cambia evidentemente il risultato, che diventa -85.   ,.

Nell'espressione:

(a  +  b  -    (15   +  4) )    *   c

 

viene prima valutata l'espressione presente nella parentesi più interna (15+4) e successivamente quella nella parentesi esterna (a+b-19); il risultato viene infine moltiplicato per il valore di c, che restituisce -45. Il risultato dell'espressione

 

a  + b  +  c mod 2

 

è 11, in quanto l'operatore mod restituisce il resto della divisione intera tra il valore di e (5) e 2, che è 1. Invece il risultato di

 

(a + b +  c)   mod 2

 

è 1. Infatti prima viene effettuata la somma dei valori di a, b e e, successivamente viene calcolato il resto della divisione intera del risultato (15) per 2. Il risultato di

 

(a  + b)*32   +   4

  

è 340, mentre quello di

 

((((((c + 6)   * 3 + a)   div 2)   + 10 * 4)   div 12)   + b)

 

è 8. Non esiste alcun limite al numero di parentesi tonde aperte. Attenzione: l'assegnamento a un intero di un valore non compreso nell'intervallo previsto, da -32768 a +32767, genera effetti difficilmente prevedibili. Provate, durante l'esecuzione del programma del listato 2.6 che calcola l'area del rettangolo, a inserire i valori 751 e 63. Tali valori verranno immessi nelle variabili base e altezza e l'istruzione

area := base*altezza;

 

assegnerà ad area il valore -18223, mentre il risultato corretto sarebbe 47313. Si ha quello che si definisce un overflow (traboccamento): l'operazione genera un valore intero che in binario non è rappresentabile con due byte, il bit che costituisce la parte più rappresentativa del numero viene perciò perso e il risultato è completamente errato. Nel capitolo 9 (Tipi di dato) vedremo come il Turbo Pascal metta a disposizione dell'utente altri tipi numerici che permettono di gestire variabili intere che possono assumere valori ben più grandi di quelli consentiti dal tipo integer.

 

 

2.6 Funzioni e procedure predefinite

 

funzione, analogamente a quanto definito in matematica, è uno strumento che, a partire da uno o più valori presi in input, restituisce un valore associato ai primi in modo univoco.

Più avanti impareremo a creare le nostre funzioni; esistono però delle funzioni predefinite o standard, già pronte all'uso, che il linguaggio mette a disposizione del programmatore. Da questo punto di vista non interessa come il compito affidato alla funzione venga svolto, basta sapere cosa deve esserle passato in entrata e cosa restituisce in uscita. Un esempio di funzione predefinita è abs, che applicata a un numero ne restituisce il valore assoluto.

Se dopo il nome della funzione abs, all'interno di parentesi tonde, viene inserito un numero intero, abs restituisce il suo valore assoluto, valore che è possibile assegnare a una variabile o utilizzare direttamente all'interno di un'espressione. Se w e j sono variabili di tipo intero, l'istruzione

 

w   := abs (j) ;

 

assegna a w il valore assoluto di j.

All'interno delle parentesi tonde può essere inserito direttamente un valore, come nel caso

w   :=  abs (3) ;

 

che assegna a w il valore 3; o come nel caso

 

w   := abs(-186);

 

che assegna a w 186.

 

Il risultato restituito da una funzione può essere inserito all'interno di

un'espressione:

 

w   :=  j*abs(k);

 

dove, se j è uguale a 100 e k a -73, viene assegnato a w il valore 7300, mentre con w   : = j * k a w sarebbe stato assegnato -7300. Osserviamo nel listato 2.7 un programma completo che utilizza la funzione abs. Si tratta del calcolo della lunghezza di un segmento i cui estremi vengono immessi dall'utente.

Se consideriamo la successione dei numeri interi, ognuno dei due estremi del segmento può essere sia positivo che negativo: perciò la lunghezza corrisponde al valore assoluto della differenza tra i due valori.

 

 

 

 

 


 

Per esempio, se il primo estremo corrisponde a -5 e il secondo a -1, la lunghezza del segmento sarà 4, cioè il valore assoluto di - 5 - (-1). L'esecuzione del programma del listato 2.7, nel caso l'utente inserisca i valore 7 e -2, produrrà la seguente visualizzazione:

 

LUNGHEZZA SEGMENTO

Primo estremo: 7

Secondo estremo: -2

Lunghezza segmento: 9

 

 

 

 

 

 

 

 

 

 

 

 

{ Esempio utilizzo di funzioni }

program lunghezza_segmento;

var

a, b: integer;

segmento, lunghezza: integer;

begin

writeln;

writeln;

writeln('LUNGHEZZA SEGMENTO');

writeln;

write('Primo estremo: ');

readln(a);

write('Secondo estremo: ');

readln(b);

segmento := a - b; lunghezza := abs(segmento);

writeln('Lunghezza segmento: 'lunghezza);

 readln;

end.

 
 


 

Listato 2.7

Utilizzo

della funzione

abs

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I parametri di wri te e writeln possono essere espressioni al cui interno sono presenti delle funzioni, come nel caso delle istruzioni:

 

writeln(' valore assoluto: ', abs(j));

writeln(' valore assoluto +1: ', abs(k)+1);

 

Passiamo adesso a considerare altre funzioni disponibili in Pascal.

Se num è una variabile numerica integer, abbiamo i seguenti esempi

di funzioni standard del Turbo Pascal:

 

pred (num)    restituisce il predecessore di num

succ (num)    restituisce il successore di num

sqr (num) restituisce il quadrato di num

 

Se x è una variabile intera, l'istruzione

 

x := pred(50); assegna a x il valore 49, mentre

x := succ(50); assegna a x il valore 51.

 

 

Se y ha valore 7,

 

x   :=  succ(y+3); assegna a x il valore 11 e

x   :=   sqr(y); assegna a x il valore 49. Infine in

x   :=  prec(sqr(y));

 

prima viene calcolata la funzione più interna sqr ( y ), che restituisce 49, poi quella più esterna, per cui a x viene assegnato il valore 48. Un'altra funzione numerica importante è random (n), che restituisce un numero intero casuale compreso fra O e n - 1. Quindi, se x è una variabile intera, l'istruzione

 

x   :=  random(10);

 

assegna a x un valore casuale compreso fra O e 9, mentre

 

 x   := random(lOO)   +   100;

 

assegna a x un valore casuale compreso fra 100 e 199.

Nel listato 2.8 si ha un esempio di utilizzo della funzione random per simulare al computer il lancio di due dadi.

Osserviamo che iterando più volte l'esecuzione del listato 2.8 otteniamo sempre lo stesso risultato. Questo perché la funzione random genera numeri solo apparentemente casuali, in realtà determinati a partire da un valore iniziale (detto seme) memorizzato nella variabile di sistema RandSeed.

 

 

 

Listalo 2.8

Utilizzo della

{Esempio di utilizzo della funzione random}

program lancio_dadi ;

 var a, b: integer;

     totale : integer;

begin

  writeln;

  writeln ('LANCIO DI DUE DADI');

  a := random(6) + 1;

  b := random(6) +1;  

  totale := a + b;

 

  writeln ('Lancio : ',totale);

 

  readln;

end.

 

 
funzione

casuale

random(n)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Per modificare questo valore occorre utilizzare l'istruzione randomize;

che modifica il valore dei seme. Per avere lanci di dadi sempre diversi occorrerà quindi inserire all'inizio del programma:

 

begin

randomize;

writeln;

 

Le procedure, come le funzioni, svolgono un compito specifico ma, a differenza di queste, non restituiscono direttamente un valore in uscita e non possono cosi essere utilizzate all'interno di espressioni. Vengono richiamate, come abbiamo fatto con randomize, specificandone il nome seguito da un punto e virgola; per esempio l'istruzione

 

ClrScr;

 

invoca la procedura ClrScr (CLeaRSCReen) che pulisce completamente lo schermo e posiziona il cursore nell'angolo in alto a sinistra dello stesso. Un'altra procedura molto utilizzata è

 

GotoXY{c, r);

 

che sposta il cursore in una certa posizione dello schermo. Analogamente allo schema di una battaglia navale, il video è infatti costituito da una griglia invisibile formata da linee verticali e orizzontali; in ogni istante il cursore è localizzato all'incrocio tra una colonna e una riga. La procedura GotoXY (c, r) sposta il cursore sulla colonna c, riga r. I valori interi che c e r possono assumere sono normalmente compresi tra 1 e 80 per il primo, tra 1 e .25 per il secondo; c e r possono essere valori costanti o variabili. L'istruzione

 

GotoXY(25,10);

 

posiziona il cursore nella decima riga in corrispondenza della venticinquesima colonna.

Infine, se il computer con cui lavoriamo dispone di uno schermo a colori sono interessanti le procedure predefinite

 

TextColor(n);

 

che modifica il colore con cui i dati vengono visualizzati sullo schermo; e TextBackground   (n);

che modifica il colore dello sfondo (background) su cui viene visualizzato il testo. Per esempio, le istruzioni

 

textcolor (14);

textbackground(4);

writeln('Prova testo a colori');

 

 

Tabella 2.1

Codici dei colori

 

 

 

nero                 0          grigio scuro                  8

blu                   1          blu chiaro                     9

verde               2          verde chiaro                 10

turchese           3          turchese chiaro 11

rosso                4          rosso chiaro                 12

magenta           5          magenta chiaro 13

marrone           6          giallo    14

grigio chiaro     7          bianco  15

 

 

 

 

visualizzano sullo schermo la scritta Prova testo a colori in caratteri gialli su sfondo rosso. I colori disponibili per il testo e lo sfondo dipendono dal computer; nella tabella 2.1 sono riportati i valori corrispondenti ai codici più comuni.

Le procedure ClrScr, TextColor, TextBackground e GotoXY non vengono collegate automaticamente ai nostri programmi come avviene per le funzioni viste in precedenza. Si deve quindi richiedere esplicitamente questa connessione al sistema, inserendo dopo l'intestazione del programma e prima della dichiarazione di costanti e variabili

 

uses   crt;

 

dove crt (Cathode Ray Tube) è il nome della libreria (o modulo) contenente l'insieme delle funzioni e delle procedure per la gestione del video. In precedenza abbiamo potuto utilizzare direttamente le funzioni esaminate perché queste, come molte altre funzioni e procedure, sono contenute nel modulo system che viene automaticamente collegato al programma dal compilatore.

Nel listato 2.9 è riportato un esempio di uso delle procedure standard comprese nella libreria crt. Il programma visualizza nel mezzo dello schermo, dopo averlo pulito, alcuni semplici testi scritti con colori e su sfondi differenti. Si osservi che abbiamo utilizzato delle write e non delle wr i te In in quanto la posizione della visualizzazione viene comunque determinata dalla GotoXY precedente.

Una dichiarazione uses può riguardare un modulo oppure una lista di moduli: in quest'ultimo caso gli elementi della lista devono essere separati da una virgola.

La possibilità di includere diversi moduli utilizzando le relative funzioni e procedure predefinite ci porta a definire una struttura sintattica del programma più generale:

 

 

{ Uso delle procedure della libreria crt}

program provaCRT;

uses

  crt;

begin

  ClrScr;

  GotoXY(30, 7);

  write ('BIANCO SU NERO');

  TextColor(14);

  TextBackground(4) ;

  GotoXY(30,ll);

  write('GIALLO SU ROSSO');

  TextColor(lO);

  TextBackground(7);

  GotoXY(30,15);

  write('VERDE SU GRIGIO');

  readln;

end.

 

 
Listato 2.9

Utilizzo delle

procedure

della libreria

standard

crt

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

program nome_programma;

uses

lista_di_moduli;

parte_dichiarativa

begin

istruzionel;

istruzioneN;

end.

 

Altri moduli importanti del Turbo Pascal sono printer per l'uso della stampante e Graph per la grafica.

Anche read e write sono in realtà procedure standard. La procedura read accetta in ingresso le variabili in cui immettere i valori letti e write accetta i commenti e le variabili da scrivere.

I valori che le funzioni e le procedure accettano tra parentesi tonde sono detti parametri; si noti che ClrScr non accetta alcun parametro in ingresso, mentre GotoXY ne accetta due.

In seguito utilizzeremo numerose funzioni e procedure predefinite e vedremo in quale modo costruirne di proprie.

 

2.7 Precedenti versioni del Turbo Pascal

 

L'esposizione principale di questo volume si riferisce alla versione 7 del Turbo Pascal, anche se le differenze con le precedenti versioni sono minime.

In particolare, quanto illustrato in questo capitolo è valido per tutte le versioni del Turbo Pascal eccetto che per le seguenti differenze relative alla versione 3.

In quest'ultima non è presente il concetto di inclusione di librerie di funzioni e procedure, per cui non esiste la direttiva uses. Le procedure GotoXY eClrScr sono comunque disponibili direttamente: per quanto riguarda i programmi di questo capitolo è quindi sufficiente togliere uses crt dal listato 2.9.

Viceversa, se avete dei programmi scritti nella versione 3 che usano tali procedure, per renderli compatibili alle versioni successive dovete aggiungere l'inclusione del modulo crt dopo l'intestazione:

uses   crt;

 

Nella sola versione 3 il nome del programma che nell'intestazione segue la parola chiave program è considerato non un identificatore ma un semplice commento. Non deve quindi rispettare le regole per la costruzione degli identificatori e può essere in conflitto con un identificatore, per esempio di variabile o costante.

Se un programma scritto per la versione 3 del Turbo Pascal quando viene eseguito in una versione successiva produce per questa ragione un errore, è sufficiente cambiargli nome seguendo le regole previste per gli identificatori.

 

 

 

 

 

 

 

 

 

 

 

Domande di verifica

 

Qual è la struttura generale di un programma?

Come si dichiarano le variabili di tipo intero?

Qual è l'operatore che permette di assegnare un valore a una variabile?

Quale compito svolgono le istruzioni write e read?

Qual è la differenza fra write e writeln? E fra read e readln?

Quale utilizzo viene fatto delle costanti e come si definiscono?

Quali operatori possono essere utilizzati con le variabili di tipo

integer? Qual è il loro effetto?

Qual è la gerarchla fra gli operatori aritmetici?

Come operano random e randomize?

Quali funzioni e procedure predefinite conosci? Qual è il loro effetto?

Che cosa è una libreria?

In quale libreria si trovano le procedure GotoXY e TextColor? Ache

cosa servono?

Come possono essere utilizzate nei programmi funzioni e procedure

predefinite?

 

 

 

Esercizi

1                    Scrivere un programma che visualizzi sullo schermo:

 

Esercizio   n.l,   tutto  bene!

 

2                    Scrivere un programma che, utilizzando tre istruzioni write, visualizzi:

 

Esercizio n. 2, prove di visualizzazione

 

3                    Scrivere un programma che produca in uscita:

 

Esercizio n. 3, prima riga

Esercizio n.3, seconda riga

Esercizio n.3, terza riga

 

4          Scrivere un programma che calcoli l'espressione^ = ax + b, dove x è uguale a 5, o è uguale a 18 e b è uguale a 7 e dove x,a, b ey devono essere

dichiarate come variabili intere.

Si visualizzi infine il valore finale:

y=97

 

5   Trasformare il programma dell'esercizio precedente in modo che x sia una variabile il cui valore viene richiesto all'utente in fase di esecuzione.

O   Modificare il programma dell'esercizio precedente in modo che a e b non siano variabili ma costanti.

7   Scrivere un programma che calcoli e visualizzi i valori di a, b e e ricavati dalle espressioni indicate:

 

a := ZERO - abs (x)

b := TOP- abs (y)

c := a * b

 

dove x e y sono variabili intere immesse dall'utente, ZERO e TOP sono costanti intere di valore zero e mille.

 

8   Determinare il valore assunto dalle variabili a, b e e al termine di questa sequenza di istruzioni:

a   :=   -2;

b   := a + 1;

b   := b  -  abs (a) ;

c   :=  a*b

b   :=   3;

 

9   Scrivere un programma che richieste all'utente lunghezza, larghezza e altezza di un parallelepipedo ne calcoli il volume.

 

1 0 Scrivere un programma che richieste all'utente lunghezza, larghezza e altezza di un parallelepipedo ne calcoli la superficie totale.

 

1 1 Scrivere un programma che richieda all'utente un numero di riga r e di colonna e, scriva in quella posizione una O e attorno a questa quattro X nelle posizioni (r,c+2), (r+2,c), O,c-2) e (r-2,c).

 

12 Se x e y sono variabili intere e x ha valore 25, quali valori vengono assegnati a y da ognuna delle seguenti istruzioni?

a)         y= pred(x) ;

b)   y= succ (x) ;

e)   y= sqr (x) ;

d)   y= pred(succ (x) )

e)   y= sqr (pred (x) ) ;

f)   y= abs(-(x * 2));

g)   y= sqr(-x) ;

h)   y= sqr (31 div x)

i)   y= (31 mod x)*2;

j)   y= abs(sqr(31 div x) - (31 mod x) * 2) ;

 

 

1 3   Trascrivere in Pascal le seguenti espressioni matematiche:

 

a)    ab + c-5 c)    |x + 3 | (x2 - 3x (x2 - 1))

 

 

1 4 Scrivere un programma che, richiesti all'utente i valori dix ey, visualizzi sul video il resto di x diviso y.

 

1 5 Sapendo che in un parcheggio ogni ora costa 2500 lire, scrivere un programma che richieda il numero complessivo delle ore e visualizzi il totale da pagare.

1 6 Sapendo che una moto percorre n kilometri con* litri di benzina, scrivere un programma che richieda n e x e quindi calcoli quanti kilometri si possono percorrere con un litro.

 

1 7 Sapendo che in un parcheggio la prima ora costa 2500 lire mentre tutte le successive costano 1500 lire, scrivere un programma che richieda il numero complessivo delle ore e visualizzi il totale da pagare.

 

1 8 Modificare il programma del precedente esercizio in modo tale che il totale sia visualizzato in rosso su fondo nero.

 

1 9 Scrivere un programma che richieda all'utente un tempo in secondi e ne visualizzi quindi l'equivalente in ore, minuti e secondi.

 

 

program tutto sbagliato;

cost

base, altezza, area := integer;

begin

base = 3;

altezza := 7

area := base x altezza;

writeln('Base: , base); writeln('Altezza:'; altezza); writelm('Area: \ area); end

 

 

 

 

 
Listato 2.10

Listato tutto sbagliato

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2 O [ Inverso del precedente ] Scrivere un programma che richieda il numero di ore, minuti e secondi che compongono un tempo e visualizzi quindi l'equivalente espresso in secondi.

21        Indicare tutti gli errori commessi nel listato 2.10.

22        Scrivere un programma che simuli al computer tre lanci consecutivi di

palline in una roulette.