Exercice sur Langage de programmation c :

Chapitre 15 – Langage C | NSI
15.1 Premier programme en C — Hello World C

Nous allons écrire quelques programmes en langage C. Afin de faciliter cette première approche, nous n'allons pas directement manipuler un compilateur : nous utiliserons un service en ligne qui s'occupe de la compilation puis de l'exécution du code machine.

Outil recommandé : Online C Compiler — OnlineGDB — collez votre code, cliquez sur Run, le résultat s'affiche immédiatement.

Testez le programme C suivant :

main.c
#include <stdio.h>

int main(void) {
    printf("Hello C\n");
    return 0;
}
Correction & explications

#include <stdio.h> — importe la bibliothèque standard d'entrées/sorties (équivalent Python de import).

int main(void) — point d'entrée obligatoire de tout programme C. Il renvoie un entier (int) à l'OS.

printf("Hello C\n") — affiche du texte. Le \n correspond à un saut de ligne (comme print() en Python).

return 0; — indique que le programme s'est terminé sans erreur (convention Unix : 0 = succès).

Après compilation et exécution, la console affiche : Hello C

15.2 Fonction estMajeur C

Écrivez en C une fonction estMajeur qui prend en paramètre un age et qui renvoie 1 si l'âge est supérieur ou égal à 18, et 0 dans le cas contraire.

Rappel : En C, il n'existe pas de type booléen natif (avant C99). On retourne conventionnellement 1 pour vrai et 0 pour faux.
Correction
estMajeur.c
#include <stdio.h>

int estMajeur(int age) {
    if (age >= 18) {
        return 1;
    } else {
        return 0;
    }
}

/* Version condensée avec opérateur ternaire */
int estMajeur2(int age) {
    return (age >= 18) ? 1 : 0;
}

int main(void) {
    printf("%d\n", estMajeur(20)); // affiche 1
    printf("%d\n", estMajeur(15)); // affiche 0
    return 0;
}

Le format %d dans printf indique qu'on affiche un entier (integer en anglais).

15.3 Fonction facture — calcul avec remise C

Vous êtes gérant d'un magasin et vous souhaitez écrire un programme C qui calcule automatiquement le montant de la facture des clients.

Tout client qui achète au moins 5 fois le même article se voit octroyer une remise de 5 % (uniquement sur le montant de cet article). On considère qu'un client n'achète qu'un seul type d'article.

Écrivez une fonction facture qui prend en paramètre le prix unitaire et le nombre d'articles achetés, et renvoie le montant total de la facture.

Astuce : Le type float (ou double) est adapté pour manipuler des prix en C. Utilisez %f ou %.2f pour l'affichage.
Correction
facture.c
#include <stdio.h>

double facture(double prixUnitaire, int nbArticles) {
    double montant = prixUnitaire * nbArticles;
    if (nbArticles >= 5) {
        montant = montant * 0.95; // remise de 5 %
    }
    return montant;
}

int main(void) {
    printf("Facture (3 x 10€) : %.2f €\n", facture(10.0, 3));
    // → 30.00 € (pas de remise)

    printf("Facture (5 x 10€) : %.2f €\n", facture(10.0, 5));
    // → 47.50 € (remise 5 %)

    printf("Facture (8 x 7.5€) : %.2f €\n", facture(7.5, 8));
    // → 57.00 € (remise 5 %)

    return 0;
}

%.2f affiche un double avec exactement 2 décimales — idéal pour un montant en euros.

La remise est appliquée en multipliant le total par 0.95 (= enlever 5 %).

15.4 Tests unitaires — fonction distance Python

La fonction distance ci-dessous prend en paramètre 2 points (représentés par des tuples) et renvoie la distance euclidienne entre ces deux points :

distance.py
from math import sqrt

def distance(point1, point2):
    return sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)

Proposez une série de tests unitaires pour la fonction distance en utilisant des assertions (assert).

Rappel : Une assertion s'écrit assert condition, "message d'erreur". Si la condition est fausse, Python lève une AssertionError. Pour comparer des flottants, pensez à utiliser abs(a - b) < 1e-9 plutôt que a == b.
Correction
test_distance.py
from math import sqrt

def distance(point1, point2):
    return sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)

# ── Tests unitaires ──────────────────────────────────

# Cas 1 : deux points identiques → distance = 0
assert distance((0, 0), (0, 0)) == 0, "distance nulle attendue"

# Cas 2 : triangle rectangle 3-4-5 (théorème de Pythagore)
assert distance((0, 0), (3, 4)) == 5.0, "hypoténuse 5 attendue"

# Cas 3 : déplacement horizontal uniquement
assert distance((0, 0), (7, 0)) == 7.0, "déplacement horizontal"

# Cas 4 : déplacement vertical uniquement
assert distance((0, 0), (0, 5)) == 5.0, "déplacement vertical"

# Cas 5 : symétrie (distance(A,B) == distance(B,A))
assert distance((1, 2), (4, 6)) == distance((4, 6), (1, 2)), "symétrie"

# Cas 6 : coordonnées négatives
assert abs(distance((-1, -1), (2, 3)) - 5.0) < 1e-9, "coordonnées négatives"

# Cas 7 : résultat flottant (diagonale du carré unité = √2)
assert abs(distance((0, 0), (1, 1)) - sqrt(2)) < 1e-9, "diagonale unité"

print("✅ Tous les tests sont passés !")

Pourquoi abs(...) < 1e-9 ? Les flottants sont représentés de façon approximative en mémoire. Comparer directement avec == peut échouer à cause d'infimes erreurs d'arrondi. On préfère vérifier que la différence est inférieure à un seuil très petit (ici 10⁻⁹).

Les cas 3, 4 et le triangle 3-4-5 donnent des entiers exacts, donc == est acceptable pour eux.