La programmazione strutturata

Materie:Appunti
Categoria:Informatica

Voto:

1 (2)
Download:106
Data:15.03.2001
Numero di pagine:7
Formato di file:.doc (Microsoft Word)
Download   Anteprima
programmazione-strutturata_1.zip (Dimensione: 15.06 Kb)
readme.txt     59 Bytes
trucheck.it_la-programmazione-strutturata.doc     68 Kb


Testo

LA PROGRAMMAZIONE STRUTTURATA

§1. La programmazione strutturata in Pascal
La stesura di un programma è un'attività difficile ed anche delicata, perché ogni minima imperfezione può bloccare il programma o dare risultati errati. Non esiste una regola semplice valida per tutte le situazioni: nei casi più complessi, la via maestra consiste nel suddividere il problema in sottoproblemi più semplici per ricomporre il tutto alla fine. Nel I° secolo a.C. il generale romano Giulio Cesare riuscì, con un esercito di appena 40.000 uomini, a sottomettere in pochi anni tutta l'antica Francia allora popolata da una decina di milioni di Galli ostili, coraggiosi e di costituzione fisica certamente più robusta dei Romani. Fu merito esclusivo della superiore organizzazione militare romana? Certo, anche questa giovò a Cesare. Ma la sua risorsa principale fu l'applicazione sistematica della strategia dìvide et ìmpera, dividi (i tuoi nemici) e comanda. In Pascal faremo proprio questo: suddivideremo il programma principale da creare in sottoprogrammi più semplici (in Informatica: routine), ciascuno dei quali è rivolto alla soluzione di un sottoproblema: risolveremo così un sottoproblema alla volta e alla fine richiameremo insieme tutte le routine per risolvere il problema complessivo.
Quando si procede in questo modo si parla di programmazione strutturata: vedremo che il Pascal è un linguaggio che ben si presta ad essere strutturato.
La strutturazione ha i vantaggi di
1) rendere più trasparente la lettura del programma, perché ogni routine identifica con il suo blocco d'istruzioni la mansione cui è dedicata;
2) risparmiare memoria, perché anche se una routine è impiegata più volte nello stesso programma la sua memorizzazione tuttavia avviene una volta sola;
3) migliorare l'affidabilità dei programmi, perché la eventuale presenza di errori può essere rimossa intervenendo su un solo sottoprogramma, invece di dover rivoluzionare l'intero programma. Il software originale per il jet da combattimento F-16 conteneva un piccolo errore (in Informatica, bug=baco), che provocava una scossa dall'alto verso il basso ogni volta che il top gun attraversava l'equatore: per la correzione dell'errore (debugging) non si dovette sconvolgere l'intero software avionico, ma bastò intervenire su una singola routine;
4) accrescere la versatilità dei programmi, perché una stessa routine finalizzata ad una determinata azione, può essere impiegata in programmi diversi che richiedono quell'azione;
5) diminuire i tempi ed i costi di realizzazione dei programmi, perché ogni routine può essere progettata da programmatori diversi specializzati. Di fatto, solo la divisione del lavoro rende possibile la creazione materiale di programmi molto complessi che nessun singolo programmatore, per quanto bravo, riuscirebbe da solo a sviluppare.
§2. Procedure
In Pascal esistono due tipi di routine: le procedure e le funzioni.
Definizione. Una procedura è un sottoprogramma che, come una singola istruzione, svolge il suo ruolo in una successione di azioni concentrate ad uno scopo.
La sua sintassi, molto simile a quella di un programma, è
procedure Nome(parametri opzionali);
Dichiarazione delle variabili locali;
begin
Istruzione1;
Istruzione2;
...........
end;
Notiamo:
1) la parola riservata "procedure" (anziché "program");
2) l'eventuale presenza di parametri contenuti tra parentesi dopo il nome della procedura: che cosa siano e a che cosa servano, vedremo meglio più avanti;
3) come nei programmi, c'è la Dichiarazione delle variabili, che sono dette "locali" perché funzionano solo all'interno della procedura e non nel programma principale;
4) come nei programmi, il Blocco delle istruzioni è contenuto tra un begin ed un end, quest'ultimo però seguito dal ; non dal .;
5) la procedura va inserita nel programma principale, immediatamente prima del begin di esso;
6) la procedura viene richiamata dal programma principale semplicemente usando il Nome della procedura all'interno del Blocco delle istruzioni del programma principale.
I seguenti es. illustrano quanto spiegato.
program FrasePosizionata;
uses Crt;
var i, j: byte;
S: string;
procedure Parola(Col, Riga: byte; Frase: string);
begin
ClrScr;
GotoXY(Col, Riga);
Write(Frase)
end;
begin
ClrScr;
Write('A quali coordinate vuoi iniziare a scrivere? ');
ReadLn(i, j);
Write('Che frase vuoi scrivere? ');
ReadLn(S);
Parola(i, j, S);
ReadLn
end.
Osserviamo innanzitutto la struttura:
- program FrasePosizionata; è la solita intestazione del programma principale;
- uses Crt; è la solita clausola per l'uso di istruzioni che controllano il display, come ClrScr;
- var i,j: byte; S: string; è la Dichiarazione delle variabili del programma principale;
- procedure Parola(Col, Riga: byte; Frase: string); è l'intestazione d'una procedura di nome Parola, con i tre parametri Col e Riga di tipo byte e Frase di tipo string. Questa procedura non ha variabili locali;
- begin... end; è il Blocco delle istruzioni della procedura. Che azione specifica fa Parola? 1) Cancella lo schermo, 2) posiziona il cursore alla colonna Col e alla riga Riga, 3) scrive la stringa Frase. Col, Riga e Frase sono parametri, cioè variabili (il cui tipo è indicato tra le parentesi tonde del nome della procedura) che acquisiranno specifici valori solo dal programma principale. È questo il significato del termine parametri di una procedura;
- begin... end. Questo è il Blocco delle istruzioni del programma principale, cioè quello che in effetti viene eseguito dalla CPU. Vediamo che cosa fa il chip: 1) Cancella lo schermo; 2) fa apparire la scritta "A quali coordinate vuoi iniziare a scrivere? ", 3) attende l'introduzione di due numeri byte che depositerà nelle celle di memoria d'indirizzo rispettivo i e j; 4) fa apparire la scritta "Che frase vuoi scrivere? ", 5) attende la digitazione da parte dell'utente d'una frase, che poi depositerà nella cella d'indirizzo S (la Dichiarazione delle variabili del programma principale aveva riservato 3 celle degli indirizzi e dei tipi appositi); 6) a questo punto, con l'istruzione Parola(i, j, S), viene richiamata la procedura, cioè CPU esegue adesso proprio il sottoprogramma avente quel nome, utilizzando i due numeri e la frase digitati dall'utente al posto dei parametri formali: ossia 1) ri-cancella lo schermo, 2) posiziona il cursore alla colonna i e alla riga j digitate dall'utente e 3) scrive la stringa S digitata dallo stesso.
Altro es.:
program FraseMaiuscola;
var S: string;
procedure ScriviMaiuscolo(S1: string);
var i: integer;
begin
For i:= 1 To Length(S1) Do S1[i]:= UpCase(S1[i]);
WriteLn(S1)
end;
begin
Write('Scrivi una stringa: ');
ReadLn(S);
ScriviMaiuscolo(S);
ReadLn
end.
Notiamo che questa volta la procedura ha una variabile locale (i, di tipo integer) ed un solo parametro (S1, di tipo string). La variabile i funziona soltanto all'interno della procedura e serve a numerare tutti i caratteri della stringa per trasformarli ordinatamente in maiuscolo.
III° es.:
program EstrazioneLotto;
uses Crt;
var Num_Lotto, Mio_Numero, N, V: byte;
Tasto: char;
procedure Inizio;
begin
ClrScr;
N:= 1;
V:= 0;
Randomize
end;
procedure Controllo;
begin
Repeat
Tasto:= Readkey;
If not(Tasto in['0'..'9', #27]) Then begin
N:= N-1;
WriteLn('Tasto errato,
riprova')
end;
Until Tasto in ['0'..'9', #27]
end;
procedure MessaggioFinale;
begin
WriteLn('Numero scelto: ', Mio_Numero);
WriteLn('Numero vincente: ', Num_Lotto);
If Num_Lotto= Mio_Numero Then begin
WriteLn('Hai vinto!', ^G^G);
Inc(V)
end
Else WriteLn('Hai perso...');
WriteLn('Hai vinto ', V, ' volte su ', N);
WriteLn('Premere per uscire, altrimenti continuare');
Inc(N);
WriteLn
end;
begin
Inizio;
Repeat
Num_lotto:= Random(10);
WriteLn('Scegli un numero fra 0 e 9');
Controllo;
Mio_Numero:= Ord(Tasto)-Ord('0');
MessaggioFinale;
Until Tasto= #27
end.
In questo programma vengono utilizzate ben tre procedure, Inizio, Controllo e MessaggioFinale, nessuna delle quali è dotata di parametri.
IV° es.:
program Animazione;
uses Crt;
var Colonna, i: byte;
procedure Movimento(var X: byte);
begin
If X= 80 Then X:= 1
Else Inc(X)
end;
procedure Disegno;
begin
GotoXY(Colonna, 10);
TextColor(i); {Il colore}
Write(#219); {La forma}
Delay(50); {La velocità}
GotoXY(Colonna, 10);
Write(' '); {Cancella il blocchetto precedente}
Movimento(Colonna)
end;
begin
ClrScr;
Colonna:= 1;
For i:= 1 To 160 Do Disegno
end.
Questo è un programma un tantino più complicato degli altri. Innanzitutto notiamo la presenza di due procedure, Disegno e Movimento, la seconda delle quali è annidata nella prima. Questa è una performance caratteristica del Pascal, suscettibile di notevoli prestazioni: una procedura può essere richiamata non solo dal programma principale, ma anche da un'altra procedura. Quando la CPU esegue il Blocco delle istruzioni di Disegno, arrivata all'istruzione Movimento, esegue necessariamente il Blocco delle istruzioni di questa.
Nello stesso programma va notata un'altra circostanza: mentre la procedura Disegno non ha parametri, la procedura Movimento ha un parametro X di tipo byte, che però è preceduto dalla parolina var. Perché? proviamo ad eliminare var e a far girare il programma: stavolta il disegno non si muove. Come mai? Il fatto è che quando un parametro, come in tutti i programmi precedenti, è semplicemente messo tra le parentesi tonde senza la parolina var esso è solo formale ed aspetta, per assumere un valore preciso, il programma principale, senza poter variare all'interno della procedura. Esso si chiama parametro valore e viene momentaneamente depositato in un'area speciale della memoria (stack), nella quale non subisce variazioni fino alla definizione del suo valore per azione del programma principale. Perché il disegnino si muova però, noi abbiamo bisogno che X vari da 1 ad 80 all'interno della procedura Movimento: in questo caso si parla di parametro variabile e deve essere preceduto da var. La parolina ha il compito di collocarlo in RAM, in celle dove può assumere valori variabili.
V° es.:
program EquazioneIIGrado;
uses Crt;
var
a1, b1, c1: real;
Risposta: char;
procedure RadiciReali(a, b, c: real);
var Radice1, Radice2, D: real;
begin
D:= sqr(b)-4*a*c;
If D< 0 Then begin
WriteLn('Equazione impossibile!');
Exit
end
Else
Radice1:= (-b-sqrt(D))/(2*a);
Radice2:= (-b+sqrt(D))/(2*a);
WriteLn('La radice1 è = ', Radice1:0:3);
WriteLn('La radice2 è = ', Radice2:0:3)
end;
begin
ClrScr;
Repeat
Write('I coefficiente? = ');
ReadLn(a1);
Write('II coefficiente? = ');
ReadLn(b1);
Write('III coefficiente? = ');
ReadLn(c1);
RadiciReali(a1, b1, c1);
Write ('Vuoi continuare? [S]ì, [N]o: ');
ReadLn(Risposta)
Until (Risposta= 'N') or (Risposta= 'n')
end.
Questo, ed il seguente, sono es. molto semplici, che non richiedono commenti.
VI° es.:
program AlgoritmoEuclideo;
uses Crt;
var M, N: integer;
procedure Scambio; {Se M 0) e Indice (naturale): ');
ReadLn(Radicando, Indice);
B1:= (Radicando < 0);
B2:= (Indice

Esempio