Les boucles


Les boucles
Autre chapitre important en Java : les boucles !
Oui, mais ...c'est quoi, ces fameuses boucles ?
Une boucle est une instruction qui permet de faire plusieurs fois la même chose...
Très pratique lors de protocoles lourds en exécution. Comme lorsque nous demandons si un utilisateur souhaite refaire quelque chose ou non. Ou encore, lorsque nous devons trier des données dans un tableau... Eh bien, dans ce genre de cas, on se sert d'une boucle !

En gros, en français ça donnerait :
tant que nombre de lignes est inférieur à 100,
alors fais ceci, ou cela, mais n'oublie pas de faire ça...

Ne vous inquiétez pas : ce chapitre est facile à digérer.
Bon appétit !
Sommaire du chapitre :
  • La boucle while
  • La boucle do....while
  • La boucle for

La boucle while

Décortiquons précisément ce qui se passe dans une boucle.
Pour cela, nous allons voir comment elle se forme.

Une boucle commence par une déclaration. Ici : while qui veut dire, à peu de chose près, TANT QUE.
Ensuite, nous avons une condition. C'est elle qui permet à la boucle de s'arrêter. Une boucle n'est pratique que si nous pouvons la contrôler, et donc lui faire répéter une instruction un certain nombre de fois. C'est à ça que servent les conditions.
Puis nous avons l'instruction. C'est ce que va répéter notre boucle ! Dans une boucle, il peut y avoir une ou plusieurs instructions.

Remarque : il peut même y avoir des boucles, dans une boucle...

À ce stade, la boucle va tester la condition, et en fonction de celle-ci, va recommencer ou s'arrêter.

Un exemple concret est toujours le bienvenu... Voici comment une boucle de type while se fait en Java.

D'abord, réfléchissons au "comment notre boucle va travailler". Pour cela, il faut déterminer notre exemple.
Nous allons afficher "bonjour", <un prénom> que vous allez taper à l'écran, puis vous demanderez si vous voulez recommencer. Pour réussir ceci, il nous faut une variable pour recevoir le prénom, donc de type String, et une variable pour récupérer votre réponse et là, plusieurs choix s'offrent à nous : soit un caractère, soit une chaîne de caractères, soit un entier. Ici, nous prendrons une variable de type char.
Et c'est parti !

Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Une variable vide
String prenom;
// On initialise celle-ci à O pour oui !
char reponse = 'O';
//Notre objet Scanner, n'oubliez pas l'import de java.util.Scanner
Scanner sc = new Scanner(System.in);
//Tant que la réponse donnée est égale à oui
while (reponse == 'O')
{
        //On affiche une instruction
        System.out.println("Donnez un prénom : ");
        //On récupère le prénom saisi
        prenom = sc.nextLine();
        // On affiche notre phrase avec le prénom
        System.out.println("Bonjour " +prenom+ " comment vas-tu ?");
        //On demande si la personne veut faire un autre essai
        System.out.println("Voulez-vous réessayer ?(O/N)");
        //On récupère la réponse de l'utilisateur
        reponse = sc.nextLine().charAt(0);
}
 
System.out.println("Au revoir...");
//Fin de la boucle

Avant tout, vous avez dû cligner des yeux sur cette ligne "reponse = sc.nextLine().charAt(0);". Rappelez-vous comment on récupère un char avec l'objet Scanner. Nous devons récupérer un objet String et ensuite prendre le premier caractère de celui-ci ! Eh bien cette syntaxe est une contraction de ce que je vous avais fait voir auparavant.
Cette façon de faire permet d'économiser une variable et donc de la mémoire ! Ici sc.nextLine() renvoie un String sur lequel on applique tout de suite la méthode qui retourne le premier caractère de la chaîne (charAt(0)), nous pouvons donc, sans crainte, initialiser une variable de type char avec le résultat obtenu.
Détaillons un peu ce qui ce passe.
Dans un premier temps, nous avons déclaré et initialisé nos variables.
Ensuite, la boucle teste la condition qui nous dit : "Tant que la variable reponse contient OUI, on exécute la boucle". Celle-ci contient bien la chaîne OUI, donc nous entrons dans la boucle. Rappelez-vous qu'on teste l'égalité des conditions avec un double égal ==.
Puis c'est l'exécution des instructions, dans l'ordre où elles apparaissent dans la boucle.
Et à la fin, c'est-à-dire à l'accolade fermante de la boucle, le compilateur retourne au début de la boucle.
Cette boucle n'est exécutée que lorsque la condition est remplie : ici, nous avons initialisé la variable "reponse" à 'O' pour que la boucle se fasse. Si nous ne l'avions pas fait, nous n'y serions jamais rentrés. Normal, puisque nous testons la condition avant de rentrer dans la boucle !

Voilà. C'est pas mal, mais il y a un petit problème, dans ce programme... Vous ne voyez pas ? Oh ! Je suis sûr qu'il y a des petits malins qui se sont amusés à mettre autre chose que 'O' ou 'N' en "reponse". Ces petits filous-là ont dû remarquer que nous sortons de la boucle si on tape autre chose que 'O'... Essayez de trouver comment pallier à ce problème....
Il faudrait forcer les utilisateurs à ne tapez que 'OUI' ou 'NON'... Mais non, pas en leur mettant un couteau sous la gorge, bande de barbares !
Avec une boucle !
Comment faire ? C'est très simple, vous allez voir ! Il suffit, comme je l'ai dit plus haut, de forcer les utilisateurs à rentrer soit 'NON'soit 'OUI' ! Avec un while ! Mais cela sous-entend de réinitialiser notre variable reponse à ' ' (caractère vide).
Nous allons utiliser ici la méthode. Occupons-nous de la condition de notre boucle, maintenant. Il faut répéter la phase "Voulez-vous réessayer ?" tant que la "reponse" donnée n'est pas 'OUI' et 'NON' : voilà, tout y est.
On appelle ce genre de condition des conditions multiples. Vous avez vu les opérateurs logiques au chapitre 2, normalement... (et == &&) Nous en reparlerons dans le prochain chapitre...

Voici notre programme dans son intégralité :

Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//Une variable vide
String prenom;
// On initialise celle-ci à O pour oui !
char reponse = 'O';
//Notre objet Scanner, n'oubliez pas l' import de java.util.Scanner
Scanner sc = new Scanner(System.in);
//Tant que la réponse donnée est égale à oui
while (reponse == 'O')
{
   //On affiche une instruction
   System.out.println("Donnez un prénom: ");
   //On récupère le prénom saisi
   prenom = sc.nextLine();
   // On affiche notre phrase avec le prénom
   System.out.println("Bonjour " +prenom+ " comment vas-tu ?");
                        
   //réinitialisation de la variable réponse. 
   //Sans ça, nous n' entrions pas dans la deuxième boucle
   reponse = ' ';
                        
   //tant que la réponse n'est pas O ou N, on repose la question
   while(reponse != 'O' && reponse != 'N')
   {
       //On demande si la personne veut faire un autre essai
       System.out.println("Voulez-vous réessayer ?(O/N)");
       //On récupère la réponse de l'utilisateur
       reponse = sc.nextLine().charAt(0);
   }
}
//Fin de la boucle
System.out.println("Au revoir...");

Je vous le répète une dernière fois : PENSEZ A L'INDENTATION !
Vous pouvez tester ce code (c'est d'ailleurs vivement conseillé) : vous verrez que si vous ne rentrez pas la bonne lettre, le programme vous demandera sans cesse votre réponse !

Attention à bien écrire vos conditions, et à bien vérifier vos variables dans vos while, et dans toutes vos boucles en général. Sinon c'est le drame ! Essayez le programme précédent sans la réinitialisation de la variable reponse, et vous verrez le résultat... on ne rentre jamais dans la 2° boucle, car "reponse" = 'O' (initialisé au début du programme). Là, vous ne pourrez jamais changer sa valeur... donc le programme ne s'arrêtera jamais ! On appelle ça une boucle infinie.

Voilà un autre exemple de boucle infinie, encore plus flagrante :
Code : Java
1
2
3
4
5
int a = 1, b = 15;
while (a < b)
{
        System.out.println("coucou " +a+ " fois !!");
}

Si vous lancez ce programme, vous allez voir une quantité astronomique de coucou 1 fois !!, car, dans cette condition, a sera toujours inférieur à b.
Si nous voulions faire en sorte que ce programme fonctionne comme il faut, nous aurions dû rajouter une instruction dans le bloc d'instructions de notre while, pour changer la valeur de a à chaque tour de boucle...
Comme ceci :
Code : Java
1
2
3
4
5
6
int a = 1, b = 15;
while (a < b)
{
        System.out.println("coucou " +a+ " fois !!");
        a++;
}
Ce qui nous donnerait cela :

Notre a a bien augmenté de 1 à chaque tour. Et si vous me dites que vous n'avez jamais vu a++; je vous renvoie illico au second chapitre ==> sous chapitre 3 !

Qu'en dites-vous ? Pas trop mal, non ? Je dirais même bien !
Une petite astuce : lorsque vous n'avez qu'une instruction dans votre boucle, vous pouvez enlever les accolades { }, celles-ci deviennent superflues, tout comme les instructions if, else if ou else.


Vous auriez pu aussi utiliser cette syntaxe :
Code : Java
1
2
3
int a = 1, b = 15;
while (a++ < b)
   System.out.println("coucou " +a+ " fois !!");
Ici, l'opérateur '++' n'agit qu'après avoir évalué 'a'. Ce qui veut dire que l'effet de l'opérateur '++' (qui est une incrémentation) n'est perçu qu'une instruction après. Par contre, testez ce code :
Code : Java
1
2
3
int a = 1, b = 15;
while (++a < b)
   System.out.println("coucou " +a+ " fois !!");


Vous devez remarquer qu'il y a un tour de boucle en moins !
Eh bien, avec cette syntaxe, l'incrémentation est immédiate. C'est-à-dire que la boucle incrémente la variable a et, seulement après avoir fait cela, elle teste la condition !
Vous avez dû remarquer aussi que notre instruction n'affiche plus "coucou 1 fois !!". Cela à cause de l'incrément dans la condition. Au premier tour de boucle, on entre dans la condition et, quelque soit l'ordre d'incrémentation, à la fin du premier test de condition, a vaut 2. Donc réfléchissez bien à vos conditions de boucles !

Avant d'aller voir un autre type de boucle, j'insiste sur le fait que vous devez bien réfléchir à vos conditions, ainsi qu'à vos variables, avant de lancer une boucle, sous peine de ne jamais y rentrer, ou comme on l'a vu, de faire une boucle infinie !
Bon, continuons avec la boucle do{...}while().

La boucle do....while

Vu que je viens de vous expliquer comment marche une boucle while, je ne vous expliquerai que très brièvement la boucle do... while.
Euh... t'es sûr de ton coup, là?

Bien entendu. En fait, ces deux boucles ne sont pas cousines, mais plutôt frangines (soeurs, si vous préférez...). Dans le fonctionnement, elles sont identiques, à deux détails près. Soeurs, mais pas jumelles, quoi...

Première différence


La boucle do... while s'exécutera au moins une fois, contrairement à sa soeur. C'est-à-dire que la phase de test de la condition se fait à la fin. Car la condition se met après le while.

Deuxième différence


Différence de syntaxe. Et elle se situe après la condition du while.
Exemple :
Code : Java
1
2
3
do{
         blablablablablablablabla
}while(a < b);

Vous voyez la différence ? Oui ? Non ?
Il y a un ; après le while. C'est tout ! Par contre, ne l'oubliez pas, sinon le programme ne compilera pas.
Mis à part ces deux éléments, ces boucles fonctionnent exactement de la même manière. D'ailleurs, nous allons refaire les deux programmes de la boucle while ci-dessus, avec une boucle do... while. C'est parti !
Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
//une variable vide !
String prenom = new String();
//pas besoin d'initialiser la variable car on entre au moins une fois dans la boucle !
char reponse = ' ';
 
//Notre objet Scanner, n'oubliez pas l'import de java.util.Scanner
Scanner sc = new Scanner(System.in);
 
do{
        System.out.println("Donnez un prénom : ");
        prenom = sc.nextLine();
        System.out.println("Bonjour " +prenom+ ", comment vas-tu ?");
        System.out.println("Voulez-vous réessayer ?(O/N)");
        reponse = sc.nextLine().charAt(0);
}while (reponse == 'O');
 
System.out.println("Au revoir...");

Et faites-moi confiance : ça marche ! Mais toujours le même problème de réponse... Voici donc le code complet :
Code : Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
//une variable vide !
String prenom = new String();
//pas besoin d'initialiser la variable car on entre au moins une fois dans la boucle !
char reponse = ' ';
 
//Notre objet Scanner, n'oubliez pas l'import de java.util.Scanner
Scanner sc = new Scanner(System.in);
 
do{
        System.out.println("Donnez un prénom : ");
        prenom = sc.nextLine();
        System.out.println("Bonjour " +prenom+ ", comment vas-tu ?");
       
        do{
                System.out.println("Voulez-vous réessayer ? (O/N)");
                reponse = sc.nextLine().charAt(0);
        }while(reponse != 'O' && reponse != 'N');
        
}while (reponse == 'O');
 
System.out.println("Au revoir...");

Vous voyez donc que ce code ressemble beaucoup à celui utilisé avec la boucle while, mais avec une petite subtilité. Avec celui-ci, plus besoin de réinitialiser la variable reponse, puisque, de toute manière, la boucle s'exécutera au moins une fois !

Normalement, vous devriez avoir compris du premier coup ! On va pouvoir se lancer sur la dernière boucle : la boucle for.

La boucle for

Cette boucle est un peu particulière, puisque qu'elle prend tous ses attributs dans sa condition, et agit en conséquence. Je m'explique : jusqu'ici, nous avions fait des boucles avec :
  • déclaration d'une variable avant la boucle
  • initialisation de cette variable
  • incrémentation de celle-ci dans la boucle.

Eh bien on met tout ça dans la condition de la boucle for, et c'est tout. Mais je sais bien qu'un long discours ne vaut pas un exemple, alors voilà une boucle for sous vos yeux ébahis :
Code : Java
1
2
3
4
for(int i = 1; i <= 10; i++)
{
        System.out.println("Voici la ligne "+i);
}

Et ça nous donne :

Vous aurez sûrement remarqué la présence des ';' dans la condition pour la séparation des champs. Et là, ne les oubliez surtout pas, sinon, le programme ne compilera pas.

Je vous fais la même remarque que pour la boucle while concernant les accolades...
Nous pouvons aussi tourner la boucle dans le sens inverse. C'est-à-dire qu'au lieu de partir de zéro pour aller à 10, nous allons aller de 10 pour atteindre 0. Comme ceci :
Code : Java  
1
2
for(int i = 10; i >= 0; i--)
        System.out.println("Il reste "+i+" ligne(s) à écrire");

Ce qui nous donne :

Bien entendu, ces structures servent essentiellement à répéter des instructions rébarbatives ; mais elles servent aussi à faire des recherches dans certains cas de figure, ce que nous aborderons dans un prochain chapitre.

Bon : vu que nous sommes de bons ZérOs et que nous n'aimons pas les fautes d'orthographe, nous voulons mettre "ligne" au pluriel lorsqu'il nous en reste plusieurs à écrire, et au singulier lorsqu'il nous en reste 1 ou moins ! Il va de soit que nous allons utiliser les conditions pour réussir ce tour de force.
Je vous laisse réfléchir.


Il existe une autre syntaxe de boucle for depuis le JDK 1.5, celle-ci se rapprocherait d'une boucle foreach présente dans d'autres langages (PHP, C#...). Nous verrons celle-ci lorsque nous aborderons les tableaux.

Un petit détail, tout de même... Ici, nous avons utilisé un entier bien défini pour gérer nos boucles, tel que 0 ou 10. Nous pouvons tout aussi bien faire les mêmes boucles avec une variable en guise d'attribut. Là, vous commencez à apercevoir leur intérêt. Ne vous inquiétez pas : vous allez voir tout ceci plus tard. Et plus précisément dans le chapitre sur les tableaux, qui arrive à pas de loup !
Et voilà : la boucle est bouclée !!
Normalement, vous n'aurez pas besoin de digestif pour ce chapitre ! Mais on ne sait jamais...
Je crois qu'il est temps pour un petit TP


0 comments to "Les boucles"

Post a Comment

About This Blog

Aller au debut de la page