Intéressé par des cours d'informatique en ligne ?
Visitez mon nouveau site https://www.yesik.it !

Une boucle est une structure de contrôle qui permet d'indiquer dans le programme qu'un groupe d'instructions doit être répété.

La plupart des langages proposent différents types de boucles. Dans les exemples ci-dessous, nous présenterons différentes variantes de la même boucle.

Un exemple

Tableaux et boucles sont intimement liés. La boucle étant souvent utilisée pour parcourir un tableau. C'est ce que nous allons mettre en oeuvre ici. Notre exemple sera celui d'un programme chargé d'afficher un poème à l'écran.

Pseudo-code

Vous savez utiliser des tableaux. On pourrait donc envisager le programme suivant – qui n'utilise pas de boucle:

chaque Poète
    sait que déclamer c'est:
        définir poème ← {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        }

        afficher poème[0]
        afficher poème[1]
        afficher poème[2]
        afficher poème[3]
        afficher poème[4]

le programme principal fait:
    définir apollinaire ← créer un nouveau Poète
    demander à apollinaire de déclamer

De façon évidente, cette solution n'est pas très élégante avec sa répétition d'instruction afficher... C'est l'exemple typique où une boucle est préférable. Celle-ci va indiquer à l'ordinateur que l'affichage va se répéter pour chacun des éléments du tableau:

chaque Poète
    sait que déclamer c'est:
        définir poème ← {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        }

        pour chaque vers du tableau poème
            afficher vers

Simple non? En fait, trop! En effet, tous les langages ne supportent malheureusement pas les boucles pour chaque permettant de parcourrir simplement un tableau.

Heureusement, il existe une alternative basée sur le fait que les éléments du tableau possèdent un index séquentiel: les index se suivent: 0, 1, ... N-1 (où N est le nombre d'éléments du tableau). Par conséquent, on peut exploiter cette propriété ainsi:

chaque Poète
    sait que déclamer c'est:
        définir poème ← {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        }

        pour i variant de 0 à taille du tableau( poème )-1
            afficher poème[i]


C'est moins expressif, mais ça se comprend quand même. Enfin, il existe encore une dernière manière assez classique d'exprimer la même boucle. Celle-ci décompose encore plus la construction:

chaque Poète
    sait que déclamer c'est:
        définir poème ← {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        }

        définit i ← 0
        tant que i < taille du tableau( poème )
            afficher poème[i]
            i ← i+1

Incrément

Peut-être vous interrogez vous sur l'expression:

            i ← i+1

Celle-ci pourait se lire "i reçoit son ancienne valeur plus un". Autrement dit:

  • si la variable i contenait la valeur 0, elle contiendra 1 après cette instruction
  • si la variable i contenait la valeur 1, elle contiendra 2 après cette instruction
  • si la variable i contenait la valeur 2, elle contiendra 3 après cette instruction
  • etc.

Autrement dit encore, elle fait passer i à la valeur suivante. En informatique, on appelle cette opération incrémenter.

Dans la mise en oeuvre dans différents langages ci-après, nous commencerons systématiquement par la version avec boucle tant que puis avec une boucle pour. Enfin, si le langage considéré supporte une boucle de la forme pour chaque, nous la présenterons en dernier.

PHP

Tout d'abord, voici la version avec boucle tant que – aussi appelée boucle while:

<?php
 
class Poete {
    public function declamer() {
        $poeme = array(
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        );
 
        $i = 0;
        while($i < count($poeme)) {
            print $poeme[$i] . "\n";
            $i = $i + 1;
        }
    }
}
 
header("text/plain");
$apollinaire = new Poete();
$apollinaire->declamer();

Comme souvent en PHP, le code est assez proche du pseudo-code de la section précédente. Si le code avec la boucle while est le plus long (en "lignes" de code, s'entend), il est sans doute plus simple à comprendre au premier abord que la version avec boucle pour – autrement dit boucle for:

<?php
 
class Poete {
    public function declamer() {
        $poeme = array(
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        );
 
        for($i = 0; $i < count($poeme); $i = $i + 1) {
            print $poeme[$i] . "\n";
        }
    }
}
 
header("text/plain");
$apollinaire = new Poete();
$apollinaire->declamer();

Point de syntaxe:

A chaque fois que vous avez une boucle for vous pouvez la remplacer par une boucle while. En effet la structure d'une boucle for est la suivante:

for( initialisation ; test ; incrément ) {
    corps de la boucle
}

Ce qui peut toujours se ré-écrire ainsi:

initialisation
while( test ) {
    corps de la boucle
    incrément
}
Etre capable de pouvoir passer d'une forme à l'autre est une des clés pour comprendre facilement les boucles que vous trouverez dans du code!

Point de syntaxe: Accolades

Les accolades sont facultatives si le corps de la boucle ne contient qu'une seule instruction (i.e.: une seule "ligne" terminée par un point-virgule).

Ainsi, les deux boucles suivantes produiront le même résultat:

       for($i = 0; $i < count($poeme); $i = $i + 1) {
           print $poeme[$i] . "\n";
       }
       for($i = 0; $i < count($poeme); $i = $i + 1)
           print $poeme[$i] . "\n";

Par contre, attention aux "erreurs d'inattention". Ainsi le code suivant (supposé numéroter les vers):

       for($i = 0; $i < count($poeme); $i = $i + 1)
           print $i . ": ";
           print $poeme[$i] . "\n";

Produira le résultat suivant:

0: 1: 2: 3: 4:
Notice: Undefined offset:  5 in /home/sylvain/Developpement/boucles/php/Poete.php on line 15

Surprenant au premier abord, mais compréhensible. En effet, contrairement à ce que laisse supposer la présentation du programme, la seule instruction dans le corps de la boucle est:

           print $i . ": ";

Ce qui explique l'affichage successif 0: 1: 2: ... Quand au message d'erreur, il est causé parce que le seul affichage d'un vers du poème se trouve après la fin de la boucle, à un moment ou la variable i contient 5, c'est à dire un index invalide pour un tableau de 5 éléments (donc numérotés de 0 à 4).

Pour que les choses soient plus claires, voici le même code, mais cette fois avec les accolades et la bonne présentation:

       for($i = 0; $i < count($poeme); $i = $i + 1) {
           print $i . ": ";
       }
       print $poeme[$i] . "\n";

Maintenant, il devrait être évident pour vous que ce code ne fait certainement pas ce que le programmeur voulait initialement faire. La morale? Utilisez systématiquement les accolades, même si c'est facultatif!

Le code correct aurait donc été:

       for($i = 0; $i < count($poeme); $i = $i + 1) {
           print $i . ": ";
           print $poeme[$i] . "\n";
       }

Enfin, après les boucles while et for, la boucle foreach qui comme son nom l'indique permet de parcourir chaque élément d'un tableau:

<?php
 
class Poete {
    public function declamer() {
        $poeme = array(
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        );
 
        foreach($poeme as $vers) {
            print $vers . "\n";
        }
    }
}
 
header("text/plain");
$apollinaire = new Poete();
$apollinaire->declamer();

Piège:

Plus compact, plus lisible, la boucle foreach réserve tout de même un léger piège en PHP: en effet, comme vous l'avez vu dans le code, la syntaxe fait d'abord apparaître le nom du tableau, et ensuite le nom de la variable qui stocke l'élément, ce qui est quelque peu contre-intuitif:

       foreach($poeme as $vers) {
           ...
       }

Se lit:

       pour chaque vers du tableau poème
           ...

JavaScript

Commençons par la version "avec boucle while" (je ne l'inclus pas ici, mais vous savez qu'il vous faut un document HTML pour charger le programme JavaScript dans votre navigateur!):

var Poete = function () {
    var that = {};
 
    that.declamer = function () {
        var poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        var i = 0;
        while(i < poeme.length) {
            document.write(poeme[i] + "<br />");
            i = i + 1;
        }
    };
 
    return that;
};
 
var apollinaire = Poete();
apollinaire.declamer();

br?

Le programme JavaScript est chargé par un document HTML dans votre navigateur. Il est donc possible d'écrire du HTML à partir de votre programme JavaScript, et celui-ci sera interprété par le navigateur exactement comme si ce code était dans le document HTML. Ainsi la ligne:

           document.write(poeme[i] + "<br />");

Envoie une balise <br /> au navigateur à la fin de chaque vers, ce qui est la version HTML du "retour à la ligne".

Maintenant passons à la boucle for. Comme vous le constaterez, rien de particulièrement notable ici:

var Poete = function () {
    var that = {};
 
    that.declamer = function () {
        var poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        for(var i = 0; i < poeme.length; i = i + 1) {
            document.write(poeme[i] + "<br />");
        }
    };
 
    return that;
};
 
var apollinaire = Poete();
apollinaire.declamer();

Enfin, plus intéressant, la boucle for ... in qui permet en JavaScript de parcourir un tableau. Plus intéressante, parce qu'un peu différente dans son approche de sa contre-partie PHP:

var Poete = function () {
    var that = {};
 
    that.declamer = function () {
        var poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        for(var i in poeme) {
            document.write(poeme[i] + "<br />");
        }
    };
 
    return that;
};
 
var apollinaire = Poete();
apollinaire.declamer();

Curieux! Pas de variable vers? Et qui plus est, on retrouve toujours la notation avec index poeme[i]? Et oui, contrairement au foreach PHP, le for ... in JavaScript parcourt la liste des index pas des éléments du tableau! Bref, il simplifie simplement l'écriture de la boucle for elle-même. Mais ne change rien au corps de la boucle.

JavaScript 1.6

Si vous utilisez Firefox, il existe une façon alternative de parcourir un tableau. En effet, la version 1.6 de JavaScript mise en oeuvre dans les navigateurs de la fondation Mozilla dotent les tableaux d'une méthode forEach qui permet d'appliquer une fonction à tous les éléments d'un tableau.

Comme JavaScript supporte les fonctions anonymes, la fonction à appliquer peut directement être définie au moment de l'appel à la méthode forEach. Ce qui nous donne le code suivant:

var Poete = function () {
    var that = {};
 
    that.declamer = function () {
        var poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        poeme.forEach( function(vers) {
            document.write(vers + "<br />");
        } );
    };
 
    return that;
};
 
var apollinaire = Poete();
apollinaire.declamer();

Piège:

Cette possibilité n'est offerte pour l'instant qu'avec Firefox et les navigateurs apparentés. En particulier, elle n'est pas supportée par Internet Explorer. Par conséquent ne l'utilisez que si vous destinez une application JavaScript à ne fonctionner qu'avec Firefox!

C++

Vous le savez, C++ est un langage statiquement typé. Par conséquent, il faudra indiquer le type de la variable de boucle i. Les index étant des entiers, le type int ferait parfaitement l'affaire. Néanmoins, en étant un peu plus observateur, on remarque que les index sont des entiers oui, mais des entiers positifs. Or C++ possède un type spécifique pour les entiers dont le signe n'a pas d'importance: unsigned int. C'est ce type que nous utiliserons:

#include <iostream>
#include <string>
 
class Poete
{
    public:
    void declamer() {
        std::string poeme[] = {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        };
 
        unsigned int i = 0;
        while(i < sizeof(poeme)/sizeof(std::string))
        {
            std::cout << poeme[i] << std::endl;
            i = i + 1;
        }
    }
};
 
int main()
{
    Poete   apollinaire;
    apollinaire.declamer();
 
    return 0;
}

Comme à l'habitude, le programme C++ est le plus verbeux de ceux présentés ici. Essayons de réduire un peu ce code à l'aide d'une boucle for:

#include <iostream>
#include <string>
 
class Poete
{
    public:
    void declamer() {
        std::string poeme[] = {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        };
 
        for(unsigned int i = 0; i < sizeof(poeme)/sizeof(std::string); i = i + 1)
        {
            std::cout << poeme[i] << std::endl;
        }
    }
};
 
int main()
{
    Poete   apollinaire;
    apollinaire.declamer();
 
    return 0;
}

Impressionnante boucle for! Peut-être peut-on faire mieux avc le boucle foreach? Et bien non: le C++ ne possède pas de telle boucle. Il faudra donc se contenter des deux boucles précédentes...

Java

La boucle while en Java ressemble trait pour trait à celles que nous avons déjà vues dans d'autres langages. Différence avec C++, Java ne connaît pas de type "non signé". Il faudra donc utiliser un entier signé (int) pour la variable de boucle:

public class Poete
{
    public void declamer() {
        String[] poeme = {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        };
 
        int i = 0;
        while(i < poeme.length) {
            System.out.println(poeme[i]);
            i = i + 1;
        }
    }
 
    public static void main(String[] args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

Que fait le main là?

En Java, on peut mettre le main dans n'importe quelle classe du programme. En fait, on peut même mettre un programme principal différent dans chacune des classes du programme.

Sans en arriver à cette extrémité, rien ne m'empêche donc de profiter de la classe Poete pour y inclure le programme principal. Cela m'évite simplement de créer une autre classe uniquement pour lui.

La version avec boucle for est également très similaire à ce que nous avons déjà vu:

public class Poete
{
    public void declamer() {
        String[] poeme = {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        };
 
        for(int i = 0; i < poeme.length; i = i + 1) {
            System.out.println(poeme[i]);
        }
    }
 
    public static void main(String[] args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

Quand à la boucle for each, celle-ci nous réserve encore une syntaxe différente de toutes celles que nous avons vu:

public class Poete
{
    public void declamer() {
        String[] poeme = {
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        };
 
        for(String vers : poeme) {
            System.out.println(vers);
        }
    }
 
    public static void main(String[] args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

La notation peut paraître surprenante après toutes les autres versions que nous avons vu dans d'autres langages – et puis aussi à cause de l'utilisation du "deux points" qui rend la notation peu lisible. Néanmoins, c'est la version la plus proche du pseuso-code que nous ayons rencontré:

Le code......se lit bien
       for(String vers : poeme) {
           ...
       }
       pour chaque vers du poeme {
           ...
       }

Groovy

public class Poete
{
    def declamer() {
        def poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        def i = 0;
        while(i < poeme.size()) {
            System.out.println(poeme[i]);
            i = i + 1;
        }
    }
 
    static main(args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

Note:

Tout comme en Java, il est possible d'inclure le programme principal dans une classe. Soit une classe séparée, soit une classe déjà présente dans le programme. Contrairement à Java, il est aussi possible de "définir" le programme principal en dehors de toute classe à la manière du programme principal en PHP.

Le choix de l'une ou l'autre méthode pour définir le programme principal est une affaire de style principalement...

public class Poete
{
    def declamer() {
        def poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        for(def i = 0; i < poeme.size(); i = i + 1) {
            System.out.println(poeme[i]);
        }
    }
 
    static main(args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

Rien à dire sur la version avec boucle for. Mais que nous réserve Groovy pour la suite? Surprise: Groovy ne propose pas une, ni deux, mais ... pfouu ... plein de syntaxes alternatives pour la boucle for!

Commençons tout d'abord par la version Java-like de la boucle for each. Celle-ci reprend donc la syntaxe Java mais en remplaçant le "deux-points" par le mot-clé in définitivement plus lisible:

public class Poete
{
    def declamer() {
        def poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        for(vers in poeme) {
            System.out.println(vers);
        }
    }
 
    static main(args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

Dans le même ordre d'idée, Groovy permet aussi une écriture plus compacte pour définir l'intervalle parcouru dans une boucle for. Dans le jargon de Groovy, on parle de boucle for in range:

public class Poete
{
    def declamer() {
        def poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        for(i in 0..<poeme.size) {
            System.out.println(poeme[i]);
        }
    }
 
    static main(args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

Enfin, dernière possibilité, la version Groovy-style. Celle-ci utilise une fermeture (closure). Il s'agit là d'une notion équivalente à celle des fonction anonymes JavaScript et qu'on ne retrouve dans aucun autre des langages présentés ici (hormis peut-être Java 7 – qui n'est pas encore sorti à l'heure ou j'écris ces lignes).

Sans entrer trop dans les détails, la notation peut se comprendre sans trop d'effort:

public class Poete
{
    def declamer() {
        def poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        poeme.each() {
            System.out.println(it);
        }
    }
 
    static main(args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

Point de syntaxe: D'où vient ce it?

Dans la fermeture utilisée dans le code précédent, vous voyez apparaître une variable it qui n'est définie nulle part:

       poeme.each() {
           System.out.println(it);
       }

En fait, cette variable est définie automatiquement par Groovy dans la fermeture (le bloc entre accolades), et elle contient "à chaque tour" une référence sur l'élément courant du tableau.

Si le nom it ne vous plaît pas, vous pouvez également explicitement définir la variable de boucle:

       poeme.each() {
           vers -> System.out.println(vers);
       }

Et ce n'est pas encore tout! En effet, pour exécuter une fermeture un certain nombre de fois, Groovy ajoute aussi une méthode times aux entiers:

public class Poete
{
    def declamer() {
        def poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        poeme.size.times() {
            System.out.println(poeme[it]);
        }
    }
 
    static main(args) {
        Poete apollinaire = new Poete();
        apollinaire.declamer();
    }
}

Définitivement, avec autant d'alternatives, il devient possible de choisir la boucle la plus adaptée à chaque circonstance – et celle qui transmettra au mieux les intentions du programmeur, rendant par là même le code plus lisible.

A vous de jouer

Mystère...

Peut-être ne l'avez vous pas remarqué, mais le poème utilisé dans les exemples est un cryptogramme qui contient le nom de la destinataire de ces vers.

On pourrait mettre en évidence le dédicataire de ce poème en ré-écrivant la version JavaScript de la méthode declamer ainsi:

/* ... */
    that.declamer = function () {
        var poeme = [
            "L'ombre de la très douce est évoquée ici,",
            "Indolente, et jouant un air dolent aussi:",
            "Nocturne et lied mineur qui fait pâmer son âme",
            "Dans l'ombre où ses longs doigts font mourir une gamme",
            "Au piano qui geint comme une pauvre femme."
        ];
 
        var initiale;
        var reste;
 
        initiale    = poeme[0].substring(0,1);
        reste       = poeme[0].substring(1);
        document.write("<strong>" + initiale + "</strong>" + reste + "<br />");
 
        initiale    = poeme[1].substring(0,1);
        reste       = poeme[1].substring(1);
        document.write("<strong>" + initiale + "</strong>" + reste + "<br />");
 
        initiale    = poeme[2].substring(0,1);
        reste       = poeme[2].substring(1);
        document.write("<strong>" + initiale + "</strong>" + reste + "<br />");
 
        /* et ainsi de suite pour les autres vers... */

Évidement, ce programme est loin d'être optimum...

  1. Ré-écrivez le fragment de code ci-dessus en utilisant une boucle;
  2. Ecrivez le même programme en PHP (note: vous aurez besoin de la fonction PHP substr).

Un peu de statistiques

Par sa capacité à faire de grands nombres de calculs très rapidement, un ordinateur peut servir à effectuer des simulations. Le programme ci-dessous détermine par simulation la probabilité du résultat du lancé de deux dés à 6 faces.

Le programme est assez long, mais son principe est très simple: deux boucles imbriquées simulent les deux dés, et un tableau sert à compter le nombre de lancé ayant donné chaque score.

class Simulateur {
    public void afficheDescription() {
        System.out.print("Ce programme calcule la probabilité");
        System.out.println(" du résultat du lancé de deux dés à");
        System.out.println("six faces.");
        System.out.println();
        System.out.println("Le calcul est effectué par simulation.");
        System.out.println();
    }
 
    public void execute() {
        /* Tableau mémorisant le nombre de jets
         * produisant un résultat donné.
         *
         * Le score est l'index du tableau
         * (même si on sait que deux dés ne peuvent
         * totaliser 0 ou 1...)
         */
        int[]   resultats = {
            0, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0,
            0
        };
 
        /* simulation */
        int de1 = 1;
        while(de1 < 7) { // de1 est le score du dé n°1 - de 1 à 6
            int de2 = 1;
            while(de2 < 7) { // de2 est le score du dé n°2 - de 1 à 6
                int total = de1 + de2;
                resultats[total] = resultats[total]+1;
 
                de2 = de2 + 1;
            }
 
            de1 = de1 + 1;
        }
 
        /* affichage des résulats */
        int n = 0;
        while(n < resultats.length) {
            System.out.print("Score: " + n);
            System.out.println("\tprobabilité: " + resultats[n] + "/36");
 
            n = n + 1;
        }
    }
}
 
public class Probabilite {
    static public void main(String[] args) {
        Simulateur simulateur = new Simulateur();
        simulateur.afficheDescription();
        simulateur.execute();
    }
}

Le code ci-dessus utilise uniquement des boucles while. Ce n'était pas forcément le meilleur choix ici:

  1. Modifiez ce programme pour utiliser des boucles for pour simuler les dés;
  2. Modifiez ce programme pour utiliser une boucle for ... in afin de parcourir le tableau des résultats.