École Supérieure de Technologie
et d’Informatique
A.U. 2011/2012
Cours atelier de programmation avancée
Chapitre: Les structures (9 pages)
LA ARS (Licence Appliquée Administration des réseaux et Services)
1. Déclaration d’une structure
Le tableau permet de désigner sous un seul nom un ensemble de valeurs de même
type, chacune d’entre elles étant repérée par un indice
La structure permet de désigner sous un seul nom un ensemble de valeurs pouvant être
de types différents. L’accès à chaque élément de la structure (nommé champ) se fait
par son nom au sein de la structure.
struct produit
{
int code;
int qte ;
float prix;
};
Le Modèle de structure s’appelle produit (ne réserve pas de variables correspondant
à cette structure). Il précise le nom et le type de chaque champ.
2. Déclaration des variables:
struct produit art1;
Réservation d’un emplacement nommé art1 de type produit destiné à contenir deux entiers et
un flottant.
Il est possible de regrouper la définition du modèle de structure et la déclaration des
types des variables dans une seule instruction:
struct produit
{
int code;
int qte;
float prix;
} art1, art2;
3. Utilisation d’une structure
a) En travaillant individuellement sur chacun de ses champs
Chaque champ d’une structure peut être manipulé comme n’importe quelle variable du
type correspondant.
Désignation d’un champ: nom de la variable structure.nom du champ tel que défini
dans le modèle
Exemples :
art1.code=15;
Mme Wiem Yaiche Elleuch Les structures
Page 1
printf(« %f »,art1.prix);
scanf(« %f », &art1.prix);
art1.code ++;
La priorité de l’opérateur « . » est très élevée, de sorte qu’aucune des expressions
précédentes ne nécessite de parenthèses.
#include<stdio.h>
struct produit
{
int code;
int qte;
float prix;
};
void main()
{
struct produit pdt;
printf("saisir code, qte et prix \t");
scanf("%d%d%f",&pdt.code, &pdt.qte,&pdt.prix);
printf("\n le produit est %d %d %5.2f \t", pdt.code, pdt.qte, pdt.prix);
}
b) En travaillant de manière globale sur l’ensemble de la structure
Il est possible d’affecter à une structure le contenu d’une structure définie à partir du
même modèle.
art1=art2
est équivalent à:
art1.code=art2.code;
art1.qte=art2.qte;
art1.prix=art2.prix
Une affectation globale de structure est impossible avec des variables ayant une structure
analogue mais définies sous deux noms différents.
L’opérateur d’affectation et l’opérateur d’adresse sont les seuls opérateurs s’appliquant à
une structure (de manière globale)
Remarque : L’affectation globale n’est pas possible entre tableaux, elle l’est par contre entre
structures.
4. Initialisation des structures
En l’absence d’initialisation explicite, les structures sont initialisées à zéro.
Il est possible d’initialiser explicitement une structure lors de sa déclaration
struct produit art1={4 , 5 , 7.9} ;
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.
Publicité
5. Déclaration des synonymes avec typedef
Pour simplifier la déclaration de types, on définit des synonymes avec typedef.
La déclaration typedef permet de définir des types synonymes
Elle s’applique à tous les types et pas seulement aux structures.
Mme Wiem Yaiche Elleuch Les structures
Page 2
typedef int entier; => entier est synonyme de int
Exemples :
int n,p; entier n, p;
int p1, p2; ptr p1, p2;
typedef int ptr; => ptr est synonyme de int
struct produit
{
int code;
int qte;
float prix;
};
typedef struct produit PRODUIT;
PRODUIT art1, art2;
6. Imbrication de structures
typedef struct
{
int code;
int qte;
float prix;
} PRODUIT;
PRODUIT art1, art2;
Chaque champ d’une structure peut être de type entier, réel, pointeur, tableau structure,
pointeur sur une structure, etc
a. Structures comportant des tableaux
struct personne
{
int cin ;
char nom [30];
int heures [31];
};
typedef struct personne PERSONNE;
PERSONNE per ;
per
12345
A l i \0 7 6 8
0 1 2 3 …..
nom
29 0 1 2
Cin
heures
…..
30
F800
F820
F870
Cette déclaration réserve un emplacement pour une variable structure nommée « per ».
Le tableau heures représente le nombre d’heures de travail pendant chacun des jours du
mois courant. Dans cet exemple : per.heures[0] contient 7, ceci veut dire que per a
travaillé 7 heures le 1er jour du mois.
printf(« %d »,per.heures [2]) : affiche le nombre d’heures travaillées par per, le 3ème
jour du mois (=>8).
printf(« %c »,per.nom[0]) : affiche le 1er caractère du nom de per (=>A).
&per.heures[4] : désigne l’adresse du 5ème élément du tableau heures de per
printf(« %s »,per.nom): affiche le nom de per (=> Ali).
printf(« %p »,per.nom): affiche l’adresse du tableau nom de per (=>F820)
printf(« %p »,per.heures): affiche l’adresse du tableau heures de per (=> F870)
Mme Wiem Yaiche Elleuch Les structures
Page 3
printf(« %p », &per): affiche l’adresse de début de la variable per (=> F800)
Exemple d’initialisation:
struct personne per={12345, «Ali»,{7,6,8}};
b. Tableaux de structures
struct point
{
char nom;
int x;
int y;
};
typedef struct point POINT;
POINT courbe [50];
courbe
‘A’ 3 5 ‘B’ 8 2 ‘C’ 9 4 etc
nom x y nom x y nom x y
F800 F810 F820
0
1
2
Publicité
…….
49
La structure point peut servir à représenter un point d’un plan (défini par son nom, et ses
deux coordonnées).
Courbe représente un tableau de 50 éléments de type POINT.
Exemples
courbe[i].nom : représente le nom du point de rang i du tableau courbe. C’est une valeur
de type char.
printf(« %c », courbe[2].nom) ; => C
printf(« %d », courbe[2].x) ; => 9
printf(« %d », courbe[2].y) ; => 4
courbe.nom[i] : n’a pas de sens.
courbe[i].x : désigne la valeur du champ x de l’élément d’indice i du tableau courbe.
courbe [1] : représente la structure de type POINT correspondant au 2ème élément du
tableau
courbe : identificateur de tableau, désigne son adresse de début.
printf(« %p »,courbe) ; => F800
printf(« %p »,&courbe[0]) ; => F800
printf(« %p »,&courbe[1]) ; => F810
printf(« %p »,&courbe[2]) ; => F820
Exemple d’initialisation (partielle):
POINT courbe[50]={{‘A’, 3,5},{‘B’,8,2},{‘C’,9,4}}
Mme Wiem Yaiche Elleuch Les structures
Page 4
c. Structures comportant d’autres structures
struct date
{
int jour;
int mois;
int annee;
};
typedef struct date DATE;
struct employe
{
int cin ;
char nom [30];
int heures [31];
DATE date_embauche;
DATE date_poste;
} ;
Typedef struct employe EMPLOYE ;
EMPLOYE emp ;
emp
12345 A L I \0 7 6 8
12 10 2008
19 11 2009
0 1 2 …… 29 0 1 2 … 30 jour mois annee jour mois annee
Cin
date_embauche
date_poste
heures
nom
F800 F810 F830 F850 F870
emp.date_embauche.annee : représente l’année d’embauche de emp => 2008
emp.date_embauche : représente la date d’embauche de emp (de type DATE)
emp.date_embauche= emp.date_poste; => date d’embauche devient 19 11 2009
Exemple d’initialisation
EMPLOYE emp={12345, "ali", {7,6,8}, {12, 10, 2008}, {19,11,2009}};
Afficher date d’embauche de emp :
printf(« %d %d %d », emp.date_embauche.jour, emp.date_embauche.mois,
emp.date_embauche.annee); => 12 10 2008
Exemple : soit un tableau de 5 employés.
//remplissage des deux premiers employés
EMPLOYE tab[5]={
{123, "med", {3,8,9,5}, {03,12,2005}, {03,12,2006} },
{456, "ali", {8,6,3,9,7}, {04,11,2004},{04,11,2005} }
};
// remplissage des 5 employés du tableau
printf("remplissage du tableau");
for (i=0; i<5; i++)
{
void remplir_tab (int *tab)
{ int i ;
for (i=0 ; i<31 ; i++)
scanf(« %d », tab+i) ;
scanf("\n %d %s ", &tab[i].cin, tab[i].nom);
remplir_tab(tab[i].heures);
scanf("%d%d%d", &tab[i].date_embauche.jour, &tab[i].date_embauche.mois,
&tab[i].date_embauche.annee);
scanf("%d%d%d", &tab[i].date_poste.jour, &tab[i].date_poste.mois,
&tab[i].date_poste.annee);
}
Mme Wiem Yaiche Elleuch Les structures
Page 5
printf("affichage du tableau");
Publicité
// affichage des 5 employés du tableau
for (i=0; i<5; i++)
{
void afficher_tab (int *tab)
{ int i ;
for (i=0 ; i<31 ; i++)
printf(« %d », *(tab+i)) ;
printf("\n %d %s ", tab[i].cin, tab[i].nom);
afficher_tab(tab[i].heures);
printf("%d%d%d", tab[i].date_embauche.jour, tab[i].date_embauche.mois,
tab[i].date_embauche.annee);
printf("%d%d%d", tab[i].date_poste.jour, tab[i].date_poste.mois,
tab[i].date_poste.annee);
}
7. La portée du modèle de structure
Dépend de l’emplacement de sa déclaration
Si elle se situe au sein d’une fonction (y compris la fonction main), elle n’est
accessible que depuis cette fonction.
Si elle se situe en dehors d’une fonction, elle est accessible de toute la partie du fichier
source qui suit sa déclaration; elle peut ainsi être utilisée par plusieurs fonctions.
Exemple
struct produit
{
int code;
float prix;
};
typedef struct produit PRODUIT;
void main()
{
PRODUIT art1;
…..
}
void fonct (……)
{
PRODUIT art2;
……
}
Exemple du modèle de structure produit déclaré à un
niveau global et accessible depuis les fonctions main et
fonct.
8. Transmission d’une structure en argument d’une fonction
En C, la transmission des arguments se fait par valeur, ce qui implique une recopie de
l’information transmise à la fonction.
Il est possible de transmettre la valeur d’un pointeur sur une variable, au quel cas la
fonction peut, si besoin est, en modifier la valeur.
Ces remarques s’appliquent également aux structures.
Attention: il n’en est pas de même pour un tableau, dans la mesure où on ne peut
transmettre que l’adresse du tableau.
Mme Wiem Yaiche Elleuch Les structures
Page 6
a) Transmission d’une structure en argument d’une fonction: Transmission de
la valeur d’une structure
struct produit
{
int code;
int qte;
float prix ;
};
typedef struct produit PRODUIT;
void changer (PRODUIT y)
{
y.code=3;
y.qte=3;
y.prix=9.9 ;
}
void main()
{
PRODUIT x;
x.code=1;
x.qte=2;
x.prix=4.5 ;
printf(« avant modification: %d %d %f", x.code, x.qte, x.prix); // 1 2 4.5
changer(x);
printf(« après modification: %d %d %f", x.code, x.qte, x.prix); // 1 2 4.5
}
Les valeurs de la structure x sont recopiées localement dans la fonction changer lors de son
appel; les modifications de y au sein de la fonction changer n’ont aucune incidence sur les
valeurs de x.
PRODUIT pdt ;
PRODUIT *t ;
t=&pdt ;
t
F100
pdt
Publicité
123
9 7.6
code qte prix
F100 F120 F140
pdt.code :123
pdt.qte : 9
pdt.prix : 7.6
&pdt.code : F100
&pdt.qte : F120
&pdt.prix : F140
t->code : 123
t->qte : 9
t->prix : 7.6
&t->code : F100
&t->qte : F120
&t->prix : F140
Mme Wiem Yaiche Elleuch Les structures
Page 7
b) Transmission d’une structure en argument d’une fonction: Transmission de
l’adresse d’une structure
void changer2 (PRODUIT *y)
{
(*y).code =3;
(*y).qte= 3;
(*y).prix=9.9 ;
struct produit
{
int code;
int qte;
float prix ;
};
typedef struct produit PRODUIT;
void changer2 (PRODUIT *y)
{
}
y->code =3;
y->qte= 3;
y->prix=9.9 ;
}
void main()
{
PRODUIT x;
x.code=1;
x.qte=2;
x.prix= 4.5 ;
printf(« avant modification: %d %d %f", x.code, x.qte, x.prix); // 1 2 4.5
changer2(&x);
printf(« après modification: %d %d %f", x.code, x.qte, x.prix); // 3 3 9.9
}
c) Accès aux champs de la structure en utilisant un pointeur
L’opérateur « . » ne convient plus car il suppose comme premier opérande un nom de
structure et non une adresse.
Adopter une notation telle que (*y).code pour désigner le champ code de la structure
d’adresse y.
Utiliser l’opérateur (->) qui permet d’accéder aux différents champs d’une structure à
partir de son adresse de début.
(*y).code y->code
9. Transmission d’une structure en valeur de retour d’une fonction
struct produit
{
int code;
int qte;
float prix ;
};
typedef struct produit PRODUIT ;
PRODUIT remplir ()
Mme Wiem Yaiche Elleuch Les structures
Page 8
{
PRODUIT x;
printf("saisir la structure ");
scanf("%d%d%f", &x.code, &x.qte, &x.prix);
return x;
}
void main()
{
PRODUIT s;
s=remplir();
printf("la structure est %d %d %f", s.code, s.qte, s.prix);
}
Mme Wiem Yaiche Elleuch Les structures
Page 9