C_facile : Introduction au langage C
Cours

Erreurs à ne pas commettre

La déclaration de structure suivante est incorrecte :

struct personne

{

     int age;

     char age;

     struct personne pere;

};

Pour deux raisons :

  • Premièrement le nom de variable "age" n'est pas unique, deux champs ont pour identificateur "age". Là, je ne vois pas trop l'intérêt ? Corrigeons cette première erreur :

struct personne

{

     int age;

     struct personne pere;

};

  • Il y a toujours une erreur car "struct personne pere" n'est pas autorisé. La déclaration d'une structure ne fait que donner la façon de construire la structure. On cherche à utiliser "struct personne pere", c'est-à-dire que l'on veut un champ "pere" lui-même avec un champ "age" et un champ "pere". Puisque la déclaration n'est pas terminée, le compilateur ne peut pas savoir comment construire le champ "pere".

Par contre cette écriture est autorisée :

struct personne

{

     int age;

     struct personne * pt_pere;

};

Dans cette écriture, le champ "pt_pere" est un pointeur, et le compilateur sait construire un réceptacle pour un pointeur. Nous avons vu au chapitre 3, que toutes les informations de type "pointeur vers" ont la même taille de réceptacle, car les valeurs qui y sont rangées sont des adresses mémoire. Il en est donc de même pour les pointeurs vers les variables structurées.

AttentionErreur plus difficile à comprendre

Si on utilise un pointeur "identi_pt" pour accéder au champ "truc" d'une variable structurée la syntaxe est :

identi_pt -> truc

"indenti_pt" est l'identificateur d'une variable de type pointeur vers structure. Elle contient donc une valeur qui l'adresse de la variable structurée.

Nous pouvons donc a priori utiliser l'opérateur * et la syntaxe :

(* identi_pt).truc

est équivalente à :

identi_pt -> truc

Attention : la paire de parenthèses est nécessaire. En effet, l'écriture :

*identi_pt.truc

ne donne pas le résultat escompté, car l'opérateur '.' s'évalue de gauche à droite et il est plus prioritaire que l'opérateur '*' qui s'évalue lui de droite à gauche. Ce qui veut dire que la syntaxe

* identi_pt.truc

est en faite équivalente à

* (identi_pt.truc)

La syntaxe '->' a été introduite pour simplifier les écritures et éviter les erreurs.

Exemple

L'exemple suivant a été conçu pour provoquer des erreurs de compilation, il illustre le problème :

#include <stdio.h>

struct machin

{

                        int truc;

};

int main(){

struct machin * identi_pt, variable;

identi_pt = &variable;

identi_pt -> truc = 7;

      // les deux ecritures suivantes sont evidemment equivalentes

printf("\n variable.truc = %d",variable.truc);

printf("\n identi_pt->truc = %d",identi_pt->truc);

      // autre forme equivalente en utilisant l'operateur *

      // (* identi_pt).truc c'est la meme chose que identi_pt->truc

      // les parentheses sont obligatoires

printf("\n (* identi_pt).truc = %d",(* identi_pt).truc);

      // la ligne suivante genere une erreur a la compilation

      // car ce n'est pas equivalent a identi_pt->truc

printf("\n *identi_pt.truc = %d",*identi_pt.truc);

      // la ligne suivante genere aussi la meme erreur car

       // *identi_pt.truc est equivalent a *(identi_pt.truc)

      // a cause de la priorite des operateurs

printf("\n *(identi_pt.truc) = %d",*(identi_pt.truc));

return 0;

}

Variables structurées et passage de paramètres (page suivante)Accès aux champs d'une structure et affectation (page Précédente)
AccueilImprimer creativecommons : by-nc-ndRéalisé avec SCENARI