• Aucun résultat trouvé

Tours de main

1. Traitement des exemples

1.3 Le dernier et le précédent

La tâche est, on va le voir, bien proche de la précédente :

1.3.1 Enoncé (Quoi faire ?)

Faire :

- lire successivement des mots (d'au plus 20 caractères),

- arrêter à la donnée de "STOP", à condition que "ATTENTION" ait été fourni juste avant, - dire alors combien de mots ont été lus.

Les étapes essentielles de la démarche ont été longuement illustrées et commentées sur les deux exemples précédents. Je me permettrai à présent d'être un peu plus laconique.

1.3.2 Comment faire ?

1. On retient un instant chaque mot lu, en étant particulièrement attentif au mot suivant lorsque c'est "ATTENTION" qui vient d'être lu. Si le mot suivant n'est pas "STOP", alors on "oublie" que "ATTENTION" venait d'être lu. De plus, on compte tous les mots.

Ou encore

2. On retient un instant le dernier mot lu et l'avant-dernier. On compte au fur et à mesure.

1.3.3 Comment faire faire ? Première solution

Je vais faire usage, à nouveau, d'un signal qui détectera le passage de 'ATTENTION'. Signal passera à 'ROUGE' à la lecture de 'ATTENTION'. Mais ce 'ROUGE' ne comptera que si, à la lecture suivante, le mot 'STOP' est fourni. Sinon, Signal doit repasser au 'VERT'. Autrement dit, lorsque le mot lu n'est pas 'ATTENTION' et que le signal est 'ROUGE' (donc 'ATTENTION' vient d'être lu), il est impératif qu'il repasse à 'VERT', si le mot lu n'est pas 'STOP'. (Ouf ... !)

Cette approche, qui privilégie une nouvelle utilisation de variable signal est, on en conviendra, assez complexe, pour ne pas dire obscure. On le verra, la deuxième solution semble nettement plus simple et "naturelle". Rappelons encore que "lu" signifie ici que l'exécutant-ordinateur saisit l'information correspondante à travers la porte-clavier.

Liste des variables

- MotLu, de type chaîne d'au plus 20 caractères, - Compteur, de type entier,

- Signal, de type chaîne d'au plus 5 caractères. Il passera au 'ROUGE' si 'ATTENTION' est lu, mais en restant 'ROUGE', seulement si c'est 'STOP' qui suit; sinon, il repasse au 'VERT'.

Place 0 dans le casier Compteur Place 'VERT' dans le casier Signal

Affiche 'Donnez un mot' Lis et place dans MotLu

Place Compteur + 1 dans le casier Compteur

MotLu = 'ATTENTION'

V ? F

Place 'ROUGE' dans Signal MotLu ≠ 'STOP'

V ? F

Place 'VERT' dans Signal

MotLu = 'STOP' et Signal = 'ROUGE' Affiche Compteur

ou sous forme pseudo-code :

Place 0 dans le casier Compteur Place 'VERT' dans le casier Signal REPETER

Affiche 'Donnez un mot' Lis et place dans MotLu

Place Compteur + 1 dans le casier Compteur SI MotLu = 'ATTENTION' ALORS

Place 'ROUGE' dans Signal

SINON

SI MotLu ≠ 'STOP' ALORS Place 'VERT' dans Signal

JUSQU'A CE QUE MotLu = 'STOP' et Signal = 'ROUGE' Affiche Compteur

Deuxième Solution

Elle correspond à l'attitude consistant à retenir chaque mot, ainsi que le précédent, tout en les comptant. Trois variables seront dès lors nécessaires : celle contenant le dernier mot lu, celle contenant le précédent et celle permettant de compter.

Liste des variables

- Dernier, de type chaîne d'au plus 20 caractères, qui contiendra le dernier mot lu,

- AvantDernier, de type chaîne d'au plus 20 caractères, qui contiendra l'avant-dernier mot, - Compteur, de type entier.

Marche à suivre

La seule difficulté, c'est de faire en sorte, qu'au "bon moment", le contenu de Dernier soit transféré dans AvantDernier.

Après les initialisations d'usage, je commanderai de répéter un même groupe d'actions. On va voir que l'ordre dans lequel ces actions sont commandées est, ici, fort important. Si je commande de répéter :

- recopie Dernier dans AvantDernier, - compte.

et cela, jusqu'à, ce que Dernier contienne 'STOP' et AvantDernier contienne 'ATTENTION', j'aboutis à une absurdité, puisque Dernier et AvantDernier contiendront à coup sûr le même mot.

En réalité, il faut d'abord faire transférer le contenu de Dernier dans AvantDernier avant de faire lire un nouveau mot pour le placer dans Dernier (et non après, comme ci-dessus). Je commanderai donc la répétition des actions suivantes (cette fois dans le bon ordre) :

- recopie Dernier dans AvantDernier, - lis un mot et place le dans Dernier, - compte.

Avec l'habituelle initialisation du Compteur, ceci conduit au GNS : Place 0 dans le casier Compteur

Place Dernier dans le casier AvantDernier Affiche 'Donnez un mot'

Lis et place dans Dernier

Place Compteur + 1 dans le casier Compteur

Dernier = 'STOP' et AvantDernier = 'ATTENTION' Affiche Compteur

Malheureusement, un détail rend ce programme incorrect. Imaginons un instant que par un improbable et malheureux hasard, le casier Dernier contienne, avant le début des opérations, le mot 'ATTENTION' et que le tout premier mot fourni par l'utilisateur soit 'STOP'. L'exécutant va successivement poser les actions suivantes (commandées par la marche à suivre) :

- mettre 0 dans Compteur,

- recopier le contenu de Dernier (il y "traîne" 'ATTENTION') dans AvantDernier, qui contiendra alors, lui aussi, 'ATTENTION',

- lire le premier mot ('STOP') et le placer dans Dernier, - augmenter le contenu de Compteur, qui passe donc à 1,

- voir si Dernier contient bien 'STOP' (c'est le cas) et AvantDernier contient 'ATTENTION' (c'est aussi le cas) et donc interrompre immédiatement la répétition,

- afficher 1, contenu de Compteur et arrêter.

Il est facile de voir qu'il faut à tout prix éviter que Dernier contienne primitivement 'ATTENTION' et prendre la peine de le faire initialiser en y plaçant par exemple 'BONJOUR'.

Ceci nous enseigne qu'il faut obligatoirement être fort attentif à ce problème d'initialisation des casiers. Lorsque la première manipulation commandée à propos d'un casier consiste à en prendre le contenu (comme ce serait le cas ici, si je n'avais pas fait les initialisations, pour

Dernier et Compteur), il faut impérativement réfléchir à l'importance de son contenu primitif. Par contre, lorsque la première manipulation faisant intervenir un casier commande d'y placer une information, son initialisation est, généralement, inutile.

Cette précaution conduit au GNS :

Place 0 dans le casier Compteur REPETER

Place Dernier dans le casier AvantDernier Affiche 'Donnez un mot'

Lis et place dans Dernier

Place Compteur + 1 dans le casier Compteur JUSQU'A CE QUE Dernier = 'STOP' et

AvantDernier = 'ATTENTION' Affiche Compteur

Place 0 dans le casier Compteur

Place 'BONJOUR' dans le casier Dernier Place Dernier dans le casier AvantDernier

Affiche 'Donnez un mot' Lis et place dans Dernier

Place Compteur + 1 dans le casier Compteur

Dernier = 'STOP' et AvantDernier = 'ATTENTION' Affiche Compteur

1.4 Compteur et compteur

1.4.1 Enoncé (Quoi faire ?)

Faire

simuler des jets successifs d'un dé en montrant les résultats et en arrêtant au troisième six obtenu; indiquer alors combien de jets ont été effectués.

Simuler signifie ici "faire comme si". Le programme à rédiger doit faire en sorte qu'apparaisse à l'utilisateur une succession de nombres, compris entre 1 et 6 (les résultats des "lancers"). Cette liste doit s'interrompre à l'apparition du troisième 6 et être alors suivie du nombre total de chiffres apparus.

Cet énoncé n'a évidemment de sens que si l'exécutant dispose d'un outil permettant de tirer des nombres au hasard.

Disons simplement à ce propos qu'on pourra se permettre d'écrire l'instruction d'affectation :

Place un nombre au hasard entre 1 et 6 dans ... Je me permets donc de désigner une information entière à manipuler par :

un nombre (entier) au hasard entre 1 et 6,

en réservant au chapitre suivant le problème d'indiquer comment ceci sera traduit, lors du codage en Pascal.

1.4.2 Comment faire ?

Ce qui importe, une fois de plus, c'est de percevoir ce que je retiendrais comme informations (susceptibles de se modifier), si c'était moi qui lançais le dé.

Je garderais à l'esprit :

- un instant, chaque résultat, pour l'annoncer (le faire connaître à l'utilisateur);

- le décompte de tous les lancers, puisqu'il faudra, à la fin, pouvoir indiquer combien il y en a eu au total;

- le nombre de six déjà obtenu, pour être en mesure d'arrêter au troisième.

Ces informations retenues vont à nouveau donner naissance aux casiers nécessaires lorsqu'il s'agira de s'intéresser à l'exécutant "gestionnaire de casiers".

1.4.3 Comment faire faire ?

Nous pouvons donc immédiatement dresser la

Liste des variables

Place 0 dans le casier Compteur

Place 'BONJOUR' dans le casier Dernier REPETER

Place Dernier dans le casier AvantDernier Affiche 'Donnez un mot'

Lis et place dans Dernier

Place Compteur + 1 dans le casier Compteur JUSQU'A CE QUE Dernier = 'STOP' et

AvantDernier = 'ATTENTION' Affiche Compteur

- Resultat, de type entier, qui contiendra un instant chaque résultat du tirage au hasard;

- Compteur, de type entier, pour compter les "lancers"; il s'augmentera de 1 à chaque nouveau

tirage au hasard;

- CompteurDeSix, de type entier, pour compter les six qui se présenteront.

On remarquera que, pour préparer la traduction en Pascal, j'ai, dès à présent, choisi de noter "Resultat" (sans accent), la variable comportant les résultats des tirages. En effet, les noms de variables ne pourront, en Pascal, comporter de lettres accentuées.

Marche à suivre

Son écriture est immédiate. Je vais à nouveau commander une répétition au cours de laquelle un "tirage" sera effectué, affiché, compté et comptabilisé dans CompteurDeSix, s'il s'agit d'un 6. Cette répétition s'arrêtera lorsque le CompteurDeSix contiendra 3.

Place 0 dans le casier Compteur Place 0 dans le casier CompteurDeSix

Place un nombre au hasard entre 1 et 6 dans Resultat Affiche Resultat

Place Compteur + 1 dans le casier Compteur

Resultat = 6

V ? Place CompteurDeSix + 1 dans

CompteurDeSix CompteurDeSix = 3 Affiche Compteur