1.17k likes | 1.29k Vues
TESTI UFFICIALI MEYERS R.A. PASCAL Prentice Hall FIORENTINO G., LAGANA’ M.R., ROMANI F., TURINI F. PASCAL LABORATORIO DI PROGRAMMAZIONE McGraw-Hill. ESAMI FEBBRAIO 2001 - MOD. A. ESAMI MOD. A.
E N D
TESTI UFFICIALI MEYERS R.A. PASCAL Prentice Hall FIORENTINO G., LAGANA’ M.R., ROMANI F., TURINI F. PASCAL LABORATORIO DI PROGRAMMAZIONE McGraw-Hill
ESAMI MOD. A • Sia dato un file di testo riguardante un insieme di soggetti di cui è fornito il cognome seguito dalla nazionalità e dalla data di nascita, giorno mese anno. Nel primo rigo sono indicati e nome e cognome dell’autore della registrazione e il numero di soggetti registrati. • Il file sarà perciò così composto: • tipo dato esempio rigo • stringa, integer <eoln> carlo bruni^ 76 1 • stringa stringa^ integer integer integer <eoln> rossi italiano^22 12 1930 2 • stringa stringa^ integer integer integer <eoln> smith inglese^ 28 9 1990 3 • …………………………………………………………………………………………… • ……………………………………………………………………………………………. • ……………………………………………………………………………………………. • <eof> • Leggere il file mostrando a video i nomi ordinati per nazionalità e con la data di nascita.
PROGRAM Esercizio1(output,Client); CONST LunMax=40; MassimoCli=100; TYPE StringaNome=STRING[LunMax]; AnagraficaRecord=RECORD Cognome, Nome:StringaNome; END; DataRecord=RECORD Giorno, Mese, Anno:integer; END; ClienteRecord=RECORD CognCli:StringaNome; Nazione:StringaNome; Nascita:DataRecord; END; RappresentanteRecord=RECORD Anagrafe:AnagraficaRecord; NumeroCli:integer; END; IndiceTipo=0.. MassimoCli; CliArray=ARRAY[IndiceTipo] OF ClienteRecord; VAR Clienti:CliArray; IndiceCli:IndiceTipo; ClientiFile:text; UnCliente: ClienteRecord; UnRappresentante: RappresentanteRecord; AnagraficaRecord Cognome Nome DataRecord ClienteRecord Giorno CognCli Mese Nazione Anno Nascita RappresentanteRecord Numero Anagrafe BEGIN assign(ClientiFile,'C:\Modapr\test1.TXT'); reset(ClientiFile); LeggiRappresentante(ClientiFile, IndiceCli); readln; OrdinaClienti(IndiceCli,Clienti, ClientiFile); MostraRisultati(Clienti,IndiceCli); readln END.
Clienti IndiceCli Clienti ClientiFile ClientiFile IndiceCli ClientiFile IndiceCli ApriFile LeggiRappresentante OrdinaClienti MostraRisultati ClientiFile ClientiFile ClientiFile Clienti[I] IndiceCli Sentinella Sentinella Cognome Nome CostruisciRecordCliente LeggiParola LeggiParola ClientiFile ClientiFile ClientiFile ClientiFile ClientiFile Sent Sent Sent Nazione Mese Anno Sent CognCli Sent Giorno LeggiParola LeggiParola LeggiParola LeggiParola LeggiParola BEGIN assign(ClientiFile,'C:\Modapr\test1.TXT'); reset(ClientiFile); LeggiRappresentante(ClientiFile, IndiceCli); readln; OrdinaClienti(IndiceCli,Clienti, ClientiFile); MostraRisultati(Clienti,IndiceCli); readln END.
PROCEDURE LeggiParola(Sentinella:char;VAR Parola:StringaNome;VAR Clienti:text); VAR Carattere:char; BEGIN Parola:=''; read(Clienti,Carattere); WHILE (Carattere<>Sentinella) DO BEGIN Parola:=Parola+Carattere; read( Clienti,Carattere) END; END;
PROCEDURE CostruisciRecordCliente(UnCliente:ClienteRecord;VAR ClientiFile:text); BEGIN WITH UnCliente, Nascita DO BEGIN LeggiParola(' ',CognCli, ClientiFile); LeggiParola('^',Nazione, ClientiFile); read(ClientiFile,Giorno); read(ClientiFile,Mese); read(ClientiFile,Anno); readln(ClientiFile); writeln(' Cliente ',CognCli,' ',' Nazionalita'' ',Nazione); writeln(' Nato il ',Giorno,'/',Mese,'/',Anno); writeln END END; PROCEDURE LeggiRappresentante (VAR ClientiFile:text; VAR IndiceCli1:IndiceTipo); VAR UnRappresentante: RappresentanteRecord; BEGIN WITH UnRappresentante, Anagrafe DO BEGIN LeggiParola(' ',Cognome, ClientiFile); LeggiParola('^',Nome, ClientiFile); read(ClientiFile,IndiceCli1); readln(ClientiFile); writeln('Rappresentante ',Cognome,' ',Nome,'N. Clienti',IndiceCli); END END;
PROCEDURE Scambia(VAR Ch1,Ch2: StringaNome); VAR Temp: StringaNome; BEGIN Temp:=Ch1; Ch1:=Ch2; Ch2:=Temp END; PROCEDURE Ordina(VAR Clienti:CliArray; IndiceCli:IndiceTipo); VAR Ordinato, Indice: IndiceTipo; BEGIN WITH UnCliente DO FOR Ordinato:=1 TO IndiceCli DO FOR Indice:= IndiceCli DOWNTO Ordinato DO IF Clienti[Indice].Nazione > Clienti[Indice+1].Nazione THEN Scambia(Clienti[Indice].Nazione,Clienti[Indice+1].Nazione); END;
PROCEDURE OrdinaClienti(VAR IndiceCli:IndiceTipo;VAR Clienti:CliArray; VAR ClientiFile:text); VAR Indice:IndiceTipo; BEGIN FOR Indice:=1 TO IndiceCli DO BEGIN CostruisciRecordCliente(Clienti[Indice],ClientiFile); END; Ordina(Clienti,IndiceCli) END; PROCEDURE MostraRisultati(VAR Clienti:CliArray;IndiceCli:IndiceTipo); VAR I:integer; BEGIN WITH UnCLiente DO FOR I:=1 TO IndiceCli DO writeln(Clienti[I].CognCli,' ',Clienti[I].Nazione,' ',Clienti[I].Nascita.Giorno,'/',Clienti[I].Nascita.Mese,'/',Clienti[I].Nascita.Anno); END;
BEGIN assign(ClientiFile,'C:\Modapr\test1.TXT'); reset(ClientiFile); LeggiRappresentante(ClientiFile, UnRappresentante, IndiceCli); readln; OrdinaClienti(IndiceCli,Clienti, ClientiFile); MostraRisultati(Clienti,IndiceCli); readln END. TP\ESEMPI|MODA
Esercizio n° 5 Scrivere un programma che, dato un file testo prova.txt estragga dal testo tutti i caratteri di tipo numerico sostituendoli con spazi vuoti. Memorizzare il file così corretto con il nome di prova1.txt. Fare la somma dei numeri estratti. Es. DATI Ab73cqSw1yt Ab cqSw yt A video deve comparire 73 1 Somma = 74
ProInput ProOut ProInput ProOut Somma Somma CercaNumero ChiudiEStampa ApriFile Ch Pot Numero CostruisciNumero Pot Potenza ApriFile(ProInput,ProOut); CercaNumero(ProInput,ProOut,Somma); ChiudiEStampa(ProInput,ProOut,Somma); readln
PROGRAM Esercizio5(output,ProInput,ProOut); VAR ProInput,ProOut: text; Somma:integer; FUNCTION Potenza(P:integer):integer; VAR I,Pote:integer; BEGIN Pote:=1; FOR I:=1 TO P DO Pote:=Pote*10; Potenza:=Pote END; PROCEDURE CostruisciNumero(VAR Numero,Pot:integer;Ch:char); VAR CharNum:integer; BEGIN CharNum:=ord(Ch)-ord('0'); Numero:= CharNum +Numero*potenza(Pot); END; PROCEDURE ApriFile(VAR PrIn,Prout:text); BEGIN assign(PrIn,'C:\TP\ESEMPI\TEST5.TXT'); assign(Prout,'C:\TP\ESEMPI\COPIA5.TXT'); reset(PrIn); rewrite(Prout); END;
PROCEDURE CercaNumero(VAR ProInp,ProOu:text; VAR Somm:integer); VAR Numero, Pot:integer; Ch: Char; BEGIN WHILE NOT eof(ProInp) DO BEGIN WHILE NOT eoln(ProInp) DO BEGIN Numero:=0; Pot:=0; read(ProInp,Ch); IF (ord(Ch)<58) AND (ord(Ch)>47) THEN BEGIN WHILE (ord(Ch)<58) AND (ord(Ch)>47) DO BEGIN write(ProOu,' '); CostruisciNumero(Numero,Pot,Ch); Pot:=Pot+1; read(ProInp,Ch); END; writeln(Numero); Somm:=Somm+Numero; write(ProOu,Ch); END ELSE write(ProOut,Ch); END; END; END;
PROCEDURE ChiudiEStampa(VAR ProInpu,ProOu:text;Som:integer); BEGIN close(ProInpu); close(ProOu); writeln('File Duplicato -- La somma vale: ',Som); END; {*************MAIN**************} BEGIN ApriFile(ProInput,ProOut); CercaNumero(ProInput,ProOut,Somma); ChiudiEStampa(ProInput,ProOut,Somma); readln END. TP\ESEMPI|MODA
Esercizio 3 Sia data la successione: an=an-3+3*an-2 -2*an-1+c Calcolare la somma dei valori della successione per n che va da 3 a un valore prefissato K sapendo che: a0=-1 a1=2 a2=-5 e che c è una costante prefissata a priori.
PROGRAM Esercizio3(input,output); VAR C,K,I:integer; An,An1,An2,An3:real; PROCEDURE AssegnaValori(VAR C1,K1:integer); BEGIN Write(' Dammi C '); Readln(C1); Write(' Dammi K '); Readln(K1); END; PROCEDURE CalcolaSuccessione(an11,an22,an33:real;C1,K1:integer); VAR An:real; BEGIN writeln('Valori della successione da 1 a ',K); writeln('1 = ',an11:5:0); writeln('2 = ',an22:5:0); writeln('3 = ',an33:5:0); FOR I:=3 TO K1 DO BEGIN An:=an3+3*an2*an1+C1; An3:=an2; An2:=an1; An1:=an; writeln(I:1,' = ',An:5:0); END; END;
{****************** MAIN ****************} BEGIN An3:=-1; An2:=2; An1:=-5; AssegnaValori(C,K); CalcolaSuccessione(an1,an2,an3,C,K); writeln(' FINE COMPUTAZIONE '); readln END. TP\ESEMPI|MODA
PROGETTO PROGRAMMA PRINCIPALE - Program …………………...….. end. uses xxxx, yyyy; unit xxxx ………………... end. MODULO 1 - …………………………………………. unit yyyy ………………... end. MODULO n -
DATA ABSTRACTION Qualunque tipo di dati può essere descritto sulla base dei valori che esso può prendere e delle operazioni che ad esso si possono applicare. ESEMPIO TipoValoriOperazioni integer - maxint ÷ + maxint +, -, *, DIV real 10-38 ÷ 10+38 +, -, *, / boolean TRUE, FALSE AND, OR, NOT
Un abstract data type (ADT) e’ un Type definito in termini del nome logico che gli si attribuisce e delle operazioni che possono essere applicate ad esso. DATA ABSTRACTION Separazione del significato logico delle operazioni in un ADT dai dettagli implementativi.
ESEMPIO NUMERI COMPLESSI Un numero complesso in genere è scritto come a + bi dove a e b sono dei numeri reali e i, detta parte immaginaria, ed è tale che i2=-1
Nel 1572 tale Raffaele Bombelli, colui che per primo introdusse le parentesi, propose di trattare la come una entità a parte e di applicare ad essa tutte le regole che valevano per i numeri normali. Cartesio chiamò i numeri che prevedevano la presenza della numeri “immaginari” mentre Gauss li chiamò “complessi”. Solo nel 1777 Eulero propose di sostituire con la lettera “i”. I numeri complessi sono usati in elettrotecnica, dinamica dei fluidi, aerodinamica etc. Notizie sui numeri complessi si trovano in il TEOREMA DEL PAPPAGALLO di Denis Guedj, ed. Longanesi, pag.326
Progettare una ADT per i numeri complessi significa realizzare un software che permette di definire un TypeComplesso e implementi tutta una serie di operazioni tipiche dei numeri complessi. Es. addizione, sottrazione, moltiplicazione, divisione, valore assoluto, …………………………….. Una ADT, una volta implementata viene memorizzata su un file e richiamata da un programma solo quando richiesta. Ognuno di questi file è definito come unit e come tale è riconosciuto dal programma principale quando viene richiamato.
UNIT (pag. 906 testo) E’ un insieme di costanti, tipi, dati, variabili funzioni e procedure che può essere memorizzato su un file e compilato separatamente dal programma principale che lo chiama. Nel Turbo Pascal per compilare una unit si deve scegliere sotto la voce COMPILE l’option DISK (per i programmi generali si usa invece MEMORY). Per richiamare una unit in un programma si usa la parola chiave uses nome_unit, ….;
UNIT interfaccia Contiene le dichiarazioni globali a tutta la unit e le definizioni di procedure e funzioni da esportare implementazione Contiene i corpi delle procedure e funzioni sopra dichiarate insieme alle dichiarazioni di costanti, tipo, variabili e procedure locali all’unità. unit xxxxxxxx; interface ………. implementation ……………… end.
ComplexNo XRe YIm NUMERI COMPLESSI X + Yi TYPE ComplexNo=RECORD XRe, YIm: real END;
UNITADTComplexNo; {documentazione} INTERFACE {sezione interfaccia} {definizioni dell’ADT} TYPE ComplexNo=RECORD XRe, YIm: real END; { le operazioni } PROCEDURE …………………….. FUNCTION …………………………. IMPLEMENTATION {sezione implementazioni} PROCEDURE …………………….. FUNCTION ………………………….
NUMERI COMPLESSI a + bi Le operazioni con i numeri complessi: Parte Reale: a Parte Immaginaria: b Modulo: Somma : (a + bi) + (c + di) = (a + c) + (b + d) i Sottrazione: (a + bi) - (c + di) = (a - c) + (b - d) i Moltiplicazione: (a + bi) * (c + di) = (ac - bd) -(ad + bc) i Divisione:
UNITADTComplexNo; {documentazione} INTERFACE {inizio della sezione INTERFACE} { definizioni dell’ADT } TYPE ComplexNo=RECORD Xre, Yim: real END; { le operazioni } PROCEDURE MakeComp(Xpart, Ypart:real; VAR Cnumber: ComplexNo); { costruisci il numero complesso } FUNCTION RealPart(Cnumber: ComplexNo):real; { identifica la parte reale del numero complesso } FUNCTION ImaginaryPart(Cnumber: ComplexNo):real; { identifica la parte immaginaria del numero complesso } FUNCTION Magnitude(Cnumber: ComplexNo):real; { identifica il modulo del numero complesso }
PROCEDURE AddComp(Term1, Term2:ComplexNo; VAR Sum: ComplexNo); { addiziona i numeri complessi Term1 e Term2 } PROCEDURE SubtrComp(Term1, Term2: ComplexNo; VAR Difference: ComplexNo); { sottrae i numeri complessi Term1 e Term2 } PROCEDURE MultComp(Factor1, Factor2: ComplexNo; VAR Product: ComplexNo); { moltiplica i numeri complessi Factor1 e Factor2 } PROCEDURE DivComp(Factor1, Factor2: ComplexNo; VAR Quotient: ComplexNo); { divide i numeri complessi Factor1 e Factor2 } { fine della sezione INTERFACE }
IMPLEMENTATION {inizio della sezione IMPLEMENTATION} PROCEDUREMakeComp(Xpart, Ypart:real; VAR Cnumber: ComplexNo); { costruisci il numero complesso } BEGIN Cnumber.Xre:=Xpart; Cnumber.Yim:=Ypart END; FUNCTIONRealPart(Cnumber: ComplexNo):real; { identifica la parte reale del numero complesso } BEGIN RealPart:= Cnumber.Xre END; FUNCTIONImaginaryPart(Cnumber: ComplexNo):real; { identifica la parte immaginaria del numero complesso } BEGIN ImaginaryPart:= Cnumber.Yim END;
FUNCTIONMagnitude(Cnumber: ComplexNo):real; { identifica il modulo del numero complesso } BEGIN Magnitude:= sqrt(sqr(Cnumber.Xre)+sqr(Cnumber.Yim)) END; PROCEDUREAddComp(Term1, Term2:ComplexNo; VAR Sum: ComplexNo); { addiziona i numeri complessi Term1 e Term2 (a + bi) + (c + di) = (a + c) + (b + d) i } BEGIN WITH Sum DO BEGIN Xre:=Term1.Xre+Term2.Xre; Yim:=Term1.Yim+Term2.Yim END END;
PROCEDURESubtrComp(Term1, Term2:ComplexNo; VAR Difference: ComplexNo); { addiziona i numeri complessi Term1 e Term2 (a + bi) - (c + di) = (a - c) + (b - d) i } BEGIN WITH Difference DO BEGIN Xre:=Term1.Xre - Term2.Xre; Yim:=Term1.Yim - Term2.Yim END; END;
PROCEDUREMultComp(Factor1, Factor2:ComplexNo; VAR Product: ComplexNo); { addiziona i numeri complessi Term1 e Term2 (a + bi) * (c + di) = (ac - bd) -(ad + bc) i } BEGIN WITH Product DO BEGIN Xre:=Factor1.Xre * Factor2.Xre - Factor1.Yim * Factor2.Yim; Yim:=Factor1.Xre * Factor2.Yim + Factor2.Xre * Factor1.Yim END END;
PROCEDUREDivComp(Factor1, Factor2:ComplexNo; VAR Quotient: ComplexNo); { addiziona i numeri complessi Term1 e Term2 } VAR Divisor: real;{divisore del quoziente} BEGIN Divisor:=sqr(Factor2.Xre) + sqr(Factor2.Yim); WITH Quotient DO BEGIN Xre:=(Factor1.Xre * Factor2.Xre + Factor1.Yim * Factor2.Yim)/Divisor; Yim:= (Factor1.Yim *Factor2.Xre - Factor1.Xre * Factor2.Yim)/Divisor END END;
ESEMPIO Risolvere l’equazione di primo grado AX+B=C con A, B, C numeri complessi. Supponiamo A 0. Soluzione: X=(C-B)/A Input: Introdurre i coefficienti nell’ordine: A, B, C Per ogni coefficiente introdurre prima la parte reale e poi la parte immaginaria. Ouput: Mostrare la soluzione X sotto forma di numero complesso
Equazione A A B B X X C C Mostra Istr. Leggi Calcola Mostra Ris. ADTComplexNo ADTComplexNo ADTComplexNo Pseudo codice Richiama la unit per i numeri complessi; Mostra le istruzioni per l’introduzione dei dati; Leggi i coefficienti; Calcola la soluzione; Mostra la soluzione.
PROGRAM Equazione(input,output); USES Compl; VAR A,B,C, {coefficienti} X: ComplexNo; {soluzione} PROCEDURE MostraIstruzioni; BEGIN writeln('L'' equazione e'' immaginata sotto la forma AX+B=C. ' ); writeln('I coefficienti A,B,C vanno introdotti come coppie di numeri:'); writeln('prima la parte reale e poi quella immaginaria') END;
PROCEDURE MC(Z:ComplexNo); {mostra il numero complesso Z} VAR Segno:STRING[3]; BEGIN Segno:=' '; IF ImaginaryPart(Z)>=0 THEN Segno:=' + '; writeln(RealPart(Z):3:1,Segno,ImaginaryPart(Z):3:1,'i'); writeln END;
PROCEDURE LeggiCoefficienti(VAR A,B,C:ComplexNo); VAR ARe,BRe,CRe,AIm,BIm,CIm:real; BEGIN write('Coefficiente A= '); readln(ARe,AIm); write('Coefficiente B= '); readln(BRe,BIm); write('Coefficiente C= '); readln(CRe,CIm); MakeComp(ARe,AIm,A); MakeComp(BRe,BIm,B); MakeComp(CRe,CIm,C) END;
PROCEDURE Soluzione(A,B,C:ComplexNo; VAR X:ComplexNo); {documentazione} VAR CmenoB:ComplexNo; BEGIN SubtrComp(C,B,CmenoB); DivComp(CmenoB,A,X) END; PROCEDURE MostraRisultato(X:ComplexNo); BEGIN writeln('La radice dell''equazione assegnata e'': '); MC(X) END;
{ BODY } BEGIN MostraIstruzioni; LeggiCoefficienti(A,B,C); Soluzione(A,B,C,X); MostraRisultato(X) END.
OUTPUT L' equazione e' immaginata sotto la forma AX+B=C. I coefficienti A,B,C vanno introdotti come coppie di numeri: prima la parte reale e poi quella immaginaria Coefficiente A= 5 66 Coefficiente B= 77 55 Coefficiente C= 4 2 La radice dell'equazione assegnata e': -0.9 + 1.0i
c b d a f ESERCIZIO 1-B Progettare e realizzare una Unit che permetta il calcolo delle aree e dei perimetri delle seguenti figure geometriche: Triangolo rettangolo – assegnata la base e l’altezza Rettangolo – assegnata la base e l’altezza Utilizzando la Unit di cui sopra trovare l’area dell’appartamento la cui planimetria è data in figura assegnando alle dimensioni a,b,c,d,e,f valori a piacere (da tastiera) e per ogni vano calcolare la superficie complessiva dei muri sapendo che l’altezza di ogni vano vale k. e
REGOLE GENERALI PER LA PROGETTAZIONE DI UNIT ADT Completezza: non necessita di operazioni addizionali per essere usata Ogni operazione deve appartenere ad una delle seguenti categorie: Constructor - cambia o inizializza i valori di una variabile astratta Primitive constructor - assegna un valore ad una variabile astratta senza fare uso di altre variabili astratte dello stesso tipo. Ha una sola variabile di output e quelle di input servono per costruire l’output. Es. MakeComp(Xpart, Ypart:real; VAR Cnumber: ComplexNo); { costruisci il numero complesso } Ogni ADT richiede almeno un Primitive constructor così che il client può assegnare un valore iniziale alla variabile astratta.
Non-primitive constructor -. Ha almeno una variabile di input il cui tipo è uguale a quello dell’output. Es. AddComp(Term1, Term2:ComplexNo; VAR Sum: ComplexNo); { addiziona i numeri complessi Term1 e Term2 }
SELECTOR - fornisce informazioni su una variabile di input ADT ad un parametro di uscita. Spesso è una funzione (il parametro di uscita in tal caso è la funzione stessa). Primitive selector - ritorna il valore di uno dei componenti della variabile astratta. Es. RealPart(Cnumber: ComplexNo):real; { identifica la parte reale del numero complesso } Ogni unit necessita di un Primitive selector altrimenti il client non può mostrare i valori della variabile. Non-primitive selector - ritorna il valore che non è relativo ad uno dei componenti della variabile astratta ma ciò nonostante è utile al client. Es. Magnitude(Cnumber: ComplexNo):real; { identifica il modulo del numero complesso }