====== 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".