cd free pascal prof. tramontano aula a5
DESCRIPTION
NON VERRANNO CORRETTI ESERCIZI A CHI NON E’ IN ELENCO. LE ISCRIZIONI NELL’ELENCO SI CHIUDONO IL 6 NOVEMBRE p.v. ULTIMA SETTIMANA PER CONSEGNARE ESERCIZIO N.2. PER SPIEGAZIONI RICEVO OGGI DALLE 10.30 ALLE 12.30 STUDIO CCL accanto ai laboratori. CD Free Pascal prof. Tramontano AULA A5. - PowerPoint PPT PresentationTRANSCRIPT
CD Free Pascal prof. Tramontano AULA A5
NON VERRANNO CORRETTI ESERCIZI A CHI NON E’ IN ELENCO
LE ISCRIZIONI NELL’ELENCO SI CHIUDONO IL 6 NOVEMBRE p.v.
PER SPIEGAZIONI RICEVO OGGI DALLE 10.30 ALLE 12.30
STUDIO CCL accanto ai laboratori
ULTIMA SETTIMANA PER CONSEGNARE ESERCIZIO N.2
PROCEDURE
E’ un sotto-programma che rende più facile la programmazione TOP-DOWN
Un programma che richiama procedure è organizzato in maniera tale che le procedure sono descritte prima di essere
chiamate dal programma.
Quando si chiama una procedura questo implica il cambiamento dello stato del programma per cui è necessario conoscere lo stato del programma prima della chiamata alla
procedura e lo stato dopo la chiamata.
Riduzione di programmi grandi in tanti programmi più piccoli
Fare eseguire una procedura all’interno di un programma viene indicato come chiamata ad una procedura (procedure call).
Quando si fa una chiamata ad una procedura, ad esempio una readln o una writeln implica che noi sappiamo esattamente quello che la procedura fa, ma possiamo assolutamente non sapere come lo fa.
Questo tipo di tecnica di programmazione è detta dell’astrazione procedurale: procedural abstraction.
Viene detta lista dei parametri la lista delle variabili e/o delle espressioni che intervengono durante una chiamata di procedura
CAMBIO EUROPSEUDO CODICE
•Introdurre i valori dei cambi
•Introduci le spese in Lit, FF, DD e la cifra iniziale
•Trasforma le spese in Euro
•Calcola la spesa totale in Euro e la differenza tra la spesa in Euro e la cifra iniziale
•Mostra il risultato
RAPPRESENTAZIONE GRAFICA
Trasforma le spese in
Euro
Mostra ValoriCambi
LitEuroFFEuro DMEuro
Calcola la spesa totale in Euro e
resto
SpeseLitSpeseFFSpeseDM
LitEuroFFEuro DMEuro
SpeseLitEuroSpeseFFEuroSpeseDMEuro
SpeseLitEuroSpeseFFEuroSpeseDMEuroCifraEuro
SpeseTotEuroRestoEuro
SpeseLitSpeseFFSpeseDMCifraEuro
Introduci le spesein
Lit, FF, DM ela cifra iniziale
in Euro Mostra ilrisultato in
Euro, Lit, FF e DM
CifraEuroSpeseTotEuroRestoEuroLitEuroFFEuro DMEuro
Il caso di studio Euro può essere così rappresentato secondo la tecnica dell’astrazione procedurale:
Mostra i valori dei cambi (LitEuro, FFEuro, DMEuro)IntroduciSpeseEcifra(SpeseLit,SpeseFF,SpeseDM,CifraEuro)
TrasformaSpeseEuro (SpeseLit,SpeseFF,SpeseDM, LitEuro, FFEuro, DMEuro,
SpeseLitEuro, SpeseFFEuro,SpeseDMEuro)
CalcolaSpesaERestoEuro(SpeseLitEuro,SpeseFFEuro,SpeseDMEuro,CifraEuro,
SpeseTotEuro,RestoEuro)
Mostra il risultato(CifraEuro , SpeseTotEuro, RestoEuro , RestoEuro*LitEuro,
RestoEuro*FFEuro, RestoEuro*DMEuro)
MAIN BLOCKprecondizioni
postcondizioni
postcondizioni
precondizioni
postcondizioni
Mostra i valori dei cambi (LitEuro, FFEuro, DMEuro)
IntroduciSpeseEcifra(SpeseLit,SpeseFF,SpeseDM,CifraEuro)
TrasformaSpeseEuro (SpeseLit,SpeseFF,SpeseDM, LitEuro, FFEuro, DMEuro,
SpeseLitEuro, SpeseFFEuro,SpeseDMEuro)
CalcolaSpesaTotaleEuro(SpeseLitEuro,SpeseFFEuro,SpeseDMEuro, CifraEuro ,SpeseTotEuro, RestoEuro )
Mostra il risultato(CifraEuro , SpeseTotEuro, RestoEuro , RestoEuro*LitEuro,
RestoEuro*FFEuro, RestoEuro*DMEuro)
precondizioni
precondizioni
postcondizioni
postcondizioni
precondizioni
PROGRAM Euro(input,output);CONST{Introduci valori del cambio}LitEuro=1936.27; { Valute }FFEuro=1.955830258;DMEuro=6.559580191;
VARSpeseLit, SpeseFF, SpeseDM, {Spese}SpeseLitEuro, SpeseFFEuro, SpeseDMEuro, CifraEuro, SpeseTotEuro, RestoEuro : real;
BEGINwriteln(' I valori attuali di cambio sono:' );writeln(' Lit/Euro = ', LitEuro:18:5);writeln(' FF/Euro = ', FFEuro:18:5);writeln(' DM/Euro= ', DMEuro:18:5);
PROGRAM Euro(input,output);
CONSTLitEuro=1936.27; FFEuro=1.955830258;DMEuro=6.559580191;
VARSpeseLit, SpeseFF, SpeseDM,SpeseLitEuro, SpeseFFEuro, SpeseDMEuro,CifraEuro, SpeseTotEuro, RestoEuro: real;
PROCEDURE MostraValoriCambi(LE, FE, DE: real);{in:rapporti di cambio out:mostra i rapporti di cambio}BEGIN writeln(' I valori attuali di cambio sono:');writeln( ' Lit/Euro = ',LE:18:5);writeln( ' FFEuro = ', FE: 18:5);writeln(' DMEuro = ',DE: 18:5);END;
PROCEDURE IntroduciSpeseEcifra(VAR SL,SF, SD,CE: real);
BEGINwrite('Introduci le spese in Lire '); readln(SL);write('Introduci le spese in Franchi ');readln(SF);write('Introduci le spese in Marchi ');readln(SD);write('Introduci la cifra disponibile in Euro ');readln(CE);END;
{Introduci le spese in Lit, FF, DM e la cifra iniziale in Euro}write('Introduci le spese in Lire ');readln(SpeseLit);write('Introduci le spese in Franchi ');readln(SpeseFF);write('Introduci le spese in Marchi ');readln(SpeseDM);write('Introduci la cifra disponibile
in Euro ');readln(CifraEuro);
{Trasforma le spese in Euro}SpeseLitEuro:=SpeseLit/LitEuro;SpeseFFEuro:=SpeseFF/FFEuro;SpeseDMEuro:=SpeseDM/DMEuro;writeln(SpeseLitEuro:10:2, SpeseFFEuro:10:2,
SpeseDMEuro:10:2);
PROCEDURE TrasformaSpeseEuro (LE, FE, DE, SL,SF,SD: real; VAR SLE, SFE,SDE: real);
{in: spese sostenute, rapporti cambio out:spese in euro}
BEGINSLE := LE/SL;SFE := FE/SF;SDE := DE/SD ;END;
{Calcola la spesa totale in Euro la differenza tra cifra iniziale e spesa in Euro }SpeseTotEuro:= SpeseLitEuro+
SpeseFFEuro+ SpeseDMEuro;RestoEuro:= CifraEuro- SpeseTotEuro;
PROCEDURE CalcolaSpesaERestoEuro(SLE,SFE,SDE,CifEuro: real; VAR STE,Res: real);
{Calcola la spesa totale in Euro}{in: spese in euro out: spese in euro totali}BEGINSTE := SLE + SFE + SDE;RES:=CifEuro-STE;END;
PROCEDURE MostraRisultato(CE,STE,RE,RELE,REFE,REDE: real);
{in: cifra disponibile , spese in euro totali out: resto in euro, in Lit, FF e DM}
BEGINRE := CE - STE;writeln('La cifra disponibile era: ',
CE :12:2, ' Euro');writeln( 'La cifra rimanente dopo le spese e'' : ',
RE :12:2,' Euro');writeln('Equivalente a Lit. : ',
RELE :12:2,' Euro');writeln('Equivalente a FF : ', REFE :12:2);writeln('Equivalente a DM: ', REDE :12:2);readlnEND;
{Mostra il risultato}writeln('La cifra disponibile era : ',CifraEuro:12:2,' Euro');writeln('La cifra rimanente dopo le
spese e'' : ',RestoEuro:12:2,' Euro');writeln('Equivalente a Lit : ',
RestoEuro*LitEuro:12:2,' Lit');writeln('Equivalente a FF : ',
RestoEuro*FFEuro:12:2,' FF');writeln('Equivalente a DD : ',
RestoEuro*DMEuro:12:2,' DD');readlnEND.
{ *************************** MAIN BLOCK ************************************}
BEGIN
MostraValoriCambi(LitEuro, FFEuro, DMEuro);
IntroduciSpeseEcifra(SpeseLit,SpeseFF,SpeseDM,CifraEuro);
TrasformaSpeseEuro (SpeseLit,SpeseFF,SpeseDM, LitEuro,
FFEuro, DMEuro,SpeseLitEuro, SpeseFFEuro,SpeseDMEuro);
CalcolaSpesaERestoEuro(SpeseLitEuro,SpeseFFEuro,SpeseDMEuro,
CifraEuro,SpeseTotEuro,RestoEuro);
MostraRisultato(CifraEuro , SpeseTotEuro, RestoEuro ,
RestoEuro*LitEuro, RestoEuro*FFEuro, RestoEuro*DMEuro);
readlnEND.
•Quali e quante variabili sono necessarie (9)
•Quante procedure bisogna definire (5)
COSA CI DICE IL MAIN BLOCK?
•Le variabili presenti nel Main Block sono dette variabili globali
•Le variabili non presenti nel Main Block ma utilizzate all’interno delle singole procedure sono dette variabili locali
•Analogamente le costanti presenti nel Main Block sono dette costanti globali e quelle utilizzate solo all’interno delle singole procedure sono dette costanti locali queste ultime di solito non si usano.
{ *************************** MAIN BLOCK ************************************}
BEGINMostraValoriCambi(LitEuro, FFEuro, DMEuro);IntroduciSpeseEcifra(SpeseLit,SpeseFF,SpeseDM,CifraEuro);TrasformaSpeseEuro (SpeseLit,SpeseFF,SpeseDM, LitEuro,
FFEuro, DMEuro,SpeseLitEuro, SpeseFFEuro,SpeseDMEuro);CalcolaSpesaERestoEuro(SpeseLitEuro,SpeseFFEuro,SpeseDMEuro,
CifraEuro,SpeseTotEuro,RestoEuro);MostraRisultato(CifraEuro , SpeseTotEuro, RestoEuro ,
RestoEuro*LitEuro, RestoEuro*FFEuro, RestoEuro*DMEuro);readlnEND.
REGOLE SINTATTICHE PER LA CHIAMATA DI PROCEDURE
Chiamata di procedura
( )espressioneidentificatore
variabile
,
Mostra il risultato(CifraEuro , SpeseTotEuro, RestoEuro ,
RestoEuro*LitEuro, RestoEuro*FFEuro, RestoEuro*DMEuro)
REGOLE SINTATTICHE PER LA DICHIARAZIONE DI PROCEDURE
PROCEDURE ( Lista parametriidentificatore ;)
blocco ;
;
VAR
: identificatoreidentificatore
,
PROCEDURE CalcolaSpesaERestoEuro(SLE,SFE,SDE,CifEuro: real; VAR STE,Res: real);
PROCEDURE ControlloVariabili(A:real;VAR B:real);
Un identificatore non preceduto dalla parola riservata VAR rappresenta una chiamata per valore.
PROCEDURE ControlloVariabili(A:real;VAR B:real);
ControlloVariabili(A:real;VAR B:real);
Un identificatore preceduto dalla parola riservata VAR rappresenta una chiamata per variabile.
ControlloVariabili(A:real;VAR B:real);
A= un valore
A= lo stesso valore
B= un valore
B= il valore elaborato dalla procedura
******* MAIN ********
IntroduciDati(ChiamataPerValore, ChiamataPerVariabile);ControlloVariabili(ChiamataPerValore,ChiamataPerVariabile);Risultati(ChiamataPerValore, ChiamataPerVariabile);
IntroduciDati ControlloVariabili Risultati
ChiamataPerValoreChiamataPerVariabile
ChiamataPerValoreChiamataPerVariabile
ChiamataPerValoreChiamataPerVariabile
ChiamataPerValoreChiamataPerVariabile
PROGRAM Variabili(input,output); {Questo programma mette in rilievo le differenze tra la ChiamataPerValore e la ChiamataPerVariabile} CONST C=10; VAR ChiamataPerValore, ChiamataPerVariabile: real; PROCEDURE IntroduciDati(VAR CPerValore, CperVariabile:real); BEGIN write(' Assegna ChiamataPerValore: '); readln(CPerValore); write(' Assegna ChiamataPerVariabile: '); readln(CPerVariabile); END; PROCEDURE ControlloVariabili(A:real;VAR B:real); VAR Int1,Int2:integer; BEGIN writeln('-----------'); writeln(' La costante vale : ',C:10); writeln(' La ChiamataPerValore in ingresso alla procedura vale: ', A:10:2 ); write(' Per calcolare il prodotto ChiamataPerValore*Costante*Intero, assegna Int1 = '); readln(Int1); A:=A*Int1*C; writeln(' Ora nella procedura ChiamataPerValore= ChiamataPerValore*Costante*Intero vale: ',A:10:2); writeln(' La ChiamataPerVariabile in ingresso alla procedura vale: ', B:10:2 ); B:=B*Int1*C; writeln(' Nella procedura la ChiamataPerVariabile= ChiamataPerVariabile*Costante*Intero vale: ',B:10:2); writeln('-----------') END; PROCEDURE Risultati(CPValore, CPVariabile:real); BEGIN writeln('Fuori della procedura ChiamataPerValore vale: ', CPValore:10:2); writeln('Fuori della procedura ChiamataPerVariabile vale:', CPVariabile:10:2); END; { ************** MAIN BLOCK *************** } BEGIN IntroduciDati(ChiamataPerValore, ChiamataPerVariabile); ControlloVariabili(ChiamataPerValore,ChiamataPerVariabile); Risultati(ChiamataPerValore, ChiamataPerVariabile); readln; END.
Costante globale
Variabile locale
valvar
Nella progettazione di un qualunque programma si possono, e
conviene farlo, definire le procedure a partire dallo pseudo-codice
semplicemente indicando cosa elaborano e quali sono le
precondizioni e postcondizioni che le riguardano. Sulla base di
queste considerazioni vengono identificate le variabili coinvolte e il
tipo di chiamata che le riguarda.
Solo dopo aver scritto il MAIN BLOCK si cominciano a scrivere le
singole procedure.
La procedura descritta in prima approssimazione si chiama stub (pezzetto)
RIASSUMENDO
I parametri di una procedura possono essere di:
input - le variabili corrispondenti sono chiamate per valore, e in uscita dalla procedura non cambiano valore
output - le variabili corrispondenti sono chiamate per variabile, non hanno un valore in ingresso
input/output - le variabili corrispondenti sono chiamate per variabile e hanno un valore in ingresso che viene modificato dalla procedura
PROCEDURE MostraValoriCambi (LE, FE, DE: real);
{in: rapporti di cambio out:mostra i rapporti di cambio}
BEGIN writeln(‘ I valori attuali di cambio sono: Lit/Euro = ‘, LE:18:5,’ FFEuro = ‘, FE: 18:5,’ DMEuro = ‘,DE: 18:5);END;
PROCEDURE IntroduciSpeseEcifra(VAR SL,SF,SD,CE: real)
{Introduci le spese in Lit, FF, DM e la cifra iniziale in Euro}
{in: nessuno out: spese sostenute, cifra disponibile}
BEGIN write('Introduci le spese in Lire '); readln(SL);write('Introduci le spese in Franchi ');readln(SF);write('Introduci le spese in Marchi ');readln(SD);write('Introduci la cifra disponibile in Euro ');readln(CE);
END;
PROCEDURE TrasformaSpeseEuro (LE, FE, DE, SL,SF,SD: real; VAR SLE, SFE,SDE: real){Trasforma le spese in Euro}
{in: spese sostenute, rapporti cambio out:spese in euro}
BEGIN SLE := SL / LE;SFE := SF / FE;SDE := SD / DE;
END;
PROCEDURE CalcolaSpesaRestoEuro(SLE,SFE,SDE, CifEuro : real; VAR STE ,Res : real){Calcola la spesa totale in Euro}
{in: spese in euro out: spese in euro totali}
BEGIN STE := SLE + SFE + SDE;RES:=CifEuro-STE;
END;
PROCEDURE Mostra il risultato(CE , STE, RE , RE*LE, RE*FE, RE*DE: real)
{Mostra il risultato}
{in: cifra disponibile , spese in euro totali out: resto in euro, in Lit, FF e DM}
BEGIN RE := CE - STE;
writeln(’La cifra disponibile era: ‘, CE :12:2, ‘ Euro’)
writeln( ‘La cifra rimanente dopo le spese e'' : ', RE :12:2,' Euro');
writeln(‘Equivalente a Lit. : ', RE * LE :12:2,' Euro’, ‘ a FF : ‘, RE * FE :12:2,’ a DM: ‘, RE * DE :12:2);
readln
END;
Gestione della memoria quando si usa una procedura
Chiamata per VariabileVAR Variab1,…. : integer;
Area Dati
main procedure
Variab2 V23344Variab1 331 V1
alias
3344
Nuova memoria
Chiamata per Valore Variab2,…. :Integer;
Variabile locale VarLoc,…. :Integer;
VarLoc21
main procedure
3344881
Nuovo valore
Area Dati
PROCEDURE Chiama(VAR V1:integer; V2:integer)VAR VarLoc:real;………..{********* MAIN********}Chiama(Variab1, Variab2);
ESEMPIOPROGRAM GestioneMemoria(input,output); Esempio di gestione di variabili globali e locali . VAR Xint, Yint, Zint : integer; Variabile del mainPROCEDURE ManipolaVariabili(VIn:integer; VAR VInOut, VOut:integer);VAR VLocal : integer Variabili localeBEGIN VInOut:=VInOut+Vin;readln(VLocal);VOut:=Vlocal+1; END;***************** MAIN BLOCK ***************BEGINXint:=8; Yint:=2;ManipolaVariabili(Yint+2, Xint, Zint);END.
main procedure
Prima di uscire da ManipolaVariabili
VIn
VInOut
VOut
Yint
Xint
Zint
VLocal2
12
21
4
20
main procedure
Entra in ManipolaVariabili
VInOut
VOut
Yint
Xint
Zint
2
8
?
VLocal?
VInYint+2 4
main procedure
Uscita da ManipolaVariabili
Yint
Xint
Zint
2
12
21
PROGRAM EsempioChiamate(input;output)VARXint, Yint, Zint: integer;
PROCEDURE Chiama
BEGIN Aint:=Bint+2; Bint:=2*Cint;
Cint:=Aint+BintEND;
{******* MAIN *******}Xint:=1;Yint:=3;Zint:=5;Chiama(Xint, Yint, Zint);writeln(Xint:5, Yint:5, Zint:5)END:
(Aint, Bint,Cint: integer);(VAR Aint, Bint,Cint: integer);(VAR Cint, Bint, Aint : integer);(Aint:integer; VAR Bint,Cint: integer);
(VAR Aint, Bint : integer;Cint: integer);
Chiama1(Aint, Bint,Cint:integer) 1 3 5Chiama2(VAR Aint, Bint,Cint: integer) 5 10 15Chiama3(VAR Bint,Cint,Aint: integer) 6 9 3Chiama4(Aint: integer; VAR Bint,Cint: integer) 1 10 15Chiama5(VAR Aint, Bint: integer;Cint: integer) 5 10 5Esemva / esemvar2
Esemvarlis
NOTA BENE NELLA SEGUENTE DEFINIZIONE IL RUOLO DELLE , E DEI ;
PROCEDURE VirgolePuntiVirgole(Int1,Int2:integer;Car1:char;VAR Var1,Var2:real;VAR Bol1:boolean)
UNA PROCEDURA PUO’ ESSERE CHIAMATA PIU’VOLTE NEL CORSO DI UN PROGRAMMA
ESERCIZIO
Assegnata una figura geometrica composta dalla sovrapposizione di un rettangolo e di due triangoli (v. figura) calcolare l’area totale utilizzando il metodo della astrazione procedurale.
•Descrivere in ordine:•Il problema a parole•L’input e l’output atteso•Lo pseudo codice•La rappresentazione grafica•La gestione della memoria•Il codice Pascal
PROGRAM areatot (input,output);VAR {imposto le variabili globali}arearett,areatriangB,areatriangC,aareatot,brett,hrett,btriangB,htriangB,btriangC,htriangC:real;
PROCEDURE valoredimensioni(baserett,altrett,basetriangC,alttriangB:real);{procedura per l'immissione dei dati}BEGIN {in=brett,hrett,btriangC,htriangB}writeln(' base del rettangolo=base triangoloB '); readln(brett);writeln('altezza del rettangolo=altezza del triangoloC '); readln(hrett);writeln('base triangoloC '); readln(btriangC); writeln('altezza triangoloB '); readln(htriangB);END;
PROCEDURE areefigsovr(baserett,altrett,alttriangB,basetriangC:real);{procedura per calcolare le aree delle figure sovrapposte}BEGIN {in=brett,hrett,btriangC,htriangB out=arearett,areatriangB,areatriangC} arearett:=(brett*hrett); areatriangB:=brett*htriangB/2; areatriangC:=btriangC*hrett/2; writeln('area del rettangolo= ',arearett:7:3); writeln('area del triangolo B= ',areatriangB:7:3); writeln('area del triangolo C= ',areatriangC:7:3);END;
PROCEDURE areatotale; {procedura per calcolare l'area totaledella figura geometrica}BEGIN aareatot:=arearett+areatriangB+areatriangC; writeln('area totale= ',aareatot:7:3);{in=arearett,areatriangB,areatriangC out=aareatot}END;
{**************MAIN BLOCK**********}
BEGIN {richiamo tutte le procedure}valoredimensioni(brett,hrett,btriangC,htriangB);areefigsovr(brett,hrett,btriangC,htriangB);areatotale;readln;END.
VAR
VAR arearett,areatriangB,areatriangC:real
arearett,areatriangB,areatriangC
USARE GLI ALIAS
(arearett, areatriangB,areatriangC)
STUBS
PROCEDURE TrasformaSpeseEuro (LE, FE, DE, SL,SF,SD: real; VAR SLE, SFE,SDE: real){Trasforma le spese in Euro}
{in: spese sostenute, rapporti cambio out:spese in euro}
BEGIN writeln(‘sono nella procedura TrasformaSpeseEuro );END;
PROCEDURE TrasformaSpeseEuro (LE, FE, DE, SL,SF,SD: real; VAR SLE, SFE,SDE: real){Trasforma le spese in Euro}
{in: spese sostenute, rapporti cambio out:spese in euro}
BEGIN END;
PROCEDURE TrasformaSpeseEuro (LE, FE, DE, SL,SF,SD: real; VAR SLE, SFE,SDE: real){Trasforma le spese in Euro}
{in: spese sostenute, rapporti cambio out:spese in euro}
BEGIN SLE:=100; SFE:=1000; SDE:=10000;END;
PROCEDURE TrasformaSpeseEuro (LE, FE, DE, SL,SF,SD: real; VAR SLE, SFE,SDE: real){Trasforma le spese in Euro}
{in: spese sostenute, rapporti cambio out:spese in euro}
BEGIN writeln(‘dammi valori di LE, FE, DE ‘ ); readln(‘LE, FE, DE ‘ ); END;
DRIVERS
I drivers sono procedure che simulano le precondizioni della procedura da controllare, chiamano la procedura e mostrano i valori in uscita da questa (postcondizioni).
PROCEDURE DriverProvaVAR
lista delle variabili utili per la procedura da testareBEGIN
leggi i valori delle variabili utili per la procedura da testarechiama la procedura da testaremostra i valori restituiti dalla procedura testata
END
PROCEDURE TrasformaSpeseEuro (LE, FE, DE, SL,SF,SD: real; VAR SLE, SFE,SDE: real){Trasforma le spese in Euro}
{in: spese sostenute, rapporti cambio out:spese in euro}
BEGIN writeln(‘dammi valori di LE, FE, DE, SL,SF,SD ‘ ); readln(‘LE, FE, DE, SL,SF,SD‘ ); SLE := SL / LE;SFE := SF / FE;SDE := SD / DE;
END;
………………………………………………….
PROCEDURE ProvaDriver (LE, FE, DE, SL,SF,SD: real);
VAR
SLE, SFE,SDE: real;
BEGIN
writeln(‘I valori in ingresso a TrasformaSpeseEuro sono: ‘, LE, FE, DE);
TrasformaSpeseEuro (LE, FE, DE, SL,SF,SD, SLE, SFE,SDE)
writeln(‘I valori in uscita a TrasformaSpeseEuro sono: ‘, SLE, SFE,SDE); END;
SIDE EFFECTS
Tutte le variabili globali possono essere usate come identificatori nelle procedure. Questa prassi è altamente sconsigliata mentre è più opportuno quando si scrive una procedura usare variabili alias.
Se non si segue questa strategia gli effetti collaterali o SIDE EFFECTS che si possono avere sono dannosissimi e difficili da identificare.
MODULARITA’
Ogni procedura si dice auto sufficiente se non fa riferimento, nella lista dei parametri, alle variabili globali con il nome che esse hanno nel main, ma usa degli alias.Se questo avviene il programma si dice modulare.
E’ consigliabile introdurre i TYPE a livello globale, cioè nel MAIN BLOCK.
I TYPE introdotti a livello locale non vengono riconosciuti nel resto del programma.
E’ consigliabile introdurre dei named type a livello globale e utilizzarli poi a livello locale.
CASO DI STUDIO
Supponiamo di volere cambiare un assegno di una certa cifra in moneta.Supponiamo siano assegnati i tagli delle monete.Vogliamo sapere, la cifra assegnata in quali e quanti tagli di monete sarà convertita.
Esempio:Siano i tagli da 100, 500, 1000, 5000, 10000 assegnata la cifra di Lit. 68.500 avremo 6 monete da 10.0001 moneta da 5.0003 monete da 1.0001 moneta da 500.
Pseudo Codice
•Acquisire la cifra da cambiare•Per ogni taglio cerca quanti pezzi sono necessari•Mostra il risultato
RAPPRESENTAZIONE GRAFICA
L100L500L1000L5000L10000
Mostra ilrisultato
Introduci cifra da cambiare
CifraCifraIniziale
Taglio 10000
Cifra
CifraP10000
Mostra tagli
moneteTaglio 5000
Cifra
CifraP5000
Taglio 1000
Cifra
CifraP1000
Taglio 500
Cifra
CifraP500
Taglio 100
Cifra
CifraP100
P100P500P1000P5000P10000CifraIniziale
PROGRAM Monete(input,output);CONSTL100=100; {Introduci tagli delle monete}L500=500;L1000=1000;L5000=5000;L10000=10000;VARCifra,P100, P500,P1000,P5000,P10000,CifraIniziale: real;
{ ******** MAIN BLOCK *****}
BEGINMostraTagliMonete(L100, L500,L1000,L5000,L10000);IntroduciCifra(Cifra);CercaTaglio(10000,Cifra, P10000);CercaTaglio(5000,Cifra, P5000);CercaTaglio(1000,Cifra, P1000);CercaTaglio(500,Cifra, P500);CercaTaglio(100,Cifra, P100);MostraRisultato(P100, P500,P1000,P5000,P10000,Cifra);readlnEND.
PROCEDURE MostraTagliMonete (L100, L500,L1000,L5000,L10000: real);{in: tagli out:mostra i tagli}BEGIN END;
PROCEDURE IntroduciCifra(VAR Cif:real);{Introduci la cifra da cambiare}{da tastiera cifra da cambiare out: cifra da cambiare}BEGINEND;
PROCEDURE CercaTaglio(T:real;VAR C,NT:real);{Ricava il numero di pezzi e la cifra ancora da cambiare}{in: taglio, cifra da cambiare out:numero pezzi}BEGINEND;
PROCEDURE MostraRisultato(P1, P5,P10,P500,P100,CI: real);{Mostra il risultato}{in: cifra da cambiare , n° pezzi per ogni taglio out: mostra cifra da cambiare ,
n° pezzi per ogni taglio }
BEGIN
END;
PROCEDURE MostraTagliMonete (L100, L500,L1000,L5000,L10000: real);{in: tagli out:mostra i tagli}BEGIN writeln(' I tagli disponibili sono: ');writeln(' da ', L100:5:0);writeln(' da ', L500:5:0);writeln(' da ', L1000:5:0);writeln(' da ', L5000:5:0);writeln(' da ', L10000:5:0);END;
PROCEDURE IntroduciCifra(VAR Cif:real);{Introduci la cifra da cambiare}{da tastiera cifra da cambiare out: cifra da cambiare}BEGINwriteln('Dammi la cifra da cambiare: ');readln(Cif);END;
PROCEDURE CercaTaglio(T:real;VAR C,NT:real);{Ricava il numero di pezzi e la cifra ancora da cambiare}{in: taglio, cifra da cambiare out:numero pezzi}BEGINNT:=Int(C / T);C:=C-NT*T;END;
PROCEDURE MostraRisultato(P1, P5,P10,P50,P100,CI: real);{Mostra il risultato}{in: cifra da cambiare , n° pezzi per ogni taglio out: mostra cifra da cambiare , n° pezzi per ogni taglio }BEGIN writeln('La cifra di ',Cifra:5:0,' e'' divisa in ');writeln(P100:5:0,' monete da 10.000 Lit.');writeln(P50:5:0,' monete da 5.000 Lit.');writeln(P10:5:0,' monete da 1.000 Lit.');writeln(P5:5:0,' monete da 500 Lit.');writeln(P1:5:0,' monete da 100 Lit.');END;
Pseudo Codice
•Acquisire la cifra da cambiare•Per ogni taglio cerca quanti pezzi sono necessari•Mostra il risultato
RAPPRESENTAZIONE GRAFICA
L100L500L1000L5000L10000
Mostra ilrisultatoIntroduci
cifra da cambiare
Cifra
Taglio 10000
Cif
CifP10000
Mostra tagli
monete
Taglio 5000
Cif
CifP5000
Taglio 1000
Cif
CifP1000
Taglio 500
Cif
CifP500
Taglio 5000
Cif
CifP100
P100P500P1000P5000P10000Cifra
Calcola Tagli
Cifra
P100P500P1000P5000P10000
PROGRAM Monete(input,output);CONSTL100=100; {Introduci valori delle valute}L500=500;L1000=1000;L5000=5000;L10000=10000;
VARCifra, P100, P500,P1000,P5000,P10000: real;
PROCEDURE MostraTagliMonete (L100, L500,L1000,L5000,L10000: real);{in: tagli out:mostra i tagli}BEGIN END;
PROCEDURE IntroduciCifra(VAR Cif:real);{Introduci la cifra da cambiare}{da tastiera cifra da cambiare out: cifra da cambiare}BEGINEND;
PROCEDURE CercaTaglio(T:real;VAR C,NT:real);{Ricava il numero di pezzi e la cifra ancora da cambiare}{in: taglio, cifra da cambiare out:numero pezzi}BEGINEND;
PROCEDURE CalcolaTaglio(Ci:real;VAR P1, P5,P10,P50,P100:real);{in: la cifra out il numero di pezzi per ogni taglio}END;
PROCEDURE MostraRisultato(P1, P5,P10,P50,P100,Ci: real);{Mostra il risultato}{in: cifra da cambiare , n° pezzi per ogni taglio out: mostra cifra da cambiare , n° pezzi per ogni taglio }BEGIN END;
{ **********MAIN BLOCK ******************}
BEGINMostraTagliMonete(L100, L500,L1000,L5000,L10000);IntroduciCifra(Cifra);CalcolaTaglio(Cifra, P100, P500,P1000,P5000,P10000);MostraRisultato(P100, P500,P1000,P5000,P10000,Cifra);readlnEND.
PROCEDURE CalcolaTaglio(Ci:real;VAR P1, P5,P10,P50,P100:real);
{in: la cifra out il numero di pezzi per ogni taglio}
BEGIN
CercaTaglio(10000,Ci,P100);
CercaTaglio(5000,Ci,P50);
CercaTaglio(1000,Ci,P10);
CercaTaglio(500,Ci,P5);
CercaTaglio(100,Ci,P1);
END;
ERRORI PIU’ FREQUENTI
Danno errore in compilazione
PROCEDURE Chiama(Parola:STRING[20]); in alcuni dialetti PASCAL
PROCEDURE Chiama(Xint, Yint);
Chiama(Xint:6:4, Yint:7:3);
ALCUNE REGOLE DI BUONA PROGETTAZIONE
Non usare la chiamata_per_valore di una variabile se il valore di questa variabile non è stato istanziato almeno una volta prima della chiamata.
Non usare la chiamata_per_variabile se il valore in uscita non viene usato nel resto del programma.
PROCEDURE ChiamataSbagliata(Numero:integer;………);BEGINreadln(Numero):END;
PROCEDURE ChiamataInutile(VAR Numero:integer;………);BEGIN END;{************* MAIN **************}BEGINChiamataInutile(Numero);END.
QUANDO SI SCRIVE UNA PROCEDURA BISOGNA PRIMA PROGETTARE E SCRIVERE LA TESTA E POI IL CONTENUTO DELLA PROCEDURA.
PER EVITARE I SIDE EFFECTS NON BISOGNA MAI CHIAMARE UNA VARIABILE ALL’INTERNO DI UNA PROCEDURA CON LO STESSO NOME
USATO A LIVELLO GLOBALE.USARE GLI ALIAS.
TROVARE GLI ERRORI PRESENTI IN QUESTA PROCEDURA
PROGRAM tuttoSbagliato(input;output)VARAint, Bint: integer;
PROCEDURE Chiama(VAR A2int, Cint:integer); VAR Aint:integer; BEGIN Cint:=Cint+1; Bint:=2*Cint; Aint:=Cint+12;
END;{******* MAIN *******}BEGINAint:=2;Bint:=4;Chiama(Aint, Bint);writeln(Aint:5, Bint:5)END.
Distrugge il valore globale di Aint dichiarandola con lo stesso nome come variabile locale
Bint assume un valore prima della chiamata e un altro valore nella procedura producendo un side effects
Questo valore di Aint non è portato fuori della procedura
PROGRAM tuttoSbagliato(input,output);VARAint, Bint: integer;
PROCEDURE Chiama1(VAR Ant, Cint:integer);VAR Aint:integer;BEGINCint:=Cint+1;Bint:=2*Cint*Aint;Aint:=Bint+Cint+12;END;
PROCEDURE Chiama2(VAR Aint, Cint:integer);VAR Bint:integer;BEGINCint:=Cint+1;Bint:=2*Cint*Aint;Aint:=Bint+Cint+12;END;
PROCEDURE Chiama3(VAR Ant, Cint:integer);VAR Aint:integer;BEGIN Cint:=Cint+1; Bint:=2*Cint*Ant; Aint:=Bint+Cint+12;END;
{******* MAIN *******}BEGINAint:=2;Bint:=4;Chiama1(Aint, Bint);writeln(‘ dopo Chiama1',Aint:5, Bint:5);Aint:=2;Bint:=4;Chiama2(Aint, Bint);writeln(‘ dopo Chiama2',Aint:5, Bint:5);Aint:=2;Bint:=4;Chiama3(Aint, Bint);writeln(‘ dopo Chiama3',Aint:5, Bint:5);readlnEND.