Séance 5 — Les fonctions et procédures

Découper, nommer, appeler

Dr. El Hadji Bassirou TOURÉ

Département de Mathématiques et Informatique, Faculté des Sciences et Techniques, Université Cheikh Anta Diop de Dakar

Objectifs de la séance

Ce que la séance construit

La fonction et la procédure, qui donnent un nom à un traitement écrit une seule fois : la fonction rend une valeur par Retourner, la procédure agit sans rien rendre. Leurs paramètres reçoivent, à chaque appel, une copie des valeurs effectives (passage par valeur) ou désignent les variables de l’appelant (passage en entrée-sortie, E/S). Chaque appel a son cadre dans la pile des appels, avec ses variables locales ; chaque algorithme est suivi pas à pas : la ligne exécutée, la pile, ce qu’écrit Écrire.

  • Découper un problème en traitements nommés, chacun écrit une fois.
  • Écrire et appeler une fonction : paramètres formels et effectifs, valeur rendue.
  • Écrire et appeler une procédure ; choisir entre passage par valeur et E/S.
  • Passer un tableau à une fonction ou à une procédure.
  • Dérouler un appel à la main avec la pile des appels, y compris des appels imbriqués.
  • Repérer trois erreurs : Retourner oublié, paramètre par valeur modifié en vain, variable locale utilisée hors de sa fonction.

Les conventions du pseudo-code : les fonctions

écriture sens
\(x\leftarrow e\) ; Lire ; Écrire ; Si ; TantQue ; Pour ; Répéter Séances 1 à 3
T : tableau[1..n] déntiers ; T[i], \(1\leq i\leq n\) Séance 4 ; ET, OU : deux membres évalués (Séance 2) ; \(58/5\) donne 11,6
Fonction f(a : entier, b : entier) : entier … FinFonction paramètres formels, type de la valeur rendue
Retourner \(e\) rend la valeur de \(e\) et termine l’appel ; FinFonction sans Retourner : erreur
Procédure p(…) … FinProcédure aucune valeur rendue ; appel seul sur sa ligne : p(x, y)
z \(\leftarrow\) f(x, y + 1) appel dans une expression ; effectifs : valeurs, variables, expressions
Début … Fin programme principal, après les fonctions ; l’exécution y commence

Dans les traces, la pile des appels est à droite : un cadre par appel en cours, le cadre actif en orange, une valeur écrite en rouge.

Les conventions du pseudo-code : les paramètres

écriture sens
paramètre sans mention par valeur : copie de l’effectif (un tableau est copié case par case)
T : tableau[1..n] déntiers en paramètre \(n\leq\) taille de l’effectif : les \(n\) premières cases ; \(n\) plus grand : erreur
E/S a : entier ; E/S T : tableau[1..n] déntiers entrée-sortie, procédures seulement : a désigne la variable effective
variables locales paramètres et variables affectées dans la fonction ; disparaissent au retour

E/S dit ce que la procédure fait de la variable : elle la lit en entrée, la modifie en sortie.

Choix du cours, celui de Pascal

En C, Java et Python, un tableau passé en paramètre n’est pas copié : ses cases modifiées le sont chez l’appelant, comme en E/S.

Le découpage d’un problème en traitements nommés

Sous-programme

Un traitement écrit une fois, sous un nom, avec des paramètres ; il s’exécute à chaque appel, sur les valeurs données à l’appel. Une fonction rend une valeur ; une procédure agit (écrit, modifie des variables) sans rendre de valeur.

Lecture. Le bulletin d’une classe de Thiès en quatre traitements : le maximum, écrit une fois, se corrige à un seul endroit ; le programme principal se lit comme la liste des étapes.

La fonction : en-tête, paramètres, valeur rendue

Paramètres formels et effectifs

Les paramètres formels sont les noms de l’en-tête (a, b) ; les paramètres effectifs sont les valeurs données à l’appel : dans z \(\leftarrow\) max2(x, y), x et y. À l’appel, chaque formel reçoit, dans l’ordre, la valeur de son effectif.

Lecture. Une fonction calcule une valeur à partir de ses paramètres. L’appel crée un cadre d’appel où vivent a, b et m ; Retourner m renvoie sa valeur à la ligne de l’appel et retire le cadre.

L’appel d’une fonction, pas à pas

Écrit par Écrire \(\rightarrow\)

maximum : 17
2

Lecture. Ligne 10 : x reçoit 12.

Lecture. Ligne 11 : y reçoit 17.

Lecture. Ligne 12 : appel de la fonction max2 ; un cadre d’appel est empilé, où a \(=\) 12, b \(=\) 17 ; suite à la ligne 2.

Lecture. Ligne 2 : test du Si, a ≥ b, soit 12 ≥ 17 : faux ; le bloc Sinon est exécuté.

Lecture. Ligne 5 : m reçoit b, soit 17.

Lecture. Ligne 7 : Retourner m, soit 17 : max2 rend 17 ; son cadre d’appel est retiré, retour à la ligne 12.

Lecture. Ligne 12 : z reçoit 17, valeur rendue par max2.

Lecture. Ligne 13 : Écrire écrit « maximum : 17 ».

Lecture. Ligne 14 : appel de la fonction max2 ; un cadre d’appel est empilé, où a \(=\) 2, b \(=\) 1 ; suite à la ligne 2.

Lecture. Ligne 2 : test du Si, a ≥ b, soit 2 ≥ 1 : vrai ; le bloc Alors est exécuté.

Lecture. Ligne 3 : m reçoit a, soit 2.

Lecture. Ligne 7 : Retourner m, soit 2 : max2 rend 2 ; son cadre d’appel est retiré, retour à la ligne 14.

Lecture. Ligne 14 : Écrire écrit « 2 », avec la valeur rendue. Second appel, nouveau cadre : rien n’y reste du premier.

Un tableau en paramètre, pas à pas : la moyenne

Écrit par Écrire \(\rightarrow\)

moyenne : 11,6

Lecture. Ligne 10 : déclaration de notes, tableau de 5 entiers ; ses cases ne sont pas encore remplies.

Lecture. Ligne 11 : notes reçoit ses 5 valeurs, dans l’ordre des indices.

Lecture. Ligne 12 : appel de la fonction moyenne ; un cadre d’appel est empilé, où T reçoit une copie des 5 cases, n \(=\) 5 ; suite à la ligne 3.

Lecture. Ligne 3 : s reçoit 0.

Lecture. Ligne 4 : Pour donne à i sa première valeur, 1 ; test 1 ≤ 5 : vrai ; un tour du corps.

Lecture. Ligne 5 : s ← s + T[i] : lit T[1] \(=\) 12 ; s passe de 0 à 12.

Lecture. Ligne 4 : Pour augmente i : 2 ; test 2 ≤ 5 : vrai ; un tour du corps.

Lecture. Ligne 5 : s ← s + T[i] : lit T[2] \(=\) 8 ; s passe de 12 à 20.

Lecture. Ligne 4 : Pour augmente i : 3 ; test 3 ≤ 5 : vrai ; un tour du corps.

Lecture. Ligne 5 : s ← s + T[i] : lit T[3] \(=\) 15 ; s passe de 20 à 35.

Lecture. Ligne 4 : Pour augmente i : 4 ; test 4 ≤ 5 : vrai ; un tour du corps.

Lecture. Ligne 5 : s ← s + T[i] : lit T[4] \(=\) 9 ; s passe de 35 à 44.

Lecture. Ligne 4 : Pour augmente i : 5 ; test 5 ≤ 5 : vrai ; un tour du corps.

Lecture. Ligne 5 : s ← s + T[i] : lit T[5] \(=\) 14 ; s passe de 44 à 58.

Lecture. Ligne 4 : Pour augmente i : 6 ; test 6 ≤ 5 : faux ; fin du Pour ; suite à la ligne 7.

Lecture. Ligne 7 : Retourner s / n, soit 11,6 : moyenne rend 11,6 ; son cadre d’appel est retiré, retour à la ligne 12.

Lecture. Ligne 12 : moy reçoit 11,6, valeur rendue par moyenne.

Lecture. Ligne 13 : Écrire écrit « moyenne : 11,6 ». La fonction a travaillé sur une copie de notes ; \(58/5=11{,}6\).

Une recherche rendue par une fonction, pas à pas

Écrit par Écrire \(\rightarrow\)

case : 3

Lecture. Ligne 11 : déclaration de C, tableau de 5 entiers ; ses cases ne sont pas encore remplies.

Lecture. Ligne 12 : C reçoit ses 5 valeurs, dans l’ordre des indices.

Lecture. Ligne 13 : appel de la fonction position ; un cadre d’appel est empilé, où T reçoit une copie des 5 cases, n \(=\) 5, x \(=\) 478 ; suite à la ligne 3.

Lecture. Ligne 3 : Pour donne à i sa première valeur, 1 ; test 1 ≤ 5 : vrai ; un tour du corps.

Lecture. Ligne 4 : test du Si, T[i] = x, soit 305 = 478 : faux ; le bloc est sauté.

Lecture. Ligne 3 : Pour augmente i : 2 ; test 2 ≤ 5 : vrai ; un tour du corps.

Lecture. Ligne 4 : test du Si, T[i] = x, soit 112 = 478 : faux ; le bloc est sauté.

Lecture. Ligne 3 : Pour augmente i : 3 ; test 3 ≤ 5 : vrai ; un tour du corps.

Lecture. Ligne 4 : test du Si, T[i] = x, soit 478 = 478 : vrai ; le bloc Alors est exécuté.

Lecture. Ligne 5 : Retourner i, soit 3 : position rend 3 ; son cadre d’appel est retiré, retour à la ligne 13. Placé dans la boucle, Retourner l’arrête.

Lecture. Ligne 13 : p reçoit 3, valeur rendue par position.

Lecture. Ligne 14 : Écrire écrit « case : 3 ». La boucle s’est arrêtée au tour 3 : Retourner termine l’appel.

Quoi, pourquoi, quand ça échoue : l’appel

Quoi

Un appel f(e1, e2) : évaluer les effectifs, empiler un cadre d’appel, y copier les valeurs dans les formels, exécuter le corps jusqu’à Retourner, retirer le cadre, utiliser la valeur rendue. Un tableau passé par valeur est copié : la fonction lit sa copie.

Pourquoi une copie

La fonction ne dépend que de ses paramètres : max2(x, y) et max2(x - 10, 1) exécutent le même corps sur d’autres valeurs, et aucune variable de l’appelant ne change.

Quand ça échoue

Effectifs dans le désordre : position(C, 478, 5) donne \(n=478\), plus que les 5 cases de C : appel incorrect, arrêt. Nombre d’effectifs différent du nombre de formels : appel incorrect. Retourner oublié sur un chemin : la fonction ne rend rien (section 5).

Exercice : deux appels d’une même fonction

Fonction compter(T : tableau[1..n] d'entiers,
    n : entier, s : entier) : entier
  c ← 0
  Pour i de 1 à n Faire
    Si T[i] ≥ s Alors
      c ← c + 1
    FinSi
  FinPour
  Retourner c
FinFonction
Début
  V : tableau[1..5] d'entiers
  V ← [5000, 2000, 5000, 3000, 5000]
  a ← compter(V, 5, 5000)
  Écrire a, compter(V, 5, 3000) - a
Fin

Tontine de Thiès : versements (F)

  1. Relever, pour l’appel de la ligne 14, T[i], le test de la ligne 5 et c à chaque tour.
  2. Qu’écrit la ligne 15 ?
  3. Combien de cadres d’appel sont créés ? Combien de fois la ligne 9 est-elle exécutée ?
  4. Quels sont les paramètres formels et effectifs de l’appel de la ligne 15 ?

Exercice : deux appels d’une même fonction, correction

Fonction compter(T : tableau[1..n] d'entiers,
    n : entier, s : entier) : entier
  c ← 0
  Pour i de 1 à n Faire
    Si T[i] ≥ s Alors
      c ← c + 1
    FinSi
  FinPour
  Retourner c
FinFonction
Début
  V : tableau[1..5] d'entiers
  V ← [5000, 2000, 5000, 3000, 5000]
  a ← compter(V, 5, 5000)
  Écrire a, compter(V, 5, 3000) - a
Fin

Correction

\(i\) 1 2 3 4 5
T[i] 5000 2000 5000 3000 5000
T[i] \(\geq\) s vrai faux vrai faux vrai
c après 1 1 2 2 3
  1. c augmente aux cases 1, 3 et 5 ; la fonction rend 3 : a \(=3\).
  2. 3 1 : le second appel compte 4 versements d’au moins 3000 F ; \(4-3=1\).
  3. Deux cadres, un par appel, retirés au Retourner ; ligne 9 : 2 fois.
  4. Formels T, n, s ; effectifs V, 5, 3000 : T est une copie de V.

La procédure : agir sans rendre de valeur

Échanger deux variables, inverser un tableau : le résultat n’est pas une valeur, mais des variables modifiées.

Procédure

Procédure nom(paramètres) … FinProcédure : un traitement nommé qui ne rend pas de valeur. Son appel est une instruction seule sur sa ligne, echanger(x, y) ; il se termine à FinProcédure.

Deux modes de passage

Par valeur (par défaut) : le formel reçoit une copie ; le modifier ne change que la copie. En entrée-sortie, E/S a : entier : a désigne la variable effective elle-même (passage par référence) ; l’effectif doit être une variable ou une case, et chaque affectation de a la modifie.

Lecture. La mention E/S est écrite dans l’en-tête, devant chaque paramètre concerné : l’en-tête dit à lui seul quelles variables de l’appelant la procédure peut changer.

Le passage par valeur, pas à pas : un échange sans effet

Écrit par Écrire \(\rightarrow\)

5 9

Lecture. Ligne 8 : x reçoit 5.

Lecture. Ligne 9 : y reçoit 9.

Lecture. Ligne 10 : appel de la procédure echanger ; un cadre d’appel est empilé, où a \(=\) 5, b \(=\) 9 ; suite à la ligne 3.

Lecture. Ligne 3 : tmp reçoit a, soit 5.

Lecture. Ligne 4 : a ← b ; a passe de 5 à 9.

Lecture. Ligne 5 : b ← tmp ; b passe de 9 à 5.

Lecture. Ligne 6 : FinProcédure ; le cadre d’appel de echanger est retiré ; retour dans le programme principal ; suite à la ligne 11.

Lecture. Ligne 11 : Écrire écrit « 5 9 ». a et b ont été échangés, puis retirés avec leur cadre : x et y n’ont pas changé.

Le passage en entrée-sortie, pas à pas

Écrit par Écrire \(\rightarrow\)

9 5

Lecture. Ligne 8 : x reçoit 5.

Lecture. Ligne 9 : y reçoit 9.

Lecture. Ligne 10 : appel de la procédure echanger ; un cadre d’appel est empilé, où a désigne x, b désigne y ; suite à la ligne 3.

Lecture. Ligne 3 : tmp reçoit a, soit 5.

Lecture. Ligne 4 : a ← b ; a désigne x : x, variable du programme principal, passe de 5 à 9.

Lecture. Ligne 5 : b ← tmp ; b désigne y : y, variable du programme principal, passe de 9 à 5.

Lecture. Ligne 6 : FinProcédure ; le cadre d’appel de echanger est retiré ; retour dans le programme principal ; suite à la ligne 11.

Lecture. Ligne 11 : Écrire écrit « 9 5 ». Par E/S, la procédure a modifié x et y eux-mêmes.

Un tableau en entrée-sortie, pas à pas

Écrit par Écrire \(\rightarrow\)

42 31 23 17

Lecture. Ligne 10 : déclaration de F, tableau de 4 entiers ; ses cases ne sont pas encore remplies.

Lecture. Ligne 11 : F reçoit ses 4 valeurs, dans l’ordre des indices.

Lecture. Ligne 12 : appel de la procédure inverser ; un cadre d’appel est empilé, où T désigne F, n \(=\) 4 ; suite à la ligne 3.

Lecture. Ligne 3 : Pour donne à i sa première valeur, 1 ; test 1 ≤ 4 div 2, soit 1 ≤ 2 : vrai ; un tour du corps.

Lecture. Ligne 4 : tmp reçoit T[i], soit 17 (case lue : T[1] \(=\) 17).

Lecture. Ligne 5 : T[i] ← T[n - i + 1] ; T désigne F : la case F[1] du programme principal passe de 17 à 42.

Lecture. Ligne 6 : T[n - i + 1] ← tmp ; T désigne F : la case F[4] du programme principal passe de 42 à 17.

Lecture. Ligne 3 : Pour augmente i : 2 ; test 2 ≤ 4 div 2, soit 2 ≤ 2 : vrai ; un tour du corps.

Lecture. Ligne 4 : tmp ← T[i] : lit T[2] \(=\) 23 ; tmp passe de 17 à 23.

Lecture. Ligne 5 : T[i] ← T[n - i + 1] ; T désigne F : la case F[2] du programme principal passe de 23 à 31.

Lecture. Ligne 6 : T[n - i + 1] ← tmp ; T désigne F : la case F[3] du programme principal passe de 31 à 23.

Lecture. Ligne 3 : Pour augmente i : 3 ; test 3 ≤ 4 div 2, soit 3 ≤ 2 : faux ; fin du Pour ; suite à la ligne 8.

Lecture. Ligne 8 : FinProcédure ; le cadre d’appel de inverser est retiré ; retour dans le programme principal ; suite à la ligne 13.

Lecture. Ligne 13 : Écrire écrit « 42 31 23 17 ». Une seule rangée de cases, celle de F : T la désignait.

Quoi, pourquoi, quand ça échoue : valeur ou E/S

Quoi

Par valeur, le cadre d’appel contient une copie ; en E/S, il contient un renvoi vers la variable de l’appelant (a \(\rightarrow\) x) : lire a, c’est lire x ; écrire a, c’est écrire x. Un tableau en E/S n’est pas copié : ses cases sont celles de l’effectif.

Pourquoi les deux

Le passage par valeur protège l’appelant : une fonction ne change aucune de ses variables. L’E/S est réservée aux procédures dont le but est de modifier : échanger, inverser, remplir, ajouter un versement.

Quand ça échoue

Modifier un paramètre par valeur pour changer l’appelant : sans effet, sans message (5 9). Mettre E/S partout : la procédure peut alors changer une variable que l’appelant croyait protégée. Effectif en E/S qui n’est pas une variable (echanger(x, 3)) : appel incorrect.

Exercice : valeur ou entrée-sortie

Procédure verser(E/S solde : entier,
    m : entier)
  solde ← solde + m
  m ← 0
FinProcédure
Début
  caisse ← 20000
  part ← 5000
  verser(caisse, part)
  verser(caisse, part)
  Écrire caisse, part
Fin

Caisse d’un GIE de Kaolack (F)

  1. Pour chaque appel, relever solde après la ligne 3, m après la ligne 4, puis caisse et part après le retour.
  2. Qu’écrit la ligne 11 ?
  3. Qu’écrit l’algorithme sans E/S devant solde ?
  4. Qu’écrit-il avec E/S devant solde et devant m ?

Exercice : valeur ou entrée-sortie, correction

Procédure verser(E/S solde : entier,
    m : entier)
  solde ← solde + m
  m ← 0
FinProcédure
Début
  caisse ← 20000
  part ← 5000
  verser(caisse, part)
  verser(caisse, part)
  Écrire caisse, part
Fin

Correction

appel **solde** **m** **caisse** **part**
1 (l. 9) 25000 0 25000 5000
2 (l. 10) 30000 0 30000 5000
  1. solde désigne caisse : chaque appel ajoute 5000 à caisse. m est une copie de part : \(\texttt{m}\leftarrow0\) ne touche pas part.
  2. 30000 5000 : deux versements de 5000 F.
  3. 20000 5000 : solde est une copie, augmentée puis retirée avec le cadre d’appel.
  4. 25000 0 : le premier appel met part à 0, le second verse 0.

Les variables locales, pas à pas : deux variables i

Écrit par Écrire \(\rightarrow\)

2 3
3 6

Lecture. Ligne 9 : Pour donne à i sa première valeur, 2 ; test 2 ≤ 3 : vrai ; un tour du corps.

Lecture. Ligne 10 : appel de la fonction triangle ; un cadre d’appel est empilé, où n \(=\) 2 ; suite à la ligne 2.

Lecture. Ligne 2 : s reçoit 0.

Lecture. Ligne 3 : Pour donne à i sa première valeur, 1 ; test 1 ≤ 2 : vrai ; un tour du corps.

Lecture. Ligne 4 : s ← s + i ; s passe de 0 à 1.

Lecture. Ligne 3 : Pour augmente i : 2 ; test 2 ≤ 2 : vrai ; un tour du corps.

Lecture. Ligne 4 : s ← s + i ; s passe de 1 à 3.

Lecture. Ligne 3 : Pour augmente i : 3 ; test 3 ≤ 2 : faux ; fin du Pour ; suite à la ligne 6.

Lecture. Ligne 6 : Retourner s, soit 3 : triangle rend 3 ; son cadre d’appel est retiré, retour à la ligne 10.

Lecture. Ligne 10 : Écrire écrit « 2 3 », avec la valeur rendue.

Lecture. Ligne 9 : Pour augmente i : 3 ; test 3 ≤ 3 : vrai ; un tour du corps.

Lecture. Ligne 10 : appel de la fonction triangle ; un cadre d’appel est empilé, où n \(=\) 3 ; suite à la ligne 2.

Lecture. Ligne 2 : s reçoit 0.

Lecture. Ligne 3 : Pour donne à i sa première valeur, 1 ; test 1 ≤ 3 : vrai ; un tour du corps.

Lecture. Ligne 4 : s ← s + i ; s passe de 0 à 1.

Lecture. Ligne 3 : Pour augmente i : 2 ; test 2 ≤ 3 : vrai ; un tour du corps.

Lecture. Ligne 4 : s ← s + i ; s passe de 1 à 3.

Lecture. Ligne 3 : Pour augmente i : 3 ; test 3 ≤ 3 : vrai ; un tour du corps.

Lecture. Ligne 4 : s ← s + i ; s passe de 3 à 6.

Lecture. Ligne 3 : Pour augmente i : 4 ; test 4 ≤ 3 : faux ; fin du Pour ; suite à la ligne 6.

Lecture. Ligne 6 : Retourner s, soit 6 : triangle rend 6 ; son cadre d’appel est retiré, retour à la ligne 10.

Lecture. Ligne 10 : Écrire écrit « 3 6 », avec la valeur rendue.

Lecture. Ligne 9 : Pour augmente i : 4 ; test 4 ≤ 3 : faux ; fin du Pour ; l’algorithme est terminé. Le i de triangle n’a pas touché celui-ci.

La pile des appels

Variable locale, portée

Une variable locale (paramètre, ou variable affectée dans la fonction) n’existe que pendant l’appel, dans son cadre d’appel ; sa portée est le corps de la fonction.

Pile des appels (pile d’exécution)

Les cadres des appels en cours, empilés : un appel empile un cadre d’appel, Retourner ou FinProcédure retire celui du sommet ; seul le cadre du sommet est actif. Au pas 2 de l’algorithme suivant, max3 attend la valeur de max2, qui travaille.

Lecture. Deux variables a, une dans max3, une dans max2 : deux variables différentes, dans deux cadres différents.

pas 2 : max3 appelle max2

Une fonction qui en appelle une autre, pas à pas

Écrit par Écrire \(\rightarrow\)

maximum : 38

Lecture. Ligne 13 : appel de la fonction max3 ; un cadre d’appel est empilé, où a \(=\) 31, b \(=\) 38, c \(=\) 35 ; suite à la ligne 9.

Lecture. Ligne 9 : appel de la fonction max2 ; un cadre d’appel est empilé, où a \(=\) 31, b \(=\) 38 ; suite à la ligne 2.

Lecture. Ligne 2 : test du Si, a ≥ b, soit 31 ≥ 38 : faux ; le bloc est sauté.

Lecture. Ligne 5 : Retourner b, soit 38 : max2 rend 38 ; son cadre d’appel est retiré, retour à la ligne 9.

Lecture. Ligne 9 : m reçoit 38, valeur rendue par max2.

Lecture. Ligne 10 : appel de la fonction max2 ; un cadre d’appel est empilé, où a \(=\) 38, b \(=\) 35 ; suite à la ligne 2.

Lecture. Ligne 2 : test du Si, a ≥ b, soit 38 ≥ 35 : vrai ; le bloc Alors est exécuté.

Lecture. Ligne 3 : Retourner a, soit 38 : max2 rend 38 ; son cadre d’appel est retiré, retour à la ligne 10.

Lecture. Ligne 10 : Retourner max2(m, c), soit 38 : max3 rend 38 ; son cadre d’appel est retiré, retour à la ligne 13.

Lecture. Ligne 13 : t reçoit 38, valeur rendue par max3.

Lecture. Ligne 14 : Écrire écrit « maximum : 38 ». Pile la plus haute : trois cadres (principal, max3, max2).

L’oubli de Retourner, pas à pas

Écrit par Écrire \(\rightarrow\)

arrêt : pas de Retourner

Lecture. Ligne 9 : x reçoit 12.

Lecture. Ligne 10 : y reçoit 17.

Lecture. Ligne 11 : appel de la fonction max2 ; un cadre d’appel est empilé, où a \(=\) 12, b \(=\) 17 ; suite à la ligne 2.

Lecture. Ligne 2 : test du Si, a ≥ b, soit 12 ≥ 17 : faux ; le bloc Sinon est exécuté.

Lecture. Ligne 5 : m reçoit b, soit 17.

Lecture. Ligne 7 : FinFonction est atteinte sans Retourner : max2 ne rend aucune valeur ; arrêt. Il manque Retourner m avant FinFonction.

Une variable locale hors de sa fonction, pas à pas

Écrit par Écrire \(\rightarrow\)

arrêt : total inconnue

Lecture. Ligne 7 : appel de la fonction prix ; un cadre d’appel est empilé, où q \(=\) 3, pu \(=\) 750 ; suite à la ligne 3.

Lecture. Ligne 3 : total reçoit q × pu, soit 2250.

Lecture. Ligne 4 : Retourner total, soit 2250 : prix rend 2250 ; son cadre d’appel est retiré, retour à la ligne 7.

Lecture. Ligne 7 : p reçoit 2250, valeur rendue par prix.

Lecture. Ligne 8 : total n’est pas une variable du programme principal : elle était locale à prix et a disparu avec son cadre d’appel ; arrêt. Écrire p, qui a reçu la valeur rendue.

Exercice : pile des appels et erreurs

Fonction carre(x : entier) : entier
  Retourner x × x
FinFonction
Fonction somCarres(a : entier,
    b : entier) : entier
  s ← carre(a) + carre(b)
  Retourner s
FinFonction
Début
  x ← 3
  r ← somCarres(x, x + 1)
  Écrire x, r
Fin

Énoncé

  1. Donner la pile des appels, cadre par cadre, à chaque exécution de la ligne 2.
  2. Qu’écrit la ligne 12 ? Pourquoi x vaut-il encore 3 ?
  3. La ligne 2 devient y \(\leftarrow\) x \(\times\) x. Que se passe-t-il ?
  4. La ligne 12 devient Écrire x, s. Que se passe-t-il ?

Exercice : pile des appels et erreurs, correction

Fonction carre(x : entier) : entier
  Retourner x × x
FinFonction
Fonction somCarres(a : entier,
    b : entier) : entier
  s ← carre(a) + carre(b)
  Retourner s
FinFonction
Début
  x ← 3
  r ← somCarres(x, x + 1)
  Écrire x, r
Fin

Correction

l. 2 principal somCarres carre
1 x \(=\) 3 a \(=\) 3, b \(=\) 4 x \(=\) 3
2 x \(=\) 3 a \(=\) 3, b \(=\) 4 x \(=\) 4
  1. Trois cadres, du bas vers le sommet ; deux appels de carre, ligne 6.
  2. 3 25 : le x de carre n’est pas celui du principal ; \(9+16=25\).
  3. Premier appel de carre : ligne 3 atteinte sans Retourner, arrêt ; rien n’est écrit.
  4. s, locale à somCarres, a disparu : arrêt, ligne 12.

À retenir

rend appel paramètres
fonction une valeur, par Retourner dans une expression : z \(\leftarrow\) f(x) par valeur (copies)
procédure rien instruction seule : p(x, y) par valeur ou E/S (la variable elle-même)
tableau par valeur copié case par case (choix du cours) ; la fonction lit sa copie
tableau en E/S non copié ; la procédure modifie les cases de l’effectif

À retenir

  • Un appel empile un cadre d’appel ; Retourner ou FinProcédure le retire avec ses variables locales.
  • Une variable locale n’existe que dans son cadre d’appel : deux variables de même nom dans deux fonctions sont différentes.
  • Trois erreurs : Retourner oublié, paramètre par valeur modifié pour changer l’appelant, variable locale lue hors de sa fonction.

Synthèse du cours

séance ce qu’elle apporte
0 — l’algorithme problème, algorithme, instruction ; exécution à la main
1 — variables types, affectation \(\leftarrow\), Lire, Écrire ; trace d’exécution
2 — conditions Si, Sinon, SinonSi, Selon ; ET, OU, NON ; bornes
3 — boucles TantQue, Pour, Répéter ; compteur, accumulateur ; décalage d’une unité
4 — tableaux indices, parcours, recherche avec arrêt, maximum, inversion ; indice hors bornes
5 — fonctions fonction, procédure, passage par valeur et E/S ; pile des appels

Ce que le cours permet

Écrire un algorithme en traitements nommés, chacun fait de variables, de conditions, de boucles et de tableaux, et le vérifier par une trace sur un cas ordinaire et sur un cas limite.

Pour réviser : reprendre un algorithme de chaque séance (une condition, une boucle, un parcours de tableau), l’écrire sous forme de fonction et en dresser la trace avec la pile des appels.

Références

  • Cormen — Algorithms Unlocked, MIT Press, 2013 (ch. 1, « What Are Algorithms and Why Should You Care? », et ch. 2, « How to Describe and Evaluate Computer Algorithms » : procédures et paramètres en pseudo-code).
  • Cormen, Leiserson, Rivest, Stein — Introduction to Algorithms, 4e éd., MIT Press, 2022 (ch. 2, « Getting Started », § 2.1 : conventions du pseudo-code, paramètres passés par valeur).
  • Bhargava — Grokking Algorithms, 2e éd., Manning, 2024 (ch. 3, « Recursion » : la pile des appels).
  • Notes de cours en ligne : CS50 (Harvard), 6.100A (MIT), CS106A (Stanford), séances sur les fonctions.