Vous êtes sur la page 1sur 7

Sofia Douda 1

Les structures et les unions

Différence entre une structure et un tableau


Un tableau permet de regrouper des éléments de même type, c'est-à-dire codés sur le même nombre de
bit et de la même façon. Toutefois, il est généralement utile de pouvoir rassembler des éléments de type
différents tels que des entiers et des chaînes de caractères.
Les structures permettent de remédier à cette lacune des tableaux, en regroupant des objets (des
variables) au sein d'une entité repérée par un seul nom de variable.
Les objets contenus dans la structure sont appelés champs de la structure.

Déclaration d'une structure


Lors de la déclaration de la structure, on indique les champs de la structure, c'est-à-dire le type et le
nom des variables qui la composent:
struct nom_structure {
type_champ1 nom_champ1;
type_champ2 nom_champ2;
type_champ3 nom_champ3;
... };

La dernière accolade doit être suivie d'un point-virgule.


• Le nom des champs répond aux critères des noms de variable
• Deux champs ne peuvent avoir le même nom
• Les données peuvent être de n’importe quel type hormis le type de la structure dans laquelle
elles se trouvent

Exemple 1 :
struct point
{ float abs_x;
float abs_y ;
int couleur;
};

Cette déclaration définit un modèle de structure mais ne réserve pas de variables correspondant à cette
structure. Ce modèle porte le nom point et il précise le nom et le type de chacun des champs de la
structure (abs_x, abs_y et couleur).
Une fois un tel modèle défini, nous pouvons déclarer des variables du type correspondant.

Par exemple :
struct point pt1 ;
réserve un emplacement nommé pt1 de type point destiné à contenir deux flottants et un entier.

De manière semblable :
struct point pt1, pt2 ;
réserve deux emplacements pt1 et pt2 de type point.

Il est également possible de regrouper la définition du modèle de structure et la déclaration du type des
variables dans une seule instruction comme dans cet exemple :

struct point
{ float abs_x;
float abs_y ;

LST GI : Cours de structures et d’union en Langage C 2010/2011


Sofia Douda 2

int couleur;
} pt1, pt2 ;

Dans ce dernier cas, il est possible d’omettre le nom de modèle (point), à condition, bien sûr, que l’on
n’ait pas à déclarer par la suite d’autres variables de ce type.
L’instruction typedef permettra de simplifier quelque peu les déclarations de structures.

Utilisation d’une structure


En C, comme en pascal, il est possible d’utiliser une structure de deux manières :
- en travaillant individuellement sur chacun de ses champs
- en travaillant de manière globale sur l’ensemble de la structure.

Utilisation des champs d’une structure


Chaque champ d’une structure peut être manipulé comme n’importe quelle variable du type
correspondant. La désignation d’un champ se note en faisant suivre le nom de la variable structure du
nom de champ tel qu’il a été défini dans le modèle.

Exemple :
pt1.abs_x = 20. ;
affecte la valeur 20 au champ abs_x de la structure pt1.
printf(″%f″, pt1.abs_x) ;
affiche, suivant le code format %f, la valeur du champ abs_x de la structure pt1.
scanf(″%f″,pt2.abs_y) ;
lit suivant le code format %f, une valeur qui sera affectée au champ abs_y de la structure pt2.
pt1.couleur++
incrémente de 1 la valeur du champ couleur de la structure pt1.

Utilisation globale d’une structure

Il est possible d’affecter à une structure le contenu d’une structure définie à partir du même modèle.

Exemple :

struct point
{ float abs_x;
float abs_y ;
int couleur;
} pt1, pt2 ;

pt1= pt2 ;

Initialisation de structures
- les structures possédant la classe statique sont, par défaut, initialisées à zéro.
- Les structures ayant la classe automatique ne sont pas initialisées et contiennent donc, à priori,
des valeurs aléatoires.

Exemple d’initialisation :
struct point pt1 ={2.5, 30.5, 125} ;

La description des différents champs se présente sous la forme d’une liste de valeurs séparées par des
virgules, chaque valeur étant une constante ayant le type du champ correspondant. Là aussi, il est
possible d’omettre certaines valeurs.

LST GI : Cours de structures et d’union en Langage C 2010/2011


Sofia Douda 3

Déclaration de types synonymes : typedef


La déclaration typedef permet de définir ce que l’on nomme en langage C des types synonymes. A
priori, elle s’applique à tous les types et pas seulement aux structures.

Exemples d’utilisation de typedef


La déclaration :
typedef int entier ;
signifie que entier est synonyme de int, de sorte que les déclarations suivantes sont équivalentes :
int n, p ; entier n, p ;

De même
typedef int *ptr ;
signifie que ptr est synonyme de int * . Les déclarations suivantes sont équivalentes :

int * p1, *p2 ; ptr p1, p2 ;

Autre exemple :
typedef int vecteur[3] ;

Les déclarations suivantes sont équivalentes :


int v[3], w[3] ;vecteur v, w ;

Application aux structures


En faisant usage de typedef, les déclarations précédentes des structures pt1 et pt2 peuvent être réalisées
comme suit :

struct point
{ float abs_x;
float abs_y ;
int couleur;
};

typedef struct point point_C ;


point_C pt1,pt2;

ou encore, plus simplement:

typedef struct
{ float abs_x;
float abs_y ;
int couleur;
} point_C;

point_C pt1, pt2;

Exemples de structures
- Structure comportant des tableaux

Soit la déclaration suivante :


struct personne
{ char nom[30] ;

LST GI : Cours de structures et d’union en Langage C 2010/2011


Sofia Douda 4

char prenom[20] ;
float heures[31] ;
} employe, courant ;

La notation : employe.heures[4]
désigne le cinquième élément du tableau heures de la structure employe.
De même : employe.nom[0]
représente le premier caractère du champ nom de la structure employe.

Par ailleurs :
&courant.heures[4]
Désigne l’adresse du cinquième élément du tableau heures de la structure courant.

Enfin :
courant.nom représente le champ nom de la structure courant, c'est-à-dire plus précisément l’adresse
de ce tableau.

- Tableaux de structures

Soient les déclarations suivantes :

struct point
{ char nom ;
int x ;
int y ;
};
struct point courbe[50] ;

La structure point pourrait, par exemple, servir à représenter un point d’un plan, point qui serait défini
par son nom (caractère) et ses deux cordonnées.
point est un nom de modèle de structure, tandis que courbe représente effectivement un objet de type
tableau de 50 éléments du type point.

Si i est un entier, la notation : courbe[i].nom représente


représente le nom du point de rang i du tableau courbe. Il s’agit donc d’une valeur de type char.
De même, la notation : courbe[i].x
désigne la valeur du champ x de l’élément de rang i du tableau courbe.

Par ailleurs :
courbe[4]
représente la structure de type point correspondant au quatrième élément du tableau courbe.

Enfin, courbe est un identificateur de tableau, et, comme tel, désigne son adresse de début.

Structures comportant d’autres structures


Exemple :
struct date
{ int jour ;
int mois ;
int annee ;
};
struct personne

LST GI : Cours de structures et d’union en Langage C 2010/2011


Sofia Douda 5

{ char nom[30] ;
char prenom[20] ;
float heures[31] ;
struct date date_embauche ;
struct date date_poste ;
} employe, courant ;

Dans la deuxième déclaration, il y a intervention du modèle de structure (date) précédemment défini.


La notation : employe.date_embauche_annee
représente l’année d’embauche correspondant à la structure employe.
De même : courant.date_embauche
représente la date d’embauche correspondant à la structure courant. Il s’agit cette fois d’une structure
de type date. Elle pourra éventuellement faire l’objet d’affectations globales comme dans :
courant.date_embauche = employe.date_poste ;

Structure transmise en argument d’une fonction : l’opérateur ->

Une structure peut être transmise (par valeur) en argument d’une fonction.

Exemple :
struct enreg
{ int a ;
double b ;
};

void main()
{ struct enreg x ;
void fct(struct enreg x) ;
x.a = 1 ;
x.b =12.5 ;
printf(″\n avant appel fct : %d %e″, x.a, x.b) ;
fct(x) ; A l’exécution, on aura :
printf(″\n après appel fct : %d %e″, x.a, x.b) ; avant appel fct : 1 1.25000e+01
} dans fct : 0 1.00000e+00
void fct(struct enreg s) après appel fct : 1 1.25000e+01
{
s.a=0 ; s.b=1;
printf(″\n dans fct : %d %e″, s.a, s.b) ;
}

Il illustre le mécanisme de transmission par valeur:


- lors de l’appel de la fonction fct, il y a recopie des valeurs x dans la pseudo variable locale s,
- les valeurs de x ne sont pas modifiées par la fonction fct qui travaille, en fait, sur s.

Structure transmise par adresse

Il est possible de transmettre en argument l’adresse d’une structure. Ainsi, par exemple, avec les
mêmes déclarations que dans le programme précédent, un appel fct(&x) transmettra l’adresse de x à la
fonction fct. Dans la mesure où le modèle enreg a été défini à un niveau global, l’en-tête de la fonction
fct pourra être de cette forme :
fct(struct enreg * p)

LST GI : Cours de structures et d’union en Langage C 2010/2011


Sofia Douda 6

Pour accéder à chacun des champs, il existe deux solutions :

- adopter une notation telle que (*p).a ou (*p).b pour désigner les champs de la structure d’adresse s.
- faire appel à un nouvel opérateur noté ->, lequel permet d’accéder aux différents champs d’une structure à
partir de son adresse de début. Ainsi, par exemple, au sein de fct, la notation p->b désignera le second champ
de la structure reçue en argument ; elle sera équivalent à (*p).b.

L’exemple suivant illustre l’emploi de cet opérateur :


struct enreg
{ int a ;
double b ;
};
void main()
{ struct enreg x ;
void fct(struct enreg *) ;
x.a = 1 ; x.b =12.5 ;
printf(″\n avant appel fct : %d %e″, x.a, x.b) ;
fct(&x) ;
printf(″\n après appel fct : %d %e″, x.a, x.b) ;
}
A l’exécution, on aura :
avant appel fct : 1 1.25000e+01
void fct(struct enreg *s)
dans fct : 0 1.00000e+00
{
après appel fct : 0 1.00000e+00
s->a=0 ; s->b=1.
printf(″\n dans fct : %d %e″, s->a, s->b) ;
}

Remarque :
En C, une structure peut être fournie comme valeur de retour d’une fonction.

Les champs de bits

Nous avons déjà vu que le langage C disposait d’opérateurs de bits très puissants permettant de
travailler au niveau du bit. De plus, ce langage permet de définir, au sein des structures, des variables
occupant un nombre défini de bits (de 1 à 16 ou à 32).

Exemple :
struct etat
{ unsigned pret : 1 ;
unsigned ok1 : 1 ;
int donnee1: 5;
int : 3;
unsigned ok2: 1;
int donnee2: 4;
};
struct etat mot ;

Avec ces déclarations, la notation: mot.donnee1


désigne un entier signé pouvant prendre des valeurs comprises entre -16 et +15.
Les seuls types susceptibles d’apparaître dans des champs de bits sont int et unsigned int.

LST GI : Cours de structures et d’union en Langage C 2010/2011


Sofia Douda 7

Les unions
L’union en langage C, permet de faire partager un même emplacement mémoire par des variables de
types différents. Cela peut s’avérer utile :
- pour économiser des emplacements mémoire, en utilisant un même emplacement pendant des
phases différentes d’un même programme.
- Pour interpréter de plusieurs façons différentes un même « motif binaire». Dans ce cas, il sera
alors fréquent que l’union soit elle-même associée à des champs de bits.

Exemple :
int main()
{ union essai
{ long n ;
float x ;
} u;
u.x= 12.5 ;
printf(″en réel est : %f\n″, u.x) ;
u.n = 6 ;
printf(″en entier est : %ld\n″, u.n) ;
printf(″en réel est : %f\n″, u.x) ;
return(0) ;
}
/* fin */

LST GI : Cours de structures et d’union en Langage C 2010/2011

Vous aimerez peut-être aussi