Partie 1 - Applications pratiques et Problèmes résolus

@joekakone

Joseph Konka @joekakone

03/03/2026 · 10 min

Consolidez vos bases en C avec trois projets d'application corrigés : distributeur de billets (DAB), calculateur statistique de notes et testeur de nombres premiers.

Félicitations pour avoir parcouru les bases fondamentales du langage C ! Vous maîtrisez désormais l'affichage avec printf, la saisie au clavier avec scanf, les variables typées, les calculs arithmétiques et les boucles itératives.

Pour ancrer durablement ces mécanismes, cette section vous propose trois problèmes d'application concrets et progressifs, intégralement rédigés, commentés et conformes aux meilleures pratiques ANSI C.


Problème 1 : Simulateur de Distributeur Automatique de Billets (DAB)#

Énoncé#

Dans une banque, un distributeur automatique doit délivrer une somme demandée par un client en minimisant le nombre total de billets remis (algorithme glouton). Le distributeur ne dispose que de coupures de 50 €, 20 € et 10 €.

Votre programme doit : 1. Demander à l'utilisateur de saisir le montant souhaité en euros. 2. Vérifier que la somme est un multiple de 10 € strictement positif. 3. Calculer et afficher le nombre optimal de billets de 50 €, 20 € et 10 € à distribuer en exploitant la division entière et l'opérateur modulo %.

flowchart TD
    Saisie[Montant Total Saisi] --> Calc50["Billets de 50 € = Montant / 50\nReste = Montant % 50"]
    Calc50 --> Calc20["Billets de 20 € = Reste / 20\nReste = Reste % 20"]
    Calc20 --> Calc10["Billets de 10 € = Reste / 10\nReste = 0"]
    Calc10 --> Affichage[Affichage du décompte des coupures]

Solution complète en C#

dab.c
#include <stdio.h>

int main(void)
{
    int montant = 0;

    printf("=========================================\n");
    printf("     DISTRIBUTEUR AUTOMATIQUE DE BILLETS \n");
    printf("=========================================\n\n");

    // 1. Validation de la somme saisie
    do
    {
        printf("Entrez le montant a retirer (multiple de 10 €) : ");
        if (scanf("%d", &montant) != 1)
        {
            printf("Erreur : Saisie non numerique.\n");
            return 1;
        }

        if (montant <= 0 || montant % 10 != 0)
        {
            printf("Montant invalide ! Le montant doit etre positif et se terminer par 0.\n");
        }
    } while (montant <= 0 || montant % 10 != 0);

    // 2. Décomposition gloutonne par coupures
    int reste = montant;

    int billets50 = reste / 50;
    reste = reste % 50;

    int billets20 = reste / 20;
    reste = reste % 20;

    int billets10 = reste / 10;
    reste = reste % 10;

    // 3. Affichage du résultat détaillé
    printf("\n--- RECAPITULATIF DE LA TRANSACTION ---\n");
    printf("Montant total retire : %d €\n", montant);
    printf("Billets de 50 €       : %d\n", billets50);
    printf("Billets de 20 €       : %d\n", billets20);
    printf("Billets de 10 €       : %d\n", billets10);
    printf("Total de billets     : %d\n", billets50 + billets20 + billets10);
    printf("-----------------------------------------\n");

    return 0;
}

Problème 2 : Calculateur statistique de notes d'une promotion#

Énoncé#

Dans le cadre de notre projet fil conducteur de gestion académique, écrivez un programme permettant à un enseignant de saisir les notes d'une classe d'étudiants.

Le programme doit : 1. Demander le nombre total d'étudiants \(N\) (\(N \ge 1\)). 2. Lire successivement les \(N\) notes en s'assurant que chaque note est bien comprise entre \(0.0\) et \(20.0\). 3. Déterminer en un seul passage : - La moyenne générale de la promotion. - La note la plus basse (minimum) et la note la plus haute (maximum). - Le nombre d'étudiants admis (note \(\ge 10.0\)).

Solution complète en C#

statistiques_notes.c
#include <stdio.h>

int main(void)
{
    int nb_etudiants = 0;

    printf("=========================================\n");
    printf("   GESTION DES NOTES DE LA PROMOTION     \n");
    printf("=========================================\n\n");

    // 1. Contrôle du nombre d'étudiants
    do
    {
        printf("Nombre d'etudiants dans la classe : ");
        scanf("%d", &nb_etudiants);
        if (nb_etudiants <= 0)
        {
            printf("Veuillez saisir un effectif superieur a 0.\n");
        }
    } while (nb_etudiants <= 0);

    float somme = 0.0f;
    float note_min = 20.0f; // Initialisée au maximum possible
    float note_max = 0.0f;  // Initialisée au minimum possible
    int nb_admis = 0;

    // 2. Boucle de saisie des notes individuelles
    for (int i = 1; i <= nb_etudiants; i++)
    {
        float note_courante = -1.0f;

        do
        {
            printf("Note de l'etudiant n°%d / %d (0 a 20) : ", i, nb_etudiants);
            scanf("%f", &note_courante);
            if (note_courante < 0.0f || note_courante > 20.0f)
            {
                printf("Erreur : La note doit etre comprise entre 0 et 20.\n");
            }
        } while (note_courante < 0.0f || note_courante > 20.0f);

        // Cumul pour la moyenne
        somme += note_courante;

        // Mise à jour des extrema
        if (note_courante < note_min)
        {
            note_min = note_courante;
        }
        if (note_courante > note_max)
        {
            note_max = note_courante;
        }

        // Décompte des admissions
        if (note_courante >= 10.0f)
        {
            nb_admis++;
        }
    }

    // 3. Calculs finaux et affichage
    float moyenne = somme / (float)nb_etudiants;
    float taux_reussite = ((float)nb_admis / (float)nb_etudiants) * 100.0f;

    printf("\n=========================================\n");
    printf("         RESULTATS DE LA PROMOTION       \n");
    printf("=========================================\n");
    printf("Effectif total       : %d etudiants\n", nb_etudiants);
    printf("Moyenne de la classe : %.2f / 20\n", moyenne);
    printf("Note minimale        : %.2f / 20\n", note_min);
    printf("Note maximale        : %.2f / 20\n", note_max);
    printf("Etudiants admis      : %d (%.1f %%)\n", nb_admis, taux_reussite);
    printf("=========================================\n");

    return 0;
}

Problème 3 : Détecteur et Générateur de Nombres Premiers#

Énoncé#

Un nombre entier \(N > 1\) est dit premier s'il ne possède que deux diviseurs distincts : 1 et lui-même (ex: 2, 3, 5, 7, 11, 13...).

Écrivez un programme qui : 1. Demande un nombre entier \(N \ge 2\). 2. Teste si ce nombre est premier en recherchant un éventuel diviseur \(d\) tel que \(2 \le d \le \sqrt{N}\). 3. Affiche la liste de tous les nombres premiers compris entre 2 et \(N\).

Solution complète en C#

nombres_premiers.c
#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int limite = 0;

    printf("Entrez un nombre limite N (>= 2) : ");
    if (scanf("%d", &limite) != 1 || limite < 2)
    {
        printf("Erreur : Valeur non valide.\n");
        return 1;
    }

    printf("\nNombres premiers compris entre 2 et %d :\n", limite);
    int total_premiers = 0;

    for (int n = 2; n <= limite; n++)
    {
        bool est_premier = true;

        // Optimisation : tester jusqu'à d * d <= n (équivaut à d <= racine de n)
        for (int d = 2; d * d <= n; d++)
        {
            if (n % d == 0)
            {
                est_premier = false;
                break; // Dès qu'un diviseur est trouvé, on arrête
            }
        }

        if (est_premier)
        {
            printf("%d ", n);
            total_premiers++;
        }
    }

    printf("\n\nTotal trouve : %d nombres premiers.\n", total_premiers);
    return 0;
}

Auto-évaluation : Checklist de fin de Partie 1#

Avant de passer à la Partie 2, assurez-vous de maîtriser les points suivants :

  • Je sais afficher du texte et des nombres formatés avec printf et ses spécificateurs (%d, %.2f, %c, %s).
  • Je n'oublie jamais le symbole & devant une variable scalaire lors d'un appel à scanf.
  • Je comprends la différence entre division entière (5 / 2 = 2) et division réelle (5.0 / 2 = 2.5).
  • Je sais choisir entre for (nombre d'itérations connu), while (condition dynamique) et do ... while (contrôle de saisie).
  • Je sais prémunir mes boucles contre les boucles infinies.

Félicitations pour cette première étape ! Dans la Partie 2, nous allons structurer notre code en sous-programmes modulaires grâce aux fonctions et à la récursivité.

Commentaires

Inscrivez-vous à une formation complète

Voir le catalogue