LES STRUCTURES RENCONTREES DANS UN PROGRAMMEDans un programme, on peut rencontrer les trois structures suivantes :
• Le bloc ou la séquence
• Le choix ou la structure alternative
• La boucle ou la structure itérative
La séquenceC’est un ensemble d’instructions exécutées une fois et une seule, instruction après instruction de façon séquentielle.
Voici un exemple de programme qui demande à l’utilisateur de saisir son nom, puis il affiche un texte de bienvenue.
- Code:
-
' ******************************************************************************
' sequence.bas
' Exemple de programme utilisant une séquence d'instructions
' ******************************************************************************
dim nom$ : ' Variable du type chaîne de caractères qui recevra le Nom
' On défini ici deux objets ALPHA
' un alpha permet de visualiser un texte statique que l'utilisateur ne peut pas
' modifier. C'est une alternative bien plus commode à l'instruction PRINT
' On défini sa position (TOP et LEFT) ainsi que la couleur et la taille du texte
alpha 1 : top 1,50 : left 1,50 : font_color 1,255,0,0 : font_size 1,16
alpha 2 : top 2,150 : left 2, 50: font_color 2,0,0,255 : font_size 2, 14
' Saisie du nom
' Pour cela on utilise au lieu de INPUT, MESSAGE_INPUT$ qui nous permet de
' traiter d'une façon confortable un texte saisi par l'utilisateur
nom$ = message_input$("Donnez-moi votre nom","Votre est ","")
nom$ = upper$(nom$) : ' on transforme le nom en majuscules
' Affichage par caption plus souple que par PRINT
caption 1,"Bienvenue " + nom$ + chr$(13) + "et bonne programmation en PANORAMIC"
caption 2,"Vous avez testé la structure séquentielle"
end : ' fin du programme; cette instruction n'est pas obligatoire DANS CE CAS.
' Mais dans d'autres cas, elle doit ABSOLUMENT figurer.
' Alors, autant prendre les bonnes habitudes et la faire figurer toujours.
' ******************************************************************************
Le choix ou la décision ou la structure alternative Nous pouvons attendre d'un programme qu'il prenne des décisions dont dépendra son déroulement.
Panoramic dispose de deux structures de prise de décision :
1 – La structure IF … THEN ... ELSE ... END_IF
2 – La structure SELECT ... CASE … END_SELECT
Décision type IF ... THEN … ELSE ... END_IFPanoramic distingue trois possibilités dans une structure IF.
• IF condition THEN instruction(s)
Si la condition est vraie, l'instruction ou le groupe d'instructions après THEN est exécuté, sinon l'exécution saute à la ligne suivante.
• IF condition
instruction(s)
END_IF
Dans ce cas, si la condition est vraie, l'instruction ou le groupe d'instructions jusqu'à END_IF est exécuté. Autrement, l'exécution saute à l'instruction après IF.
• IF condition
instruction(s)
ELSE
instruction(s)
END_IF
Dans ce cas, si la condition est vraie, l'instruction ou le groupe d'instructions entre IF et ELSE est exécuté. Autrement, l'instruction ou le groupe d'instructions entre ELSE et END_IF est exécuté.
Remarque : Les décisions peuvent s'imbriquer. De plus, chacune des branches de ces décisions peut à son tour recevoir une structure IF ... THEN ... ELSE … END_IF. Cette possibilité offerte permet de construire des structures de prise de décision extrêmement puissantes.
Voici, pour illustrer la structure alternative, un programme de calcul du salaire imposable à partir du salaire brut et du statut de la personne, saisis par l'utilisateur.
- Code:
-
' **************************************************************************
' Calcul du salaire imposable : Salaire_Imposable.bas
' **************************************************************************
dim taux_pension_ouvrier : taux_pension_ouvrier = 0.08
dim taux_pension_employe : taux_pension_employe = 0.08
dim taux_maladie_ouvrier : taux_maladie_ouvrier = 0.0415
dim taux_maladie_employe : taux_maladie_employe = 0.024
dim statut$, salaire_brut, salaire_imposable
dim rep$
' saisie du salaire brut
' Deux boucles REPEAT imbriquées :
' La boucle intérieure pour s'assurer que la saisie soit numérique et
' la boucle extérieure pour s'assurer que la valeur soit positive
repeat
repeat
rep$ = message_input$("Saisie du salaire brut","Salaire brut =","")
until numeric (rep$) > 0
salaire_brut = val(rep$)
until salaire_brut > 0
' Saisie du statut
' Une seule boucle REPEAT pour s'assurer que la saisie soit E pour employé
' ou O pour ouvrier.
' Vous pouvez faire votre saisie indifféremment en minuscule ou en majuscule.
' De toute façon, le système la transforme en majuscule.
repeat
rep$ = message_input$("Saisie du statut","Employé = E ; Ouvrier = O","E")
until (upper$(rep$) = "E") or (upper$(rep$) = "O")
statut$ = upper$(rep$)
' Calcul du salaire imposable
if statut$ = "E"
' Calculer le salaire imposable relatif à un employé
salaire_imposable = salaire_brut * ((1 - taux_pension_employe) - taux_maladie_employe)
else
' Calculer le salaire imposable relatif à un ouvrier
salaire_imposable = salaire_brut * ((1 - taux_pension_ouvrier) - taux_maladie_ouvrier)
end_if
' Arrondir à deux chiffres après le point décimal
salaire_imposable = int(100 * salaire_imposable + 0.5) / 100
' Afficher le résultat
message "Salaire imposable : " + str$(salaire_imposable)
end
' **************************************************************************
Décision type SELECT … CASE … END_SELECTUne prise de décision multiple se programme beaucoup plus rapidement et de manière plus lisible au moyen de l'instruction SELECT … CASE … END_SELECT.
Voici sa structure générale :
SELECT expression_arithmétique
CASE valeur1 : commande1
CASE valeur2 : commande2
…....
CASE valeurN : commandeN
END_SELECT
Lors d'un SELECT, Panoramic évalue l'expression arithmétique (également nommée « sélecteur ») et compare le résultat avec les valeurs (on dit aussi marques ou constantes de cas). Le nombre de marque est indifférent.
Lorsque la valeur du sélecteur correspond à celle d'une marque, alors le système exécute la commande ou le bloc de commandes qui la suivent. Les autres marques sont sautées.
Lorsque Panoramic ne trouve pas de marque dont la valeur correspond au sélecteur, le programme se poursuit par la commande qui suit END_SELECT.
Le type de données du sélecteur doit correspondre à celui des marques.
En Panoramic, n'est valide que le type entier et la valeur du sélecteur doit être positive.
Veillez à ce qu'une marque donnée n'apparaisse qu'une seule fois dans une même structure SELECT.
Voici, pour illustrer l'emploi de SELECT … CASE … END_SELECT, un programme d'écriture en chiffres romains, des entiers de 1 à 999 écrits en chiffres arabes.
- Code:
-
' **************************************************************************
' Chiffres romains de 1 à 999
' **************************************************************************
dim i%,n$
alpha 1 : top 1,5 : left 1, 20 : color 1,0,0,0 : font_color 1,255,255,0
font_size 1,14 : caption 1," Liste de chiffres romains de 1 à 999 "
list 2 : top 2,40 : left 2,100 : height 2,400
for i% = 1 to 999
Romain(i%)
if n$ = "" then exit_for
next i%
end
' **************************************************************************
SUB Romain(n%)
if n% > 999
n$ = " !!! Ce nombre est trop grand pour moi !!!" + chr$(13)
n$ = n$ + "Mon programmeur m'a enseigné les chiffres romains de 1 à 999 seulement !"
message n$ : n$ = "" : exit_sub
end_if
n$ = ""
select int(mod(n%,1000)/100)
case 9 : n$ = n$ + "CM"
case 8 : n$ = n$ + "DCCC"
case 7 : n$ = n$ + "DCC"
case 6 : n$ = n$ + "DC"
case 5 : n$ = n$ + "D"
case 4 : n$ = n$ + "CD"
case 3 : n$ = n$ + "CCC"
case 2 : n$ = n$ + "CC"
case 1 : n$ = n$ + "C"
end_select
select int(mod(n%,100)/10)
case 9 : n$ = n$ + "XC"
case 8 : n$ = n$ + "LXXX"
case 7 : n$ = n$ + "LXX"
case 6 : n$ = n$ + "LX"
case 5 : n$ = n$ + "L"
case 4 : n$ = n$ + "XL"
case 3 : n$ = n$ + "XXX"
case 2 : n$ = n$ + "XX"
case 1 : n$ = n$ + "X"
end_select
select mod(n%,10)
case 9 : n$ = n$ + "IX"
case 8 : n$ = n$ + "VIII"
case 7 : n$ = n$ + "VII"
case 6 : n$ = n$ + "VI"
case 5 : n$ = n$ + "V"
case 4 : n$ = n$ + "IV"
case 3 : n$ = n$ + "III"
case 2 : n$ = n$ + "II"
case 1 : n$ = n$ + "I"
end_select
item_add 2,str$(n%) + " = " + n$
END_SUB
' **************************************************************************
La boucle ou la structure itérativePanoramic connaît 3 types de boucles. Elles diffèrent par la structure permettant de les quitter.
• La boucle FOR … NEXT
• La boucle REPEAT … UNTIL
• La boucle WHILE … END_WHILE
Dans le cas d'une boucle de type FOR, nous savons, avant même de pénétrer dans la boucle, le nombre de parcours à effectuer.
La boucle de type REPEAT teste la condition de sortie en fin de parcours. Si la condition est remplie (vraie), le système quitte la boucle.
La boucle WHILE teste la condition de sortie dès le début. Si la condition n'est pas remplie (fausse), le système n'exécute pas les instructions contenues dans la boucle.
L’existence de ces 3 boucles se justifie, et chacune possède un domaine d'application distinct.
La boucle FORLa syntaxe générale d'une boucle FOR s'énonce ainsi :
FOR compteur = ValeurDebut TO ValeurFinale STEP pas
instruction1
instruction2
…..
instructionN
NEXT compteur
Le compteur reçoit une certaine valeur de début, puis, à chaque parcours désigne l’élément suivant de son domaine jusqu'à atteindre ou dépasser la valeur finale.
Vous pouvez également compter « à l'envers » ! Dans ce cas, le pas (après STEP) doit être négatif.
Les variables compteur et de valeur de début et de fin ainsi que celle du pas doivent être de même type (entier ou flottant).
Remarques :1/ STEP pas est facultatif. Si c'est omis, le système se comporte comme s'il s'agit de STEP 1.
Pour toute valeur d'un pas autre que 1, le STEP est nécessaire.
2/ Il existe une contrainte (ou une souplesse !) s'appliquant à la variable compteur qui est qu'aucune instruction de la boucle FOR ne doit en modifier la valeur.
Cela risquerait de perturber la structure de manière interne, les conséquences en seraient imprévisibles. Un blocage de l'ordinateur ne serait pas exclu!
Par contre, vous avez le droit d'utiliser le compteur pour calculer, ou dans un autre but, au sein de la boucle.
3/ Les valeurs de début et de fin peuvent se constituer de constantes et / ou de variables.
Voici comment déterminer le nombre précis de parcours de la boucle :
Parcours = ValeurFinale – ValeurDebut + 1
Si ValeurFinale = ValeurDebut, Le nombre de parcours est donc 1.
Remarque :Si ValeurDebut > ValeurFinale avec un STEP positif, ou si ValeurDebut < ValeurFinale avec un STEP négatif alors Panoramic exécute la boucle une fois.
Dans ce cas précis, les autres langages de programmation ont un comportement différent :
Certains ignorent purement et simplement la boucle (donc zéro parcours), d'autres signalent une erreur.
Par exemple pour exécuter 3 fois les commandes contenues dans une boucle FOR, il n'est pas indispensable que le compteur évolue de 1 à 3. Ce qui importe c'est que ce compteur augmente, ou diminue, 3 fois.
Ainsi, les boucles For ci-dessus sont parfaitement identiques, à condition toutefois que vous n'ayez pas besoin du compteur au sein de la boucle :
FOR i = 1 TO 3 : PRINT "Salut" : NEXT i
FOR i = 15 TO 17 : PRINT "Salut" : NEXT i
FOR i = -5 TO -7 : STEP -1 : PRINT "Salut" : NEXT i
FOR i = 0 TO 0.5 STEP 0.25 : PRINT "Salut" : NEXT i
Le programme suivant exploite le compteur pour effectuer un calcul ; vous remarquerez qu'il n'en modifie pas la valeur. Il calcule la somme des 100 premiers nombres entiers.
- Code:
-
' *****************************************************************************
' Utilisation d'une boucle FOR
' *****************************************************************************
DIM i, somme : ' variable compteur et variable qui contiendra le résultat
somme = 0 : ' cette instruction n'est pas nécessaire dans ce cas, car elle est
' automatiquement initialisée à 0 dès sa déclaration par DIM
FOR i = 1 to 100 : ' Le compteur évolue de 1 à 100 avec un pas implicite de 1
somme = somme + i : ' on cumule le résultat dans la variable somme
NEXT i : ' i suivant
' On sort de la boucle et on affiche le résultat
PRINT "La somme des entiers de 1 à 100 est de : ", somme
END
' *****************************************************************************
On peut imbriquer plusieurs boucles FOR. La boucle la plus intérieure est toujours intégralement traitée en premier avant que le compteur de la boucle qui la précède ne soit modifié (augmenté ou diminué).
La boucle REPEATLorsque nous avons employé les boucles FOR, nous connaissons, avant le 1er parcours, le nombre de répétitions qui seraient effectués.
Ce n'est pas toujours le cas.
Exemple : on veut calculer les moyennes des élèves d'une classe ; or nous ne savons pas d'avance, le nombre des élèves de cette classe, donc la boucle FOR n'est pas adaptée à un tel traitement.
La boucle REPEAT et aussi la boucle WHILE (voir plus loin) vont nous simplifier la vie car la fin du bouclage dépend d'une condition nommée condition de sortie.
Ces deux boucles se différencient par le fait que la condition de sortie est testée au début dans un cas, et à la fin de la boucle dans l'autre cas.
Pour la boucle REPEAT, la condition de sortie est testée à la fin de la boucle, qui de ce fait est au moins parcourue une fois.
Pour la boucle WHILE, la condition de sortie est testée au début de la boucle, il est donc possible qu'elle ne soit pas exécutée du tout.
La différence entre ces deux structures indique que le choix de l'une ou de l'autre dépendra de la tâche à réaliser.
Voici la syntaxe de la boucle REPEAT :
REPEAT
commande1
commande2
…
commandeN
UNTIL condition_de_sortie
Les commandes contenues par la boucle REPEAT sont exécutées au 1er parcours sans que le test ait lieu. En fin de boucle, le programme teste si la condition est remplie (vraie).
Si c'est le cas, il quitte la boucle, sinon les commandes seront à nouveau exécutées, et ce jusqu'à ce que la condition de sortie soit remplie.
La boucle REPEAT, exécutant au moins une fois les commandes qu'elles contient, il convient évidemment de l'utiliser lorsque nous souhaitons que ce soit le cas et que cela ne risque pas de provoquer une erreur ! Sinon nous emploierons la boucle WHILE.
La procédure de sortie d'une boucle REPEAT implique évidemment que l'élément testé en fin de boucle évolue, de façon à ce que nous ayons une chance de quitter un jour la boucle, autrement dit que la condition puisse devenir vraie.
Lorsqu'il est impossible de remplir la condition de sortie, nous sommes en face de ce l'on nomme une « boucle sans fin », et le programme y est coincé !
Vous devez être très attentif sur ce point lorsque vous employez des structures de type « boucle ».
Lorsque vous programmez une boucle REPEAT, testez toujours les 2 éléments suivants :
1 / Les commandes contenues dans la boucle REPEAT modifient-elles au moins l'élément du test ?
2 / La condition de sortie peut-elle être remplie dans un avenir proche ?
Si vous pouvez répondre « oui » à ces 2 questions, vous avez des bonnes chances que la boucle REPEAT que vous venez de programmer se comporte de la manière prévue !
L'extrait de programme suivant expose une boucle REPEAT que nous ne quittons jamais :
- Code:
-
r$ ="x"
REPEAT
PRINT "Veuillez appuyer sur une touche …"
UNTIL r$ ="o"
Par contre,
- Code:
-
REPEAT
PRINT "Veuillez appuyer sur une touche ..."
UNTIL SCANCODE <> 0
sera quittée lorsque nous appuierons sur n'importe quelle touche ou lorsque nous cliquons sur l'un ou l'autre bouton de la souris.
Le programme suivant fait la même chose que le programme précédent, mais en utilisant cette fois, la boucle REPEAT.
- Code:
-
' *****************************************************************************
' La boucle REPEAT ... UNTIL
' Calcul la somme des n premiers nombres entiers positifs, où n est un nombre
' positif initialisé dans le programme
' Il s'agit donc de calculer la somme : 1 + 2 + 3 + ... + n, en supposant que
' nous ne savons pas la formule pour la calculer directement et qui est pour
' info : somme = n *(1 + n)/2
' *****************************************************************************
dim i,n,somme
' Initialisation de n
n = 100
' Calcul de la somme à l'aide de la boucle REPEAT ... UNTIL
i = 1 : ' On initialise i à 1 qui représente la condition de sortie
REPEAT : ' Entrée dans la boucle
somme = somme + i : ' on cumule le résultat dans somme
i = i + 1 : ' on modifie la condition de sortie pour s'assurer que le
' programme ne reste pas coincé dans la boucle
UNTIL i > n : ' on teste la condition de sortie de la boucle
' Sortie de la boucle
' Affichage du résultat
PRINT "La somme des ";n;" premiers entiers vaut : "; somme
END
' *****************************************************************************
La boucle WHILELa boucle WHILE fait, elle aussi, dépendre d'une condition l'exécution des commandes qu'elle contient.
Voici la syntaxe de la boucle WHILE :
WHILE condition
instruction1
instruction2
….
END_WHILE
Au contraire d'une boucle REPEAT, la condition est testée d'entrée dans la boucle. Si elle est remplie, les instructions sont exécutées, elles ne le sont pas dans le cas contraire. Il est donc tout à fait possible que le contenu d'une boucle WHILE ne soit jamais exécuté.
Une fois la boucle parcourue, avant toute nouvelle exécution, la condition est à nouveau testée. Ce n'est que si elle s'avère à nouveau vraie que les instructions seront à nouveau exécutées.
De même que la boucle REPEAT, la boucle WHILE nécessite que l'élément de la condition soit modifié à l'intérieur de la boucle elle-même. Il faut également qu'une chance existe que la condition se révèle fausse! Dans le cas de la boucle REPEAT, la condition de sortie devait pouvoir devenir vraie.
S'il est impossible que la condition de parcours de la boucle devienne fausse, il s'agit d'une boucle infinie dans laquelle le programme reste coincé.
Lorsque vous programmez une boucle WHILE, vous devez toujours tester les points suivants :
1 / Les commandes contenues dans la boucle WHILE modifient-elle au moins l'élément du test ?
2 / Est-il possible que la condition de parcours s'avère un jour ou l'autre fausse ?
Si vous pouvez répondre « oui » à ces deux questions, vous avez des bonnes chances que la boucle WHILE se comporte de la manière prévue.
L'extrait de programme suivant correspond à une boucle WHILE que nous ne quitterons jamais.
- Code:
-
…
i = 0
WHILE i <= 10
i = i + 1
PRINT "I vaut maintenant : " ; i
i = i – 1
END_WHILE
Par contre
- Code:
-
…
i = 0
WHILE i <= 10
i = i + 1
PRINT "I vaut maintenant : " ; i
END_WHILE
fera que nous quitterons la boucle après que les instructions de la boucle aient été exécutées onze fois ; en effet la variable i aura alors 11 pour valeur.
Les boucles WHILE, comme les boucles REPEAT et comme les boucles FOR, peuvent être imbriquées.
Pour terminer, voici un programme utilisant deux boucles WHILE imbriquées.
- Code:
-
' ******************************************************************************
' Carre.bas
' Ce programme, pour un entier donné, affiche un carré de la forme suivante :
' Exemple pour : 5
' 1 2 3 4 5
' 2 3 4 5 6
' 3 4 5 6 7
' 4 5 6 7 8
' 5 6 7 8 9
' ******************************************************************************
DIM nombre, nombre_ligne, nombre_colonne, valeur_colonne
' initialisation de la constant nombre
nombre = 5
' Affichage
nombre_ligne = 1
WHILE nombre_ligne <= nombre
' Afficher une ligne
valeur_colonne = nombre_ligne
nombre_colonne = 1
WHILE nombre_colonne <= nombre
PRINT valeur_colonne ; " ";
nombre_colonne = nombre_colonne + 1
valeur_colonne = valeur_colonne + 1
END_WHILE
PRINT : ' passer à la ligne suivante
nombre_ligne = nombre_ligne + 1
END_WHILE
END
' ******************************************************************************
Comparatif entre la boucle REPEAT et la boucle WHILEREPEATLa condition de sortie est testée après chaque
parcours de la boucle.
Le test détermine l'interruption des répétitions.
La boucle sera exécutée jusqu'à ce que la condition de sortie soit remplie.
La boucle sera parcourue au moins une fois.
WHILELa condition de sortie est testée avant chaque
parcours de la boucle.
Le test détermine la continuation des répétitions.
La boucle sera exécutée tant que la condition de sortie soit remplie.
La boucle peut très bien ne jamais être parcourue.