Salve a tutti ragazzi, è la prima volta che scrivo nel forum (non c'è una sezione di presentazione?). Devo realizzare un progetto per l'uni. Al momento mi sto cimentando nelle varie esercitazioni prima di lanciarmi sul progetto vero e proprio.
Una di queste chiede di realizzare funzioni che manipolino liste con due campi generici: una chiave (key) ed un'informazione (payload). Il codice di partenza è il seguente:
----------------------------------------------------------------------
codice:
#ifndef __GENLIST__H
#define __GENLIST__H
typedef struct elem {
void * key;
void * payload;
struct elem * next;
} elem_t;
typedef struct {
elem_t * head;
int (* compare) (void *, void *); //confronta due chiavi, ritorna 0 se uguali
void * (* copyk) (void *); //copia una chiave
void * (* copyp) (void *); //copia un payload
} list_t;
list_t * new_List(int (* compare) (void *, void *),void* (* copyk) (void *),void* (*copyp) (void*));
void free_List (list_t ** pt);
int add_ListElement(list_t * t,void * key, void* payload);
int remove_ListElement(list_t * t,void * key);
elem_t * find_ListElement(list_t * t,void * key);
#endif
-----------------------------------------------------------------------
Partiamo dalla più semplice (cioè l'add_ListElement). Nel caso si trattasse di liste di int (sia la key che il payload), dovrebbe essere qualcosa di questo tipo:
inserisce una nuova coppia (key, payload) in testa alla lista, sia key che payload devono essere copiate nel nuovo elemento della lista. Nella lista non sono permesse chiavi replicate
//Return values:
-1 se si sono verificati errori (errno settato opportunamente)
0 se l'inserimento è andato a buon fine
codice:
int add_ListElement (list_t* head, int k, int p) {
elem_t* tmp;
tmp = malloc(sizeof(elem_t));
if ( tmp == NULL ) return -1;
tmp -> next = head;
tmp -> key = k;
tmp -> payload = p;
return 0;
}
Proviamo ora con liste generiche:
codice:
int add_ListElement (list_t* head, void* k, void* p, void * (* copyk) (void *), void * (* copyp) (void *)) {
elem_t* tmp;
tmp = malloc(sizeof(elem_t));
if ( tmp == NULL ) return -1;
tmp -> next = head;
tmp -> key = copyk(k);
tmp -> payload = copyp(p);
return 0;
}
questo perché non possiamo dereferenziare i puntatori di tipo void (non sto tentando di spiegare...semplicemente vi spiego il mio "pensiero" così da permettervi di correggermi là dove sbagliassi).
Bisogna quindi implementare la copyk e la copyp. La domanda è: come? prendono come argomento la sola chiave/informazione d'aggiungere, possibile che sia una cosa del tipo:
codice:
void *copyk (void* k) {
return k;
}
???