Interpréter les déclarations de types complexes en C et C++

La détermination du type d'une variable à partir de sa déclaration peut parfois s'avérer délicate en C et C++, surtout lorsqu'elle implique des pointeurs, des tableaux et des combinaisons des deux. Une règle de lecture systématique permet de déchiffrer ces syntaxes, souvent perçues comme intimidantes.

La règle fondamentale : Lecture de droite à gauche Lorsqu'une déclaration de varible ne contient pas de parenthèses, le type est déterminé en lisant la déclaration de droite à gauche, en partant du nom de la variable. Le premier qualificateur rencontré en allant vers la gauche définit la nature immédiate de la variable.

Considérons quelques exemples basiques :

int val_simple;         // Lisez : "val_simple est un int"
char *ptr_char;         // Lisez : "ptr_char est un pointeur (à droite de *), vers un char (à gauche)"
double **ptr_sur_ptr_double; // Lisez : "ptr_sur_ptr_double est un pointeur (à droite de *), vers un pointeur (à gauche du premier *), vers un double (encore à gauche)"

Cette règle s'applique également aux tableaux. La déclaration int tableau[10]; se lit "tableau est un tableau de 10 éléments, ces éléments sont des int".

Un point de confusion courant est la distinction entre un tableau de pointeurs et un pointeur vers un tableau. Prenons le cas de char *liste_noms[5]; : En lisant de droite à gauche, le premier qualificateur après liste_noms est [5]. Cela signifie que liste_noms est un tableau de 5 éléments. Ensuite, en allant vers la gauche, nous trouvons *, puis char. Donc, liste_noms est un "tableau de 5 éléments, où chaque élément est un pointeur vers un char". Il s'agit d'un tableau de chaînes de caractères.

Pour déclarer un pointeur vers un tableau (et non un tableau de pointeurs), les parenthèses sont essentielles :

int (*ptr_vers_tableau)[15]; // Correct : un pointeur vers un tableau de 15 entiers

Ici, les parenthèses (*ptr_vers_tableau) sont lues en premier. Cela indique que ptr_vers_tableau est un pointeur. Après avoir traité le contenu des parenthèses, la lecture se poursuit à l'extérieur vers la droite, où nous voyons [15], puis vers la gauche avec int. Ainsi, ptr_vers_tableau est un "pointeur vers un tableau de 15 entiers".

long *(*ptr_tab_long_ptr)[7];

  1. ptr_tab_long_ptr (variable principale).
  2. Priorité aux parenthèses : (*ptr_tab_long_ptr) indique que ptr_tab_long_ptr est un pointeur.
  3. En dehors des parenthèses, à droite : [7] signifie qu'il pointe vers un tableau de 7 éléments.
  4. À gauche de l'astérisque de la parenthèse : long * indique que les éléments du tableau sont des pointeurs vers des long. Conclusion : ptr_tab_long_ptr est un pointeur vers un tableau de 7 pointeurs vers des long.

Un autre exemple plus avancé :

float (*(*ptr_vers_matrice))[3][4];

  1. ptr_vers_matrice (variable principale).
  2. Parenthèses intérieures : (*ptr_vers_matrice) indique que ptr_vers_matrice est un pointeur.
  3. Parenthèses extérieures : (*...) indique que ce que pointe ptr_vers_matrice est également un pointeur.
  4. À droite de la parenthèse extérieure : [3][4] signifie qu'il pointe vers un tableau 3x4 (une matrice).
  5. À gauche du type principal : float indique que les éléments de cette matrice sont des float. Conclusion : ptr_vers_matrice est un pointeur vers un pointeur qui lui-même pointe vers une matrice de float de dimensions 3x4.

En récapitulatif, la règle "lecture de droite à gauche, avec priorité aux parenthèses" est un outil puissant pour décoder les déclarations de types les plus complexes en C et C++.

Étiquettes: C C++ pointeurs tableaux DéclarationDeVariables

Publié le 3 juillet à 09h48