Malheur du pointeur de la fonction C

Bon alors j’essaie d’apprendre les pointeurs de fonction. J’ai un pointeur de fonction de base de configuration comme tel.

Fonction pour imprimer la liste chaînée:

void seq_print(Seq seq, void (* print_func)(void *)){ Node * p = seq->top; if(p == NULL){ printf("%s %c", "There is no data to print.", '\n'); return; } while(p != NULL){ print_func(p->data); p = p->next; } } 

Test de la fonction:

 seq_print(s, printFunc(1)); 

Je reçois cette erreur:

 seq.h:113:32: error: expected declaration specifiers or '...' before '(' token extern void seq_print(Seq seq, (void *) print_func(void *)); 

Je ne sais vraiment pas quoi faire, toute idée serait utile.

Vous avez deux erreurs:

Tout d’abord, remarquez la déclaration dans le message d’erreur: dans votre fichier d’en-tête seq.h , la déclaration de fonction est fausse!

  extern void seq_print(Seq seq, (void *) print_func(void *)); // ^ ^ wrong = parenthesis return type 

CA devrait etre:

  extern void seq_print(Seq seq, void (*print_func) (void *)); // ^ correct ^ = parenthesis function name 

Deuxièmement, au lieu d’appel.

 seq_print(s, printFunc(1)); // ^^^ you are calling function, and passes returned value 

devrait être:

 seq_print(s, printFunc); // ^^^^^^^^^^ don't call pass function address 

Les exemples de code suivants vous aideront à mieux comprendre (lire les commentaires):

 #include void my_g2(int i, (void*) f(int)); // Mistake: Notice () around void* void f(int i){ printf("In f() i = %d\n", i); } int main(){ my_g2(10, f(1)); // wrong calling return 0; } void my_g2(int i, void (*f)(int)){ printf("In g()\n"); f(i); } 

Vérifiez le codepad pour le code fonctionne. Vous pouvez voir que l’erreur est similaire à ce que vous obtenez:

 Line 2: error: expected declaration specifiers or '...' before '(' token In function 'main': Line 8: error: too many arguments to function 'my_g2' 

Maintenant, corrigez la version de ce code:

 #include void my_g2(int i, void (*f)(int)); // Corrected declaration void f(int i){ printf("In f() i = %d\n", i); } int main(){ my_g2(10, f); // corrected calling too return 0; } void my_g2(int i, void (*f) (int)){ printf("In g()\n"); f(i); } 

Maintenant, vérifiez codepade pour la sortie:

 In g() In f() i = 10 

Edit: Ajout sur la base du commentaire.

Mais que se passe-t-il si c’est comme void (*f) (void *) comment puis-je transmettre des valeurs à cela?

En appelant function dans main () (dans mon exemple = my_g2 ), vous devez passer le pointeur de la fonction que vous voulez appeler (dans mon exemple f() ) depuis la fonction que vous appelez dans main (c’est my_g2 ).

Vous vouliez appeler f() depuis my_g2()

Nous passons toujours les parameters pour fonctionner au moment de l’appel de la fonction. Donc, si vous voulez passer des parameters à la fonction f() , vous devez passer quand vous appelez cela dans my_g2() .

Une expression d’appel comme ci-dessous (lire les commentaires):

 seq_print(s, printFunc(1)); ^ // first printFunc(1) will be called then seq_prints pass returned value from printFunc(1) 

est faux car si vous le faites, seq_print sera appelé avec le second paramètre, valeur = valeur renvoyée par la fonction printFunc(1) .

Pour passer le pointeur vide, mon code suivant peut vous aider davantage:

 #include void my_g2(void* i, void (*f)(void*)); void f(void *i){ printf("In f(), i = %d\n", *(int*)i); *(int*)i = 20; } int main(){ int i = 10; my_g2(&i, f); printf("Im main, i = %d", i); return 0; } void my_g2(void* i, void (*f)(void*)){ printf("In g()\n"); f(i); } 

Sortie @ codepade :

 In g() In f(), i = 10 Im main, i = 20 

Il y a une faute de frappe dans la déclaration de transfert citée dans le message d’erreur. Il doit correspondre à l’extrait de code que vous avez publié, avec une déclaration de paramètre void (* print_func)(void *) .

On dirait que votre en-tête a une faute de frappe. La déclaration devrait être

 extern void seq_print(Seq seq, void (*print_func)(void *)); 

(void *)print_func(void *) n’est pas une déclaration de pointeur de fonction valide. Pour déclarer une fonction print_func qui accepte un pointeur vide et ne renvoie aucune valeur, utilisez void (*print_func)(void *)

EDIT: omettre les parenthèses autour (* print_func) crée un pointeur de fonction mais pour une fonction renvoyant un pointeur