Les sous-programmes
Transcription
Les sous-programmes
S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 Chapitre 5 : Les sous-progra mmes INTRODUCTION Lorsqu'un programme est long, il est irréaliste d'écrire son code d'un seul tenant. En fait, on décompose le programme en plusieurs parties plus petites, on donne un nom à chacune de ces parties, et on les assemble pour former le programme final. C'est le principe de la programmation modulaire , qui repose sur l'écriture de sous-programmes. Un sous-programme est, comme son nom l'indique, un petit programme réalisant un traitement particulier qui s'exécute à l'intérieur d'un autre programme. Les sous-programmes sont utilisés pour deux raisons essentielles : - quand un même traitement doit être réalisé plusieurs fois dans un programme (ou qu'il est utilisé dans plusieurs programmes): on écrit un sous-programme pour ce traitement et on l'appelle à chaque endroit où l'on en a besoin. On évite ainsi de réécrire plusieurs fois le code du traitement. - pour organiser le code , améliorer la conception et la lisibilité des gros programmes. En effet, le découpage en sous-programmes permet de traiter séparément les difficultés. Certains sous-programmes ont déjà été écrits et peuvent être utilisés directement dans n'importe quel programme. Ce sont des sous -programmes standards ou prédéfinis. C'est le cas par exemple des sousprogrammes permettant de faire des calculs mathématiques (racine carrée, exposant, …). La nature et le nombre de programmes standards dépendent des langages. Mais les sous-programmes prédéfinis ne suffisent pas pour découper un gros programme : le programmeur est amené à écrire le code de ses propres sous-programmes. Il existe deux sortes de sous-programmes : les procédures et les fonctions Nous allons étudier d'abord les procédures simples, puis les fonctions. Nous reviendrons ensuite sur les procédures pour étudier tous les types de passage de paramètres. LES PROCEDURES (1 ière partie) Une procédure est un ensemble d'instructions regroupées sous un nom, qui réalise un traitement particulier dans un programme lorsqu'on l'appelle. Comme un programme, une procédure possède un nom, des variables, des instructions, un début et une fin. Mais contrairement à un programme, un sous-programme ne peut pas s'exécuter indépendamment d'un autre programme. Syntaxe de la DEFINITION d'une procédure: Procédure ligneEtoile( ) Var i : entier Début Pour i de 1 jusqu'à 10 Faire Afficher '*' FinPour Afficher '\n' FinProc EN-TETE CORPS Cette procédure permet d'afficher une ligne de 10 étoiles puis passe à la ligne. 1 S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 APPEL d'une procédure Pour déclencher l'exécution d'une procédure dans un programme, il suffit de l'appeler, c'est-à-dire d'indiquer son nom suivi de parenthèses. Programme RectangleEtoile Var nlignes: entier cpt : entier Début Afficher "Ce programme dessine un rectangle d'étoiles. Combien voulez-vous de lignes?" Saisir nlignes Pour cpt de 1 jusqu'à nlignes Faire Var ligneEtoile ( ) i : entier FinPour Début Fin Pour i de 1 jusqu'à 10 Faire Afficher '*' FinPour appel de la Afficher '\n' procédure FinProc Lorsque le processeur rencontre l'appel d'une procédure, il arrête momentanément l'exécution du programme appelant pour aller exécuter les instructions de la procédure. Quand il a terminé l'exécution de la procédure, le processeur reprend l'exécution du programme appelant là où il s'était arrêté. Une procédure peut être appelée soit par un programme, soit par un autre sous-programme (qui lui même a été appelé). Les appels de sous-programmes peuvent s'imbriquer autant qu'on le désire. Notions de variables locales et de paramètres Les variables déclarées dans une procédure ne sont pas utilisables dans le programme appelant et inversement, les variables déclarées dans le programme appelant ne sont pas utilisables dans les procédures. Chaque programme et sous-programme a son propre espace de variables, inaccessible par les autres. On dit que les variables sont LOCALES. (on verra qu'il existe des variables globales, mais elles sont très peu utilisées). 2 S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 Dans notre exemple, on ne pourrait pas saisir ou afficher la variable i dans le programme principal, car i est une variable de la procédure, utilisable seulement dans celle -ci. Le programme principal n'a pas le droit de l'utiliser. De même, la procédure n’a pas le droit d’utiliser la variable cpt déclarée en local dans le programme principal. Une question qui se pose alors est de savoir comment procédures et programmes vont pouvoir communiquer des données. Par exemple, on pourrait vouloir que le programme principal communique à le procédure combien d'étoiles afficher par ligne. Cela est possible grâce aux paramètres. Un paramètre est une variable particulière qui sert à la communication entre programme appelant et sous -programme. Exemple : Dans notre exemple, nous allons mettre le nombre d'étoiles par lignes en paramètre. Pour cela, nous indiquons entre parenthèses la déclaration du paramètre (qui est une variable de la procédure !), précédé du mot clé donnée pour indiquer que le paramètre constitue une donnée du traitement réalisé par la procédure. La valeur de cette donnée est communiquée à l'appel, par le programme appelant. Procédure ligneEtoile(donnée nombre : entier ) //sous-programme Var paramètre formel cpt : entier Début Pour cpt de 1 jusqu'à nombre Faire Afficher '*' FinPour Afficher '\n' FinProc Programme RectangleEtoile //programme appelant Var nlignes, netoiles: entier //nombre de lignes et nombre d'étoiles par ligne i : entier Début Afficher "Ce programme dessine un rectangle d'étoiles." Afficher "Combien voulez-vous d'étoiles par ligne?" Saisir netoiles Afficher "Combien voulez-vous de lignes?" Saisir nlignes Pour i de 1 jusqu'à nlignes Faire ligneEtoile (netoiles) FinPour paramètre effectif Fin Fonctionnement du passage des paramètres (de type donnée) Lors de l'appel de la procédure, la valeur de la variable netoiles passée en argument est copiée dans le paramètre formel nombre (qui est une variable). La procédure effectue alors le traitement avec la variable nombre qui a bien la valeur voulue: celle de netoiles. La procédure n'utilise par directement la variable netoile : elle utilise sa valeur, qu'elle a recopiée dans sa propre variable -paramètre. 3 S. Laporte Chap 5 Programme RectangleEtoile copie Lycée Louise Michel BTS IG 1 Procédure ligneEtoile paramètre donnée netoiles nombre i nlignes cpt I $ Remarque importante sur l'ordre et le nombre des paramètres Lorsqu'il y a plusieurs paramètres dans la définition d'une procédure, il faut absolument qu'il y en ait le même nombre à l'appel et que l'ordre soit respecté (car la copie se fait dans l'ordre). Les paramètres réels et formels Il est primordial de bie n distinguer les paramètres qui se trouvent dans l'en-tête d'une procédure, lors de sa définition et les paramètres (ou arguments) qui se trouvent placés entre parenthèses lors de l'appel. Ø Les paramètres placés dans la définition d'une procédure sont les paramètres formels . Ils servent à décrire le traitement à réaliser par la procédure indépendamment des valeurs traitées. Les paramètres formels sont des variables locales à la procédure, et à ce titre ils sont déclarés dans l'entête de la procédure. Ø Les paramètres placés dans l'appel d'une procédure sont les paramètres réels ou effectifs. Lorsqu'ils sont de type donnée, ils contiennent effectivement les valeurs sur lesquelles sera effectué le traitement de la procédure. Lors de l'appel, leur valeur est recopiée dans les paramètres formels correspondants. Un paramètre effectif en donnée peut être soit une variable du programme appelant, soit une valeur littérale, soit le résultat d'une expression. LES FONCTIONS Les fonctions sont des sous-programmes qui retournent un et un seul résultat au programme appelant. De ce fait, les fonctions sont appelées pour récupérer une valeur, alors que les procédures ne renvoient aucune valeur au programme appelant. L'appel des fonctions est différent de l'appel des procédures : L'appel d'une fonction doit obligatoirement se trouver à l'intérieur d'une instruction (affichage, affectation,…) qui utilise sa valeur. Le résultat d'une fonction doit obligatoirement être retourné au programme appelant par l'instruction Retourne. Syntaxe générale Fonction nom(déclaration des paramètres) : type de la valeur retournée Var //variables locales I instruction obligatoire Début //traitement Retourne valeur à retourner FinFonction correspond à la valeur d'une variable, d'une expression ou d'une valeur littérale. 4 S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 Exemple : déclaration du paramètre formel Fonction factorielle(n: entier) : entier type de la valeur retournée /*Cette fonction retourne la factorielle du nombre n passé en paramètre*/ Var commentaires de spécifications i : entier fact : entier Début fact ß 1 Si n ? 0 Alors Pour i de 1jusqu'à n faire fact ß fact * n FinPour FinSi Retourne fact instruction de retour FinFonction DEFINITION de la fonction factorielle Fonction saisie_nb_positif( ) : entier /*Cette fonction permet de faire saisir à l'utilisateur un nombre positif qui est alors retourné*/ Var nb_saisi :entier Début Afficher "Veuillez entrer un nombre positif" Saisir nb_saisi Tantque nb_saisi < 0 Faire Afficher "Erreur. Saisissez un nombre supérieur à 0 s'il vous plait !" Saisir nb_saisi FinTantque Retourne nb_saisi FinFonction Exemple de programme appelant utilisant ces deux fonctions: Programme affiche_factorielle Var nombre: entier appel de la fonction saisie_nb_positif rep : chaîne et affectation de sa valeur retournée à la Début variable nombre Répéter nombre ß saisie_nb_positif( ) paramètre effectif Afficher "La factorielle de ", nombre, " est ", factorielle(nombre) Afficher "Voulez-vous recommencez? (oui/non)" appel de la fonction Saisir rep factorielle et affichage de sa valeur retournée Jusqu'à rep = "non" Afficher "A bientôt" Fin Remarque : Les paramètres d'une fonction sont toujours de type donnée. La valeur des paramètres effectifs à l'appel est recopiée dans les paramètres formels qui servent à réaliser le traitement de la fonction. 5 S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 LES PROCEDURES (suite et fin) Comment faire pour qu'un sous-programme communique plusieurs résultats au programme appelant? C'est impossible avec une fonction qui ne donne qu'un seul résultat, mais c'est possible grâce aux procédures ayant des paramètres de statut résultat. Une procédure peut renvoyer plusieurs résultats au programme appelant à travers des paramètres de statut résultat. Elle peut aussi modifier la valeur d'un paramètre : ce paramètre doit alors avoir le statut de donnéerésultat. Rappel et mise en garde: une fonction ne communique pas son résultat à travers un paramètre, mais à travers une simple valeur de retour. Ne pas confondre avec les paramètres résultats utilisés dans les procédures ! Le mode de communication est totalement différent Il existe donc trois statuts pour les paramètres des procédures: donnée, résultat et donnée-résultat Programme appelant Procédure à l'appel à la fin de la procédure donnée résultat à l'appel donnée-résultat à la fin de la procédure copie de valeur Nous avons déjà étudié le fonctionnement des paramètres données dans la première partie de ce cours; nous allons voir ci-dessous le fonctionnement des deux autres. Les paramètres résultats (en sortie) Les paramètres résultats sont communiqués au programme appelant au moment du retour d'appel, c'est-àdire à la fin de la procédure. La valeur du paramètre formel résultat est alors copiée dans la variable passée en paramètre dans l'appel (le paramètre effectif). La valeur initiale du paramètre effectif (à l'appel) n'a aucune importance ; elle est même souvent indéterminée. La procédure se charge de lui affecter une valeur. Exemple: Voilà tout d'abord une procédure qui permet de saisir les valeurs (c'est-à-dire d'initialiser) un tableau de 30 réels. Cette procédure n'a qu'un paramètre : le tableau. C'est un résultat de la procédure. Procédure Saisietab( résultat untab : tableau[1..30] de réels) Var i: entier Début Pour i de 1 jusqu'à 30 Faire Saisir untab[i] FinPour /*à la fin de la boucle, le tableau est rempli*/ FinProc 6 S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 Voilà une autre procédure qui trouve le minimum et le maximum dans un tableau de 30 réels. Le tableau est une donnée, le minimum et le maximum sont des résultats. Procédure minmax (donnée letab : tableau [1..30] de réels résultats mini, maxi : réels ) Var i : entier Début mini ß letab[1] maxi ßletab[1] Pour i de 2 jusqu'à 30 Faire Si tab[i]< mini Alors mini ß letab[i] FinSi Si tab[i]> maxi Alors maxi ß letab[i] FinSi FinPour /*A la sortie de la boucle, mini et maxi contiennent respectivement la valeur du minimum et la valeur du maximum*/ FinProc Voilà comment ces procédures peuvent être appelées dans un programme qui saisit 30 notes et affiche la note maximale et la note minimale Programme notes Var tabnotes: tableau [1..30] de réels notemin, notemax: réels Début Afficher "Veuillez saisir les 30 notes" Appel de la procédure Saisietab Le paramètre est un tableau I Attention : on ne met pas de crochets ! Saisietab(tabnotes) minmax(tabnotes, notemin, notemax) I Attention à l'ordre des paramètres Afficher " La note la plus haute est ", notemax, "et la note la plus basse est ", notemin Fin Programme notes appel notemin au retour d'appel Procédure Saisietab notemax i 7 S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 Programme notes à l'appel Procédure minmax notemin au retour d'appel mini maxi notemax i $ Remarques : Ø On peut passer tout un tableau en paramètre. C'est une exception à la règle de manipulation des tableaux : normalement, on ne peut pas les manipuler globalement, mais par exception, on peut les utiliser globalement lorsqu'on les passe en paramètre. Ø Les deux procédures utilisent toutes les deux une variable appelée i. Mais i correspond à deux variables différentes. Le i de la première procédure ne correspond pas à la même variable que le i de la deuxième procédure : chaque sous-programme a son espace mémoire propre. Paramètres donnée-résultat (en entrée-sortie) Les paramètres données-résultats correspondent à des données qui doivent être modifiées par une procédure. A l'appel, la valeur du paramètre effectif est copié dans le paramètre formel de la procédure. La procédure se sert de cette valeur pour la modifier. A la fin de la procédure, la nouvelle valeur du paramètre formel est recopiée dans le paramètre effectif du programme appelant. Exemple : Voilà une procédure qui prend pour paramètre un tableau de 10 entiers non trié et qui le renvoie trié en ordre croissant. Le tableau est à la fois une donnée et un résultat de la procédure. Procédure tabtri( donnée-résultat letab : tableau[1...10] d'entiers) Var échange : booléen i, fin : entier //indices (fin = dernier indice traité) temp : entier //variable servant à l'échange Début échange ß faux fin ß 10 -1 Répéter Tantque i < fin Faire Si letab[i] > letab[i+1] Alors échange ß vrai temp ß letab[i] letab[i] ß letab[i+1] letab[i+1] ß letab[i] FinSi 8 S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 iß i + 1 FinTantque fin ß fin – 1 Jusqu'à non échange /* à la sortie de la boucle, il n'y a plus d'échanges possibles donc le tableau est trié */ FinProc Programme tri Var montablo: tableau[1..10] d'entiers i :entier Début Afficher "Tapez 10 valeurs entières" Pour i de 1 jusqu'à 10 Faire Saisir montab[i] FinPour Appel de la procédure Le paramètre est un tableau I Attention : on ne met pas les crochets à l'appel! tabtri(montab) Affiche r "Voilà les valeurs triées dans l'ordre" Pour i de 1 jusqu'à 10 Faire Afficher montab[i] FinPour Fin Résumé des différents statuts pour les paramètres • paramètre donnée (appelant à sous-programme) la valeur du paramètre effectif est utilisée dans la procédure et elle reste inchangée. • paramètre résultat (sous-programmeà appelant) la valeur initiale du paramètre effectif est ignorée par la procédure. La valeur final du paramètre formel résultat est copiée dans le paramètre effectif correspondant (qui doit obligatoirement être une variable de même type) • paramètre donnée-résultat ( appelant ßà sous-programme) La valeur initiale paramètre effectif est utilisée par la procédure qui modifie cette valeur. Au retour d'appel, la nouvelle valeur est recopiée dans le paramètre effectif correspondant (qui est obligatoirement une variable) Résumé des différences entre fonctions et procédures. Les fonctions ne peuvent avoir que des paramètres données. Les fonctions ne peuvent communiquer qu'un seul résultat au programme appelant à travers une valeur de retour (et non à travers un paramètre) Une s'appelle à l'intérieur d'une instruction. L'instruction utilise la valeur retournée par la fonction. Les procédures peuvent avoir des paramètres résultats, données ou données-résultats. Les procédures peuvent communiquer de 0 à plusieurs résultats au programme appelant à travers des paramètres résultats ou donnéesrésultats. La valeur de ces résultat est affectée aux paramètres effectifs correspondant (qui doivent obligatoirement être des variables du programme appelant). L'appel d'une procédure représente une instruction en elle- même. On ne peut pas appeler une procédure au milieu d'une instructio n 9 S. Laporte Chap 5 Lycée Louise Michel BTS IG 1 10