Chapitre 15 — Découverte du Langage C
Compilation, fonctions, tests unitaires : une première approche pratique du C comparée à Python.
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.
Testez le programme C suivant :
#include <stdio.h>
int main(void) {
printf("Hello C\n");
return 0;
}
#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
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.
1 pour vrai et 0 pour faux.
#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).
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.
float (ou double) est adapté pour manipuler des prix en C. Utilisez %f ou %.2f pour l'affichage.
#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 %).
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 :
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).
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.
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.
