IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Corrections des exercices du livre "Java pour les enfants, les parents et les grand-parents"


précédentsommairesuivant

III. Chapitre 4

III-A. La classe ConvertisseurTemperatures

J'ai ici décidé cette fois-ci d'inclure la méthode main() dans la classe ConvertisseurTemperatures elle-même.

Sur Internet on trouve facilement les formules de conversion. Soient Tc la température en degrés celcius et Tf la température en degrés Farenheit.

Formule de conversion d'une température Celcius à partir d'une température Farenheit
Sélectionnez
Tc = (5/9) * (Tf - 32)
Formule de conversion d'une température Farenheit à partir d'une température Celcius
Sélectionnez
Tf = (9/5) * Tc + 32

Il convient de traiter les différents cas possibles pour la méthode convertirTemperature :

  • l'utilisateur a employé le format 'C' ;
  • l'utilisateur a employé le format 'F' ;
  • l'utilisateur n'a pas du tout employé un format attendu.

J'ai alors pensé à l'utilisation d'une structure switch. Sachez que le cas default correspond à toute valeur du switch que nous n'avons pas choisi de traiter.

Par conséquent, on peut ici s'en servir pour retourner un message d'erreur (la fonction doit retourner un String, profitons-en).

Par contre, ne pas oublier d'utiliser le mot-clé break pour chaque cas, hormis le cas default étant donné que c'est le dernier à traiter.

III-A-1. La division entière et la division réelle

Certains d'entre vous ont certainement entendu parler (ou appris) de la division euclidienne. Ce n'est pas compliqué.

Si vous calculez 6 / 3 : pas de problème, vous obtiendrez un nombre entier. Et ce, que cela soit par vous-même ou à l'aide d'un programme Java. En revanche, une opération telle que 9 / 4 dépendra énormément de la manière dont vous la coderez.

Pourquoi ? Parce que l'ordinateur peut aboutir sur deux valeurs :

  • ou bien 2,25 : qui est le résultat auquel, à priori, tout le monde s'attend ;
  • ou bien 2 : qui est le quotient (ou simple valeur entière) de la division.

Quand aura-t-on 2,25 et quand aura-t-on 2 ?

  • si vous calculez la division avec deux int, vous aurez forcément un int en retour. Donc vous obtiendrez la valeur 2 en calculant 9 / 4 ;
  • mais si vous calculez la division avec un float et un int, ou avec deux float, alors vous aurez un float en retour. Donc ici : 2,25.

Eh bien, sachez-le, en codant 9f et non simplement 9, je déclare : "Je veux utiliser la valeur flottante de 9 et non pas simplement la valeur entière de 9.".

Ainsi :

  • en utilisant les formules de conversion, le résultat sera beaucoup plus précis ;
  • en calculant 5f/9f je n'aurais pas la valeur 0 (qui faussera donc toute la formule de conversion en degrés celcius), mais une valeur comprise entre 0 et 1. Avec précision en plus.

Et ça, c'était vraiment le piège à éviter.

III-A-2. Variable locale et initialisation

Enfin une dernière difficulté technique : toute variable déclarée (c'est-à-dire créée) à l'intérieur d'une méthode doit être initialisée (c'est-à-dire qu'on lui donne sa première valeur) avant d'être utilisée.

En d'autres termes, toute variable locale doit être initialisée avant toute utilisation.

Dans le code suivant, la variable locale valeurDeRetour n'a pas été initialisée à sa création. Quant à son utilisation, il n'y en a qu'une seule : lors du retour de la méthode convertirTemperature (return valeurDeRetour).

En revanche, dans le switch, tous les cas possibles aboutissent à une initialisation.

C'est-à-dire que pour toutes les valeurs que peut prendre la variable (de type char) convertirEn, on aboutit à une initialisation de la variable valeurDeRetour. Des valeurs à tester, il y en a trop : car un char peut avoir 256 valeurs. D'où l'utilité du mot-clé default dans le switch.

III-A-3. Code

ConvertisseurTemperatures
TéléchargerCacher/Afficher le codeSélectionnez

III-B. Modification de la classe BulletinAppreciation

Pour rendre la méthode convertirNiveaux() statique, rien de plus simple. Sa nouvelle signature sera :

Nouvelle signature de la méthode convertirNiveaux()
Sélectionnez
public static char convertirNiveaux(int noteDevoir)

On n'a rien à changer dans son corps.

Et comme elle est statique, nul besoin de créer une instance de BulletinAppreciation pour appeler la méthode convertirNiveaux() :

Appel de la méthode convertirNiveaux
Sélectionnez
BulletinAppreciation.convertirNiveaux(valeurIntPassee);

Ce qui donne le code suivant :

BulletinAppreciation
TéléchargerCacher/Afficher le codeSélectionnez
public class BulletinAppreciation {
    /**
Cette methode attend un argument entier ? la note du devoir
- et retourne une mention, I, P, A, B, T ou E, en fonction
de sa valeur.
     */
    public static char convertirNiveaux(int noteDevoir) {
        char niveau;
        if (noteDevoir >= 18) {
            niveau = 'E';
        }
        else if (noteDevoir >= 16 && noteDevoir < 18){
            niveau = 'T';
        }
        else if (noteDevoir >= 14 && noteDevoir < 16){
            niveau = 'B';
        }
        else if (noteDevoir >= 12 && noteDevoir < 14){
            niveau = 'A';
        }
        else if (noteDevoir >= 10 && noteDevoir < 12){
            niveau = 'P';
        }
        else {
            niveau = 'I';
        }
        return niveau;
    }
    public static void main(String[] args) {
        char tonNiveau = BulletinAppreciation.convertirNiveaux(17);
        System.out.println("Ton premier niveau est " +
                tonNiveau);
        tonNiveau = BulletinAppreciation.convertirNiveaux(15);
        System.out.println("Ton second niveau est " +
                tonNiveau);}
}

III-C. Exercice pour les petits malins : félicitations aux joueurs

Pour les impatients, aller directement à la section réponse.

III-C-1. Le code original avec le mot-clé continue

Voici, à peu de choses près, le code utilisé dans le chapitre avec continue. J'ai juste englobé le code dans une classe. Sa méthode main() plus précisément. Et bien sûr, j'ai aussi initialisé les différentes variables utilisées.

FelicitationsAuxJoueurs
TéléchargerCacher/Afficher le codeSélectionnez
public class FelicitationsAuxJoueurs {

    public static void main(String[] args) {
        String [] joueurs = {"David", "Daniel", "Anna", "Gregory"};
        int compteur = 0;
        int nombreJoueurs = joueurs.length;

        while (compteur < nombreJoueurs) {
            compteur++;
            String leJoueur = joueurs[compteur];
            if (leJoueur.equals("David")) {
                continue;
            }
            System.out.println("Felicitations, " + leJoueur + " !");
        }
    }

}

On comprend aisément que tous les joueurs, à l'excepté de David, soient félicités. Si vous n'en êtes pas totalement convaincus, il faut analyser le code plus en détail.

Pour ce faire, on peut "simuler" l'exécution du code par l'ordinateur. Vous pouvez imprimer le code, puis griffonner et gommer au crayon à papier les valeurs des variables. Ceci, au fur et à mesure que vous avancez dans le code. Et lors de vos différents passages dans la boucle while simulez aussi, dans une zone de votre feuille, la sortie de la console.

Si vous parvenez ainsi à deviner le résultat de la console avant même d'avoir lancé le programme : cela voudra dire que vous avez vraiment bien assimilé le concept de boucles et d'irrégularités (par break / continue).

III-C-2. Le code qu'il nous est demandé d'évaluer

Code à évaluer
Sélectionnez
public class FelicitationsAuxJoueurs {

    public static void main(String[] args) {
        String [] joueurs = {"David", "Daniel", "Anna", "Gregory"};
        int compteur = 0;
        int nombreJoueurs = joueurs.length;

        while (compteur < nombreJoueurs) {
            String leJoueur = joueurs[compteur];
            if (leJoueur.equals("David")) {
                continue;
            }
            System.out.println("Felicitations, " + leJoueur + " !");
            // On a laissé compteur++ a la fin de la boucle while
            compteur++;
        }
    }

}

On nous demande alors ce qu'il peut bien se passer.

Vous n'avez pas encore testé ce code à l'ordinateur et vous avez été étonné parce que le code bloquait ? Bravo. Si tel est le cas, vous avez vraiment compris comment fonctionnent les boucles.

En effet, ce code ne s'arrêtera jamais de lui-même. Pourquoi ? Parce que la variable compteur vaudra toujours 0 et par conséquent, le test de la boucle while donnera toujours le résultat de 0 < 4 : soit true.

Démonstration par la simulation :

Au 1er passage de la boucle while
Sélectionnez
public class FelicitationsAuxJoueurs {

    public static void main(String[] args) {
        String [] joueurs = {"David", "Daniel", "Anna", "Gregory"};
        int compteur = 0;
        int nombreJoueurs = joueurs.length; // soit 4

        while (compteur /* 0 */< nombreJoueurs /* 4 */) { // true
            String leJoueur = joueurs[compteur]; //David
            if (leJoueur.equals("David")) { // true
                continue; // Donc, on revient au test de la boucle while
            }
            System.out.println("Felicitations, " + leJoueur + " !"); // Non execute
            compteur++; // Non execute
        }
    }

}
Au 2e passage de la boucle while
Sélectionnez
public class FelicitationsAuxJoueurs {

    public static void main(String[] args) {
        String [] joueurs = {"David", "Daniel", "Anna", "Gregory"};
        int compteur = 0;
        int nombreJoueurs = joueurs.length; // soit 4

        while (compteur /* 0 */< nombreJoueurs /* 4 */) { // true
            String leJoueur = joueurs[compteur]; //David
            if (leJoueur.equals("David")) { // true
                continue; // Donc, on revient au test de la boucle while
            }
            System.out.println("Felicitations, " + leJoueur + " !"); // Non execute
            compteur++; // Non execute
        }
    }

}
Au 3e passage de la boucle while
Sélectionnez
public class FelicitationsAuxJoueurs {

    public static void main(String[] args) {
        String [] joueurs = {"David", "Daniel", "Anna", "Gregory"};
        int compteur = 0;
        int nombreJoueurs = joueurs.length; // soit 4

        while (compteur /* 0 */< nombreJoueurs /* 4 */) { // true
            String leJoueur = joueurs[compteur]; //David
            if (leJoueur.equals("David")) { // true
                continue; // Donc, on revient au test de la boucle while
            }
            System.out.println("Felicitations, " + leJoueur + " !"); // Non execute
            compteur++; // Non execute
        }
    }

}

Ainsi de suite ...

III-D. Synthèse

Nous avons donc vu :

  • comment traiter, dans un switch, tous les cas non pris en compte grâce au mot-clé default ;
  • comment utiliser une méthode statique sans initialiser la classe où elle se situe ;
  • quel est le danger d'une boucle while mal utilisée : on peut bloquer son application.

précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2012 Laurent Bernabé. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.