Catégorie économique – Charleroi Bachelier en informatique de gestion ANALYSE ET CONDUITE DE PROJETS, ALGORITHMIQUE Entraînement à la construction de programmes Chapitres 5 à 7 Boc 1 - Unité 1 – Q1 Wojtalik J., maître-assistant Année académique 2016 – 2017 Préambule Le chapitre 1 a permis d'introduire quelques concepts de façon à bien saisir le contexte de ce cours. Le chapitre 2 s'est attardé sur la notion de donnée. Une introduction au langage descriptif d'algorithmes tel que nous allons l'utiliser a fait l'objet du chapitre 3. Il s'est également attardé sur la notion d'expression arithmétique. Le chapitre 4 a permis d'aborder la notion d'expression logique, tout aussi importante. Les algorithmes réalisés jusqu'à présent mettaient en place des instructions à faire exécuter dans l'ordre strictement séquentiel, en commençant par la première. Il est temps d'aborder les 2 autres structures de programmation permettant de d'afficher des "raisonnements" plus élaborés : la structure répétitive et la structure alternative. C'est également l'occasion d'introduire les notions de compteur et de totalisateur. Table des matières CHAPITRE 5. LA STRUCTURE RÉPÉTITIVE EN LDA 4 1. Programmation structurée 5 2. Boucle avec test après 6 3. Boucle avec test avant 10 4. Quelques cas « incontournables » d’utilisation de boucles 11 La boucle de programme 11 La boucle de confirmation 13 La boucle de validation 14 Imbrication de structures répétitives 17 5. Concaténation de structures répétitives 20 6. Exercices 22 CHAPITRE 6. LES COMPTEURS ET TOTALISATEURS EN LDA 23 1. Notion 24 2. Exercices d’application sur les compteurs et totalisateurs 28 CHAPITRE 7. 1. LA STRUCTURE ALTERNATIVE EN LDA Notion 30 31 Branche vide 33 Tests en cascade 35 Exercices d’application sur l’alternative 42 Exercices récapitulatifs 44 CHAPITRE 5. LA STRUCTURE RÉPÉTITIVE EN LDA 1. Programmation structurée Jusqu’à présent, nos algorithmes ont consisté à faire exécuter une séquence d’instructions une seule fois. L’usage de cet unique modèle n’est pas suffisant pour développer des algorithmes élaborés. Exemple : Soit l’énoncé du chapitre 3, ALGO03155. On entre les mesures d'un triangle en centimètres (entiers). Il faut calculer et afficher la superficie en mètres carrés, yards carrés et pieds carrés (1 pied = 0,3048 mètres). Il a été résolu en utilisant une structure séquentielle. Il peut être intéressant de le modifier, par exemple : - en indiquant que l’on doit pouvoir réaliser des calculs pour autant de triangles que souhaité sans devoir relancer le programme, - en indiquant que l’on peut sélectionner l’unité (mètres carrés ou yards carrés ou pieds carrés) dans laquelle le résultat doit être affiché. Pour couvrir ces exigences, il faut disposer de 2 modèles de structure supplémentaires : la structure répétitive et la structure alternative. La programmation structurée repose sur l’usage de ces 3 structures de base : séquence, répétitive et alternative. En les combinant, on peut construire des algorithmes de complexité variable. Nous allons d’abord étudier les possibilités offertes par la structure répétitive. Quand un traitement ou une séquence de traitement est répété, on dit qu’il y a une boucle ou une itération ou encore une répétition. En programmation structurée, on parle de structure répétitive. Si l'on indique dans un programme qu'il faut boucler, les instructions concernées seront répétées indéfiniment. C’est pour cette raison qu’il faut introduire une « condition de contrôle ». Chapitre 5. La structure répétitive en LDA, page 5 Il s’agit d’une expression logique qui permet, en fonction du résultat « vrai » ou « faux » de son évaluation, de boucler ou non (de quitter la boucle à un moment déterminé). Les variables qui interviennent dans cette expression sont appelées « variables de contrôle ». Il existe plusieurs modèles de boucles mais pour le moment, nous n’en verrons que deux. 2. Boucle avec test après FAIRE { instructions à exécuter } TANT QUE ( expression à évaluer) On constate l’utilisation d’accolades obligatoires (une ouvrante, l’autre fermante) pour délimiter les instructions du bloc. Ce modèle de boucle implique le mécanisme suivant : DEBUT Instructions FAIRE Instructions du bloc TANT QUE VRAI Expression logique FAUX Suite du programme FIN Commentaire : Chapitre 5. La structure répétitive en LDA, page 6 On exécute le bloc d’instructions délimitées par « FAIRE … TANT QUE (expression…) », On évalue l’expression de contrôle de la boucle, Une évaluation à VRAI provoquera une nouvelle exécution du bloc, Alors qu’une évaluation à FAUX provoquera l’exécution de la suite du programme (à partir de la première instruction qui suit la répétitive). Le corps de la boucle (ses instructions) sera exécuté au moins une fois puisqu'il faut passer par le corps de la boucle pour atteindre l'évaluation de l'expression de contrôle. On dit qu’une boucle « FAIRE … TANT QUE (…) » est exécutée 1 à n fois. Exemple : répétition de l’exécution d’un programme Algorithme Exemple_01 VARIABLES // vide pour le moment DEBUT_ALGORITHME FAIRE { // corps // du // programme } TANT QUE ( ???? ) FIN_ALGORITHME Comment contrôler cette boucle ? Quelle forme donner à l’expression de contrôle ? Puisqu’il s’agit de tester la volonté de l’utilisateur de quitter ou non le programme, il suffit de lui poser la question et de tester sa réponse par rapport à une ou des valeurs signifiant « je quitte » ou « je ne quitte pas ». Il est évident qu’il doit connaître ces valeurs, qu’elles doivent lui être communiquées par un affichage. Chapitre 5. La structure répétitive en LDA, page 7 Exemple : on pose une question et l’on construit l’expression correspondante Algorithme Exemple_02 VARIABLES rep : caractère DEBUT_ALGORITHME FAIRE Retenir : expression évaluée à « vrai », on boucle, expression évaluée à « faux », on quitte. { // corps du // programme AFFICHER "Voulez-vous quitter (O pour OUI)" LIRE rep } TANT QUE (rep != "O") FIN_ALGORITHME L’expression de contrôle ne doit pas être nécessairement écrite comme indiqué. On aurait pu décider de quitter par "OUI" ou "YES" ou de poser la question autrement : "Voulezvous recommencer (N pour non)". Ce qui compte, c’est que la convention soit, ici, signalée à l’utilisateur par un message clair et que l’expression logique soit construite en adéquation avec celui-ci. Exemple : une autre façon de la contrôler Algorithme Exemple_03 VARIABLES rep : caractère DEBUT_ALGORITHME Retenir : expression évaluée à « vrai », on boucle, expression évaluée à « faux », on quitte. FAIRE { // corps du // programme AFFICHER "Voulez-vous recommencer (O pour OUI)" LIRE rep } TANT QUE (rep == "O") FIN_ALGORITHME Chapitre 5. La structure répétitive en LDA, page 8 Avec la pratique, vous éviterez ce genre de bêtises : Algorithme Exemple_04 VARIABLES rep : caractère DEBUT_ALGORITHME FAIRE { // corps du programme AFFICHER "Voulez-vous recommencer (O pour OUI)" LIRE rep } TANT QUE ( rep != "O" ) FIN_ALGORITHME Algorithme Exemple_05 VARIABLES rep : caractère DEBUT_ALGORITHME FAIRE { // corps du programme AFFICHER "Voulez-vous quitter (O pour OUI)" LIRE rep } TANT QUE ( rep != "Y" ) FIN_ALGORITHME Algorithme Exemple_06 VARIABLES rep : caractère DEBUT_ALGORITHME FAIRE { // corps du programme AFFICHER "Voulez-vous quitter (O pour OUI)" LIRE rep } Chapitre 5. La structure répétitive en LDA, page 9 TANT QUE ( rep == "O" ) FIN_ALGORITHME Mais au fait, pourquoi s’agit-il de bêtises ? Le modèle de boucle étudié permet de boucler 1 à n fois. Or, dans certaines circonstances, il peut être intéressant de boucler 0 à n fois. On utilise alors un autre modèle de boucle. 3. Boucle avec test avant TANT QUE (expression à évaluer) { instructions à exécuter } FIN TANT QUE Ce modèle de boucle implique le mécanisme suivant : DEBUT Instructions TANT QUE Expression logique VRAI FAUX Instructions du bloc FAIRE Suite du programme FIN Commentaire : Chapitre 5. La structure répétitive en LDA, page 10 On évalue l’expression de contrôle de la boucle, Une évaluation à VRAI provoquera une exécution du bloc et un retour à l’évaluation de l’expression de contrôle, Alors qu’une évaluation à FAUX provoquera l’exécution de la suite du programme (à partir de la première l’instruction qui suit la structure répétitive), On notera que le corps de la boucle ne sera éventuellement pas exécuté (si l’évaluation de l’expression de contrôle donne FAUX au premier passage). Ces 2 modèles de boucles conviennent parfaitement pour traiter les cas que nous envisagerons. La syntaxe de langages comme le C, le PHP et le Javascript permet de les reproduire exactement. 4. Quelques cas « incontournables » d’utilisation de boucles Comme son nom l’indique, la structure répétitive est utilisée chaque fois qu’il faut faire répéter l’exécution d’un passage du programme. Dans l’immédiat, nous l’utiliserons pour : offrir la possibilité de ré-exécuter le corps de programme (boucle de programme), offrir la possibilité de confirmer la saisie de données (boucle de confirmation), offrir la possibilité de valider des données saisies (boucle de validation). La boucle de programme De nombreux programmes offrent la possibilité d’être ré-exécutés suite à une question posée à l’opérateur. Pour le moment nous nous contenterons de coincer les instructions du programme dans une boucle « FAIRE … TANT QUE (…) ». Cela signifie que tout programme sera exécuté au moins une fois. Chapitre 5. La structure répétitive en LDA, page 11 Algorithme Exemple_06 VARIABLES rep : caractère DEBUT_ALGORITHME FAIRE { // corps du // programme AFFICHER "* pour quitter" LIRE rep } TANT QUE (rep != "*") FIN_ALGORITHME Ici, la boucle de programme est contrôlée à partir d'une variable dont on saisit le contenu au clavier. Il pourrait en être autrement (valeur de la variable de contrôle calculée ou lue dans un fichier). Chapitre 5. La structure répétitive en LDA, page 12 La boucle de confirmation Généralement, on demande à l’utilisateur de confirmer sa saisie (une saisie de son intention est prévue expressément à cet effet). Algorithme Exemple_07 VARIABLES rep, conf : caractère DEBUT_ALGORITHME … FAIRE { … AFFICHER "C ou c pour confirmer" LIRE conf } TANT QUE ((conf != "C") ET (conf != "c")) … FIN_ALGORITHME Chapitre 5. La structure répétitive en LDA, page 13 La boucle de validation Il arrive que les données saisies ne puissent être quelconques. Le programme doit alors s’assurer de leur validité. Exemple : saisir 1 nombre de 1 à 100 La solution à ce problème est également une répétitive. En effet, on (re)saisira un nombre tant que celui introduit n’est pas correct. Le nombre accepté par la répétitive sera le premier qui tombera dans la fourchette indiquée. L'algorithme donne : Algorithme Exemple_08 VARIABLES n1 : entier DEBUT_ALGORITHME … FAIRE { LIRE n1 } TANT QUE ((n1 <1) OU (n1 > 100)) … FIN_ALGORITHME On peut compléter le bloc par un message d’erreur. Pour cela, il faut utiliser l'autre modèle de boucle. Chapitre 5. La structure répétitive en LDA, page 14 L'algorithme modifié donne : Algorithme Exemple_09 VARIABLES n1 : entier DEBUT_ALGORITHME … TANT QUE ((n1 <1) OU (n1 > 100)) { AFFICHER "Il faut un nombre de 1 à 100" LIRE n1 } FIN TANT QUE … FIN_ALGORITHME Pour éviter l'affichage systématique du message d'erreur, on introduit 2 instructions 2 saisie : une dans la boucle et une avant la boucle… Algorithme Exemple_10 VARIABLES n1 : entier DEBUT_ALGORITHME … LIRE n1 // lecture 1 TANT QUE ((n1 <1) OU (n1 > 100)) { AFFICHER "Il faut un nombre de 1 à 100" LIRE n1 // lecture 2 } FIN TANT QUE … FIN_ALGORITHME On constate que l’on a remplacé la « boucle avec test après » par une « boucle avec test avant ». Chapitre 5. La structure répétitive en LDA, page 15 Lecture 1 est appelée lecture d’amorce. La boucle qui la suit permet de passer au-dessus du processus de validation au cas où la saisie est correcte. Au cas où cette saisie est incorrecte, on entre dans la boucle de validation et l’on y reste coincé tant que la saisie reste incorrecte. Lecture 2 est appelée lecture de boucle. Chapitre 5. La structure répétitive en LDA, page 16 Imbrication de structures répétitives Les structures répétitives étudiées (programme, confirmation, validation) peuvent être combinées au sein de l’algorithme. Lorsqu' une répétitive est placée au sein d'une autre répétitive, on dit qu'elle est imbriquée ou enchâssée. Le cas le plus évident est celui d'un programme qui doit pouvoir être relancé à la demande, qui comporte des validations et des confirmations de saisies. Algorithme Exemple_11 VARIABLES n1 : entier conf, rep : caractère DEBUT_ALGORITHME FAIRE // programme { FAIRE // confirmation { LIRE n1 TANT QUE (n1 < 1) OU (n1 > 100) ) // validation n1 { AFFICHER "Il faut un nombre de 1 à 100" LIRE n1 } FIN TANT QUE AFFICHER "Confirmez votre saisie (C ou c)" LIRE conf } TANT QUE ((conf != "C") ET (conf != "c")) AFFICHER "Voulez-vous recommencer ( O pour OUI)" LIRE rep } TANT QUE (rep == "O") FIN_ALGORITHME Chapitre 5. La structure répétitive en LDA, page 17 Le schéma LDA précédent comporte 3 boucles imbriquées. On remarque les décalages de la marge (indentations) à chaque imbrication. Cette façon de procéder permet de mieux percevoir la structure de l’algorithme. Voici quelques exemples de petites « bêtises » courantes : Algorithme Exemple_12 VARIABLES n1 : entier conf, rep : caractère DEBUT_ALGORITHME FAIRE { FAIRE { LIRE n1 TANT QUE (n1 < 1) OU (n1 > 100)) { AFFICHER "Nombre de 1 à 100 SVP!" LIRE n1 } FIN TANT QUE AFFICHER "Confirmez votre saisie (C ou c)" LIRE conf } TANT QUE (rep == "O") (1) AFFICHER "Voulez-vous recommencer (O pour OUI)" LIRE rep } TANT QUE ((conf != "C") ET (conf != "c")) (2) FIN_ALGORITHME Les conditions de contrôle (1) et (2) ont été inversées! Chapitre 5. La structure répétitive en LDA, page 18 Algorithme Exemple_13 VARIABLES n1 : entier conf, rep : caractère DEBUT_ALGORITHME FAIRE { FAIRE { LIRE n1 TANT QUE (n1 < 1) OU (n1 > 100)) { AFFICHER "Nombre de 1 à 100 SVP!" LIRE n1 } FIN TANT QUE AFFICHER "Confirmez votre saisie (C ou c)" LIRE rep } TANT QUE ((conf != "C") ET (conf != "c")) AFFICHER "Voulez-vous recommencer (O pour OUI)" LIRE conf } TANT QUE (rep == "O") FIN_ALGORITHME Les conditions de contrôle sont correctement positionnées, mais les saisies des variables de contrôle ont été inversées! Chapitre 5. La structure répétitive en LDA, page 19 5. Concaténation de structures répétitives Il s'agit d'une combinaison de boucles qui consiste à les placer l'une à la suite de l'autre au lieu de l'une dans l'autre. Concaténer ou imbriquer ne se fait pas au hasard, c'est le problème posé qui nécessite une disposition plutôt que l'autre. Exemple: Saisir un nombre de 1 à 10 et un autre de 1 à 100; les additionner et afficher le résultat. L'utilisateur doit confirmer la saisie des 2 nombres (une seule confirmation pour les 2). Le programme doit pouvoir être recommencé à la demande de l'utilisateur. Algorithme Exemple_14 VARIABLES n1, n2 : entier conf, rep : caractère DEBUT_ALGORITHME FAIRE // programme { FAIRE // confirmation { LIRE n1 TANT QUE ((n1 < 1) OU (n1 > 10)) // validation n1 { AFFICHER "Nombre de 1 à 10 SVP" LIRE n1 } FIN TANT QUE LIRE n2 TANT QUE ((n2 < 1) OU (n2 > 100)) // validation n2 { AFFICHER "Nombre de 1 à 100 SVP !" LIRE n2 } FIN TANT QUE Chapitre 5. La structure répétitive en LDA, page 20 AFFICHER "Confirmez votre saisie (C ou c)" LIRE conf } TANT QUE ((conf != "C") ET (conf != "c")) AFFICHER "Voulez-vous recommencer (O pour OUI)" LIRE rep } TANT QUE (rep == "O") FIN_ALGORITHME Les 2 boucles de validation des saisies de n1 et n2 sont concaténées dans la boucle de confirmation de saisie. Chapitre 5. La structure répétitive en LDA, page 21 6. Exercices Tous les algorithmes qui suivent contiennent la boucle de programme, celle de confirmation globale et celle(s) de validation. a. ALGO05000. Calculer et afficher la superficie d'un terrain (trapèze) en mètres carrés. Les mesures sont entrées en mètres entiers (grande base de 200 à 250, petite base de 1 à 100, hauteur de 1 à 50). b. ALGO05005. Calculer et afficher la superficie d'un terrain rectangulaire en yards carrés. Les mesures sont entrées en yards (longueur de 20 à 100, largeur de 25 à 105). c. ALGO05010. Afficher la température en Celsius, si l'on entre la température en Fahrenheit (1 à 125). d. ALGO05015. Saisir 2 nombres de 1 à 100 (séparément) et afficher leur somme. Chapitre 5. La structure répétitive en LDA, page 22 CHAPITRE 6. LES COMPTEURS ET TOTALISATEURS EN LDA 1. Notion Il s’agit de 2 éléments importants en programmation. Elles sont liées à l’opérateur d’affectation, à la notion de variable ainsi qu’à celle de boucle. Elles permettent de rendre compte de l’évolution d’un « phénomène » que l’on observe (dans le programme). Exemple : on observe un phénomène Déterminer le nombre de fiches saisies ou présentes dans un fichier ; compter le nombre de cotes, calculer un total de points à partir de la saisie d’une série de cotes, exécuter telle opération autant de fois … Pour que la valeur d’un compteur ou d’un totalisateur évolue, il faut l’augmenter (incrémenter) ou éventuellement la diminuer (décrémenter). Exemple : incrémentation, décrémentation Un compteur : cpt = cpt + 1 Cette expression implique qu’il y aura d’abord évaluation de sa partie droite et ensuite affectation à sa partie gauche. La nouvelle valeur tient donc compte de l’ancienne à laquelle il y a eu ajout de 1 (incrément positif) Un totalisateur : totHtva = totHtva + prix * qte Cette expression implique qu’il y aura d’abord évaluation de sa partie droite et ensuite affectation à sa partie gauche. La nouvelle valeur tient donc compte de l’ancienne à laquelle il y a eu ajout du résultat de prix * qte Pour que le comptage ou la totalisation puisse avoir lieu, il faut que l’expression en rendant compte soit répétée. Elle doit donc être présente dans une boucle. Chapitre 6. Les compteurs et totalisateurs en LDA, page 24 Exemples : incrémentation, décrémentation dans boucle FAIRE { ……. nbEl = nbEl + 1 // incrémentation ……. } TANT QUE (condition) FAIRE { …… cumulPoints = cumulPoints + cote …… } TANT QUE (condition) À chaque (re)passage dans la boucle la valeur du compteur nbEl augmentera de 1. Il s’agit d’une augmentation à raison d’une valeur constante. À chaque (re)passage dans la boucle la valeur du totalisateurs cumulPoints augmentera de la valeur de cote. Il s’agit d’une augmentation à raison d’une valeur variable. Généralement, la valeur d’un compteur évolue par pas constant, alors que la valeur d’un totalisateur évolue par pas variable (non constant). Il a été dit précédemment que le contenu d’une variable est indéterminé, tant qu’on ne lui a pas affecté une valeur explicitement. À défaut, elle contient n’importe quoi et surtout pas nécessairement zéro. Dans les exemples précédents, nbEl et cumulPoints ont un contenu indéterminé, avant d’entrer dans la boucle qui fera varier leurs contenus respectifs. Les résultats finaux risquent seront donc faussés, en fonction de ces contenus initiaux quelconques. Il faut s’assurer que les compteurs et totalisateurs contiennent la bonne valeur initiale. Il faut les initialiser. Généralement, cela se fait avec une valeur nulle (si le compteur ou le Chapitre 6. Les compteurs et totalisateurs en LDA, page 25 totalisateur doit démarrer à cette valeur), mais il est évident que la valeur initiale à y placer dépend du traitement particulier dont il faut rendre compte dans le programme. Si l’initialisation se trouve dans la boucle, on rend inopérant l’incrémentation ou la décrémentation. Exemple : surtout à ne pas faire FAIRE { ……. nbEl = 0 // !!!!! initialisation dans la boucle !!!!! nbEl = nbEl + 1 ……. } TANT QUE (condition) FAIRE { …… cumulPoints = 0 // !!!!! initialisation dans la boucle !!!!! cumulPoints = cumulPoints + cote …… } TANT QUE (condition) Dans ces 2 boucles, les incrémentations ne servent à rien puisqu’au bouclage, il y a systématiquement remise à la valeur initiale du compteur et du totalisateur. On en déduit que l’initialisation doit être placée avant d’entrer dans la boucle concernée par le compteur ou le totalisateur. En général, on placera l’instruction d’initialisation juste avant le début de la boucle d’incrémentation. Cela donne : nbEl = 0 // initialisation = top départ, juste avant la boucle FAIRE Chapitre 6. Les compteurs et totalisateurs en LDA, page 26 { ……. nbEl = nbEl + 1 // incrémentation ……. } TANT QUE (condition) cumulPoints = 0 // initialisation = top départ, juste avant la boucle FAIRE { …… cumulPoints = cumulPoints + cote // incrémentation …… } TANT QUE (condition) La condition qui contrôle la boucle peut porter sur le contenu du compteur ou du totalisateur, mais pas nécessairement. Exemple : Il faut afficher tous les nombres pairs de 2 à 100 Algorithme exemple_18 VARIABLES pair: entier DEBUT_ALGORITHME pair= 2 // on démarre à partir de 2 FAIRE { AFFICHER pair pair = pair+ 2 // incrémentation par pas de 2 } TANT QUE (pair <= 100) FIN_ALGORITHME La condition de contrôle porte sur la variable servant au comptage. Chapitre 6. Les compteurs et totalisateurs en LDA, page 27 Exemple : Il faut afficher tous les nombres pairs à partir de 2. L’utilisateur met lui-même fin à ce processus. Algorithme exemple_19 VARIABLES pair: entier fin : caractère DEBUT_ALGORITHME pair = 2 // on démarre à partir de 2 FAIRE { AFFICHER pair pair = pair+ 2 AFFICHER "Nombre suivant ? (* pour quitter)" LIRE fin } TANT QUE (fin != "*") FIN_ALGORITHME La condition de contrôle ne porte pas sur la variable servant au comptage. 2. Exercices d’application sur les compteurs et totalisateurs Pour ces exercices, il est inutile de prévoir de boucle de programme ou de confirmation, sauf si cela est prévu explicitement. Une validation est par contre à prévoir chaque fois que cela est possible. a. ALGO06000. Afficher tous les nombres entiers pairs de 4 à 200 et tous les nombres entiers impairs de 1 à 999. b. ALGO06005. Afficher 20 nombres entiers pairs consécutifs, le premier étant entré par l’utilisateur. c. ALGO06010. Afficher les cubes des X premiers nombres entiers positifs, X (1 à 20) étant entré par l’opérateur. d. ALGO06015. Saisir 10 nombres entiers de 1 à 100. Chapitre 6. Les compteurs et totalisateurs en LDA, page 28 e. ALGO06020. Saisir des nombres entiers de 100 à 1000. Le nombre de nombres à saisir est introduit par l’utilisateur et sera une valeur de 1 à 20. f. ALGO06025. Entrer X et Y et calculer XY où Y : entier de 1 à 8 et X : entier de 1 à 100. On suppose qu’il n’existe pas d’opérateur permettant de calculer la puissance et que le seul opérateur possible est la multiplication. g. ALGO06030. Entrer X et Y et calculer X * Y où Y : réel de 1 à 1000 et X : entier de 1 à 100. On suppose qu’il n’existe pas d’opérateur permettant de calculer le produit et que le seul opérateur possible est l’addition. h. ALGO06035. Un opérateur saisit des cotes entières sur 10. Il met lui-même fin au processus (* pour fin). Le nombre de cotes saisies est affiché juste avant la fin d’exécution du programme. i. ALGO06040. Un opérateur saisit des cotes entières sur 10. Il met lui-même fin au processus (* pour fin). Il faut afficher la moyenne arithmétique de ces cotes. j. ALGO06045. On saisit prénom (25), nom (25), section (10), classe (1 à 7). On confirme l’ensemble par C ou c. On simule alors une écriture sur un fichier. On quitte le programme par O ou o. On affiche alors le nombre de fiches encodées pendant la session écoulée du programme. Chapitre 6. Les compteurs et totalisateurs en LDA, page 29 CHAPITRE 7. LA STRUCTURE ALTERNATIVE EN LDA 1. Notion Une alternative permet de donner 2 directions possibles (2 branches) au flux des traitements en fonction d’un test (évaluation d’une expression logique, comme pour les répétitives). Les branches d’une alternative sont mutuellement exclusives (l’on passe dans l’une mais pas dans l’autre en fonction du résultat de l’évaluation). SI (expression logique) ALORS { instructions à exécuter // branche « VRAI » } SINON { instructions à exécuter // branche « FAUX » } FIN SI Cette structure implique le mécanisme suivant : DEBUT Instructions FAUX SI Expression logique VRAI Instructions de branche VRAI Instructions de branche FAUX Suite du programme FIN Chapitre 7. La structure alternative en LDA, page 31 On évalue l’expression de contrôle de l’alternative, Une évaluation à VRAI provoquera une exécution du bloc de la branche VRAI suivi d’un passage à la suite du programme, Alors qu’une évaluation à FAUX provoquera l’exécution du bloc de la branche FAUX suivi d’un passage à la suite du programme. On constate, qu’après le passage dans une des 2 branches de l’alternative, on aboutit au même point du programme. L'alternative a un seul point de sortie. L’expression logique qui permet de sélectionner la branche à parcourir est appelée condition de contrôle de la structure alternative. Un « SI » est toujours suivi d’une paire de parenthèses « ( ) ». La condition de contrôle y prend place avec, éventuellement, ses propres parenthèses. Exemple: calculer et afficher le prix tvac pour un article dont on peut acheter plusieurs exemplaires et dont le taux de tva peut être 6% ou 21%, en fonction d’un code 1 ou 2. Algorithme Exemple_15 VARIABLES pHtva, qte, pTvac, taux: réel code : Entier DEBUT_ALGORITHME LIRE pHtva, qte, code SI (code == 1) ALORS { taux= .06 } SINON { taux= .21 } pTvac = pHtva * qte* taux // sortie de l’alternative avec .06 ou.21 dans taux AFFICHER pTvac Chapitre 7. La structure alternative en LDA, page 32 FIN SI Branche vide Il peut arriver qu’une des 2 branches soit vide. Cela signifie que dans ce cas, il n’y a rien de particulier à faire sur l’une des sorties et que l’on rejoint le cours normal du programme. Exemple: faire générer un nombre de 1 à 100 et afficher s'il est supérieur à 50 Algorithme Exemple_16 VARIABLES nbre: entier DEBUT_ALGORITHME … nbre : ALEA(1,100) SI (nbre > 50) ALORS { AFFICHER "Le nombre est supérieur à 50" } SINON { // dans ce cas on ne fait rien } … FIN_ALGORITHME Si l'on rédige la condition de contrôle de l'alternative autrement, on obtient le schéma qui suit. La branche VRAI est vide et la branche FAUX contient effectivement du code : Algorithme Exemple_17 VARIABLES nbre: entier DEBUT_ALGORITHME Chapitre 7. La structure alternative en LDA, page 33 … nbre = ALEA (1,100) SI (nbre <= 50) ALORS { // dans ce cas on ne fait rien } SINON { AFFICHER "Le nombre est supérieur à 50" } … FIN_ALGORITHME Généralement, si l’une des branches doit rester vide, on s'arrange pour que ce soit la branche FAUX. Cependant l'algorithme qui précède n'est pas formellement mauvais et peut même être traduit dans la plupart des langages. Chapitre 7. La structure alternative en LDA, page 34 Tests en cascade S’il faut pouvoir distinguer entre 2 cas possibles, une alternative suffira. Mais, il peut arriver qu’il faille distinguer entre plus de 2 cas possibles. Exemple: saisir un code tva (1, 2 ou 3) et charger une variable du taux correspondant (6%, 12% ou 21%). Dans une première version, on considère que l’encodeur est honnête et qu’il n’introduira bien qu’une des 3 possibilités. Dans une seconde version, on détectera un code éventuellement erroné. Il y aura donc 4 possibilités pour le code: 1, 2, 3 et n’importe quelle autre valeur entière. Cette dernière possibilité provoquera l’affichage d’un message. Première version : Algorithme Exemple_18 VARIABLES code : entier taux: réel DEBUT_ALGORITHME LIRE code SI (code == 1) ALORS // début alternative 1 { taux = .06 } SINON { SI (code == 2) ALORS // début alternative 2 { taux = .12 } SINON { taux = .21 Chapitre 7. La structure alternative en LDA, page 35 } // fin alternative 2 } // fin alternative 1 FIN_ALGORITHME Dans ce LDA, on constate que l’alternative en caractères normaux est placée dans la branche « SINON » de l’alternative en caractères gras. Ce dispositif d’alternatives consiste en une imbrication de structures alternatives. Puisque l’encodeur est honnête, on est certain que le code est 3 à la sortie SINON de la deuxième alternative. La version suivante est plus « solide » dans la mesure où elle détecte un cas non valide (autre que 1, 2 ou 3). Deuxième version : Algorithme Exemple_19 VARIABLES code : entier taux: réel DEBUT_ALGORITHME LIRE code SI (code == 1) ALORS // début alternative 1 { taux = .06 } SINON { SI (code == 2) ALORS // début alternative 2 { taux = .12 } SINON { SI (code == 3) ALORS // début alternative 3 { taux = .21 Chapitre 7. La structure alternative en LDA, page 36 } SINON { AFFICHER "Erreur : code 1, 2 ou 3 svp" } // fin alternative 3 } // fin alternative 2 } // fin alternative 1 FIN_ALGORITHME Cet algorithme prend en charge le cas où l’utilisateur se trompe et introduit un code ni 1, ni 2, ni 3. D’où, l’alternative sur la sortie SINON du test sur code == 2 (à ce stade, le code peut-être 3 ou n’importe quoi d’autre. Chaque alternative est placée sur une branche d’une autre alternative. Ce dispositif est une imbrication d’alternatives. L’alternative 3 est imbriquée dans l’alternative 2, qui est imbriquée dans l’alternative 1. Si l’on se trouve face à 3 traitements mutuellement exclusifs, il faudra utiliser 2 alternatives, puisqu’une alternative ne peut décider qu’entre 2 possibilités. D’une façon générale, face à N traitements (avec N > 2) mutuellement exclusifs, il faudra utiliser N - 1 alternatives, à condition d'imbriquer celles-ci. Il aurait été possible d'afficher l'algorithme précédent comme ceci : Algorithme Exemple_06 VARIABLES code : entier taux: réel DEBUT_ALGORITHME LIRE code SI (code == 1) ALORS { taux = .06 } SI (code == 2) ALORS Chapitre 7. La structure alternative en LDA, page 37 { taux = .12 } SI (code == 3) ALORS { taux = .21 } SI (code < 1 OU code >3) ALORS { AFFICHER "Erreur : code 1, 2 ou 3 svp" } FIN_ALGORITHME Dans la mesure du possible, nous éviterons cette façon de procéder. Les alternatives sont ici, concaténées (placées les unes à la suite des autres). Par contre, la disposition suivante est erronée: Algorithme Exemple_07 VARIABLES code : entier taux: réel DEBUT_ALGORITHME LIRE code SI (code == 1) ALORS { taux = .06 } SI (code == 2) ALORS { taux = .12 } SI (code == 3) ALORS { taux = .21 } Chapitre 7. La structure alternative en LDA, page 38 SINON { AFFICHER "Erreur : code 1, 2 ou 3 svp" } FIN_ALGORITHME En effet, dans le cas d’un code égal à 1 ou 2, on affichera quand même le message d’erreur. La programmation structurée consiste à utiliser 3 structures possibles : séquence, répétitive, alternative que l’on peut concaténer et / ou imbriquer de façon à élaborer des traitements plus ou moins complexes. Il faut veiller à la présentation du texte de l’algorithme. Pas bien ! Algorithme Exemple_17 VARIABLES n1, n2 , somme : entier conf, fin : caractère DEBUT_ALGORITHME FAIRE { FAIRE { LIRE n1 TANT QUE ((n1 < 1) OU (n1 > 10)) FAIRE { AFFICHER "Erreur : nombre de 1 à 10 svp" LIRE n1 } FIN TANT QUE LIRE n2 TANT QUE ((n2 <10) OU (n2 >100)) FAIRE { Chapitre 7. La structure alternative en LDA, page 39 AFFICHER "Erreur : nombre de 10 à 100 svp" LIRE n2 } FIN TANT QUE AFFICHER "C pour confirmer" LIRE conf } TANT QUE (conf != "c" ET conf != "C") somme= n1 + n2 AFFICHER somme SI (somme > 100) { AFFICHER "La somme est supérieure à 100" } SINON { AFFICHER "La somme n’est pas supérieure à 100." } AFFICHER "* pour quitter" LIRE fin } TANT QUE (fin != "*") FIN_ALGORITHME L’algorithme est correct, mais on a tout écrit à la marge. La relecture pour compréhension ou correction est difficile et donc source d’erreurs parfaitement évitable. À la page suivante on trouve exactement le même code, mais avec des indentations et même quelques commentaires. Les indentations permettent de repérer très facilement les diverses structures présentes, lorsqu’elles sont imbriquées. Chapitre 7. La structure alternative en LDA, page 40 Les commentaires ne sont pas toujours indispensables. Prenez l’habitude de les utiliser pour expliquer laconiquement un passage de programme un peu particulier et que vous risquez de ne plus comprendre quelques semaines après l’avoir écrit. C’est comme cela que vous devrez procéder. Bien ! Algorithme Exemple_17 VARIABLES n1, n2 , somme : entier conf, fin : caractère DEBUT_ALGORITHME FAIRE { FAIRE { LIRE n1 TANT QUE ((n1 < 1) OU (n1 > 10)) FAIRE { AFFICHER "Erreur : nombre de 1 à 10 svp" LIRE n1 } FIN TANT QUE LIRE n2 TANT QUE ((n2 <10) OU (n2 >100)) FAIRE { AFFICHER "Erreur : nombre de 10 à 100 svp" LIRE n2 } FIN TANT QUE AFFICHER "C pour confirmer" LIRE conf } TANT QUE (conf != "c" ET conf != "C") somme = n1 + n2 Chapitre 7. La structure alternative en LDA, page 41 AFFICHER somme SI (somme > 100) { AFFICHER "La somme est supérieure à 100." } SINON { AFFICHER "La somme n’est pas supérieure à 100." } AFFICHER "* pour quitter" LIRE fin } TANT QUE (fin != "*") FIN_ALGORITHME Exercices d’application sur l’alternative Rédiger les algorithmes sans prévoir les boucles de programme, de confirmation et de validation (sauf stipulation contraire). a. ALGO07000. Saisir 3 nombres différents et afficher lequel est le plus grand des trois. b. ALGO07005. Saisir un nombre entier de 1 à 100 et afficher s’il est plus grand que 50. c. ALGO07010. Saisir un nombre entier de 1 à 100 et afficher s’il est plus grand, plus petit ou égal à 50. d. ALGO07015. Saisir une cote entière sur 100 et afficher une appréciation selon les critères suivants: e. < 50 50 à 59 60 à 100 REFUS BALANCE REUSSITE f. ALGO07020. Saisir 2 nombres entiers de 1 à 100 et un code + - x : pour exécuter une des 4 opérations arithmétiques (valider + confirmation globale + boucle de programme). Chapitre 7. La structure alternative en LDA, page 42 Remarque: On peut utiliser une représentation schématique des structurogrammes utilisant le LDA pour mettre au point le « squelette » de l’algorithme. Il suffit d’utiliser 2 symboles: Pour la répétitive en indiquant la condition de contrôle en entrée (test avant d'entrer) ou en sortie (test après être entré). Pour l’alternative, en indiquant la condition de contrôle au– dessus et en commentant une des branches à l'aide de V ou F. Exemple: Programme Confirmation Lire n1 Message erreur Lire n1 TQ (n1 <1 OU n1 > 100) Lire n2 Message erreur Lire n2 TQ (n2 < 50 OU n2 > 500) TQ (conf != "c" ET conf != "C") additionner / afficher TQ (fin != "F") Le squelette est un document de préparation. Il peut donc être plus ou moins documenté (conditions de contrôle, précision de certains calculs, initialisations et incrémentations de compteurs ou totalisateurs, etc.). Son objectif est de permettre la mise en évidence des structures de programmation avant de mettre au point un algorithme compliqué. En effet, il est plus facile de Chapitre 7. La structure alternative en LDA, page 43 gommer ce genre de symboles que des parties entières de code LDA. Avec l'habitude, il peut même suffire. Pour la validation, il est possible de transformer la boucle avec test avant par une combinaison de la boucle avec test après et une alternative. Ceci … LIRE n1 TANT QUE ((n1 < 1) OU (n1 > 10)) FAIRE { AFFICHER "Erreur : nombre de 1 à 10 svp" LIRE n1 } FIN TANT QUE … devient … FAIRE { LIRE n1 SI (n1 < 1 OU n1 >10) ALORS { AFFICHER "Erreur de saisie!" } } TANT QUE ((n1 < 1) OU (n1 > 10)) Exercices récapitulatifs Chaque fois qu'une donnée ne peut être quelconque, il faut la valider avec message. Sauf indication contraire, on confirme les saisies globalement. Tout programme doit pouvoir être recommencé à la demande. a. ALGO07025. Saisir un nombre entier de 1 à 100 et afficher s’il est plus grand, plus petit ou égal à 50. Chapitre 7. La structure alternative en LDA, page 44 b. ALGO07030. Saisir un code tva (valider avec message d’erreur et confirmer) et afficher un texte indiquant à quel taux il correspond sur base de : 1 pour 0%, 2 pour 6% et 3 pour 21%. Que dire à propos de la structure de ce programme c. ALGO07035. Saisir une cote entière sur 100 et afficher une appréciation selon les critères suivants: < 50 REFUS 50 à 59 BALANCE 60 à 100 REUSSITE Que dire à propos de la structure de ce programme ? d. ALGO07040. Saisir 2 nombres, le premier de 10 à 250; le deuxième de 175 à 450. Afficher les résultats des 4 opérations élémentaires. On confirme les 2 saisies ensemble. e. ALGO07045. Saisir 2 nombres, le premier de 1 à 99; le second de 100 à 999. Il faut afficher leur différence; celle-ci ne pouvant être négative. On confirme les saisies séparément. f. ALGO07050. Saisir 2 nombres de 1 à 99. Saisir un code + ou - . Réaliser une addition ou une soustraction et afficher le résultat. Variante. Au moment de quitter, on affiche le nombre d’additions et le nombre de soustractions réalisées. g. ALGO07055. Saisir 2 nombres entiers de 1 à 100 et un code + - x : pour exécuter une des 4 opérations arithmétiques. Variante. On ne confirme que la saisie des nombres. Variante. On ne confirme pas du tout. Chapitre 7. La structure alternative en LDA, page 45 Variante. On confirme mais sans valider. Variante. On confirme tout, mais on valide seulement les nombres. Variante. On confirme globalement, on valide. Au moment de quitter, on affiche le nombre d’opérations de chaque type réalisées. h. ALGO07060. Saisir le prix unitaire, la quantité achetée d’un article et un code tva par article (1 ou 2 pour 6% et 21%). On doit déterminer les montants suivants : total htva (2 bases), total tva (2 taux), total tvac. On peut évidemment acheter plusieurs articles. i. ALGO07065. Saisir 2 nombres de 1 à 99. Saisir un code + ou - . Réaliser l’opération demandée et afficher le résultat. On sort si le premier nombre est 0. j. ALGO07070. Un opérateur introduit un nombre de 1 à 100 et le confirme. Un second opérateur doit deviner ce nombre et ce, jusqu’à la découverte du nombre recherché. Il ne faut pas prévoir de message pour guider le second opérateur. k. ALGO07075. L’ordinateur choisit un nombre de 1 à 100. L’opérateur doit deviner ce nombre. L’ordinateur indique à chaque essai si le nombre à trouver est plus grand, plus petit et ce, jusqu’à la découverte du nombre recherché. Variante. L’ordinateur indique à chaque essai un message du type « le nombre est compris entre … et … » et ce, jusqu’à la découverte du nombre recherché. Variante. L’opérateur choisit la fourchette des nombres à générer. Variante. On laisse la possibilité d’abandonner en cours de jeu. Chapitre 7. La structure alternative en LDA, page 46 l. ALGO07080. Saisir un code tva (valider avec message d’erreur et confirmer) et afficher un texte indiquant à quel taux il correspond sur base de : 1 pour 0%, 2 pour 6% et 3 pour 21%. On sort si le code tva est 0. m. ALGO07085. On saisit prénom (25), nom (25), section (10), classe (1 à 7). On confirme l’ensemble par C ou c. On simule alors une écriture sur un fichier. On quitte le programme si l’on entre le caractère * dans le champ du prénom. Chapitre 7. La structure alternative en LDA, page 47