passer différentes structures à une fonction (en utilisant void *)

Je dois comprendre comment passer deux structures différentes à une fonction. J’ai essayé d’utiliser void * pour le paramètre mais je reçois l’erreur:

warning: dereferencing 'void *' pointer error: request for member left in something not a structure or union 

même erreur pour le membre droit

voici ce que j’ai fait en termes généraux (le code ne peut pas être compilé).

 struct A{ char *a; struct A *left, *right; } *rootA; struct B{ char *b; struct B *left, *right; } *rootB; void BinaryTree(void *root, void *s){ if(condition) root->left=s; else if(condition) BinaryTree(root->left, s); if(condition) root->right=s; else if(condition) BinaryTree(root->right, s); } int main(){ // Assume the struct of nodeA and nodeB get malloc() // as well as the variables a and b with actual data. struct A nodeA; struct B nodeB; BinaryTree(rootA, nodeA); BinaryTree(rootB, nodeB); return 0 } 

Vous êtes confus sur vos déclarations de struct. Le type est donné par le mot après struct. Cette chose à la fin doit disparaître, au moins jusqu’à ce que vous en appreniez sur les types de caractères. Exemple:

 struct A{ char *a; struct A *left, *right; }; 

Lorsque vous appelez BinaryTree, vous devez toujours lui transmettre des pointeurs et non des structures. Exemple:

 BinaryTree(&nodeA, &nodeA); 

Lorsque vous effectuez des opérations sur un pointeur vide, vous devez d’abord le convertir en un type de pointeur correct. Exemple:

 (struct A*)root->left=s; 

Passer ces structures comme des pointeurs vides est définitivement une mauvaise pratique et vous allez vous perdre terriblement. Les indicateurs de vide doivent être utilisés avec parcimonie. Puisque vous semblez commencer avec C, je vous recommande de ne pas les utiliser du tout jusqu’à ce que vous compreniez un peu mieux la sémantique de valeur et de référence. Cela étant dit, j’ai fait beaucoup de code stupide quand j’ai commencé sur C, le fais encore parfois. Vous comprendrez avec le temps et la pratique.

Il y a 2 aspects de votre programme qui doivent être relus. Le premier est le paramètre qui passe où vous passez par valeur et non par référence. Par conséquent, les appels à la fonction BinaryTree devraient avoir

 BinaryTree(rootA, &nodeA); 

L’autre considération importante est la façon dont vous gérez ces pointeurs de vide dans la fonction BinaryTree . Dans la forme actuelle,

 void BinaryTree(void *root, void *s){ if(condition) root->left=s; 

Ici, root est un void * et par conséquent, root->left ne peut pas être évalué. Par conséquent, vous devez transtyper root en un type de données significatif, tel que

 struct A *hdl = (struct A*)(root); hdl->left = s; 

Même avec cette approche, une autre considération importante est que vous utilisez la même fonction pour différentes structures. Par conséquent, il serait difficile / difficile de savoir quand taper la root sous A vs B et, par conséquent, cette stratégie nécessite une petite révision.