Les types de données scalaires (int, float, char) sont parfaits pour stocker des grandeurs isolées, mais ils deviennent inadaptés pour modéliser des entités du monde réel. Comment représenter fidèlement un étudiant (ayant un matricule, un nom, un prénom, une date de naissance et une moyenne) ou un point dans l'espace (coordonnées \(x, y, z\)) ?
Le langage C permet au développeur de créer ses propres types de données composés grâce au mot-clé struct (structure). C'est l'ancêtre direct des classes de la programmation orientée objet !
1. Définition et Déclaration d'une Structure#
Une structure est un regroupement de plusieurs variables (appelées champs ou membres), qui peuvent être de types complètement différents, sous une entité sémantique unique :
struct Etudiant
{
int matricule; // Entier
char nom[30]; // Tableau de caractères
char prenom[30]; // Tableau de caractères
float moyenne; // Flottant
};
Simplifier la syntaxe avec typedef#
Pour éviter de devoir répéter le mot struct à chaque déclaration de variable (struct Etudiant e1;), on associe la structure au mot-clé typedef (type definition) :
typedef struct
{
int matricule;
char nom[30];
char prenom[30];
float moyenne;
} Etudiant;
// On peut désormais déclarer directement :
// Etudiant e1;
2. Accéder aux champs : L'opérateur point (.)#
Pour lire ou modifier un champ d'une structure directe, on utilise l'opérateur point . :
#include <stdio.h>
#include <string.h>
typedef struct
{
int id;
char nom[20];
float note;
} Stagiaire;
int main(void)
{
// 1. Déclaration et initialisation par liste
Stagiaire s1 = {101, "Konka", 18.5f};
// 2. Accès en lecture
printf("ID : #%d\n", s1.id);
printf("Nom : %s\n", s1.nom);
printf("Note : %.2f/20\n", s1.note);
// 3. Modification d'un champ
s1.note = 19.0f;
printf("Nouvelle note : %.2f/20\n", s1.note);
return 0;
}
3. Pointeurs vers structures et opérateur flèche (->)#
Lorsqu'on manipule un pointeur vers une structure, la syntaxe pour accéder à un membre serait (*ptr).moyenne. Pour rendre le code beaucoup plus lisible, le C introduit l'opérateur flèche -> :
#include <stdio.h>
typedef struct
{
float x;
float y;
} Point2D;
void DeplacerPoint(Point2D *p, float dx, float dy)
{
// Utilisation de l'opérateur flèche -> pour modifier la structure pointée
p->x += dx;
p->y += dy;
}
int main(void)
{
Point2D pt = {2.0f, 3.5f};
printf("Point initial : (%.1f, %.1f)\n", pt.x, pt.y);
DeplacerPoint(&pt, 5.0f, -1.0f);
printf("Point deplace : (%.1f, %.1f)\n", pt.x, pt.y);
return 0;
}
[!TIP] Passer une structure par pointeur (
const Etudiant *e) à une fonction est infiniment plus rapide que de la passer par valeur : au lieu de dupliquer en mémoire l'intégralité des dizaines d'octets de la structure, seul un pointeur léger de 8 octets est transmis sur la pile d'exécution !
4. Tableaux de Structures#
On peut créer des tableaux entiers dont chaque case est une structure complète :
#include <stdio.h>
#define PROMOTION_SIZE 3
typedef struct
{
int id;
char prenom[20];
float moyenne;
} Etudiant;
int main(void)
{
// Tableau de 3 structures Etudiant
Etudiant promo[PROMOTION_SIZE] = {
{101, "Alice", 16.5f},
{102, "Bob", 14.0f},
{103, "Clara", 18.25f}
};
printf("--- RELEVE DE LA PROMOTION ---\n");
for (int i = 0; i < PROMOTION_SIZE; i++)
{
printf("Matricule #%d | %-10s | Moyenne : %5.2f/20\n",
promo[i].id, promo[i].prenom, promo[i].moyenne);
}
return 0;
}
5. Structures imbriquées (Nested Structs)#
Une structure peut contenir une autre structure comme membre, permettant de modéliser des hiérarchies complexes :
typedef struct
{
int jour;
int mois;
int annee;
} Date;
typedef struct
{
char nom[30];
Date naissance; // Structure imbriquée
float salaire;
} Employe;
// Accès chaîné avec le point :
// employe.naissance.annee = 1995;
Vous maîtrisez désormais la composition de données personnalisées avec les structures. Rendez-vous dans la leçon suivante pour appliquer ces concepts au système de gestion académique complet.
Commentaires