Chapitre 11 — Fonctions et procédures
Décomposer un problème et construire des solutions réutilisables
Fiche pédagogique du chapitre
Objectifs d’apprentissage
À la fin de ce chapitre, l’étudiant devra être capable de :
- expliquer le principe de la modularité et son intérêt dans la résolution de problèmes ;
- décomposer un algorithme complexe en sous-programmes cohérents ;
- déclarer et appeler une procédure avec ou sans paramètres ;
- déclarer une fonction et utiliser sa valeur de retour dans une expression ;
- distinguer une procédure d’une fonction ;
- identifier les paramètres formels et les paramètres effectifs ;
- expliquer le passage par valeur et le passage par référence ;
- utiliser des paramètres d’entrée, de sortie et d’entrée-sortie ;
- distinguer une variable locale d’une variable globale ;
- raisonner sur la portée et la durée de vie des variables ;
- tester indépendamment un sous-programme ;
- concevoir un programme modulaire de gestion des notes.
Prérequis
- maîtriser les variables, constantes et types de données ;
- savoir utiliser les structures conditionnelles et répétitives ;
- savoir manipuler les tableaux à une dimension ;
- savoir écrire et tracer un algorithme complet ;
- connaître les principes de test et de validation.
Plan du chapitre
11.1 Principe de la modularité
11.2 Procédures
11.3 Fonctions
11.4 Paramètres
11.5 Portée des variables
Applications, travaux dirigés, corrigés et synthèse
Organisation pédagogique indicative
Activité | Durée indicative | Objectif principal |
|---|---|---|
| Cours | 3 h | Comprendre la modularité, les sous-programmes et la portée. |
| Travaux dirigés | 3 h | Décomposer des problèmes et tracer les appels. |
| Travaux pratiques | 3 h | Implémenter fonctions et procédures dans un langage. |
| Travail personnel | 2 h | Résoudre des exercices de conception modulaire. |
| Idée centrale : un sous-programme reçoit éventuellement des données, réalise une tâche précise et fournit un résultat ou un effet attendu. Il doit avoir une responsabilité claire et pouvoir être testé séparément. |
Introduction à la modularité
Lorsqu’un algorithme devient long, il devient difficile à comprendre, à tester et à modifier. Une méthode efficace consiste à le décomposer en plusieurs sous-programmes. Chaque sous-programme réalise une tâche limitée : lire une valeur, calculer une moyenne, rechercher un maximum, afficher un tableau ou vérifier une condition.
Cette organisation est appelée modularité. Elle permet de construire progressivement une solution à partir de blocs simples. Les fonctions et les procédures constituent les principaux outils de cette décomposition en algorithmique structurée.
Un programme modulaire ne doit pas être une simple découpe arbitraire. Les modules doivent correspondre à des responsabilités cohérentes, posséder des interfaces explicites et limiter leurs dépendances avec le reste du programme.
| Vocabulaire : les termes sous-programme, module, routine et sous-routine peuvent désigner une unité de traitement. Dans ce chapitre, nous utiliserons surtout fonction et procédure. |
11.1 Principe de la modularité
11.1.1 Décomposition d’un problème complexe
Décomposer un problème consiste à identifier des sous-problèmes plus simples, puis à définir un sous-programme pour chacun d’eux. Le programme principal organise les appels et coordonne les résultats.
Par exemple, un programme de gestion des notes peut être décomposé en cinq tâches : saisir les notes, vérifier leur validité, calculer la moyenne, déterminer la meilleure note et afficher un bilan.
Problème global | Sous-problèmes possibles | Sous-programmes |
|---|---|---|
| Gestion des notes | Saisir, valider, calculer, rechercher, afficher | SaisirNotes, NoteValide, Moyenne, Maximum, AfficherBilan |
| Gestion d’un stock | Lire les produits, chercher, mettre à jour, afficher | LireStock, ChercherProduit, ModifierQuantite, AfficherStock |
| Analyse d’un texte | Nettoyer, compter, rechercher, vérifier | Nettoyer, CompterMots, Rechercher, EstPalindrome |
| Méthode : pour chaque sous-problème, poser la question : quelles données faut-il fournir, quel résultat faut-il obtenir et quels effets sont autorisés ? |
11.1.2 Réutilisation du code
Un traitement écrit une seule fois peut être appelé plusieurs fois avec des données différentes. Cette réutilisation évite la duplication du code et réduit le risque d’obtenir plusieurs versions incohérentes d’un même calcul.
Exemple de réutilisation d’une fonction
| Fonction Carre(x : Réel) : Réel Début Retourner x * x FinFonction aireDisque <- PI * Carre(rayon) distance2 <- Carre(dx) + Carre(dy) |
Dans cet exemple, la fonction Carre est définie une seule fois. Elle peut être utilisée dans plusieurs calculs sans réécrire l’expression x × x.
11.1.3 Lisibilité
Des noms de sous-programmes explicites rendent le programme principal proche d’une description du problème. Le lecteur peut comprendre l’enchaînement général sans connaître immédiatement tous les détails de calcul.
Version peu lisible | Version modulaire |
|---|---|
| Une longue suite de lectures, boucles et tests | SaisirNotes(notes, n) |
| Calcul intégré au milieu du programme | moyenne <- CalculerMoyenne(notes, n) |
| Recherche répétée du maximum | maxi <- MaximumTableau(notes, n) |
| Affichages dispersés | AfficherBilan(moyenne, maxi) |
11.1.4 Maintenance
La maintenance regroupe les corrections, améliorations et adaptations effectuées après la première version. Si chaque traitement est isolé dans un module, une modification locale influence moins le reste du programme.
- Correction : une erreur dans le calcul de la moyenne est corrigée dans une seule fonction.
- Évolution : une nouvelle règle d’admission peut être ajoutée dans une fonction dédiée.
- Adaptation : l’affichage peut changer sans modifier les calculs.
- Remplacement : un algorithme lent peut être remplacé en conservant la même interface.
11.1.5 Test indépendant
Chaque sous-programme doit pouvoir être testé avec des jeux d’essai spécifiques. Tester indépendamment réduit la difficulté du diagnostic : lorsqu’une fonction Maximum est correcte, on peut se concentrer sur les autres modules.
Sous-programme | Jeu d’essai | Résultat attendu |
|---|---|---|
| Maximum(4, 9) | a = 4, b = 9 | 9 |
| EstPremier(2) | n = 2 | Vrai |
| EstPremier(15) | n = 15 | Faux |
| Moyenne([10, 14, 16], 3) | tableau de trois notes | 13,33 environ |
| Bonne pratique : un sous-programme doit être court, avoir une responsabilité principale et posséder un nom décrivant clairement son action. |
11.1.6 Cohésion et dépendances
La cohésion mesure à quel point les instructions d’un module participent à une même tâche. Un module cohérent ne mélange pas la saisie, le calcul et l’affichage sans nécessité. Les dépendances doivent également être limitées : les données utiles sont transmises par paramètres plutôt que lues directement dans des variables globales.
Critère | Situation souhaitable | Situation à éviter |
|---|---|---|
| Responsabilité | Une tâche clairement définie | Plusieurs tâches sans lien direct |
| Interface | Peu de paramètres, bien nommés | Nombreux paramètres ambigus |
| Dépendances | Données reçues explicitement | Usage caché de variables globales |
| Effets | Effets annoncés et limités | Modifications imprévues de données |
11.2 Procédures
11.2.1 Définition
Une procédure est un sous-programme qui réalise une action. Elle peut recevoir des paramètres et modifier certaines données, mais elle ne fournit pas directement une valeur utilisable dans une expression.
Une procédure est adaptée à des actions comme afficher un message, remplir un tableau, échanger deux valeurs, modifier un enregistrement ou produire plusieurs résultats par paramètres de sortie.
11.2.2 Déclaration d’une procédure
Structure générale
| Procédure NomProcedure(paramètres éventuels) Variables déclarations locales Début instructions FinProcédure |
La déclaration indique le nom de la procédure, ses paramètres éventuels, ses variables locales et les instructions exécutées lors de chaque appel.
11.2.3 Appel d’une procédure
Appeler une procédure signifie demander l’exécution de ses instructions. Une fois la procédure terminée, l’exécution reprend à l’instruction située immédiatement après l’appel.
Procédure sans paramètre et appels
| Procédure AfficherLigne() Début Écrire("--------------------") FinProcédure Algorithme Principal Début AfficherLigne() Écrire("Résultats") AfficherLigne() Fin |
Étape | Instruction exécutée | Effet |
|---|---|---|
| 1 | Premier appel à AfficherLigne | Affiche une ligne. |
| 2 | Écrire("Résultats") | Affiche le titre. |
| 3 | Deuxième appel à AfficherLigne | Affiche une seconde ligne. |
11.2.4 Procédure avec paramètres
Les paramètres rendent une procédure adaptable. Une même procédure peut produire des résultats différents selon les valeurs transmises lors de l’appel.
Exemple avec deux paramètres d’entrée
| Procédure AfficherMessage(message : Chaîne, repetitions : Entier) Variables i : Entier Début Pour i allant de 1 à repetitions Faire Écrire(message) FinPour FinProcédure AfficherMessage("Bienvenue", 3) |
11.2.5 Procédures avec ou sans paramètres
Forme | Exemple | Usage |
|---|---|---|
| Sans paramètre | AfficherMenu() | Action toujours identique ou dépendant de données internes contrôlées. |
| Avec entrée | AfficherTableau(T, n) | Action adaptée aux données reçues. |
| Avec sortie | LireValeurs(a, b) | Produit des résultats transmis au programme appelant. |
| Avec entrée-sortie | Echanger(a, b) | Modifie des données existantes. |
11.2.6 Exemple : échange de deux variables
Une procédure d’échange modifie deux variables du programme appelant. Elle utilise donc des paramètres d’entrée-sortie transmis par référence.
Procédure d’échange
| Procédure Echanger(EntréeSortie a : Réel, EntréeSortie b : Réel) Variables temporaire : Réel Début temporaire <- a a <- b b <- temporaire FinProcédure |
Avant l’appel | Appel | Après l’appel |
|---|---|---|
| x = 4, y = 9 | Echanger(x, y) | x = 9, y = 4 |
| Attention : si a et b étaient transmis uniquement par valeur, l’échange serait effectué sur des copies locales et x et y resteraient inchangés. |
11.3 Fonctions
11.3.1 Définition
Une fonction est un sous-programme qui calcule et retourne une valeur. Elle reçoit éventuellement des paramètres et possède un type de retour. La valeur produite peut être affectée à une variable, comparée, affichée ou intégrée dans une expression.
11.3.2 Déclaration d’une fonction
Structure générale
| Fonction NomFonction(paramètres éventuels) : TypeRetour Variables déclarations locales Début instructions Retourner valeur FinFonction |
L’instruction Retourner termine la fonction et transmet une valeur au programme appelant. La valeur retournée doit être compatible avec le type annoncé.
11.3.3 Valeur de retour et type retourné
Fonction | Type retourné | Exemple de résultat |
|---|---|---|
| Maximum(a, b) | Réel | 12,5 |
| EstPair(n) | Booléen | Vrai ou Faux |
| PremiereLettre(nom) | Caractère | 'A' |
| NomComplet(prenom, nom) | Chaîne | "Sara Amrani" |
| NombreVoyelles(texte) | Entier | 6 |
| Règle : une fonction doit retourner une valeur dans tous les chemins d’exécution possibles. Les conditions doivent être organisées de manière à éviter un chemin sans Retourner. |
11.3.4 Appel d’une fonction dans une expression
Exemples d’appels
| m <- Maximum(a, b) Écrire(Maximum(x, y)) Si EstPremier(n) Alors Écrire(n, " est premier") FinSi resultat <- 2 * Carre(x) + Carre(y) |
L’appel est remplacé conceptuellement par la valeur retournée. Avant d’évaluer l’expression complète, le système exécute la fonction et récupère son résultat.
11.3.5 Fonction ou procédure ?
Critère | Fonction | Procédure |
|---|---|---|
| But principal | Calculer une valeur | Réaliser une action |
| Résultat direct | Une valeur retournée | Aucune valeur directe |
| Utilisation dans une expression | Oui | Non |
| Effets sur les paramètres | À limiter en général | Possibles et souvent explicites |
| Exemples | Moyenne, Maximum, EstPremier | Afficher, Remplir, Echanger |
Certains langages représentent toutes les routines comme des fonctions, éventuellement sans valeur significative. En pseudo-code, la distinction reste utile pour clarifier l’intention.
11.3.6 Fonctions sans effet de bord
Une fonction sans effet de bord calcule son résultat uniquement à partir de ses paramètres et ne modifie aucune donnée externe. À paramètres identiques, elle retourne le même résultat. Ce comportement facilite les tests et le raisonnement.
Fonction recommandée | Fonction à éviter |
|---|---|
| CalculerMoyenne(T, n) retourne une valeur | CalculerMoyenne modifie une variable globale moyenne |
| EstPremier(n) retourne Vrai ou Faux | EstPremier affiche des messages et change n |
| Maximum(a, b) ne modifie pas a et b | Maximum réordonne silencieusement les arguments |
11.4 Paramètres
11.4.1 Paramètres formels et effectifs
Les paramètres formels apparaissent dans la déclaration du sous-programme. Ils décrivent les données attendues. Les paramètres effectifs, aussi appelés arguments, sont les valeurs ou variables fournies lors de l’appel.
Paramètres formels et effectifs
| Fonction Maximum(a : Réel, b : Réel) : Réel ... x <- 7 y <- 12 plusGrand <- Maximum(x, y) |
Élément | Dans l’exemple | Rôle |
|---|---|---|
| Paramètres formels | a et b | Noms locaux utilisés dans la fonction. |
| Paramètres effectifs | x et y | Données transmises lors de l’appel. |
| Valeur retournée | 12 | Résultat affecté à plusGrand. |
11.4.2 Correspondance des paramètres
La correspondance se fait généralement selon l’ordre. Le premier argument est associé au premier paramètre formel, le second au second, etc. Le nombre et les types doivent être compatibles.
Appel | Validité | Explication |
|---|---|---|
| Maximum(4, 9) | Valide | Deux nombres transmis dans le bon ordre. |
| Maximum(x) | Invalide | Un argument manque. |
| Maximum("A", 9) | Invalide | Type incompatible avec Réel. |
| AfficherMessage(3, "Bonjour") | Invalide selon la déclaration | Ordre des arguments inversé. |
11.4.3 Passage par valeur
Lors d’un passage par valeur, le sous-programme reçoit une copie de la valeur. Une modification du paramètre formel ne modifie pas la variable originale du programme appelant.
Effet du passage par valeur
| Procédure AjouterUn(Valeur x : Entier) Début x <- x + 1 FinProcédure a <- 5 AjouterUn(a) Écrire(a) // affiche 5 |
Moment | a dans le programme principal | x dans la procédure |
|---|---|---|
| Avant l’appel | 5 | Non créé |
| Pendant l’appel | 5 | Copie initialisée à 5 puis modifiée à 6 |
| Après l’appel | 5 | Détruit |
11.4.4 Passage par référence
Lors d’un passage par référence, le paramètre désigne la variable originale. Une modification effectuée dans le sous-programme est donc visible après l’appel. Ce mécanisme est utilisé pour les paramètres de sortie ou d’entrée-sortie.
Effet du passage par référence
| Procédure AjouterUn(Référence x : Entier) Début x <- x + 1 FinProcédure a <- 5 AjouterUn(a) Écrire(a) // affiche 6 | |
| Précaution : le passage par référence crée un effet sur le programme appelant. Cet effet doit être annoncé clairement par le mode du paramètre et par le nom du sous-programme. |
11.4.5 Paramètres d’entrée, de sortie et d’entrée-sortie
Mode | Valeur initiale utilisée ? | Modifié par le module ? | Exemple |
|---|---|---|---|
| Entrée | Oui | Non | CalculerMoyenne(T, n) |
| Sortie | Non nécessaire | Oui | LireCoordonnees(x, y) |
| Entrée-sortie | Oui | Oui | Echanger(a, b) |
Procédure produisant deux résultats
| Procédure DivisionEuclidienne(Entrée a : Entier, Entrée b : Entier, Sortie quotient : Entier, Sortie reste : Entier) Début quotient <- a div b reste <- a mod b FinProcédure |
11.4.6 Paramètres tableaux
Un tableau peut être transmis comme paramètre. Sa taille logique doit généralement être transmise séparément lorsque le tableau possède une capacité supérieure au nombre d’éléments utilisés.
Fonction recevant un tableau
| Fonction SommeTableau(Entrée T : Tableau de Réels, Entrée n : Entier) : Réel Variables i : Entier somme : Réel Début somme <- 0 Pour i allant de 1 à n Faire somme <- somme + T[i] FinPour Retourner somme FinFonction | |
| Convention : dans ce cours, un tableau utilisé seulement en lecture est un paramètre d’entrée. Un tableau rempli ou modifié est un paramètre de sortie ou d’entrée-sortie. |
11.4.7 Validation des paramètres
Un sous-programme doit préciser les conditions nécessaires à son fonctionnement. Ces conditions sont parfois appelées préconditions. Par exemple, une fonction de moyenne suppose n > 0, et une division suppose un diviseur non nul.
Sous-programme | Précondition | Réaction possible |
|---|---|---|
| Moyenne(T, n) | n > 0 | Refuser l’appel ou retourner une indication d’erreur. |
| Racine(x) | x ≥ 0 | Contrôler x avant le calcul. |
| Division(a, b) | b ≠ 0 | Demander un nouveau diviseur. |
| Acces(T, i) | 1 ≤ i ≤ n | Vérifier les bornes. |
11.5 Portée des variables
11.5.1 Variable locale
Une variable locale est déclarée dans un sous-programme. Elle est accessible uniquement à l’intérieur de ce sous-programme. Elle sert aux calculs intermédiaires et disparaît généralement lorsque l’appel se termine.
La variable resultat est locale
| Fonction Carre(x : Réel) : Réel Variables resultat : Réel Début resultat <- x * x Retourner resultat FinFonction |
Le programme principal ne peut pas utiliser directement resultat. Cette limitation protège les détails internes de la fonction.
11.5.2 Variable globale
Une variable globale est déclarée en dehors des sous-programmes et peut être accessible par plusieurs modules. Elle peut sembler pratique, mais elle crée des dépendances cachées : un module peut modifier une donnée utilisée ailleurs sans que l’appel l’indique.
Exemple d’accès à une variable globale
| Variables globales compteur : Entier Procédure IncrementerCompteur() Début compteur <- compteur + 1 FinProcédure |
11.5.3 Durée de vie d’une variable
Catégorie | Création | Destruction habituelle | Accessibilité |
|---|---|---|---|
| Variable locale | Au début de l’appel | À la fin de l’appel | Dans le module concerné |
| Paramètre | Au début de l’appel | À la fin de l’appel | Dans le module concerné |
| Variable globale | Au lancement du programme | À la fin du programme | Dans plusieurs modules selon les règles |
11.5.4 Masquage de noms
Si une variable locale porte le même nom qu’une variable globale, elle peut masquer la variable globale dans le sous-programme. Cette situation rend la lecture ambiguë et doit être évitée.
Exemple de masquage
| Variable globale total : Réel Fonction Exemple(x : Réel) : Réel Variables total : Réel // masque la variable globale Début total <- x + 1 Retourner total FinFonction |
11.5.5 Risques liés aux variables globales
- modification involontaire depuis plusieurs sous-programmes ;
- difficulté à savoir quelle instruction a changé la valeur ;
- tests indépendants plus complexes ;
- dépendances cachées entre les modules ;
- réutilisation limitée dans un autre programme ;
- risques supplémentaires lors d’exécutions simultanées.
Approche fragile | Approche recommandée |
|---|---|
| Une fonction lit directement le tableau global Notes | Le tableau Notes est transmis en paramètre |
| Une procédure modifie une variable globale moyenne | La moyenne est retournée par une fonction |
| Le nombre d’éléments est implicite | n est transmis explicitement |
| Plusieurs modules écrivent dans le même état | Un module contrôle chaque modification |
| Recommandation : privilégier les variables locales et les paramètres. Réserver les variables globales à des constantes ou à des états réellement partagés et contrôlés. |
Applications guidées
Application 1 — Fonction calculant le maximum
Concevoir une fonction qui retourne la plus grande de deux valeurs réelles. En cas d’égalité, la valeur commune est retournée.
Solution
| Fonction Maximum(a : Réel, b : Réel) : Réel Début Si a >= b Alors Retourner a Sinon Retourner b FinSi FinFonction |
a | b | Condition a ≥ b | Résultat |
|---|---|---|---|
| 7 | 12 | Faux | 12 |
| 9 | 3 | Vrai | 9 |
| 5 | 5 | Vrai | 5 |
| -2 | -8 | Vrai | -2 |
Pour obtenir le maximum de trois valeurs, on peut réutiliser la fonction précédente :
Réutilisation
| Fonction Maximum3(a : Réel, b : Réel, c : Réel) : Réel Début Retourner Maximum(Maximum(a, b), c) FinFonction |
Application 2 — Fonction vérifiant si un nombre est premier
Un entier n est premier s’il est supérieur ou égal à 2 et s’il possède exactement deux diviseurs positifs : 1 et lui-même. Il suffit de rechercher un diviseur entre 2 et la racine carrée de n.
Solution
| Fonction EstPremier(n : Entier) : Booléen Variables d : Entier Début Si n < 2 Alors Retourner Faux FinSi d <- 2 TantQue d * d <= n Faire Si n mod d = 0 Alors Retourner Faux FinSi d <- d + 1 FinTantQue Retourner Vrai FinFonction |
n | Diviseurs testés | Résultat | Justification |
|---|---|---|---|
| 1 | Aucun | Faux | Inférieur à 2. |
| 2 | Aucun | Vrai | Premier. |
| 15 | 3 | Faux | 15 mod 3 = 0. |
| 17 | 2, 3, 4 | Vrai | Aucun diviseur trouvé. |
| 49 | 2 à 7 | Faux | 49 mod 7 = 0. |
| Optimisation : tester jusqu’à d × d ≤ n évite d’examiner tous les nombres jusqu’à n − 1. |
Application 3 — Procédure affichant un tableau
La procédure reçoit un tableau et son nombre d’éléments. Elle affiche chaque valeur précédée de son indice.
Solution
| Procédure AfficherTableau(Entrée T : Tableau de Réels, Entrée n : Entier) Variables i : Entier Début Pour i allant de 1 à n Faire Écrire("T[", i, "] = ", T[i]) FinPour FinProcédure |
Entrée | Affichage produit |
|---|---|
| T = [12, 8, 15], n = 3 | T[1] = 12 ; T[2] = 8 ; T[3] = 15 |
| T = [4,5], n = 1 | T[1] = 4 |
Le paramètre T est un paramètre d’entrée : la procédure lit les valeurs sans les modifier.
Application 4 — Fonction calculant la moyenne d’un tableau
La fonction calcule la somme des n valeurs, puis la divise par n. La précondition n > 0 doit être respectée.
Solution
| Fonction MoyenneTableau(Entrée T : Tableau de Réels, Entrée n : Entier) : Réel Variables somme : Réel i : Entier Début somme <- 0 Pour i allant de 1 à n Faire somme <- somme + T[i] FinPour Retourner somme / n FinFonction |
T | n | Somme | Moyenne |
|---|---|---|---|
| [10, 12, 14] | 3 | 36 | 12 |
| [8, 15, 11, 6] | 4 | 40 | 10 |
| [13,5] | 1 | 13,5 | 13,5 |
| Cas limite : si n = 0, la division est impossible. Le programme principal doit empêcher l’appel ou une stratégie d’erreur doit être définie. |
Application 5 — Programme modulaire de gestion des notes
On souhaite saisir les notes d’une classe, calculer la moyenne, déterminer la meilleure note, compter les étudiants admis et afficher un bilan. Une note est valide si elle appartient à l’intervalle [0, 20]. Un étudiant est admis si sa note est supérieure ou égale à 10.
a) Décomposition proposée
Module | Nature | Responsabilité |
|---|---|---|
| NoteValide | Fonction | Vérifier qu’une note appartient à [0, 20]. |
| SaisirNotes | Procédure | Remplir le tableau en répétant les saisies invalides. |
| MoyenneTableau | Fonction | Calculer la moyenne des notes. |
| MaximumTableau | Fonction | Retourner la meilleure note. |
| CompterAdmis | Fonction | Compter les notes supérieures ou égales à 10. |
| AfficherBilan | Procédure | Présenter les résultats. |
b) Validation et saisie
Modules de saisie
| Fonction NoteValide(note : Réel) : Booléen Début Retourner note >= 0 ET note <= 20 FinFonction Procédure SaisirNotes(Sortie Notes : Tableau de Réels, Entrée n : Entier) Variables i : Entier Début Pour i allant de 1 à n Faire Répéter Écrire("Note ", i, " : ") Lire(Notes[i]) JusquÀ NoteValide(Notes[i]) FinPour FinProcédure |
c) Calculs
Fonctions de traitement
| Fonction MaximumTableau(T : Tableau de Réels, n : Entier) : Réel Variables i : Entier maxi : Réel Début maxi <- T[1] Pour i allant de 2 à n Faire Si T[i] > maxi Alors maxi <- T[i] FinSi FinPour Retourner maxi FinFonction Fonction CompterAdmis(T : Tableau de Réels, n : Entier) : Entier Variables i, compteur : Entier Début compteur <- 0 Pour i allant de 1 à n Faire Si T[i] >= 10 Alors compteur <- compteur + 1 FinSi FinPour Retourner compteur FinFonction |
d) Affichage du bilan
Procédure d’affichage
| Procédure AfficherBilan(moyenne : Réel, meilleure : Réel, admis : Entier, n : Entier) Début Écrire("Moyenne de la classe : ", moyenne) Écrire("Meilleure note : ", meilleure) Écrire("Nombre d’admis : ", admis, " sur ", n) FinProcédure |
e) Programme principal
Programme principal
| Algorithme GestionNotes Constantes CAPACITE <- 100 Variables Notes : Tableau[1..CAPACITE] de Réels n, admis : Entier moyenne, meilleure : Réel Début Répéter Écrire("Nombre d’étudiants : ") Lire(n) JusquÀ n >= 1 ET n <= CAPACITE SaisirNotes(Notes, n) moyenne <- MoyenneTableau(Notes, n) meilleure <- MaximumTableau(Notes, n) admis <- CompterAdmis(Notes, n) AfficherBilan(moyenne, meilleure, admis, n) Fin |
Notes | Moyenne | Meilleure | Admis |
|---|---|---|---|
| [12, 8, 15, 10, 5] | 10 | 15 | 3 sur 5 |
| [14, 16, 11] | 13,67 environ | 16 | 3 sur 3 |
| [4, 7, 9] | 6,67 environ | 9 | 0 sur 3 |
| Lecture du programme : le programme principal décrit l’enchaînement global. Les détails de validation, de parcours et de calcul sont confiés à des modules indépendants. |
Traçage des appels de sous-programmes
Lors d’un appel, les paramètres sont initialisés, les variables locales sont créées, le corps du module s’exécute, puis la valeur éventuelle est retournée. Le contexte du programme appelant est ensuite repris.
Exemple à tracer
| x <- 4 y <- 9 z <- Maximum(x, y) Écrire(z) |
Étape | Contexte actif | État ou action |
|---|---|---|
| 1 | Programme principal | x = 4, y = 9 |
| 2 | Appel de Maximum | a reçoit 4, b reçoit 9 |
| 3 | Fonction Maximum | a ≥ b est Faux |
| 4 | Fonction Maximum | Retourner b, donc 9 |
| 5 | Programme principal | z reçoit 9 |
| 6 | Programme principal | Affichage de 9 |
Dans le cas d’appels imbriqués, la fonction la plus interne est évaluée en premier. Par exemple, Maximum(Maximum(3, 7), 5) commence par calculer Maximum(3, 7), puis appelle Maximum(7, 5).
Erreurs fréquentes et bonnes pratiques
Erreur fréquente | Conséquence | Correction |
|---|---|---|
| Oublier Retourner dans une fonction | Aucune valeur exploitable | Retourner une valeur dans chaque chemin. |
| Confondre procédure et fonction | Appel invalide dans une expression | Choisir selon l’intention du module. |
| Nombre d’arguments incorrect | Erreur d’appel | Respecter l’interface. |
| Type d’argument incompatible | Erreur ou conversion risquée | Vérifier les types. |
| Modifier un paramètre d’entrée | Effet inattendu | Utiliser une variable locale. |
| Utiliser trop de variables globales | Dépendances cachées | Transmettre les données par paramètres. |
| Créer un module trop long | Lisibilité faible | Décomposer en responsabilités plus petites. |
| Donner un nom vague | Intention incompréhensible | Employer un verbe ou un nom précis. |
Règles de nommage
- Fonctions booléennes : utiliser une question comme EstPremier, NoteValide ou Contient.
- Fonctions de calcul : utiliser un nom comme Moyenne, Maximum ou NombreVoyelles.
- Procédures d’action : utiliser un verbe comme Afficher, Saisir, Trier ou Echanger.
- Paramètres : choisir des noms liés à leur rôle et éviter a, b, c lorsque le contexte est complexe.
- Variables locales : préférer somme, compteur, indice et maximum à des noms génériques.
| Interface claire : la déclaration d’un sous-programme doit suffire à comprendre les données attendues, les données modifiées et le résultat produit. |
Travaux dirigés
Exercice 1 — Valeur absolue
Écrire une fonction ValeurAbsolue(x) qui retourne la valeur absolue d’un réel. Proposer des jeux d’essai contenant une valeur positive, une valeur négative et zéro.
Exercice 2 — Pair ou impair
Écrire une fonction EstPair(n) qui retourne Vrai lorsque n est divisible par 2. Utiliser cette fonction dans un programme qui compte les nombres pairs d’un tableau.
Exercice 3 — Conversion de température
Écrire une fonction CelsiusVersFahrenheit(c) utilisant la formule f = 1,8 × c + 32. Écrire ensuite une procédure AfficherConversion(c) qui affiche les deux températures.
Exercice 4 — Minimum et position
Écrire une procédure MinimumEtPosition(T, n, minimum, position) qui produit la plus petite valeur du tableau et sa première position. Identifier le mode de chaque paramètre.
Exercice 5 — Normalisation de notes
Écrire une procédure LimiterNotes(T, n) qui remplace toute note inférieure à 0 par 0 et toute note supérieure à 20 par 20. Le tableau doit-il être transmis en entrée ou en entrée-sortie ? Justifier.
Exercice 6 — Puissance entière
Écrire une fonction Puissance(x, n) qui calcule x puissance n pour n entier positif ou nul, sans utiliser d’opérateur de puissance.
Exercice 7 — Statistiques d’un tableau
Décomposer le calcul du minimum, du maximum, de la somme et de la moyenne en plusieurs fonctions. Écrire une procédure AfficherStatistiques qui utilise ces fonctions.
Exercice 8 — Analyse d’un identifiant
Écrire une fonction IdentifiantValide(texte) qui retourne Vrai si la chaîne contient entre 5 et 12 caractères, commence par une lettre et ne contient que des lettres, des chiffres ou le caractère souligné.
Exercice 9 — Portée des variables
Analyser un pseudo-code contenant une variable globale total et une variable locale portant le même nom. Expliquer quelle variable est utilisée dans chaque instruction et proposer une version sans masquage.
Exercice 10 — Mini-projet modulaire
Concevoir un programme de gestion de cinq produits : saisie des prix, validation, calcul du prix moyen, recherche du prix maximal et affichage des produits dont le prix est supérieur à la moyenne. Proposer les fonctions et procédures nécessaires.
Corrigés indicatifs
Corrigé 1 — Valeur absolue
| Fonction ValeurAbsolue(x : Réel) : Réel Début Si x < 0 Alors Retourner -x Sinon Retourner x FinSi FinFonction |
x | Résultat attendu |
|---|---|
| 5 | 5 |
| -3,2 | 3,2 |
| 0 | 0 |
Corrigé 2 — Pair ou impair
| Fonction EstPair(n : Entier) : Booléen Début Retourner n mod 2 = 0 FinFonction Fonction CompterPairs(T : Tableau d’Entiers, n : Entier) : Entier Variables i, compteur : Entier Début compteur <- 0 Pour i allant de 1 à n Faire Si EstPair(T[i]) Alors compteur <- compteur + 1 FinSi FinPour Retourner compteur FinFonction |
Corrigé 3 — Conversion de température
| Fonction CelsiusVersFahrenheit(c : Réel) : Réel Début Retourner 1.8 * c + 32 FinFonction Procédure AfficherConversion(c : Réel) Variables f : Réel Début f <- CelsiusVersFahrenheit(c) Écrire(c, " °C = ", f, " °F") FinProcédure |
Corrigé 4 — Minimum et position
| Procédure MinimumEtPosition(Entrée T : Tableau de Réels, Entrée n : Entier, Sortie minimum : Réel, Sortie position : Entier) Variables i : Entier Début minimum <- T[1] position <- 1 Pour i allant de 2 à n Faire Si T[i] < minimum Alors minimum <- T[i] position <- i FinSi FinPour FinProcédure |
Corrigé 5 — Normalisation de notes
| Procédure LimiterNotes(EntréeSortie T : Tableau de Réels, Entrée n : Entier) Variables i : Entier Début Pour i allant de 1 à n Faire Si T[i] < 0 Alors T[i] <- 0 SinonSi T[i] > 20 Alors T[i] <- 20 FinSi FinPour FinProcédure |
Le tableau est un paramètre d’entrée-sortie, car ses valeurs initiales sont lues puis éventuellement modifiées.
Corrigé 6 — Puissance entière
| Fonction Puissance(x : Réel, n : Entier) : Réel Variables i : Entier resultat : Réel Début resultat <- 1 Pour i allant de 1 à n Faire resultat <- resultat * x FinPour Retourner resultat FinFonction |
La précondition est n ≥ 0. Pour n = 0, la boucle ne s’exécute pas et la fonction retourne 1.
Corrigé 7 — Statistiques d’un tableau
Une solution modulaire comporte les fonctions SommeTableau, MinimumTableau, MaximumTableau et MoyenneTableau. La procédure AfficherStatistiques appelle ces fonctions et affiche leurs résultats. La fonction MoyenneTableau peut réutiliser SommeTableau afin d’éviter la duplication.
| Fonction MoyenneTableau(T : Tableau de Réels, n : Entier) : Réel Début Retourner SommeTableau(T, n) / n FinFonction Procédure AfficherStatistiques(T : Tableau de Réels, n : Entier) Début Écrire("Minimum : ", MinimumTableau(T, n)) Écrire("Maximum : ", MaximumTableau(T, n)) Écrire("Moyenne : ", MoyenneTableau(T, n)) FinProcédure |
Corrigé 8 — Analyse d’un identifiant
La fonction vérifie d’abord la longueur, puis le premier caractère, puis parcourt tous les caractères. Les fonctions auxiliaires EstLettre et EstChiffre peuvent être réutilisées.
| Fonction IdentifiantValide(texte : Chaîne) : Booléen Variables i : Entier c : Caractère Début Si Longueur(texte) < 5 OU Longueur(texte) > 12 Alors Retourner Faux FinSi Si NON EstLettre(texte[1]) Alors Retourner Faux FinSi Pour i allant de 1 à Longueur(texte) Faire c <- texte[i] Si NON EstLettre(c) ET NON EstChiffre(c) ET c <> "_" Alors Retourner Faux FinSi FinPour Retourner Vrai FinFonction |
Corrigé 9 — Portée des variables
Lorsqu’un nom local masque un nom global, les instructions du sous-programme utilisent la variable locale. Pour supprimer l’ambiguïté, il faut renommer la variable locale ou, mieux, transmettre la donnée nécessaire par paramètre et éviter la variable globale.
Corrigé 10 — Mini-projet modulaire
Module proposé | Nature | Rôle |
|---|---|---|
| PrixValide | Fonction | Vérifier qu’un prix est positif ou nul. |
| SaisirPrix | Procédure | Remplir le tableau avec validation. |
| MoyennePrix | Fonction | Calculer le prix moyen. |
| MaximumPrix | Fonction | Rechercher le prix maximal. |
| AfficherSuperieurs | Procédure | Afficher les prix supérieurs à la moyenne. |
Le programme principal lit le nombre de produits, appelle SaisirPrix, calcule la moyenne et le maximum, puis appelle AfficherSuperieurs. Chaque module peut être testé indépendamment.
Synthèse du chapitre
Notion | À retenir |
|---|---|
| Modularité | Décomposer un problème en sous-programmes cohérents. |
| Procédure | Réalise une action sans retourner directement une valeur. |
| Fonction | Retourne une valeur compatible avec un type annoncé. |
| Paramètre formel | Nom déclaré dans l’interface du module. |
| Paramètre effectif | Valeur ou variable fournie lors de l’appel. |
| Passage par valeur | Le module travaille sur une copie. |
| Passage par référence | Le module peut modifier la variable originale. |
| Entrée | Donnée lue mais non modifiée. |
| Sortie | Donnée produite par le module. |
| Entrée-sortie | Donnée lue puis modifiée. |
| Variable locale | Visible uniquement dans son module. |
| Variable globale | Accessible plus largement, mais à utiliser avec prudence. |
Checklist de conception d’un sous-programme
- Le sous-programme réalise-t-il une seule tâche principale ?
- Son nom décrit-il clairement son rôle ?
- Les paramètres nécessaires sont-ils explicitement déclarés ?
- Le mode entrée, sortie ou entrée-sortie est-il correct ?
- La fonction retourne-t-elle une valeur dans tous les cas ?
- Les variables locales sont-elles correctement initialisées ?
- Les préconditions sont-elles vérifiées ?
- Le module évite-t-il les variables globales inutiles ?
- Peut-il être testé indépendamment avec plusieurs jeux d’essai ?
- Son interface permet-elle une réutilisation dans un autre contexte ?
Glossaire
Terme | Définition |
|---|---|
| Sous-programme | Bloc nommé regroupant des instructions pour une tâche déterminée. |
| Modularité | Organisation d’un programme en modules indépendants et cohérents. |
| Procédure | Sous-programme réalisant une action sans valeur de retour directe. |
| Fonction | Sous-programme retournant une valeur. |
| Appel | Instruction qui déclenche l’exécution d’un sous-programme. |
| Interface | Nom, paramètres, modes et type de retour visibles par l’appelant. |
| Paramètre formel | Paramètre déclaré dans la définition du module. |
| Paramètre effectif | Argument fourni au moment de l’appel. |
| Passage par valeur | Transmission d’une copie de la donnée. |
| Passage par référence | Transmission d’un accès à la donnée originale. |
| Portée | Zone du programme dans laquelle un nom est accessible. |
| Durée de vie | Période pendant laquelle une variable existe en mémoire. |
| Effet de bord | Modification d’un état extérieur au résultat retourné. |
| Précondition | Condition qui doit être satisfaite avant l’appel. |
Auto-évaluation
Pour chaque affirmation, indiquer : acquis, en cours d’acquisition ou à revoir.
Je suis capable de… | Auto-évaluation |
|---|---|
| décomposer un problème en sous-problèmes cohérents ; | |
| choisir entre une fonction et une procédure ; | |
| écrire la déclaration et l’appel d’une procédure ; | |
| écrire une fonction avec un type et une valeur de retour ; | |
| distinguer les paramètres formels des paramètres effectifs ; | |
| expliquer le passage par valeur et le passage par référence ; | |
| identifier les paramètres d’entrée, de sortie et d’entrée-sortie ; | |
| expliquer la portée et la durée de vie d’une variable ; | |
| éviter les variables globales inutiles ; | |
| tester indépendamment un sous-programme ; | |
| construire un programme modulaire utilisant un tableau ; |
| Conclusion : les fonctions et les procédures transforment un algorithme long en une organisation de modules compréhensibles, testables et réutilisables. La qualité d’un programme modulaire dépend autant de la clarté de ses interfaces que de la correction de ses calculs. |