• Aucun résultat trouvé

2 Diviser pour régner

1. Simulation du tirage du Lotto

1.8 Comment se passe l'exécution de l'ensemble ?

Nous allons, une fois de plus, en donner une description métaphorique et imagée, qui va faire intervenir non plus un, mais plusieurs exécutants, chacun étant accompagné de son "installateur d'étiquettes".

Disons, dès à présent, que chaque procédure aura son exécutant propre (disposant de la partie exécutable du texte de la procédure concernée) et son "installateur d'étiquettes" (disposant de la partie déclaration de cette même procédure).

1. L'exécution commence par le travail du couple exécutant-installateur chargé du programme principal. Ce dernier peut être trouvé sous forme "marche à suivre" à la page 69 et sous forme "programme" à la page 73. Il s'agit bien du seul texte (déclaration et corps du programme) du programme principal et non du texte global comportant également les textes des procédures.

L'installateur d'étiquettes note dans un coin du local les constantes (NTT = 7, NNP = 42) et les types (ici, un seul type, à savoir NumerosPossibles = 1..NNP), afin que ces définitions

soient disponibles tout au long de l'exécution. Il réserve ensuite les casiers (Compteur et

Reponse) et l'étagère (Tirages) indiqués (dans la partie déclaration dont il dispose) et y colle

les étiquettes mentionnées. Le local ressemble alors à

Tirages Compteur Reponse

32 1 14 2 3 3 3 4 40 5 3 6 3 NNT 2 L NNP=42 NNT=7 NumerosPossibles=1..NNP

On remarquera que, comme d'habitude, des informations (du type approprié) traînent dans les casiers et les tiroirs.

2. Cela fait, c'est l'exécutant-principal qui commence son travail. La première instruction qu'il rencontre, (outre randomize si on se réfère au texte du programme et qui est sans grand intérêt ici) est AVERTIR; elle ne fait pas partie des instructions élémentaires qu'il "comprend", il se tourne donc vers un coin du local où des exécutants-auxiliaires sont en train d'attendre, chacun accompagné de son installateur d'étiquettes. Il a devant les yeux trois candidats : TIRER, AVERTIR, et AFFICHER.

Il appelle donc le couple chargé d'AVERTIR et se retire dans le coin opposé du local. Le couple chargé d'AVERTIR vient alors faire le travail mentionné par le texte de la procédure correspondante. A l'issue de ce travail (que je ne détaille pas ici car sa simplicité ne nous permettrait pas d'illustrer les faits importants), il "rend la main" à celui qui avait fait appel à ses services, l'exécutant-principal.

3. Ce dernier poursuit l'exécution là où il s'était interrompu lorsqu'il avait appelé AVERTIR. Il va donc, comme commandé par le programme principal :

- placer un nombre au hasard dans le premier tiroir de Tirages;

- donner (comme le demande la boucle POUR...) la valeur 2 à Compteur.

Il tombe alors sur l'ordre TIRER. A nouveau, il se tourne vers le coin du local où les exécutants sont en attente et appelle le couple chargé de TIRER en lui laissant un local :

Tirages Compteur Reponse

23 1 2 3 4 5 6 NNT 2 NNP=42 NNT=7 NumerosPossibles=1..NNP

où cette fois, pour la facilité, les casiers et tiroirs dont le contenu est non significatif ont été dessiné vides.

4. L'installateur (qui dispose de la partie déclaration) de TIRER (Cf. page 76), installe comme demandé une étiquette Egalite sur un casier de type booléen. C'est alors l'exécutant de TIRER qui commence le travail exigé par la partie exécutable de TIRER. Comme indiqué, il consulte Compteur (contenant 2) et place un nombre au hasard (ici 6) dans le tiroir numéro

Compteur (2) de Tirages.10 L'instruction suivante est VERIFIER. L'exécutant de TIRER se tourne à son tour vers le coin du local où se tient le couple chargé de VERIFIER. Il appelle donc ce couple et rejoint dans le coin opposé, l'exécutant-principal toujours en train d'attendre, laissant aux arrivants un local :

Egalite

Tirages Compteur Reponse

23 1 6 2 3 4 5 6 NNT 2

10 Si vous disposez du docuemnt "en couleur", le travail de TIRER est présenté en bleu et ce lui de VERIFIER en vert sur les schémas qui suivent.

NNP=42 NNT=7

NumerosPossibles=1..NNP

5. L'installateur de VERIFIER colle, comme cela est exigé dans la partie déclaration de la procédure VERIFIER (page 77), l'étiquette C sur un casier entier et le travail de l'exécutant VERIFIER commence alors avec un local :

C

Egalite

Tirages Compteur Reponse

23 1 6 2 3 4 5 6 NNT 2 NNP=42 NNT=7 NumerosPossibles=1..NNP L'exécutant, comme indiqué dans la partie exécutable de VERIFIER (page 77) : - place 0 dans C;

- remplace ce contenu de C par la valeur suivante (succ(C)). C contient alors 1;

- évalue la valeur de l'expression booléenne Tirages [C] = Tirages [Compteur] (en l'occurence ici la valeur de Tirages [1] = Tirages [2], soit faux) et place le résultat de l'évaluation dans Egalite;

- il évalue alors la condition C=pred(Compteur) ou Egalite; comme elle est vraie (puisque

C=pred(Compteur) la boucle Répéter s'arrête là.

Le travail de l'exécutant chargé de VERIFIER s'arrête donc là. Son installateur d'étiquettes

reprend l'étiquette C qu'il avait fixée et tous deux retournent dans le coin du local d'où ils

venaient, non sans avoir préalablement rendu la main à l'exécutant de TIRER qui retrouve donc un local qui a l'aspect suivant :

Egalite

faux

Tirages Compteur Reponse

23 1 6 2 3 4 5 6 NNT 2 NNP=42 NNT=7 NumerosPossibles=1..NNP

où ne subsiste plus aucune trace de l'étiquette C installée par le couple chargé de VERIFIER. 6. L'exécutant de TIRER poursuit l'exécution de sa marche à suivre (page 75 ou 76)

interrompue par l'appel de VERIFIER; il lui reste seulement à tester la valeur de la condition not Egalite. La condition étant vraie, son travail s'interrompt. Il prévient son installateur d'étiquettes qui reprend l'étiquette Egalite qu'il avait apposée et tous deux retournent attendre dans le coin du local en rendant le contrôle à l'exécutant-principal.

7. Ce dernier retrouve un local qui lui est familier, le seul changement visible étant le remplissage du tiroir n° 2 de Tirages :

Tirages Compteur Reponse

23 1 6 2 3 4 5 6 NNT 2 NNP=42 NNT=7 NumerosPossibles=1..NNP

Il lui reste (page 69 ou 73) à incrémenter la valeur du Compteur (qui vaut alors 3) et à constater que cette valeur ne dépasse pas NNT (test inhérent à la boucle Pour). Comme précédemment, il appelle alors TIRER pour la suite du travail.

8. Le ballet se poursuit avec une nouvelle arrivée du couple chargé de TIRER et l'installation de l'étiquette Egalite sur un casier de type booléen (pas nécessairement le même que précédemment).

Ce sera ensuite l'appel de VERIFIER, l'installation de l'étiquette C, le travail de l'exécutant puis le départ en emportant l'étiquette C.

Le travail de TIRER se poursuivra avec soit le rappel de VERIFIER après un nouveau tirage (si le précédent était inadéquat), soit la fin du travail (de TIRER) et le retour de l'exécutant-principal.

9. Le cycle se poursuivra jusqu'à ce que Tirages soit correctement garnie. Il reste un détail important à signaler : lorsque l'exécutant-principal, face à la commande AFFICHER, appelle le couple qui en est chargé,

ce dernier découvre un local :

Tirages Compteur Reponse

23 1 6 2 14 3 4 4 31 5 35 6 2 NNT NNP=42 NNT=7 NumerosPossibles=1..NNP

Comme exigé (page 78), l'installateur colle sur un casier de type entier une nouvelle étiquette

Compteur et l'exécutant chargé de AFFICHER se met au travail. Il est fait mention du casier Compteur dans le texte de la marche à suivre dont il dispose. Et face à lui, deux casiers

étiquetés Compteur se présentent : le sien (repéré par une étiquette rouge et soulignée) et celui précédemment installé par l'exécutant-principal

⇓⇓⇓⇓⇓

Compteur

⇓⇓⇓⇓⇓

Tirages Compteur Reponse

23 1 6 2 14 3 4 4 31 5 35 6 2 NNT

NNP=42 NNT=7

NumerosPossibles=1..NNP

Le choix sera alors toujours identique : c'est du plus récemment installé (celui qui est "le plus haut" avec le type de schéma proposé où les casiers les plus récemment étiquetés sont dessinés au dessus) dont il est forcément question. C'est donc avec son casier Compteur que le travail sera effectué. Le seul casier alors tout à fait inaccessible à l'exécutant chargé d'AFFICHER est le Compteur défini par l'installateur-principal (et situé plus bas).

Cette description imagée touche donc à des concepts importants de la programmation : variables globales et locales, portée d'une variable, appel de procédure...

Notons encore que le comportement décrit est celui prescrit par le langage Pascal, mais que d'autres langages seraient redevables des mêmes explications.

Ainsi donc,

- Chaque procédure peut comporter une partie déclaration de variables (et de constantes et de types). Ces déclarations restent valables tant que l'exécutant-auxiliaire chargé de cette procédure ne clôture pas son travail : soit qu'il soit lui-même au travail, soit qu'il ait fait appel à son tour à d'autres auxiliaires.

- A la fin de l'exécution de la procédure, toutes les déclarations locales effectuées disparaissent. Dans la métaphore employée, les étiquettes (mais ce serait aussi le cas des déclarations de constantes et de type) cessent d'exister lorsque l'exécutant retourne dans le coin du local d'où il venait, rendant alors la main à l'exécutant qui l'avait appelé.

- Lorsque plusieurs variables portant le même nom sont présentes pendant le déroulement d'une procédure, c'est toujours la plus récemment installée qui prévaut.

Ces trois règles rendent compte de la manière dont un programme Pascal est exécuté au fil des appels successifs. Classiquement, on emploie les termes de variables globales pour celles définies au sein du programme principal et de variables locales pour celles définies au sein des diverses procédures. Il faut regretter cette terminologie : plutôt qu'une connotation spatiale comme celle apportée par les mots "local" ou "global", c'est d'une connotation temporelle dont nous avons besoin; plutôt que "globale" et "locale", c'est de "permanente" et "temporaire" qu'il faudrait parler.

Le terme local (ou temporaire) doit d'ailleurs être pris dans un sens relatif et non absolu. Ce qui est "local" pour une procédure est bien entendu "global" pour les procédures (filles et autres descendantes) qu'elle appelle. On parle également de portée d'une variable en évoquant la portion du programme où elle peut être invoquée et utilisée. La description imagée fournie ci-dessus suffit pour décider aisément où (ou plutôt quand) l'emploi d'une variable est permis : pendant l'exécution des procédures filles appelées (et des autres descendants appelés ensuite).

Ainsi donc, une déclaration faite au sein du programme principal ou d'une procédure est valable pour toutes les procédures "descendantes" (filles, petites-filles, ...). Autrement dit, lorsque l'exécutant d'une procédure commence son travail, il a accès à toutes les variables de ses ascendantes directes (et bien entendu du programme principal), hormis celles dont les noms sont identiques, auquel cas, seule la plus récente est accessible. Et il en va de même de toutes les déclarations.

Nous verrons dans la suite "qui peut appeler qui au sein" de la généalogie des procédures constituant l'ensemble d'un programme.

Retenons seulement pour l'instant que le programme principal ou une procédure peut seulement appeler ses procédures filles, à l'exclusion des autres descendantes. Pas question donc, dans le problème du Lotto traité ci-dessus que le programme principal puisse appeler la procédure VERIFIER (qui est une petite fille et non une fille) (Cf. page 79).