OBIETTIVO DELLA LEZIONE
Programmazione strutturata
- Comprendere il significato della programmazione strutturata ed il suo utilizzo per creare programmi riusabili, facilmente comprensibili e correggibili
Uso dei tipi di dato e delle funzioni- Comprendere le fasi di progettazione del codice di un programma complesso (simulazione di un insieme di cellule)
Rileggi velocemente i lucidi della lezione di stamattina. I costrutti presentati saranno molto utili per risolvere gli esercizi di oggi.
Esercizio 1 (Progettare funzioni per un tipo di dato astratto dato)
Per descrivere i pazienti di una clinica disponi del seguente tipo di dato:/* Paziente */ typedef struct { char nome[256] ; char cognome[256] ; int matricola; int pressione[2]; // minima e massima int temperature[3]; // temperature della mattina e pomeriggio e sera float parcella; // in euro quello che deve al dottore } Paziente; // Iniziale maiuscolaScrivi i PROTOTIPI, le CHIAMATE e il codice delle seguenti specifiche:
- definisci una variabile rossi di tipo paziente;
- definisci un array di 20 pazienti di nome clinica e di tipo paziente;
- imposta una procedura (prototipo) con il corretto passaggio dei parametri che permetta ad un utente di inserire tutti dati di un paziente che è stato passato alla procedura;
- imposta una procedura (prototipo) che stampa la pressione e la temperatura di un paziente;
- imposta una procedura (prototipo) che dato l'indirizzo dell'array clinica ed il numero di pazienti che vi sono sulla lista, calcola il saldo totale della clinica;
- imposta tutte le chiamate nel main che realizzino in sequenza i punti precedenti;
- facoltativo: ora completa l'esercizio scrivendo il codice di tutte le procedure.
Esercizio 2: (Scrittura di prototipi e definizioni di funzioni)
Immagina di disporre del seguente tipo di dato utile per descrivere un punto nello spazio bidimensionale:/* Punto */ typedef struct { float x ; float y ; } Punto; // Iniziale maiuscolaImmagina di disporre inoltre di una procedura che dati i due punti traccia un segmento:stampa( Punto punto1, Punto punto2 );Scrivi i PROTOTIPI, le CHIAMATE e il codice delle seguenti specifiche:
- dichiara un array di 5 punti di nome pentagono;
- dichiara una procedura che dato l'indirizzo di una variabile dello stesso tipo di pentagono permette all'utente di inserire i valori delle coordinate dei punti;
- dichiara una procedura che usando stampa() stampa il pentagono;
- dichiara una FUNZIONE che dato un punto ed un pentagono, ritorna 1 se il punto è interno, 0 se esterno.
Esercizio 3: SIMULAZIONE LIFE
Sviluppa le seguenti attività:
- salva il codice sotto riportato nel file strangeLife.c e crea la sua libreria strangeLife.h;
- amplia la matrice a 65 righe X 65 colonne;
- (facoltativo) modifica la funzione void aggiorna_Matrice (int a[][N_MAX]) in modo che non vi siano errori sui bordi della matrice. Assumi che le celle al di fuori della matrice siano semplicemente vuote.
// strangeLife.c // Simulazione del mondo chiamato LIFE concepito John H. Conway #include <stdio.h> #include <stdlib.h> #include "strangeLife.h" // usare " " per il vostro file #include <math.h> #include <time.h> #define N_MAX 30 // lato della matrice #define ELEM_RANGE2 2 // concentrazione in matrice di cellule #define MAX_EPOCHE 400 int main() { int epoche; // le epoche segnano il tempo che passa int a[N_MAX][N_MAX]; // ecco riempiMatrice(a); // la PROCEDURA riempie la matrice stampa_Matrice(a); for (epoche=1; epoche < MAX_EPOCHE; epoche++) { aggiorna_Matrice(a); stampa_Matrice(a); printf("-->Press a key (control C to stop)"); getchar(); } exit(0); } // segue il codice delle funzioni da portare in libreria void riempiMatrice(int a[][N_MAX]) { int i, j, num_random; float temp; int n = N_MAX; // per comodita' chiamo n N_MAX // Genero una sequenza casuale per riempire la matrice srand(time(NULL)); for(i=0;i < n;i=i+1) { for (j=0;j < n;j=j+1) { num_random = rand(); // qui genero un numero casuale temp = (num_random * ELEM_RANGE2) / RAND_MAX ; // non invertire l'ordine dei fattori!!!! a[i][j]= (int)floor( temp ); // il float ritorna ad essere un intero if ( a[i][j] ) a[i][j]=1; } } } void stampa_Matrice(int a[][N_MAX]) // notare che qui non si usa il ; { int i; int j; int n = N_MAX; // per comodita' chiamo n N_MAX //stampo una matrice facendo anche i "bordini" // -------- Quindi una riga (1) // | | Un carattere "|" all'inizio ed un "|" alla fine (2)e(3) // | | idem // -------- Una riga per chiudere (4) for(i=0;i < n+2;i=i+1) printf("_"); // (1) una riga lunga quanto una matrice for(i=0;i < n;i=i+1) { printf("\n"); // andiamo a capo printf("|"); // "|" all'inizio e (2) for (j=0;j < n;j=j+1) { if (a[i][j]==1) { printf("@"); } else { printf(" "); } } printf("|"); // "|" alla fine e (3) } printf("\n"); // andiamo a capo e tiriamo la riga for(i=0;i < n+2;i=i+1) printf("_"); // (4) una riga lunga quanto una matrice printf("\n\n"); } void aggiorna_Matrice (int a[][N_MAX]) // il codice e'stato volutamente semplificato { int i, j, ki, kj ,tot; int n = N_MAX; // per comodita' chiamo n N_MAX int stato[N_MAX][N_MAX]; for(i=1;i < n-1;i=i+1) { for (j=1;j < n-1;j=j+1) { // ispeziono le 9 celle della matrice 3x3 // e sottraggo la cella centrale tot = 0; for (ki=i-1; ki <= i+1;ki=ki+1) { for (kj=j-1; kj <= j+1;kj=kj+1) { tot = tot + a[ki][kj]; } } tot = tot - a[i][j] ; // guardo solo l'intorno // applico le regole di Conway, (ma sono giuste?) if ((a[i][j] == 0) && (tot == 3)) { stato[i][j] =1; } else if ((a[i][j] == 1) && ( (tot == 3) || (tot == 2)) ) { stato[i][j] =1; } else { stato[i][j] =0; } } } // copio lo stato sulla matrice a for(i=1;i < n-1;i=i+1) { for (j=1;j < n-1;j=j+1) { a[i][j] = stato[i][j]; } } }
Soluzione: strangeLife.c e strangeLife.h.
Esercizio 4: Estensione del programma LIFE
Partendo dal codice proposto come traccia nel precedente esercizio crea le seguenti funzioni:void riempiMatrice1(int a[][N_MAX]) // che inizializza tutte le celle a 1 void triangoloAlCentro (int a[][N_MAX]) // che inizializza a 1 solo le celle al centro // in un intorno triangolare // // // 1 // 111 // 11111 // 1111111 // void aggiungiAliante(int a[][N_MAX]) // attenzione data la matrice questa procedura // AGGIUNGE un aliante in posizione casuale (vedi lezione) // (Somma gli elementi facendo gli OR elemento ad elemento fra le matrici) // Viene chiamato glider (letteralmente "aliante") il più piccolo organismo // semovente che possa essere rappresentato all'interno del Gioco della Vita. // Ecco un esempio // @ // @ // @@@ // void aggiungiStormo(int a[][N_MAX]) // iterando aggiungiAliante si inserisce uno stormo di 30 alianti // disposti casualmente