Upload
dafne-messina
View
217
Download
0
Embed Size (px)
Citation preview
Sistemi e Tecnologie Informatiche
Requisiti per la realizzazione di un buon programma
Realizzare un programma
Cosa deve fare? A che serve?
Su quali sistemi dovrà funzionare? Quali tecnologie adopererà?
Progettiamone una implementazione …
Implementiamolo!
Ora, assicuriamoci che funzioni correttamente
Un po di tempo dopo … “Avrei bisogno di questa funzione. Lo so che inizialmente non era
prevista ma il programma ci guadagnerebbe molto se la implementassimo”
“Il colore delle finestre, rosa pallido, non è molto azzeccato. Potremmo provare uno sfondo grigio a pois rossi?”
Ciclo di vita dei programmi
Descrive le attività fondamentali alla realizzazione
di un programma:
Specifica dei requisiti
Scelta del sistema di calcolo
Progetto
Implementazione
Test e correzione
Manutenzione del codice
Requisiti per un buon programma
Correttezza Leggibilità Efficienza Parametricità Modificabilità Portabilità
Requisiti per un buon programma
Correttezza
Assicurarsi che il programma restituisca risultati corretti in tutti i possibili casi di esecuzione previsti (e.g., un algoritmo di ordinamento deve restituire sempre un elenco ordinato)
Leggibilità
Adoperare uno stile di programmazione che ne semplifichi la comprensione ed, al contempo, documentare opportunamente il codice sorgente ed il progetto nella sua interezza(e.g., evitare variabili dai nomi criptici tipo a, b, c, d, e)
Requisiti per un buon programma
ModificabilitàSemplificare la possibilità di modificare un programma preesistente per soddisfare degli eventuali nuovi requisiti(e.g., se il colore delle finestre viene memorizzato in una sola variabile mi basterà cambiare quella per passare da rosa a grigio)
Portabilità
Favorire la possibilità di riutilizzare il programma realizzato su sistemi diversi da quello inizialmente utilizzato(e.g., un gioco per telefonini scritto in Java potrà funzionare su tutti i telefonini Java compatibili, anche se di marche diverse)
Requisiti per un buon programma
Efficienza
Implementare soluzioni concettualmente e sperimentalmente efficienti rispetto ai requisiti del progetto(e.g., un programma che impiega 10 anni a terminare è probabilmente inutile)
Parametricità
Realizzare soluzioni generali riutilizzabili in contesti differenti.(e.g. una funzione per l’ordinamento di un elenco telefonico, se scritta opportunamente, andrà bene per ordinare un qualsiasi altro elenco di nomi)
Realizzare un buon programma
La possibilità di realizzare un buon programma è condizionata all’adozione di opportune metodologie di sviluppo
Queste intervengono: A priori, in fase di progetto, guidando lo sviluppatore
nell’adottare le scelte migliori per la realizzazione del programma
A posteriori, in fase di analisi, consentendo di valutare la qualità e la correttezza di un programma già realizzato
Metodologie di progettazione
Top-down (dall’alto verso il basso) Decompone il problema di partenza in
sottoproblemi di più semplice risoluzione Il processo di scomposizione si arresta quando
si giunge a problemi elementari
Bottom-up (dal basso verso l’alto) Risolve isolatamente problemi più semplici e li
assembla per la risoluzione di problemi più complessi
Trova applicazione nei linguaggi orientati agli oggetti (e.g., C++, Java)
Progettazione top-down
Vantaggi: Storicamente indicata per la risoluzione di problemi molto complessi
Tali problemi possono essere suddivisi in problemi più elementari
Diviene inoltre possibile ripartire più facilmente un lavoro tra diversi sviluppatori
Svantaggi: Le soluzioni sviluppate sono difficilmente riutilizzabili in contesti
diversi da quelli previsti originariamente
La progettazione trascura l’importanza delle strutture dati
Progettazione bottom-up
Vantaggi: Si affrontano inizialmente problemi elementari e di semplice
risoluzione
I programmi così realizzati costituiranno moduli da utilizzare nella risoluzione problemi più complessi
La possibilità di riutilizzare i programmi realizzati conseguedirettamente dalla strategia di progetto
Svantaggi: I tempi di sviluppo sono tipicamente più lunghi di quelli richiesti
dalla metodologia top-down E’ più complessa da attuare
Metodologie di progettazione
Esercizio: Progettare un programma che acquisisca una listadi valori numerici in input e ne restituisca l’elenco ordinato
1. Leggi dati in input
2. Ordina i dati letti
3. Stampa dati ordinati
1. Alloca un array di interi Vettore2. For i from 0 to n-13. Leggi da tastiera Vettore[i]4. Ordina i dati letti5. For i from 0 to n-16. Stampa Vettore[i]
Verifica correttezza#include<stdlib.h>#include<stdio.h>
#define N 6 // Numero degli elementi da ordinare
int main(void){ int vettore[N]; // Mantiene gli elementi da ordinare int scambio; // Usato come variabile temporanea effettuare lo
// scambio durante l’ordinamento int minimo, i, j, pos_minimo;
for(i=0; i<N; i++) // Legge gli N elementi da tastiera scanf("%d", &vettore[i]);
123456789
10111213
for(i=0; i<N-1; i++) {
pos_minimo=i; minimo=vettore[i];
// ricerca il valore minimo in Vettore[i+1..N] for(j=i+1; j<N; j++) if( vettore[j]<minimo ) { pos_minimo=j; minimo=vettore[j]; }
// scambia vettore[pos_minimo] e vettore[i] scambio=vettore[pos_minimo]; vettore[pos_minimo]=vettore[i]; vettore[i]=scambio; }
for(i=0; i<N; i++) // Stampa gli N elementi ordinati printf("%d\n", vettore[i]);
return 0;}
1415161718192021222324252627282930313233343536
Leggibilità di un programma
Sviluppare programmi che siano leggibili e ben documentati presenta notevoli vantaggi:
Consente di comprendere con facilità quale problema il programma risolve e con quale approccio
Facilita la possibilità di condividere con altri sviluppatori le soluzioni impiegate
Semplifica la possibilità di tornare a modificare in un secondo momento un programma sviluppato in passato
Svantaggi: E’ una attività noiosa e, spesso, apparentemente inutile
Leggibilità di un programma
Esistono numerose possibilità di intervento per migliorare la leggibilità di un programma, tra queste citiamo:
Formattare (indentare) il codice sorgente
Utilizzare nomi di variabili autoesplicativi
Commentare il codice sorgente
#include<stdlib.h>#include<stdio.h>
int main(void) {int beta, gamma, i, delta;i=1;delta=0;scanf("%d", &beta);while(i<=9) { scanf("%d", gamma);if( beta<gamma)delta++;beta=gamma; i++; }printf("%d\n", delta);return 0;}
123456789
10
???
Formattare il codice sorgente
for(int i = 0; i < 5; i++) { istruzione1; istruzione2; istruzione3;}
if (condizione) { istruzione1; istruzione2;} else { istruzione3; istruzione4;}
void funzione (int numero) { istruzione1; istruzione2; istruzione3;}
do{ istruzione1; istruzione2; istruzione3;} while (i > 0)
Una buona formattazione si ottiene disponendo opportunamente il codice su righe e colonne in modo da far risaltare le singole istruzioni ed il contesto nel quale queste vengono eseguite
Formattare il codice sorgente
#include<stdlib.h>#include<stdio.h>
int main(void){ int beta, gamma, i, delta;
i=1; delta=0;
scanf("%d", &beta); while(i<=9) { scanf("%d", &gamma); if( beta<gamma ) delta++;
beta=gamma; i++; }
printf("%d\n", delta); return 0;}
123456789
1011121314151617181920212223
123456789
10
#include<stdlib.h>#include<stdio.h>
int main(void) {int beta, gamma, i, delta;i=1;delta=0;scanf("%d", &beta);while(i<=9) { scanf("%d", gamma);if( beta<gamma)delta++;beta=gamma; i++; }printf("%d\n", delta);return 0;}
Prima ….
… Dopo
Utilizzare nomidi variabili autoesplicativi
E’ preferibile attribuire alle variabili dei nomi che aiutino a comprenderne il significato e la finalità:E.g. Definire la variabile che mantiene una somma: somma Definire un intero che mantiene un indice: indice Definire una coppia di matrici da sommare: matrice1 e matrice2
Evitare nomi criptici o incomprensibili!E.g a,b,c,d x,y,z,v,w variabile1,variabile2,variabile3
123456789
1011121314151617181920212223
#include<stdlib.h>#include<stdio.h>
int main(void){ int beta, gamma, i, delta;
i=1; delta=0;
scanf("%d", &beta); while(i<=9) { scanf("%d", &gamma); if( beta<gamma ) delta++;
beta=gamma; i++; }
printf("%d\n", delta); return 0;}
123456789
1011121314151617181920212223
#include<stdlib.h>#include<stdio.h>
int main(void){ int ultimo_numero, penultimo_numero, int i, conta_numeri;
i=1; conta_numeri=0;
scanf("%d", &penultimo_numero); while(i<=9) { scanf("%d", &ultimo_numero); if( penultimo_numero<ultimo_numero ) conta_numeri++;
penultimo_numero=ultimo_numero; i++; }
printf("%d\n", conta_numeri); return 0;}
123456789
101112131415161718192021222324
Commentare il codice I commenti sono messaggi di testo che possono essere inseriti in un
codice sorgente al fine di migliorarne la comprensibilità
Non hanno alcun effettto sul funzionamento di un programma …
… a patto che siano usati correttamente!
In C/C++ esistono due tipologie di commenti: Commenti su una sola riga, sono preceduti dalla coppia di simboli “//” e si
concludono al termine della riga stessa Commenti su più righe, sono preceduti e seguite dalle coppie di simboli “/*”
e “*/”. Tutto il testo racchiuso tra questi due coppie di simboli si intende essere un commento
I commenti possono essere utilizzati per : Definire lo scopo di una funzione e spiegare il significato dei suoi parametri Chiarire il ruolo di una variabile Commentare un gruppo di istruzioni
// Questo programma legge una sequenza di 10 numeri e calcola // quanti numeri sono maggiori del precedente.#include<stdlib.h>#include<stdio.h>
int main(void){ int ultimo_numero; // ultimo numero letto int penultimo_numero; // penultimo numero letto int i; int conta_numeri; // memorizza quante volte un numero e'
// maggiore del precedente
// assegnazione valori iniziali alla variabile di ciclo e al contatore i=1; conta_numeri=0;
scanf("%d", &penultimo_numero); // lettura del primo numero…
123456789
101112131415161718
// leggo i successivi numeri: confronto ognuno con il precedente while(i<=9) { scanf("%d", &ultimo_numero); // leggo un numero
// confronto ed eventuale incremento del contatore if( penultimo_numero<ultimo_numero ) conta_numeri++;
// l'ultimo numero letto diventa il penultimo, penultimo_numero=ultimo_numero; i++; }
printf("%d\n", conta_numeri); // stampa risultato return 0;}
192021222324252627282930313233