Algorithme:Sous-procédures
Un article de WikiTuto.
Sommaire |
Explication
Les fonctions, c'est bien, mais dans certains cas, ça ne nous rend guère service.
Il peut en effet arriver que dans un programme, on ait à réaliser des tâches répétitives, mais que ces tâches n'aient pas pour rôle de générer une valeur particulière, ou qu'elles aient pour rôle d'en générer plus d'une à la fois. Vous ne voyez pas de quoi je veux parler ? Prenons deux exemples. Premier exemple. Imaginons qu'au cours de mon application, j'aie plusieurs fois besoin d'effacer l'écran et de réafficher un bidule comme un petit logo en haut à gauche. On pourrait se dire qu'il faut créer une fonction pour faire cela. Mais quelle serait la valeur renvoyée par la fonction ? Aucune ! Effacer l'écran, ce n'est pas produire un résultat stockable dans une variable, et afficher un logo non plus. Voilà donc une situation ou j'ai besoin de répéter du code, mais où ce code n'a pas comme rôle de produire une valeur.
Deuxième exemple. Au cours de mon application, je dois plusieurs fois faire saisir un tableau d'entiers (mais à chaque fois, un tableau différent). Là encore, on serait tenté d'effectuer toutes ces saisies de tableaux dans une seule fonction. Mais problème, une fonction ne peut renvoyer qu'une seule valeur à la fois. Elle ne peut donc renvoyer un tableau, qui est une série de valeurs distinctes.
Alors, dans ces deux cas, faute de pouvoir traiter l'affaire par une fonction, devra-t-on en rester au code répétitif dont nous venons de dénoncer si vigoureusement les faiblesses ? Mhhh ? Vous vous doutez bien que non. Heureusement, tout est prévu, il y a une solution. Et celle-ci consiste à utiliser des sous-procédures.
En fait, les fonctions - que nous avons vues - ne sont qu'un cas particulier des sous-procédures - que nous allons voir : celui où doit être renvoyé vers la procédure appelante une valeur et une seule. Dans tous les autres cas, il faut donc avoir recours non à la forme particulière et simplifiée (la fonction), mais à la forme générale (la sous-procédure).
Syntaxe
Parlons donc de ce qui est commun aux sous-procédures et aux fonctions, mais aussi de ce qui les différencie. Voici comment se présente une sous-procédure :
Procédure Bidule( ... ) ... Fin Procédure
Dans la procédure principale, l’appel à la sous-procédure Bidule devient quant à lui :
Appeler Bidule(...)
Etablissons un premier état des lieux.
- Alors qu'une fonction se caractérisait par les mots-clés Fonction ... Fin Fonction, une sous-procédure est identifiée par les mots-clés Procédure ... Fin Procédure. Oui, je sais, c'est un peu trivial comme remarque, mais, bon, on ne sait jamais.
- Lorsqu'une fonction était appelée, sa valeur (retournée) était toujours affectée à une variable. L'appel à une procédure, lui, est au contraire toujours une instruction autonome. "Exécute la procédure Bidule" est un ordre qui se suffit à lui-même.
- Toute fonction devait, pour cette raison, comporter l'instruction "Renvoyer". Pour la même raison, l'instruction "Renvoyer" n'est jamais utilisée dans une sous-procédure. La fonction est une valeur calculée, qui renvoie son résultat vers la procédure principale. La sous-procédure, elle, est un traitement ; elle ne "vaut" rien.
- Même une fois qu'on a bien compris les trois premiers points, on n'est pas au bout de nos peines.
En effet, il nous reste à examiner ce qui peut bien se trouver dans les parenthèses, à la place des points de suspension, aussi bien dans la déclaration de la sous-procédure que dans l'appel. Vous vous en doutez bien : c'est là que vont se trouver les outils qui vont permettre l'échange d'informations entre la procédure principale et la sous-procédure (en fait, cette dernière phrase est trop restrictive : mieux vaudrait dire : entre la procédure appelante et la procédure appelée. Car une sous-procédure peut très bien en appeler elle-même une autre afin de pouvoir accomplir sa tâche)
Entré et sortie
Dans une fonction, les valeurs qui circulaient depuis la procédure (ou la fonction) appelante jusqu'à la fonction portaient le nom d'arguments. Là, les valeurs qui circulent depuis la procédure (ou la fonction) appelante vers la sous-procédure appelée se nomment des paramètres en entrée de la sous-procédure. Mais seul le nom change : "paramètres en entrée" pour les procédures ou "arguments" pour les fonctions, on parle en fait exactement de la même chose.
Inversement, dans une fonction, la valeur retournée par la fonction portait le nom de la fonction elle-même, et elle faisait l'objet d'une instruction spéciale ("renvoyer"). Avec une sous-procédure, les valeurs retournées, quand il y en a, s'appellent des paramètres en sortie de la sous-procédure, qui doivent être déclarés explicitement comme tels.
Ceci nous permet de reformuler en termes un peu différents la vérité fondamentale apprise un peu plus haut : toute sous-procédure possédant un et un seul paramètre en sortie peut également être écrite sous forme d'une fonction (et entre nous, c'est préférable car un peu plus facile).
Il ne vous reste plus qu'une seule chose à savoir avant de pouvoir passer à la pratique. C'est que dans la plupart des langages, on ne parlera pas de paramètres "en entrée" ou "en sortie", mais de "paramètres transmis :
- par valeur (correspondant à un paramètre en entrée)
- par référence(correspondant à un paramètre en sortie)
On peut également imaginer le cas d’un paramètre qui serait passé à une procédure à la fois en entrée et en sortie : on envoie une variable à une procédure, afin qu’elle la traite et la renvoie modifiée. Dans ce cas, le paramètre aura également le statut d’une transmission par référence (qui peut le plus peut le moins).
Tout cela peut sembler un tantinet compliqué. Mais sur le principe, c'est en réalité assez simple, et dès que vous aurez pratiqué un peu, vous ferez cela les yeux fermés. Reprenons le cas d'un programme au cours duquel on a plusieurs tableaux d'entiers à faire saisir par l'utilisateur. Puisqu'un tableau comporte plusieurs valeurs, nous savons qu'il ne peut, par définition, être renvoyé par une fonction. Mais une sous-procédure, elle, comporte autant de paramètres en sortie qu'on veut. Elle peut donc sans problème renvoyer un tableau vers la procédure qui l'appelle. Ecrivons donc notre sous-procédure : Procédure SaisieTab(T() en numérique par référence, N en entier par valeur) Pour i ← 0 à N-1 Ecrire "Saisie de la valeur n° ", i + 1 Lire T(i) i suivant Fin Procédure
Et son appel :
Tableau Truc(5), Machin(12) en Entier ... Appeler SaisieTab(Truc, 5) ... Appeler SaisieTab(Machin, 12) ... Fin Procédure
La seule chose à remarquer, c'est que les variables manipulées par la sous-procédure (notamment le tableau T) ne sont pas celles qui sont manipulées dans la procédure appelante (les tableaux Truc et Machin).
Ceci n'est pas une obligation : on pourrait imaginer une architecture où ce seraient les mêmes variables qui seraient triturées dans la procédure appelante et dans la sous-procédure (ces variables porteraient alors le même nom). Mais une telle architecture, si elle est possible, doit rester l'exception à laquelle on n'a recours qu'en cas de besoin très particulier. En effet, pour qu'une telle chose soit possible, il faut que la variable ait la capacité de conserver sa valeur d'une procédure à l'autre ; en quelque sorte, qu'elle survive même si la procédure qui la manipulait se termine. Ce genre de variable dopée à l'EPO existe, on en reparlera dans un instant, mais elle est très gourmande en ressources mémoire. Donc, comme toujours, vous connaissez la chanson, on applique le principe de l'économie de moyens.
Conclusion : une sous-procédure est un morceau de code qui comporte éventuellement des paramètres en entrée (transmis par valeur) et des paramètres en sortie (transmis par référence). La sous-procédure manipule donc des variables qui lui sont propres, et la procédure appelante agit de même. La présence des paramètres dans l'appel à la sous-procédure et dans le titre de celle-ci assure le fait que la valeur des uns sera recopiée dans les autres (transmission par valeur) et qu'en retour, celle des autres sera recopiée dans les uns (transmission par référence).
Voir aussi
- Algorithmes
- Fonctions personnalisées
- Sous-procédures
- Variables publiques et privées
- Algorithmes fonctionnels
Source : Christophe Darmangeat



