C Language Utilisation de la règle de droite ou de spirale pour déchiffrer la déclaration C


Exemple

La règle "right left" est une règle complètement régulière pour déchiffrer les déclarations C. Cela peut aussi être utile pour les créer.

Lisez les symboles lorsque vous les rencontrez dans la déclaration ...

*   as "pointer to"          - always on the left side
[]  as "array of"            - always on the right side
()  as "function returning"  - always on the right side

Comment appliquer la règle

ÉTAPE 1

Trouvez l'identifiant. C'est votre point de départ. Puis dites-vous, "l'identifiant est". Vous avez commencé votre déclaration.

ÉTAPE 2

Regardez les symboles à droite de l'identifiant. Si, par exemple, vous trouvez () , vous savez que c'est la déclaration d'une fonction. Vous auriez alors alors "l'identifiant est la fonction qui retourne" . Ou si vous avez trouvé un [] , vous diriez "identifiant est un tableau de" . Continuez tout droit jusqu'à ce que vous n'ayez plus de symboles OU appuyez sur une parenthèse droite ) . (Si vous appuyez sur une parenthèse gauche ( c'est le début d'un symbole () , même s'il y a des choses entre les parenthèses).

ÉTAPE 3

Regardez les symboles à gauche de l'identifiant. Si ce n'est pas l'un de nos symboles ci-dessus (par exemple, quelque chose comme "int"), dites-le simplement. Sinon, traduisez-le en anglais en utilisant ce tableau ci-dessus. Continuez à gauche jusqu'à épuisement des symboles OU appuyez sur une parenthèse gauche ( .

Répétez maintenant les étapes 2 et 3 jusqu'à ce que vous ayez formé votre déclaration.


Voici quelques exemples:

int *p[];

Tout d'abord, identifiant de recherche:

int *p[];
     ^

"p est"

Maintenant, déplacez-vous à droite jusqu'à ce que moins de symboles ou de parenthèses droites soient frappés.

int *p[];
      ^^

"p est un tableau de"

Ne peut plus bouger (sans symboles), déplacez-vous à gauche et trouvez:

int *p[];
    ^

"p est un tableau de pointeur vers"

Continuez à gauche et trouvez:

int *p[];
^^^

"p est un tableau de pointeur sur int".

(ou "p est un tableau dont chaque élément est de type pointeur sur int" )

Un autre exemple:

int *(*func())();

Trouvez l'identifiant.

int *(*func())();
       ^^^^

"func is"

Déplacer vers la droite.

int *(*func())();
           ^^

"func est la fonction qui retourne"

Ne peut plus bouger à cause de la parenthèse droite, alors déplacez-vous vers la gauche.

int *(*func())();
      ^

"func est la fonction qui retourne le pointeur sur"

Ne peut plus bouger à cause de la parenthèse gauche, alors continuez comme ça.

int *(*func())();
              ^^

"func est la fonction renvoyant le pointeur à la fonction retournant"

Je ne peux plus bouger parce que nous n'avons plus de symboles, alors allez à gauche.

int *(*func())();
    ^

"func est la fonction renvoyant le pointeur à la fonction retournant le pointeur à"

Et enfin, continuez à gauche, car il ne reste plus rien à droite.

int *(*func())();
^^^

"func est la fonction renvoyant le pointeur à la fonction renvoyant le pointeur à int".

Comme vous pouvez le voir, cette règle peut être très utile. Vous pouvez également l'utiliser pour vérifier vous-même pendant que vous créez des déclarations, et pour vous donner une idée de l'endroit où placer le symbole suivant et si des parenthèses sont nécessaires.

Certaines déclarations ont l'air beaucoup plus compliquées qu'elles ne le sont en raison de la taille des tableaux et des listes d'arguments sous forme de prototype. Si vous voyez [3] , cela se lit comme "array (size 3) of ..." . Si vous voyez (char *,int) qui se lit comme * "function attend (char , int) et retourne ..." .

Voici un amusant:

int (*(*fun_one)(char *,double))[9][20];

Je ne vais pas passer par chacune des étapes pour déchiffrer celle-ci.

* "fun_one est un pointeur sur la fonction qui attend (char , double) et retourne le pointeur sur le tableau (taille 9) du tableau (taille 20) de int."

Comme vous pouvez le voir, ce n'est pas si compliqué si vous vous débarrassez de la taille des tableaux et des listes d'arguments:

int (*(*fun_one)())[][];

Vous pouvez le déchiffrer de cette façon, puis placer les tailles de tableau et les listes d'arguments plus tard.

Quelques mots de conclusion:


Il est tout à fait possible de faire des déclarations illégales en utilisant cette règle, donc une connaissance de ce qui est légal dans C est nécessaire. Par exemple, si ce qui précède a été:

int *((*fun_one)())[][];

il aurait lu "fun_one est un pointeur sur la fonction retournant un tableau de tableau de pointeur sur int" . Une fonction ne pouvant pas retourner un tableau, mais uniquement un pointeur vers un tableau, cette déclaration est illégale.

Les combinaisons illégales comprennent:

[]() - cannot have an array of functions
()() - cannot have a function that returns a function
()[] - cannot have a function that returns an array

Dans tous les cas ci-dessus, vous auriez besoin d'un ensemble de parenthèses pour lier un symbole * à gauche entre ces symboles () et [] droite afin que la déclaration soit légale.

Voici quelques exemples supplémentaires:


Légal

int i;               an int
int *p;              an int pointer (ptr to an int)
int a[];             an array of ints
int f();             a function returning an int
int **pp;            a pointer to an int pointer (ptr to a ptr to an int)
int (*pa)[];         a pointer to an array of ints
int (*pf)();         a pointer to a function returning an int
int *ap[];           an array of int pointers (array of ptrs to ints)
int aa[][];          an array of arrays of ints
int *fp();           a function returning an int pointer
int ***ppp;          a pointer to a pointer to an int pointer
int (**ppa)[];       a pointer to a pointer to an array of ints
int (**ppf)();       a pointer to a pointer to a function returning an int
int *(*pap)[];       a pointer to an array of int pointers
int (*paa)[][];      a pointer to an array of arrays of ints
int *(*pfp)();       a pointer to a function returning an int pointer
int **app[];         an array of pointers to int pointers
int (*apa[])[];      an array of pointers to arrays of ints
int (*apf[])();      an array of pointers to functions returning an int
int *aap[][];        an array of arrays of int pointers
int aaa[][][];       an array of arrays of arrays of int
int **fpp();         a function returning a pointer to an int pointer
int (*fpa())[];      a function returning a pointer to an array of ints
int (*fpf())();      a function returning a pointer to a function returning an int

Illégal

int af[]();          an array of functions returning an int
int fa()[];          a function returning an array of ints
int ff()();          a function returning a function returning an int
int (*pfa)()[];      a pointer to a function returning an array of ints
int aaf[][]();       an array of arrays of functions returning an int
int (*paf)[]();      a pointer to a an array of functions returning an int
int (*pff)()();      a pointer to a function returning a function returning an int
int *afp[]();        an array of functions returning int pointers
int afa[]()[];       an array of functions returning an array of ints
int aff[]()();       an array of functions returning functions returning an int
int *fap()[];        a function returning an array of int pointers
int faa()[][];       a function returning an array of arrays of ints
int faf()[]();       a function returning an array of functions returning an int
int *ffp()();        a function returning a function returning an int pointer

Source: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html