Atelier de Programmation Avancée - Les Structures
Ce cours atelier de programmation avancée porte sur les structures en langage C, un concept fondamental permettant de regrouper sous un même nom plusieurs valeurs de types différents.
D'après le document Atelier de Programmation Avancée - Les Structures
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.
Document source
Computer Science · PDF · 9 pages · 2011
Afficher l'aperçu du document
Ce cours atelier de programmation avancée porte sur les structures en langage C, un concept fondamental permettant de regrouper sous un même nom plusieurs valeurs de types différents. Il s’inscrit dans un module d’administration des réseaux et services, et vise à approfondir la manipulation des structures, leur déclaration, utilisation, imbrication, ainsi que leur passage en argument et en valeur de retour dans les fonctions.
Déclaration et utilisation des structures
Une structure en C permet de regrouper sous un seul nom un ensemble de valeurs pouvant être de types différents, chaque élément étant appelé un champ. Contrairement aux tableaux qui regroupent des valeurs du même type indexées par un entier, les structures utilisent des noms de champs pour accéder à chaque élément.
Par exemple, la déclaration suivante définit un modèle de structure nommé produit :
struct produit
{
int code;
int qte;
float prix;
};
Ce modèle ne réserve pas de mémoire, il précise seulement le nom et le type de chaque champ. Pour créer une variable de ce type, on déclare :
struct produit art1;
Cette instruction réserve un emplacement nommé art1 capable de contenir deux entiers et un flottant. Il est aussi possible de combiner la définition du modèle et la déclaration des variables :
struct produit
{
int code;
int qte;
float prix;
} art1, art2;
Chaque champ d’une structure peut être manipulé individuellement en utilisant l’opérateur point . :
art1.code = 15;printf("%f", art1.prix);scanf("%f", &art1.prix);art1.code++;
La priorité de l’opérateur . est élevée, ce qui évite d’utiliser des parenthèses dans ces expressions.
Il est également possible d’affecter globalement une structure à une autre si elles sont du même type :
art1 = art2;
Cette affectation est équivalente à :
art1.code = art2.code;
art1.qte = art2.qte;
art1.prix = art2.prix;
En revanche, cette affectation globale n’est pas possible entre structures définies sous deux noms différents, ni entre tableaux.
Initialisation et typedef
Les structures sont initialisées à zéro par défaut si aucune initialisation explicite n’est fournie. On peut initialiser une structure lors de sa déclaration :
struct produit art1 = {4, 5, 7.9};
La liste d'initialisation doit respecter l’ordre et le type des champs.
Pour simplifier la déclaration des types, on utilise typedef pour définir des synonymes :
typedef int entier; // entier est synonyme de int
typedef int* ptr; // ptr est synonyme de int*
Appliqué aux structures :
typedef struct produit PRODUIT;
PRODUIT art1, art2;
Imbrication et tableaux dans les structures
Structures comportant des tableaux
Une structure peut contenir des tableaux. Par exemple :
struct personne
{
int cin;
char nom[30];
int heures[31];
};
typedef struct personne PERSONNE;
PERSONNE per;
Dans cet exemple, per.heures est un tableau représentant le nombre d’heures travaillées chaque jour du mois. Par exemple, per.heures[0] contient le nombre d’heures travaillées le premier jour du mois.
Exemples d’accès :
printf("%d", per.heures[2]);affiche le nombre d’heures travaillées le 3ème jour.printf("%c", per.nom[0]);affiche le premier caractère du nom.&per.heures[4]désigne l’adresse du 5ème élément du tableauheures.printf("%s", per.nom);affiche le nom complet.
Exemple d’initialisation :
struct personne per = {12345, "Ali", {7, 6, 8}};
Tableaux de structures
On peut aussi déclarer un tableau de structures. Par exemple :
struct point
{
char nom;
int x;
int y;
};
typedef struct point POINT;
POINT courbe[50];
Cette structure représente un point dans un plan avec un nom et deux coordonnées. Le tableau courbe contient 50 points. L’accès aux champs se fait ainsi :
courbe[i].nom: nom du point i (type char)courbe[i].xetcourbe[i].y: coordonnées du point i
Exemple d’affichage :
printf("%c", courbe[2].nom); // affiche 'C'
printf("%d", courbe[2].x); // affiche 9
printf("%d", courbe[2].y); // affiche 4
Exemple d’initialisation partielle :
POINT courbe[50] = {{'A', 3, 5}, {'B', 8, 2}, {'C', 9, 4}};
Structures imbriquées
Une structure peut contenir d’autres structures comme champs. Par exemple :
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;
On peut accéder aux champs imbriqués :
emp.date_embauche.anneedonne l’année d’embauche.emp.date_embaucheest une variable de typeDATE.- On peut affecter une date à une autre :
emp.date_embauche = emp.date_poste;
Exemple d’initialisation :
EMPLOYE emp = {12345, "ali", {7, 6, 8}, {12, 10, 2008}, {19, 11, 2009}};
Pour afficher la date d’embauche :
printf("%d %d %d", emp.date_embauche.jour, emp.date_embauche.mois, emp.date_embauche.annee);
Un tableau de 5 employés peut être déclaré et initialisé partiellement :
EMPLOYE tab[5] = {
{123, "med", {3, 8, 9, 5}, {3, 12, 2005}, {3, 12, 2006}},
{456, "ali", {8, 6, 3, 9, 7}, {4, 11, 2004}, {4, 11, 2005}}
};
Des fonctions peuvent être utilisées pour remplir et afficher les heures travaillées de chaque employé, ainsi que leurs informations personnelles et dates.
Portée et visibilité des structures
La portée d’un modèle de structure dépend de l’endroit où il est déclaré :
- Déclaration à l’intérieur d’une fonction (y compris
main) : la structure est accessible uniquement dans cette fonction. - Déclaration en dehors de toute fonction : la structure est accessible dans tout le fichier source à partir de sa déclaration, donc utilisable par plusieurs fonctions.
Par exemple, un modèle produit déclaré globalement peut être utilisé dans main et dans une autre fonction fonct.
Transmission des structures en argument de fonction
En C, les arguments sont transmis par valeur, ce qui signifie que la fonction reçoit une copie des données. Cela s’applique aussi aux structures :
Transmission par valeur
typedef struct produit
{
int code;
int qte;
float prix;
} 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 modifications faites dans la fonction changer n’affectent pas la variable originale x car la structure est copiée.
Transmission par adresse (pointeur)
void changer2(PRODUIT *y)
{
(*y).code = 3;
(*y).qte = 3;
(*y).prix = 9.9;
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
}
En passant l’adresse de la structure, la fonction peut modifier directement les champs originaux. L’opérateur -> est utilisé pour accéder aux champs via un pointeur, équivalent à (*y).champ.
Transmission d’une structure en valeur de retour d’une fonction
Une fonction peut retourner une structure entière :
PRODUIT remplir()
{
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);
}
Cette méthode permet de saisir et retourner une structure complète depuis une fonction.
Points clés
- Une structure regroupe plusieurs champs de types différents sous un même nom.
- L’accès aux champs se fait avec l’opérateur
.pour une variable structure, et->pour un pointeur sur structure. - Une structure peut contenir des tableaux, d’autres structures, ou être elle-même contenue dans un tableau.
- La déclaration
typedefpermet de simplifier la syntaxe des types, notamment pour les structures. - La portée d’une structure dépend de son lieu de déclaration : locale à une fonction ou globale au fichier.
- Les structures sont transmises aux fonctions par valeur (copie), sauf si on transmet leur adresse via un pointeur.
- Une fonction peut retourner une structure complète.
Commentaires
Aucun commentaire pour le moment. Posez la première question.