====== Esercitazione 3 ====== Dove si parla di librerie generiche, make e altro ..... ===== Esercizio 1. Variabili static ===== scrivere una funzione ''conta'' di segnatura int conta (void); che restituisce come valore il numero di volte che e' stata invocata dall'inizio del programma, quindi 1 la prima volta, 2 la seconda etc //senza utilizzare variabili globali//. ===== Esercizio 2. Static e visibilità ===== Verificare che dichiarando static una funzione all'interno di un file non e' possibila invocarla da funzioni definite in altri file (suggerimento: provare a definire ''static'' la funzione ''somma'' dell'esempio fatto per la compilazione separata). ===== Esercizio 3. Liste generiche in C ===== In questo esercizio si richiede di realizzare alcune funzioni che lavorano su liste generiche in C. Una lista generica e' rappresentata con la seguenti struct typedef struct elem { /** chiave */ void * key; /** informazione */ struct elem * next; } elem_t; typedef struct { /** la testa della lista */ elem_t * head; /** la funzione per confrontare due chiavi */ int (* compare) (void *, void *); /** la funzione per copiare una chiave */ void * (* copyk) (void *); } list_t; la prima struttura (''elem_t'') rappresenta un nodo della lista generica. Ogni nodo contiene una chiave ''key'' che puo' avere tipo qualsiasi. La seconda struttura (''list_t'') permette di definire una particolare lista a partire da quella generica. Per farlo bisogna fornire due funzioni: * ''compare'' permette di confrontare due chiavi, ritorna 0 se sono uguali ed un valore diverso da 0 altrimenti * ''copyk'' crea una copia della chiave (allocando la memoria necessaria) e ritorna il puntatore alla copia (se tutto e' andato bene) o NULL (se si e' verificato un errore) Si chiede di realizzare le funzioni che permettono di creare/distruggere una lista generica e quelle per inserire ed estrarre un elemento generico. Realizzare un main di test che prova ad istanziare la lista in due versioni: una prima a valori interi usando le seguenti funzioni per il confronto e la copia: /** funzione di confronto per lista di interi \param a puntatore intero da confrontare \param b puntatore intero da confrontare \retval 0 se sono uguali \retval p (p!=0) altrimenti */ int compare_int(void *a, void *b) { int *_a, *_b; _a = (int *) a; _b = (int *) b; return ((*_a) - (*_b)); } /** funzione di copia di un intero \param a puntatore intero da copiare \retval NULL se si sono verificati errori \retval p puntatore al nuovo intero allocato (alloca memoria) */ void * copy_int(void *a) { int * _a; if ( ( _a = malloc(sizeof(int) ) ) == NULL ) return NULL; *_a = * (int * ) a; return (void *) _a; } e una seconda che ha come chiavi stringhe usando analoghe funzioni per la copia ed il confronto. Sviluppare un opportuno main di test di pari passo allo sviluppo delle funzioni. ===== Esercizio 4: Ancora genericita'.... ===== Modificare il tipo dell'esercizio 3 in modo da riuscire ad implementare anche le funzioni che scrivono su file e leggono da file una lista generica. Sviluppare un opportuno main di test di pari passo allo sviluppo delle funzioni. ===== Esercizio 5: Makefile per libreria di liste di interi ===== Con riferimento [[http://didawiki.di.unipi.it/doku.php/informatica/sol/laboratorio16/esercitazionib/esercitazione2#esercizio_2creare_ed_usare_una_libreria_di_liste| all es 2 della scorsa volta]] definire un file Makefile che contenga * le regole per generare correttamente i moduli oggeto relativi amain.o e lista.o * la regola PHONY ''lib'' per generare correttamente la libreria libList.a * la regola per generare l'eseguibile a partire da oggetti e librerie * un target PHONY ''cleanall'' che elimini gli oggetti e gli eseguibili utilizzare dove possibile le regole implicite, le variabili e le convenzioni viste a lezione. Usare ''gcc -MM'' per generare automaticamente le liste di dipendenze per i target relativi ai moduli oggetto. ===== Esercizio 6: Makefile per liste generiche ===== Sviluppare un makefile opportuno che gestisca l'aggiornamento automatico dei file utilizzati per gli esercizi 3 e 4 di questa esercitazione e crei automaticamente la libreria corrispondente con un target "lib".