Voyons sur un exemple. Soit à déclarer un pointeur p vers une fonction retournant un int. Considérons l'utilisation de p : à partir de p, il faut d'abord utiliser l'opérateur indirection pour obtenir la fonction, soit *p. Ensuite, on va appeler la fonction délivrée par l'expression *p, pour cela il faut écrire (*p)()9.3. Finalement cette expression nous délivre un int. La déclaration de p s'écrira donc :
int (*p)();
De la même manière, pour interpréter un type compliqué, il vaut mieux partir d'une utilisation. Soit à interpréter :
char (*f())[];Imaginons une utilisation :
(*f(i))[j]
.
L'opérateur appel de fonction étant plus prioritaire que l'opérateur
indirection, on applique d'abord l'appel de fonction à f.
Donc f est une fonction.
Ensuite on applique l'opérateur indirection, donc f est une fonction
retournant un pointeur.
On indexe le résultat, donc f est une fonction retournant un pointeur vers
un tableau.
Finalement, on voit que
f est une fonction retournant un pointeur vers un tableau de char.
Matthieu Moy 2017-02-08