Partie 5 - Structures (struct) - Applications pratiques

@joekakone

Joseph Konka @joekakone

03/03/2026 · 10 min

Mettez en pratique vos compétences sur les structures en C : gestionnaire académique d'étudiants, géométrie 2D (cercles et points) et tri de structures par mérite.

Les structures permettent de regrouper des attributs hétérogènes pour bâtir des modèles de données complets. Cette section met en pratique les concepts de la Partie 5 à travers trois applications d'ingénierie logicielle : le système de gestion des dossiers étudiants, un module de géométrie 2D et le tri d'un tableau d'entités par classement de mérite.


Problème 1 : Gestionnaire de dossiers académiques#

Énoncé#

Dans le cadre de notre projet fil conducteur, concevez une application modulaire pour gérer la promotion d'étudiants : 1. Définissez un type Etudiant comportant : - Un identifiant entier (id). - Le nom et le prénom de l'étudiant. - Un tableau de 3 notes d'évaluations continues. - La moyenne générale calculée. 2. Implémentez les fonctions : - void CalculerMoyenne(Etudiant *e) : calcule et enregistre la moyenne dans le champ correspondant. - void AfficherEtudiant(const Etudiant *e) : affiche la fiche formatée. - int TrouverIndiceMajor(const Etudiant promo[], int taille) : renvoie l'indice de l'étudiant ayant la plus haute moyenne.

Solution complète en C#

gestion_etudiants.c
#include <stdio.h>
#include <string.h>

#define NB_EVALS 3
#define PROMO_SIZE 3

typedef struct
{
    int id;
    char nom[30];
    char prenom[30];
    float notes[NB_EVALS];
    float moyenne;
} Etudiant;

/* Calcule la moyenne des 3 notes et met à jour la structure */
void CalculerMoyenne(Etudiant *e)
{
    float somme = 0.0f;
    for (int i = 0; i < NB_EVALS; i++)
    {
        somme += e->notes[i];
    }
    e->moyenne = somme / (float)NB_EVALS;
}

/* Affiche une ligne récapitulative formatée */
void AfficherEtudiant(const Etudiant *e)
{
    printf("#%04d | %-12s %-12s | Notes: [ ", e->id, e->nom, e->prenom);
    for (int i = 0; i < NB_EVALS; i++)
    {
        printf("%.2f ", e->notes[i]);
    }
    printf("] | Moyenne: %5.2f/20\n", e->moyenne);
}

/* Renvoie l'indice de l'étudiant ayant la plus forte moyenne */
int TrouverIndiceMajor(const Etudiant promo[], int taille)
{
    int indiceMajor = 0;
    for (int i = 1; i < taille; i++)
    {
        if (promo[i].moyenne > promo[indiceMajor].moyenne)
        {
            indiceMajor = i;
        }
    }
    return indiceMajor;
}

int main(void)
{
    Etudiant promotion[PROMO_SIZE] = {
        {1001, "Konka", "Joseph", {16.0f, 18.5f, 17.0f}, 0.0f},
        {1002, "Traore", "Aminata", {14.0f, 15.0f, 16.5f}, 0.0f},
        {1003, "Dubois", "Lucas", {11.0f, 13.0f, 12.0f}, 0.0f}
    };

    printf("=========================================================================\n");
    printf("                   GESTION DES DOSSIERS ETUDIANTS                        \n");
    printf("=========================================================================\n");

    // Calcul des moyennes pour tous les étudiants
    for (int i = 0; i < PROMO_SIZE; i++)
    {
        CalculerMoyenne(&promotion[i]);
        AfficherEtudiant(&promotion[i]);
    }

    int idxMajor = TrouverIndiceMajor(promotion, PROMO_SIZE);
    printf("-------------------------------------------------------------------------\n");
    printf("MAJOR DE PROMOTION : %s %s avec %.2f/20 !\n",
           promotion[idxMajor].prenom, promotion[idxMajor].nom, promotion[idxMajor].moyenne);
    printf("=========================================================================\n");

    return 0;
}

Problème 2 : Géométrie 2D avec structures imbriquées#

Énoncé#

  1. Définissez une structure Point2D avec coordonnées \(x\) et \(y\) réelles.
  2. Définissez une structure Cercle comprenant un point centre (structure imbriquée) et un réel rayon.
  3. Écrivez les fonctions :
  4. double CalculerDistance(Point2D p1, Point2D p2) : calcule la distance euclidienne \(\sqrt{(x_2-x_1)^2 + (y_2-y_1)^2}\).
  5. bool EstDansCercle(Point2D p, Cercle c) : vérifie si le point \(p\) se trouve à l'intérieur du disque du cercle \(c\) (\(\text{distance}(p, \text{centre}) \le \text{rayon}\)).

Solution complète en C#

geometrie_struct.c
#include <stdio.h>
#include <stdbool.h>
#include <math.h>

typedef struct
{
    double x;
    double y;
} Point2D;

typedef struct
{
    Point2D centre; // Structure imbriquée
    double rayon;
} Cercle;

double CalculerDistance(Point2D p1, Point2D p2)
{
    double dx = p2.x - p1.x;
    double dy = p2.y - p1.y;
    return sqrt(dx * dx + dy * dy);
}

bool EstDansCercle(Point2D p, Cercle c)
{
    double d = CalculerDistance(p, c.centre);
    return (d <= c.rayon);
}

int main(void)
{
    Cercle radar = { {0.0, 0.0}, 10.0 }; // Centre en (0,0), rayon = 10
    Point2D cible1 = {3.0, 4.0};        // Distance = sqrt(9 + 16) = 5 <= 10
    Point2D cible2 = {8.0, 8.0};        // Distance = sqrt(64 + 64) = 11.31 > 10

    printf("Radar : Centre (%.1f, %.1f) | Portee : %.1f km\n", 
           radar.centre.x, radar.centre.y, radar.rayon);

    printf("Cible 1 (%.1f, %.1f) dans la zone ? %s\n", 
           cible1.x, cible1.y, EstDansCercle(cible1, radar) ? "OUI (Detectee)" : "NON");
    printf("Cible 2 (%.1f, %.1f) dans la zone ? %s\n", 
           cible2.x, cible2.y, EstDansCercle(cible2, radar) ? "OUI (Detectee)" : "NON (Hors portee)");

    return 0;
}

Problème 3 : Tri d'un tableau d'entités par classement de mérite#

Énoncé#

Implémentez un algorithme qui prend un tableau d'étudiants et les trie par ordre décroissant de leur moyenne générale (du premier au dernier), en déplaçant les structures entières.

Solution complète en C#

tri_structures.c
#include <stdio.h>

typedef struct
{
    int id;
    char nom[20];
    float moyenne;
} Candidat;

void TrierParMerite(Candidat promo[], int taille)
{
    for (int i = 0; i < taille - 1; i++)
    {
        for (int j = 0; j < taille - 1 - i; j++)
        {
            // Tri décroissant (> pour les meilleures notes en premier)
            if (promo[j].moyenne < promo[j + 1].moyenne)
            {
                // Échange direct des deux structures complètes !
                Candidat temporaire = promo[j];
                promo[j] = promo[j + 1];
                promo[j + 1] = temporaire;
            }
        }
    }
}

int main(void)
{
    Candidat liste[] = {
        {101, "Thomas", 13.5f},
        {102, "Sarah",  18.0f},
        {103, "Karim",  16.25f},
        {104, "Chloe",  11.0f}
    };
    int n = sizeof(liste) / sizeof(liste[0]);

    printf("--- CLASSEMENT AVANT TRI ---\n");
    for (int i = 0; i < n; i++) printf("%s : %.2f\n", liste[i].nom, liste[i].moyenne);

    TrierParMerite(liste, n);

    printf("\n--- PALMARES PAR ORDRE DE MERITE ---\n");
    for (int i = 0; i < n; i++)
    {
        printf("Rang %d : %-10s avec %5.2f/20\n", i + 1, liste[i].nom, liste[i].moyenne);
    }

    return 0;
}

Vous maîtrisez la structuration de données complexes. Dans la Partie 6, nous allons approfondir la manipulation textuelle avec les chaînes de caractères et la bibliothèque <string.h>.

Commentaires

Inscrivez-vous à une formation complète

Voir le catalogue