cd free pascal prof. tramontano aula a5

45
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

Upload: camilla-norton

Post on 02-Jan-2016

60 views

Category:

Documents


4 download

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 Presentation

TRANSCRIPT

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.

Esercizi dal testo

pag. 144 n° 7pag. 150 n° 6

pag. 153 da n° 18 a n° 28