2013-03-16 19 views
5

Yapısal Kişi türüne ait verileri bağlantılı bir listeye geçiriyorum, böylece her düğümün veri göstericisi bir struct Kişiyi işaret eder.void * 'den struct'e aktarma

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

ben listesinde geçiş ve hareket için

traverse(&list, &print); 

Prototip arayarak her düğümünde adı/metin yazdırmak çalışıyorum geçerli:

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

Liste olarak tanımlanır:

struct List { 
struct Node *head; 
}; 

My p Ben doğru Kişi, yapısına bir veri döküm gerektiğini biliyorum

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

: Rint fonksiyonu bir boşluk * verilerini kabul eder?

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

Bu, "uyumsuz işaretçi türünden başlatma" uyarısı aldığım için yeterli olmadığını biliyorum. Bu durumda nasıl bir boşluk * başarılı bir şekilde yayınlayabilirim? Teşekkür ederim.

+0

'traverse' prototipi nedir? Ve hangi liste "liste" dir? –

+0

Listeyi geçmek için nasıl geçtiğinizi ve aslında nasıl baskı yaptığınızı kontrol etmek isteyebilirsiniz. Gösterdiğin her şey eşleşiyor gibi görünüyor. – unxnut

+0

@ValeriAtamaniouk Sorularımı içerecek şekilde düzenledim. – user1889966

cevap

3

sorun alçı ile değil, hatta yolu ile etrafında işlevini eklersiniz:

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

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

Sonra çağırabilir traverseList: ne sonra gibi görünüyor . Sorun, print beyannızın bir dönüş türünün eksik olmasıdır, bu durumda int genellikle varsayılmaktadır. Derleyici bir int (*)(void*)'u void (*)(void*) beklenen bir işleve geçirdiğiniz için şikayet ediyor.

Düzeltmek kolay: print işlev bildiriminizin önüne void ekleyin. Bkz:

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

1

Benim baskı fonksiyonu bir boşluk * veri

Ben struct Person * kabul ederek print fonksiyonunu yeniden yazmak derdi

kabul eder.

+0

Bu neden önemlidir? C 'void *' yapısına herhangi bir const olmayan gösterici ile uyumludur. –

+0

Sadece o zaman gerek yok çünkü. – duDE

+0

Hala çevirmene gerek duyarsınız - işlevi geçiş yapmak için void (*) (struct Person *) 'dan' void (*) (void *) 'a çevirmeniz gerekir. Ben daha az portably güvenli, ve IMO daha az zarif olduğundan şüpheleniyorum. –

0

traverseList işleviniz bir işlev göstergesini kabul eder (boşluk işaretçisi alır), ancak bu geçersiz veriler için bir argüman kabul etmez.

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

"Traverse" öğesinin "yazdırmaya" sağladığı argümanı, "traverse" resp argümanının "struct List *" argümanının "data" üyesi olduğunu düşünürdüm. listedeki sonraki düğümler. –