Comment lire cette déclaration complexe en C?

Dupliquer possible:
quelle est la signification de ce morceau de code? void (* signal (int sig, void (* func) (int))) (int);

J’ai une déclaration complexe qui a été prise à partir du fichier d’en-tête “signal.h”, et en dessous se trouve la déclaration.

void (*signal(int sig, void (*func)(int)))(int); 

Maintenant, comment puis-je l’parsingr? Comme

signal est une fonction prenant deux arguments ‘sig’ de type int et ‘func’, qui est un pointeur sur une fonction prenant int comme argument et renvoyant le type void; elle renvoie un pointeur sur la fonction en prenant int comme argument et en renvoyant void.

Est-ce OK ou le signal est un pointeur à fonctionner?

Commencez avec l’identificateur le plus à gauche et sortez en gardant à l’esprit que [] et () liés avant * , donc *a[] est un tableau de pointeurs, (*a)[] est un pointeur sur un tableau, *f() est une fonction renvoyant un pointeur, et (*f)() est un pointeur sur une fonction:

  signal -- signal signal( ) -- is a function signal( sig, ) -- with a parameter named sig signal(int sig, ) -- of type int signal(int sig, func ) -- and a parameter named func signal(int sig, (*func) ) -- which is a pointer signal(int sig, (*func)( )) -- to a function signal(int sig, (*func)(int)) -- taking an int parameter signal(int sig, void (*func)(int)) -- and returning void *signal(int sig, void (*func)(int)) -- returning a pointer (*signal(int sig, void (*func)(int)))( ) -- to a function (*signal(int sig, void (*func)(int)))(int) -- taking an int parameter void (*signal(int sig, void (*func)(int)))(int); -- and returning void 

signal associe une fonction de gestionnaire de signal func à un signal sig et renvoie le pointeur sur l’ancienne fonction de gestionnaire de signal:

 void new_interrupt_handler(int sig) { ... // do something interesting with interrupt signal } int main(void) { void (*old_interrupt_handler)(int); ... /** * Set up our new interrupt handler */ old_interrupt_handler = signal(SIGINT, new_interrupt_handler); ... /** * Restore original interrupt handler */ signal(SIGINT, old_interrupt_handler); ... } 

En utilisant cdecl.org , vous obtenez

déclarer le signal en tant que fonction (int, pointeur sur fonction (int) renvoyant vide) renvoyant le pointeur sur fonction (int) renvoyant vide

pour l’entrée

 void (*signal(int, void(*)(int)))(int) 

Cela signifie que le signal est une fonction. Le résultat du signal appel est un pointeur sur une fonction void f(int) .

Explication: L’appel à signal() installe un nouveau gestionnaire de signal et renvoie l’ ancien gestionnaire de signal (afin que vous puissiez le restaurer ultérieurement si vous le souhaitez).

signal est une fonction qui prend deux parameters et renvoie un pointeur sur une fonction qui prend un int comme paramètre et renvoie void .

Les deux parameters pris par signal sont un int et un pointeur sur une fonction qui prend int comme paramètre et renvoie void .

Et oui, vous avez bien compris la description et l’idée générale.

Non c’est vrai. signal prend 2 arguments, un int et un pointeur sur une fonction et renvoie un pointeur sur une fonction (avec la même signature que l’argument func ).

C’est similaire au (imo) plus lisible:

 typedef void (*sig_func)(int); sig_func signal(int sig, sig_func func); 
 void (*signal(int, void (*)(int)))(int); signal( ) // signal is a function int, void (*)(int) // the parameter types of the function: // an int and a function pointer (take int, return void) void (* )(int); // the return type of the function: // a function pointer (take int, return void) 

// Edit faisant référence à la réponse de John.