2013-03-16 9 views
5

Przekazuję dane typu struct Person do listy połączonej, więc wskaźnik danych każdego węzła wskazuje na postać struct.Przesyłanie z void * do struct

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

Próbuję przemierzać listy i wydrukować nazwę/tekst w każdym węźle przez wywołanie

traverse(&list, &print); 

prototyp biegu jest:

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

Lista jest zdefiniowany jako:

struct List { 
struct Node *head; 
}; 

Moje p funkcja rint akceptuje pustkę * dane:

Wiem, że muszę rzucić dane do struct Person, prawda?

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

Wiem, że to nie wystarcza, ponieważ otrzymuję ostrzeżenie "inicjowanie z niezgodnego wskaźnika typu". Jak mogę w tym przypadku skutecznie odrzucić pustkę *? Dziękuję Ci.

+0

Co to jest prototyp 'traverse'? A który typ to 'list'? –

+0

Możesz chcieć sprawdzić, w jaki sposób przekazujesz listę do przechodzenia i jak faktycznie używasz drukowania. Wszystko, co pokazałeś, wydaje się pasować. – unxnut

+0

@ValeriAtamaniouk Zmieniłem moje pytanie, aby je uwzględnić. – user1889966

Odpowiedz

3

Problem nie jest z obsadą, lub nawet z okazji jesteś przejazdem funkcję wokół . Problem polega na tym, że w Twojej deklaracji print brakuje typu zwrotu, w którym to przypadku zwykle przyjmuje się, że int. Kompilator narzeka, ponieważ przekazujesz int (*)(void*) do funkcji, która oczekuje void (*)(void*).

Jest łatwa do naprawienia: po prostu dodaj void przed deklaracją funkcji print. Zobacz:

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

1

Moja funkcja druku akceptuje void * Dane

Powiedziałbym, przepisać swoją funkcję print akceptując struct Person *.

+0

Dlaczego to ma znaczenie? W C 'void *' jest kompatybilny z dowolnym niestałym wskaźnikiem do struktury. –

+0

Tylko dlatego, że nie trzeba wtedy rzucać. – duDE

+0

Nadal będziesz musiał rzucić - musisz przerzucić z 'void (*) (struct Person *)' do 'void (*) (void *)' podczas przekazywania funkcji do przechodzenia. Podejrzewam, że jest mniej przenośnie bezpieczny, a IMO jest mniej elegancki. –

0

Twoja funkcja traverseList przyjmuje wskaźnik funkcji (który przyjmuje wskaźnik pustych wierszy), ale nie akceptuje argumentu dla tych pustych danych. Wydaje się, że to właśnie Ty jesteś po:

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

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

Następnie można wywołać traverseList:

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

Myślę, że argumentem, który 'traverse' dostarcza do' print' jest element 'data' z argumentu' struct List * 'z' traverse' lub. kolejne węzły na liście. –

Powiązane problemy