En pratique

Lorsqu'il s'agit d'écrire ou de comprendre un type compliqué, il est recommandé non pas d'utiliser la grammaire des déclarateur, mais de partir d'une utilisation du type, étant donné que la grammaire est faite de telle sorte que les déclarations calquent très exactement les expressions.

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