Banière du site

[koala01.free.fr]->Tutoriaux->Principes de Programmation ->Retour sur les structures

Image d'imprimante   image d'enveloppe

17.1 Introduction

Lorsque je vous ai parlé des structures, les pointeurs n'étaient pas encore vus, et il aurait donc été pour le moins incompréhensible que j'essaie de vous en parler à ce moment là.

Cependant, un pointeur peut parfaitement être inclu dans une structure (et nous verrons dans les pages suivantes que c'est d'ailleurs bien souvent l'unique solution pour arriver à gérer l'allocation dynamique de la mémoire).

fleche haut

17.2 Un petit rappel

Nous avons vu qu'une structure peut très bien être constituée d'autres structures.

Nous pourrions ainsi parfaitement envisager la création de structures simples dans le genre de:

structure Nm
{
	caractere chaine[20] |
}
structure Pn
{
	caractere chaine[15] |
}
structure Adr
{
	caractere rue[50] |
	caractere cp[4] |
	caractere ville[20] |
}

qui serviraient de type de base pour la création d'une structure plus complexe telle que:

structure Personne
{
	Nm Nom |
	Pn Prenom |
	Adr Adresse |
}

Et que cette structure complexe pourrait enfin servir de type de base pour la déclaration d'une variable (que nous nommerions Contact).

Pour accéder au différentes valeurs de la structure, il s'agirait alors de suivre, au départ de notre variable Contact, le chemin qui permet d'accéder à la valeur que l'on recherche:

Oui, je suis parfaitement bien conscient que cette structure n'est clairement pas la structure la plus efficace dans le sens où il parrait clairement inutile de créer une structure Nm et une structure Pn…  Le principal but de cet exemple était de bien montrer qu'il n'est aucunement interdit d'imbriquer les structures sur plusieurs niveaux, et que rien n'interdit d'avoir dans deux structures différentes des variables qui auraient un nom identique, puis d'imbriquer ces structures (ce qui est le cas de la variable "chaine") …

fleche haut

17.3 Les pointeurs dans les structures

Comme les pointeurs sont une possiblité utilisable, il y a parfaitement moyen de déclarer un pointeur au sein d'une structure.

Il suffit de préciser dans la structure que la variable est "un pointeur du type" voulu…

La structure Personne pourrait donc parfaitement n'être composée que de pointeurs, et serait alors déclarée comme ceci:

strucutre Personne
{
	Nm *Nom |
	Pn *Prenom |
	Adr *Adresse |
}

Evidemment, la déclaration d'une variable Contact sur base de cette structure nécessitera une précaution supplémentaire, et je serais surpris que vous ne l'ayiez pas comprise… Non?… Allons, un petit effort…

Mais si, bien sûr, il s'agit de s'assurer de l'allocation mémoire des variabes que contient la structure…

Le principe sera toujours le même: il suffit de suivre, au départ de notre variable Contact, le chemin qui permet d'accéder au pointeur dont on s'apprete à demander l'allocation dynamique, et d'en demander l'allocation…

L'allocation dynamique de mémoire pour notre variable structurée Contact prendra donc la forme suivante:

//déclaration de la variable Contact
Personne Contact |
//allocation dynamique de la mémoire pour le nom
Contact.Nom=Allouer Nm |
//allocation dynamique de la mémoire pour le prénom
Contact.Prenom=Allouer Pn |
//allocation dynamique de la mémorie pour l'adresse
Contact.Adresse=Allouer Adr |

Evidemment, il ne faudra pas oublier, avant de quitter l'application, de libérer la mémoire allouée au différentes valeurs, selon le même principe…

Le code pour y parvenir prendra la forme de

Liberer Contact.Nom |
Liberer Contact.Prenom |
Liberer Contact.Adresse |
//n'oublions pas de "parquer" le pointeurs sur une adresse "de garage"
Contact.Nom=0 |
Contact.Prenom=0 |
Contact.Adresse=0 @

Comme il est possible de créer des tableaux de pointeurs et des pointeurs de pointeurs, il est tout à fait envisageable de les créer dans des structures…en prenant bien soin d'allouer la mémoire de manière correcte avant utilisation et de la libérer, au plus tard, avant de quitter définitivement l'application.

Accéder aux données des pointeurs

Je vous expliquais qu'il était parfaitement envisageable de créer un tableau du type d'une structure existante.

Le fait que la structure contienne éventuellement un pointeur n'est absolument pas une raison qui l'empecherait.

Bien sûr, il s'agit de prendre les précautions d'allocation dynamique et de libération de la mémoire propres aux pointeurs pour chaque élément du tableau créé, mais ces précautions ne sont vraiment pas insurmontables.

Par contre, selon que l'on essaie d'accéder aux données d'un pointeur qui se trouve dans une variable simple ou dans un tableau, deux cas de figures se présentent à nous:

Pour une variable simple, nous accéderons aux valeurs du pointeur en tant que tel, alors que pour un tableau, nous accéderons aux valeur du pointeur en tant qu'étiquette (ou que champs).

L'utilisation de pointeurs en tant que tel

L'utilisation du pointeur en tant que tel signifie clairement que le pointeur qui se trouve dans notre structure donne acces à une adresse méoire.

Il est donc possible de faire varier soit l'adresse mémoire à laquelle il donne accès, soit la valeur contenue par "l'élément visé par" le pointeur, et cela signifie donc que deux notations sont possibles:

La modification ou l'accès de l'adresse visée par le pointeur, qui présente peu d'intérêt, s'effectuera en indiquant de manière classique l'élément de la strucutre, alors que la modification ou l'accès de la valeur contenue par "l'élément visé par" le pointeur s'indiquera généralement à l'aide des signes -> (qui créent une fleche vers la droite)

En reprenant la structure Personne que j'ai présentée quelques lignes plus haut, voici les résultats qu'on pourrait obtenir

//déclaration de la variable
Personne Contact |
//L'allocation de la mémoire pour les pointeurs doit 
//évidemment s'effectuer avant toute chose mais ce n'est pas le but 
//de l'exemple
//Nous modifions la valeur du champs nom
Contact->Nom->chaine="Dunski" |
//Nous modifions la valeur du champs Prenom
Contact->Prenom->chaine="Philippe" |
//Nous pouvons afficher les valeurs
Affiche Contact->Nom |
//Le problème apparait si on essaie d'accéder au pointeur
//comme si c'était un simple champs de la structure
Contact.Nom="Dunski" |//Impossible, une adresse ne peut pas être
                      //une chaine de caractères
Contact.Prenom ++ |//Possible, mais dangeureux: l'adresse,
                   //qui est une valeur numérique peut
                   //être incrémentée, mais le pointeur vise
                   //alors…l'adresse mémoire qui suit celle à
                   //laquelle se touve le champs Prenom de notre
                   //structure

fleche haut

17.4 L'utilisation du pointeur en tant qu'étiquette

Dans le cadre de l'utilisation d'une structure sous la forme d'un tableau, la première chose à faire sera logiquement de déterminer l'élément du tableau auquel on souhaite accéder.

Evidemment, cela se fera par l'utilisation de l'indice indiquant la position de l'élément dans le tableau.

Dans ce cas, le pointeur ne sera plus considéré comme un pointeur, mais comme une étiquette (ou champs) tout simple…

L'accès, à la donnée qu'il contient s'effectuera alors exactement comme s'il s'agissait d'un élément de structure classique.

fleche haut

17.5 Et l'imbrication, dans tout cela?

L'utilisation de pointeur ne modifie en rien ce qu'il est possible de faire avec une structure classique …

On peut donc parfaitement envisager l'imbrication d'une structure qui contienne des pointeurs sur plusieurs niveau.

Cependant, une même cause amenant généralement les mêmes effets, il s'agira toujours de veiller à allouer la mémoire pour la strucutre correspondante.

L'acces au données des éléments déclarés en tant que pointeurs suivront bien évidememnt la même logique.

fleche haut

17.6 Le serpent qui se bouffe la queue

Bien qu'il ne soit généralement pas intéressant de le faire autrement que sous forme de pointeurs (ce qui justifie que j'aie attendu jusqu'à maintenant pour en parler) il est tout à fait possible de définir un élément qui soit du type de la structure que l'on est en train de créer.

Rien n'empecherait donc de déclarer un ou plusieurs pointeurs de types Personne dans la strucutre Personne…

Très régulièrement, vous risquez d'être amené à déclarer un ou deux pointeurs du type même de la structure que vous créez, mais rien n'empecherait, à priori d'en déclarer un nombre beaucoup plus important si vous en aviez l'usage.

Evidemment, tout ce qui a été dit plus haut s'appliquera à ces pointeurs…

image d'imprimante   image de mail   fleche haut

Evaluation donnée par les visiteurs
Cette page n'a pas encore été évaluée sur la compréhension
Mon appréciation sur la compréhensibilitéde cette page est:
  • incompréhensible
  • mal expliquée
  • compréhensible, sans plus
  • bien expliquée
  • très bien expliquée

fleche haut

[koala01.free.fr]->Tutoriaux->Principes de Programmation ->Retour sur les structures

Copyright (©) 2005 (Philippe Dunski)

Ce cours est libre, vous pouvez le redistribuer et/ou le modifier selon les termes de la Licence Publique Générale GNU publiée par la Free Software Foundation (version 2 ou bien toute autre version ultérieure choisie par vous).

Ce cours est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus de détails.

Cependant, l'auteur apprécierait grandement que vous lui fassiez part de toute modification apportée à son contnu

Vous pouvez le contacter par mail à l'adresse koala01@free.fr

Vous pouvez trouver une adaptation française de la licence GNU/GPL à l'URL http://www.linux-france.org/article/these/gpl.html