2013-03-16 6 views
5

Sto passando i dati di tipo struct Person a una lista collegata, quindi il puntatore di dati di ogni nodo punta a una struct Person.Trasmissione da void * a struct

struct Person { 
char name[16]; 
char text[24]; 
}; 

sto cercando di attraversare la lista e stampare il nome/testo in ogni nodo chiamando

traverse(&list, &print); 

Prototipo per traslazione è:

void traverseList(struct List *list, void (*f)(void *)); 

lista è definita come:

struct List { 
struct Node *head; 
}; 

My p la funzione rint accetta dati void *:

print(void *data) { .... } 

So che devo trasmettere i dati a struct Persona, corretto?

struct Person *person = (struct Person *)data; 
printf("%s", person->name); 

So che questo non è sufficiente poiché sto ricevendo un avviso di "inizializzazione dal tipo di puntatore incompatibile". Come posso lanciare un void * in questo caso? Grazie.

+0

Qual è il prototipo di 'traverse'? E quale tipo è 'list'? –

+0

Si consiglia di verificare come si passa l'elenco per attraversare e come si sta effettivamente utilizzando la stampa. Tutto ciò che hai mostrato sembra corrispondere. – unxnut

+0

@ValeriAtamaniouk Ho modificato la mia domanda per includerli. – user1889966

risposta

3

Il problema non è con il cast, o anche con il modo in cui si sta passando la funzione intorno . Il problema è che nella dichiarazione di print manca un tipo di reso, nel qual caso si assume di solito int. Il compilatore si sta lamentando perché stai passando un int (*)(void*) a una funzione che è in attesa di un void (*)(void*).

È facile da risolvere: è sufficiente aggiungere void davanti alla dichiarazione della funzione print. Vedere:

https://gist.github.com/ods94065/5178095

1

La mia funzione di stampa accetta un void * dati

direi, riscrivere la funzione print accettando struct Person *.

+0

Perché dovrebbe importare? In C 'void *' è compatibile con qualsiasi puntatore non-const alla struttura. –

+0

Solo perché non c'è bisogno di lanciare quindi. – duDE

+0

Dovresti ancora eseguire il cast: devi eseguire il cast da 'void (*) (struct Person *)' a 'void (*) (void *)' quando passi la funzione da attraversare. Sospetto che sia meno sicuro sul piano della sicurezza e IMO è meno elegante. –

0

La funzione traverseList accetta un puntatore a funzione (che accetta un puntatore void), ma non accetta un argomento per quei dati di annullamento. Sembra che questo è ciò che stai dopo:

void print (void* data) 
{ 
    printf("%s", ((struct Person*)data)->name); 
} 

void traverseList (struct List *list, void(*f)(void*), void* data) 
{ 
    f(data); 
} 

Poi si può chiamare traverseList:

traverseList (&list, &print, &person); 
+0

Penso che l'argomento che 'traverse' fornisce a' print' sia il membro 'data' dell'argomento' struct List * 'di' traverse' resp. i nodi successivi nell'elenco. –