En effet, comme je vous l'ai déjà dit et répété (et comme je le répéterai sans doute encore souvent), il n'y a pas de mauvaise manière de raisonner, pour autant que le raisonnement soit logique…
Tout au plus, vous vous rendrez compte qu'un raisonnement sera peut être plus ou moins efficace qu'un autre, peut être plus ou moins adapté à une situation donnée qu'un autre.
De cette manière, si vous souhaitez créer une boucle incrémentale, effectuée dix fois, le plus «logique» (ou du moins, à mon point de vue, et selon les circonstances) *semble* être l'utilisation d'une «Boucle Pour»…
Cependant, rien n'empêche à priori d'utiliser un autre type de boucle… Si ce n'est qu'il s'agira peut-être de concevoir l'ensemble de la boucle de manière différente.
Le "langage imaginaire" que j'ai mis au point pour ce tutorial dispose bien évidemment des trois types de boucles:
Pour créer une boucle "Pour", il utilisera fatalement l'instruction Pour (variable=valeur à valeur_maximale [éventuellement par pas de XX])
Pour créer une boucle "Tant" , il utilisera fatalement l'instruction Tant_Que (condition de rentrée dans la boucle)
Et, pour créer une boucle "Jusque", il utilisera fatalement l'instruction Jusque (condition de rentrée dans la boucle)
Evidemment, le bloc d'instructions à effectuer dans la boucle sera à mettre entre accolades "{ }"
Les instructions Pour(...) et Tant_Que(...) apparaîtront logiquement AVANT le bloc d'instructions à effectuer dans la boucle, alors que l'instruction Jusque(...) apparaîtra APRES le bloc d'instruction à effectuer dans la boucle.
Cela nous donne logiquement quelque chose ressemblant à:
vide principal(vide) { instruction hors boucle pour (variable=1 à 10) { //les instructions à effectuer dans la boucle pour } instuction hors boucle Tant_Que (test) { //les instructions à effectuer dans la boucle tant } instruction hors boucle { //les instructions à effectuer dans la boucle jusque } Jusque (test) }
Pour bien vous prouver que les boucles sont dans une large mesure interchangeable, voici la comparaison de la création d'une boucle incrémentale effectuée 10 fois, ainsi que la traduction dans mon langage imaginaire…
Pour rajouter à la vraissemblance, je vais même aller jusqu'à incérer cela dans un projet complet:
Le but de ce projet est tout simplement d'afficher la table de multiplication (entre 1 et 10) d'un nombre (entier) introduit par l'utilisateur.
Je vais donc, logiquement, commencer par énoncer le problème exactement de la manière présentée à la page "un peu de méthode"
- Que doit faire l'application: L'application doit afficher la table de multiplication, de 1 à 10, d'un entier introduit par l'utilisateur
- De quelles information l'application a-t-elle besoin?: L'application a besoin de
- un entier pour récupérer le nombre dont l'utilisateur veut la table de multiplication
- un entier servant de compteur et de multiplicateur du nombre dont l'utilisateur veux la table de multiplication
- Où l'application se procure-t-elle ces information?
- Le nombre dont l'utilisateur veut la table de multiplication sera introduit par l'utilisateur
- Le nombre servant de compteur sera une variable gérée directement par le système
- Comment l'application va-t-elle utiliser ces informations? L'application
- affichera une ligne indiquant quel nombre est multiplié par combien
- multipliera le nombre introduit par l'utilisateur par la valeur du compteur
- affichera le résultat de cette multiplication
vide principale(vide)
{
//Le code obtenu pour la boucle pour
Affich "Introduisez un nombre "|
Aquiere Nombre|
Pour (cpt=1 à 10)
{
Affich Nombre" X "cpt" = "nombre*cpt|
}
}
vide principale(vide)
{
//Le code obtenu pour la boucle Tant
Affich "Introduisez un nombre "|
Aquiere Nombre|
cpt=1|
Tant_Que (cpt<11)
{
Affich Nombre" X "cpt" = "nombre*cpt|
}
}
vide principale(vide)
{
//Le code obtenu pour la boucle Jusque
Affich "Introduisez un nombre "|
Aquiere Nombre|
cpt=1|
faire
{
Affich Nombre" X "cpt" = "nombre*cpt|
} Jusque(cpt<10)
}
Par contre, il y aura des différences essentielles sur la manière dont le résultat sera obtenu:
La boucle pour sera d'office effectuée un nombre précis de fois. Que l'on modifie la valeur de départ et/ou la valeur d'arrivée, et nous serions en mesure d'avoir par exemple, la table de multiplication entre 35 et 100.
La boucle tant quant à elle, est parfaitement susceptible de ne jamais être effectuée.
Si on avait oublié de donner une valeur permettant de rentrer dans la boucle à la variable cpt (qui sert de compteur de boucle), elle ne se serait jamais exécutée.
De plus, si on avait oublié de faire s'incrémenter le compteur à l'intérieur de la boucle, on aurait pu laisser tourner l'application jusqu'à la fin des temps, elle n'aurait jamais été quitée.
Enfin, la boucle jusque se serait effectuée, quoi qu'il arrive, au minimum une fois, quelle qu'aurait pu être la valeur de départ de cpt.
Là encore, si on n'avait pas pris la précaution d'augmenter la valeur de cpt à l'intérieur de la boucle, mais en ayant quand meme donné une valeur susceptible de faire se réexécuter la boucle à cpt, elle se serait effectuée jusqu'à la fin des temps (ou, du moins, juqu'à ce que l'utilisateur décide de mettre fin de lui même à l'application).
Deux types de tests sont généralement disponibles avec les langages de programmation de troisème génération.
On trouve en effet la possiblité de créer des tests logiques, dont le résultat ne pourra être que «vrai» ou «faux», qui sont représentables en flowchart, que je nommerai logiquement «Test vrai/ faux» au long de ce tutorial, et celle de créer des tests en fonction de la valeur d'un variable précise, qui, bien que représentables en flowchart, ne permettent pas une traduction intuitive, que je nommerai «test à choix multiple» au long de ce tutorial.
La représentation d'un test de type vrai/faux est relativement simple:
on indique le test au centre de son rectanble, et on trace une ligne oblique au départ des deux coins supérieurs du rectangle de manière à ce qu'elles se rejoingent en bas du rectangle.
Nous obtiendrons alors la représentation de deux colones, dans lesquelles nous mettrons d'un côté les instructions à suivre si le test est vérifié, et de l'autre les instructions à suivre s'il ne l'est pas.
Encore une fois, nous tâcherons d'écrire le test de manière à ce que la plus grande partie des instructions soient à effectuer si le résultat est "vrai".
Evidemment, rien n'empeche de faire varier les largeurs de colones selon les besoins…
On peut donc parfaitement envisager de laisser une très petite colone "N" si aucune instruction ne doit être effectuée dans le cas où le résutat du test serait "faux:
En flowchart, si on souhaite faire effectuer des actions différentes en fonction de la valeur d'une variable, on est obligé de faire un test sur chaque valeur différente envisagée pour la variable dans le genre de
Ce qui, lors de la traduction intuitive en code source pourrait très facilement se transformer en
si (Variable=1) { //instructions à suivre si Variable vaut 1 } Sinon { si (Variable=2) { //instructions à suivre si Variable vaut 2 } sinon { si (Variable=3) { //instructions à suivre si Variable vaut 3 } sinon { si (Variable=4) { //instructions à suivre si Variable vaut 4 } } } }
Code qui, il faut en convenir, n'est ni des plus lisibles ni le plus efficace.
En nassichneiderman, nous indiquerons la variable à tester à droite, précédé ou non du terme "Selon".
Nous tracerons ensuite la diagonale entre le coin supérieur gauche et le coin inférieur droit de la cellule actuelle et créerons autant de colones que de valeurs envisagées pour la variable.
Il ne restera plus qu'à mettre en "titre" des colones les valeurs à prendre en compte pour chaque colone d'instructions et à mettre les instructions à effectuer dans la colone correspondant à la valeur concernée de la variable.
Typiquement, la dernière colone à droite servira aux instuctions à effectuer par défaut, c'est à dire à effectuer si la variable n'avait aucune des valeurs envisagées.
Cela nous donne quelque chose ressemblant à
Intuitivement, nous serons alors tentés d'utiliser les capacités du langage de troisième générations offertes par les tests à choix multiple:
Le langage de programmation que j'ai mis au point pour ce tutorial permet évidemment la gestion de ces test à choix multiple:
Pour indiquer la variable dont on veut vérifier la valeur, il utilise logiquement l'instruction Selon (variable_à_tester).
Pour indiquer la valeur prévue, il utilise l'instruction cas valeur_prévue, et, pour indiquer les instruction à effectuer par défaut (dans le cas où la variable n'aurait aucune des valeurs prévues), il utilisera simplement le terme "defaut", à chaque fois suivie des deux points ":" .
Enfin, pour indiquer au langage qu'il ne doit pas continuer le traitement, nous pouvons à tout moment utiliser l'instruction arret.
Intuitivement, les deux nassichneiderman seraient donc traduits en code source de la même manière, à savoir:
nom_de_la_procedure
{
Selon (nom_de_la_variable)
{
cas valeur1:
Instru1|
Instru2|
arret|
cas valeur2:
Instru3|
arret|
cas valeur3:
Instru4|
Instru5|
arret|
cas valeur4:
Instru6|
Instru7|
Instru8|
arret|
defaut:
//dans l'exemple présent, je n'ai prévu aucune instruction
//par défaut mais elles se trouveraient ici
}
}
Le terme routine est un terme parfaitement générique qui représente un sous programme appelable à partir de n'importe quel point de l'application, et dont vous trouverez les explications sur la page consacrée aux routines.
Toutes les instructions des différents langages de programmation ne sont que des routines (des fonctions ou des procédures, précisément) mais il est souvent utile d'avoir recours à des routines personnalisées afin de ne pas être obligé de réécrire un code réutilisé à chaque fois que son usage est requis.
Pour faire la différence entre les instructions classiques du langage de programmation et les routines que nous aurons créées nous même, nous centrerons l'appel à nos routines personnalisées et nous créerons des carrés grisés à gauche et à droite selon le principe suivant:
Copyright (©) 2005 (Philippe Dunski)
Ce cours est libre, vous pouvez le redistribuer et/ou le modifier selon les termes de la Licence Publique Générale GNU publiée par la Free Software Foundation (version 2 ou bien toute autre version ultérieure choisie par vous).
Ce cours est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE, ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus de détails.
Cependant, l'auteur apprécierait grandement que vous lui fassiez part de toute modification apportée à son contnu
Vous pouvez le contacter par mail à l'adresse koala01@free.fr
Vous pouvez trouver une adaptation française de la licence GNU/GPL à l'URL http://www.linux-france.org/article/these/gpl.html