Bonjour ! Dans la leçon précédente, nous avons vu la distinction fondamentale entre les variables locales et globales, et l'importance de créer des fonctions autonomes qui ne dépendent pas de l'état global du programme. C'est une étape cruciale vers votre objectif d'écrire du "code clean".
Aujourd'hui, nous allons nous pencher sur le mécanisme de communication principal avec les fonctions : les paramètres. Nous allons répondre à une question essentielle : lorsque nous passons une variable à une fonction, celle-ci peut-elle modifier la variable d'origine ? La réponse dépend de la manière dont le paramètre est passé.
L'objectif de cette leçon est donc d'expliquer la différence entre le passage de paramètres par valeur et par référence. Comprendre ces deux mécanismes est indispensable pour maîtriser le comportement de vos fonctions et éviter les bugs subtils.
1. Le Passage par Valeur : La "Photocopie"
Le passage par valeur est le mécanisme le plus courant et le plus sûr.
Le principe : Quand vous passez une variable à une fonction "par valeur", le système ne transmet pas la variable elle-même, mais une copie de sa valeur. La fonction travaille alors sur cette copie, qui est une variable locale comme les autres. Toute modification apportée à cette copie à l'intérieur de la fonction n'a aucun impact sur la variable originale dans le programme qui a fait l'appel.
Analogie : C'est comme si vous me donniez une photocopie d'un document important. Je peux écrire, dessiner ou raturer ma copie autant que je veux, votre document original restera intact.
Pour formaliser cela, nous allons nous appuyer sur un document de cours.
Initiation à l'Algorithmique Cours et exercices corrigés
Le document 'Initiation à l'Algorithmique' définit clairement les deux modes de passage de paramètres et illustre parfaitement le passage par valeur.
Commencez par lire la section 2.3 'Le passage de paramètres' (page 46). Concentrez-vous sur la définition du 'passage par valeur'. Ensuite, analysez attentivement l'Exemple 3 de la section 4 (page 49), qui montre un algorithme nommé 'C' et son déroulement. Remarquez bien le commentaire : 'le x local est modifié, pas le x du programme principal'.
Analysons l'exemple Algorithme C du document.
Pseudo-code :
Algorithme C
Var x : entier // Variable globale
Procédure Modif(x : entier) // 'x' est un paramètre local (passé par valeur)
Début
x ← x + 1 // On modifie la COPIE de x
Fin
Début // Algorithme principal
x ← 1
Ecrire("Valeur de x avant l’appel : ", x) // Affiche 1
Modif(x) // On passe une copie de la valeur de x (qui est 1)
Ecrire("Valeur de x après l’appel : ", x) // Affiche TOUJOURS 1
Fin
Déroulement :
- Dans le programme principal, la variable globale
xest créée et initialisée à1. - L'appel
Modif(x)est exécuté. - Une nouvelle variable locale à la procédure
Modif, qui s'appelle aussix, est créée. - La valeur de la variable globale
x(c'est-à-dire1) est copiée dans cette nouvelle variable locale. - À l'intérieur de
Modif, l'instructionx ← x + 1s'applique à la variable locale. Sa valeur devient2. La variable globale reste inchangée à1. - La procédure
Modifse termine. Toutes ses variables locales, y compris son paramètrex, sont détruites. - De retour dans le programme principal,
Ecrireaffiche la valeur de la variable globalex, qui n'a jamais été modifiée :1.
Le passage par valeur est donc un mécanisme de protection. Il garantit qu'une fonction ne peut pas produire d'effets de bord en modifiant les variables du programme appelant.
2. Le Passage par Référence : L'"Adresse"
Parfois, nous voulons intentionnellement qu'une fonction modifie une variable. C'est là qu'intervient le passage par référence.
Le principe : Au lieu de passer une copie de la valeur, le système transmet une référence à la variable originale. On peut voir cette référence comme l'adresse mémoire de la variable. La fonction ne travaille donc plus sur une copie, mais directement sur la variable originale. Toute modification est donc répercutée à l'extérieur de la fonction.
Analogie : Cette fois, au lieu d'une photocopie, je vous donne l'adresse exacte (le numéro du tiroir et du dossier) où se trouve mon document original. Si vous allez à cette adresse et modifiez le document, c'est bien l'original qui est modifié.
L'image suivante illustre bien cette différence fondamentale.

Pour comprendre le fonctionnement en détail, nous allons utiliser une ressource qui schématise la mémoire.
[PDF] Chapitre G II LES FONCTIONS et LES PROCEDURES - Lamsade
Le document '[PDF] Chapitre G II LES FONCTIONS et LES PROCEDURES' explique de manière très détaillée le passage par référence, qu'il nomme 'passage par variable' ou 'par adresse'. Nous allons nous concentrer sur l'exemple classique de l'échange de deux valeurs.
Lisez d'abord le point 1 dans 'A. GENERALITES SUR LES PROCEDURES' (page 2) pour comprendre le concept et la terminologie ('passage par variable, passage par référence ou passage par adresse'). Ensuite, sautez à la section 'C. Les paramètres d'entrée-sortie' (page 5) et étudiez l'exemple de la procédure 'échange' (page 5-6). Observez comment les paramètres sont déclarés comme 'entrée sortie' et comment les schémas de la RAM illustrent que la procédure modifie directement les variables globales x et y.
Reprenons cet exemple d'échange de variables, qui est un cas d'usage parfait pour le passage par référence.
Pseudo-code :
// La mention 'en entrée/sortie' indique un passage par référence
Procédure Echange(a: entier en entrée/sortie, b: entier en entrée/sortie)
Variables
temp: entier
Début
temp ← a
a ← b
b ← temp
Fin
Algorithme Principal
Variables
var1: entier
var2: entier
Début
var1 ← 5
var2 ← 10
Ecrire("Avant : var1=", var1, ", var2=", var2) // Affiche 5, 10
// On passe les variables elles-mêmes (leurs adresses)
Echange(var1, var2)
Ecrire("Après : var1=", var1, ", var2=", var2) // Affiche 10, 5
Fin
Déroulement :
- Dans le programme principal,
var1est5etvar2est10. - L'appel
Echange(var1, var2)est exécuté. - Le paramètre
ade la procédureEchangedevient une référence versvar1. Le paramètrebdevient une référence versvar2. - À l'intérieur de
Echange:temp ← a:tempreçoit la valeur devar1(via la référencea), donctempvaut5.a ← b: la variablevar1(pointée para) reçoit la valeur devar2(pointée parb).var1vaut maintenant10.b ← temp: la variablevar2(pointée parb) reçoit la valeur detemp.var2vaut maintenant5.
- La procédure se termine. Les variables
var1etvar2ont été permutées.
3. Quand utiliser l'un ou l'autre ?
Le choix entre passage par valeur et par référence est une décision de conception importante qui influence la propreté de votre code.
| Mécanisme | Passage par Valeur | Passage par Référence |
|---|---|---|
| Principe | La fonction reçoit une copie. | La fonction reçoit une référence (adresse). |
| Effet | La variable originale est protégée. | La variable originale peut être modifiée. |
| Quand l'utiliser ? | Par défaut. Chaque fois qu'une fonction a juste besoin de lire une valeur pour faire un calcul. | Avec intention, quand une fonction doit : 1. Modifier la variable appelante (ex: Echange).2. "Retourner" plusieurs résultats. |
| Avantage "Code Clean" | Empêche les effets de bord, rend les fonctions prévisibles et autonomes. | Permet des modifications d'état explicites et contrôlées. |
En règle générale, pour un code propre et facile à déboguer :
- Privilégiez le passage par valeur autant que possible.
- Utilisez le passage par référence uniquement lorsque c'est nécessaire et justifié par la logique de votre algorithme.
4. À vous de jouer
Pour vérifier votre compréhension, analysez le petit algorithme ci-dessous et prédisez les valeurs finales de a et b.
// Passage par valeur
Procédure AjouteDix_Valeur(param_val: entier)
Début
param_val ← param_val + 10
Ecrire("-> Dans AjouteDix_Valeur, le paramètre vaut : ", param_val)
Fin
// Passage par référence
Procédure AjouteDix_Ref(param_ref: entier en entrée/sortie)
Début
param_ref ← param_ref + 10
Ecrire("-> Dans AjouteDix_Ref, le paramètre vaut : ", param_ref)
Fin
Algorithme Principal
Variables
a: entier ← 100
b: entier ← 100
Début
Ecrire("Initialement, a=", a, " et b=", b)
AjouteDix_Valeur(a)
AjouteDix_Ref(b)
Ecrire("Finalement, a=", a, " et b=", b)
Fin
Cliquez ici pour voir la solution et le déroulement
Résultat de l'exécution :
Initialement, a=100 et b=100
-> Dans AjouteDix_Valeur, le paramètre vaut : 110
-> Dans AjouteDix_Ref, le paramètre vaut : 110
Finalement, a=100 et b=110
Explication :
AjouteDix_Valeur(a): La procédure reçoit une copie de la valeur dea(100). Elle ajoute 10 à cette copie (qui devient 110) et l'affiche. La variable originalean'est pas touchée.AjouteDix_Ref(b): La procédure reçoit une référence versb. Quand elle ajoute 10, elle modifie directement la variable originaleb. La valeur debdans le programme principal passe donc de 100 à 110.- L'affichage final confirme que
aest restée à 100, tandis queba été modifiée et vaut 110.
Conclusion
Aujourd'hui, nous avons décortiqué un mécanisme fondamental de la programmation : la manière dont les informations circulent entre les différentes parties d'un algorithme.
Points clés à retenir :
- Passage par valeur : C'est le mode "sécurisé". La fonction travaille sur une copie et ne peut pas altérer l'original. C'est le choix par défaut pour un code prévisible.
- Passage par référence : C'est le mode "puissant" qui donne à une fonction la permission de modifier la variable originale. Il est indispensable pour certaines tâches, comme l'échange de valeurs ou quand une procédure doit retourner plusieurs résultats.
- La maîtrise de ces deux modes vous donne un contrôle total sur le comportement de vos fonctions et les données de votre programme.
Et après ?
Maintenant que nous savons définir des fonctions, gérer la portée des variables et contrôler la manière dont elles communiquent via les paramètres, nous avons tous les outils en main pour nous attaquer à des problèmes plus ambitieux. Dans la prochaine leçon, nous apprendrons à décomposer un problème complexe en plusieurs fonctions modulaires, la pierre angulaire de la conception de programmes structurés, lisibles et faciles à maintenir.