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 consegue
direttamente 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 lista
di 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 Vettore
2. For i from 0 to n-1
3.
Leggi da tastiera Vettore[i]
4. Ordina i dati letti
5. For i from 0 to n-1
6.
Stampa Vettore[i]
1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdlib.h>
#include<stdio.h>
Verifica correttezza
#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]);
14 for(i=0; i<N-1; i++) {
15
pos_minimo=i;
16
minimo=vettore[i];
17
18
// ricerca il valore minimo in Vettore[i+1..N]
19
for(j=i+1; j<N; j++)
20
if( vettore[j]<minimo ) {
21
pos_minimo=j;
22
minimo=vettore[j];
23
}
24
25
// scambia vettore[pos_minimo] e vettore[i]
26
scambio=vettore[pos_minimo];
27
vettore[pos_minimo]=vettore[i];
28
vettore[i]=scambio;
29
30 }
31
32 for(i=0; i<N; i++) // Stampa gli N elementi ordinati
printf("%d\n", vettore[i]);
33
34
35 return 0;
36 }
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
Formattare il codice sorgente
1
2
3
4
5
6
7
8
9
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;
}
???
Formattare il codice sorgente

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
if (condizione) {
istruzione1;
istruzione2;
} else {
istruzione3;
istruzione4;
}
void funzione (int numero) {
istruzione1;
istruzione2;
istruzione3;
}
for(int i = 0; i < 5; i++) {
istruzione1;
istruzione2;
istruzione3;
}
do{
istruzione1;
istruzione2;
istruzione3;
} while (i > 0)
Prima ….
1
2
3
4
5
6
7
8
9
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;
}
… Dopo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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;
}
Utilizzare nomi
di 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdlib.h>
1
#include<stdio.h>
2
int3main(void)
{ 4
5 beta, gamma, i, delta;
int
6
7
i=1;
8
delta=0;
9
10
scanf("%d",
&beta);
11
while(i<=9) {
12
scanf("%d", &gamma);
13
if( beta<gamma )
14delta++;
15
16
beta=gamma;
17
i++;
18
}
19
20
printf("%d\n",
delta);
21
return
0;
22
}
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#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;
}
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 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;
int penultimo_numero;
int i;
int conta_numeri;
// ultimo numero letto
// penultimo numero letto
// 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
…
19 // leggo i successivi numeri: confronto ognuno con il precedente
20 while(i<=9) {
scanf("%d", &ultimo_numero);
// leggo un numero
21
// confronto ed eventuale incremento del contatore
22
if( penultimo_numero<ultimo_numero )
23
conta_numeri++;
24
25
// l'ultimo numero letto diventa il penultimo,
26
penultimo_numero=ultimo_numero;
27
i++;
28
29 }
30
31 printf("%d\n", conta_numeri); // stampa risultato
32 return 0;
33 }
Scarica

Lezione 5: Strategie di Progettazione