2013-03-16 22 views
5

struct Person型のデータをリンクリストに渡しているので、各ノードのデータポインタがstruct Personを指しています。私はリストを横断し、トラバースのためのプロトタイプ void *からstructへのキャスト

traverse(&list, &print); 
を呼び出すことによって、各ノードでの名前/テキストを印刷しようとしています

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

は次のとおりです。

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

一覧は以下のように定義されます

struct List { 
struct Node *head; 
}; 

My p rint関数はvoid *を受け取ります。data:

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

私はstruct Personにデータをキャストしなければならないのは分かりますか?

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

私は、「初期化互換性のないポインタ型から」警告を取得していますので、これは十分ではありません知っています。この場合、どのようにしてvoid *をキャストできますか?ありがとうございました。

+0

「トラバース」のプロトタイプとは何ですか?そして、どのタイプが 'list'ですか? –

+0

あなたはトラバースするためにリストをどのように渡しているのか、実際にプリントをどのように使っているのかをチェックしたいかもしれません。あなたが見せてくれたすべてが一致するようです。 – unxnut

+0

@ ValeriAtamaniouk私はそれらを含めるように私の質問を編集しました。 – user1889966

答えて

3

問題は、キャストとの、あるいはあなたの周りの機能を渡している方法ではありません。問題は、printの宣言に戻り値の型がないことです。その場合は、通常、intとみなされます。コンパイラはint (*)(void*)void (*)(void*)が必要な関数に渡しているので不平を言っています。

修正するのは簡単です:voidprint関数宣言の前に追加するだけです。参照:

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

1

マイ印刷機能*データ

のボイドを受け入れ、私はstruct Person *を受け入れることによって、あなたのprint機能を書き換える、と言うでしょう。

+0

なぜそれは重要ですか? Cでは 'void *'は構造体への非constポインタと互換性があります。 –

+0

そのままキャストする必要がないからです。 – duDE

+0

キャストする必要があります。関数を渡すときに、 'void(*)(struct Person *)'から 'void(*)(void *) 'にキャストする必要があります。私はそれが移植性に劣ると思うし、IMOはそれほどエレガントではない。 –

0

traverseList関数は、関数ポインタ(voidポインタ)を受け取りますが、そのvoidデータの引数は受け入れません。あなたが後にしているものであるようだ。

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

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

次にあなたがtraverseListを呼び出すことができます。

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

'traverse'が' print'に供給する引数は 'traverse' respの' struct List * '引数の' data'メンバーだと思います。リストの後のノード –

関連する問題