exercices sur la syntaxe

Il n’est pas nécessaire de réaliser tous les exercices pendant la durée du cours. Par contre nous vous conseillons de tous les réaliser pendant une période de révision.

La plupart de ces codes représentent des situations d’erreurs courantes (la plupart sont des erreurs de syntaxe -sauf celles marquées "erreur de runtime"-). Tentez de détecter ces erreurs simplement en lisant les codes et d’apporter rapidement un correctif.

syntaxe + défauts courants de configuration

Dans fichier TestA.java :

// problème de syntaxe
// corriger le code pour qu'il puisse se compiler
//
public class TestA {
}

public class TestA1 {
}

Dans fichier TestB.java :

// problème de syntaxe
//
public class testB {
}

Dans fichier TestC.java :

// problème de syntaxe
// corriger le code pour qu'il puisse se compiler
//
public class TestC {
}

public static void main (String[] args) {
}

Dans fichier TestD.java :

// problème de syntaxe
// corriger le code pour qu'il puisse se compiler
public class TestD {
   solde ;

}
// problème de syntaxe
// corriger le code pour qu'il puisse se compiler
//
public class TestG {
        // le type BigDecimal du package java.math
        // est utilisé dans les calculs financiers

   java.math.BigDecimal solde ;

   public TestG(String val) {
      this.solde = new java.math.BigDecimal(val) ;
   }

   public setBalance( java.math.BigDecimal val) {
      this.solde = val ;
   }
}
/** permet de sélectionner au hasard
 * ici dans un objet String
 *  (erreur de runtime très courante!!!!)
 */
public class TestN {

   // une variable membre
    java.util.Random luck  ;


   // un méthode membre
   public char pickCharIn(String aString) {
      int length = aString.length() ;
      int index = luck.nextInt(length) ;
      return aString.charAt(index) ;
   }

   public static void main(String[] args) {
      TestN tst = new TestN() ;
      tst.pickCharIn("ATTENTION DANGER!") ;
   }
}
 // problème de syntaxe
// corriger le code pour qu'il puisse se compiler

public class TestO {

   //
   java.util.Random luck = new java.util.Random() ;


   //
   public char pickCharIn(String aString) {
      int length = aString.length() ;
      int index = luck.nextInt(length)
      return aString.charAt(index) ;
   }
}
// problème de syntaxe
// corriger le code pour qu'il puisse se compiler

public class TestP {

   //
    java.util.Random luck = new java.util.Random() ;


   //
   public char pickCharIn(String aString) {
      int length = aString.length() ;
      int index = luck.nextInt(length) ;
      return aString.charAt(index) ;
}
 // problème de syntaxe
// corriger le code pour qu'il puisse se compiler

public class TestV1 {
   public static int mediane (int ix, int iy) {
      int long = (ix+iy) /2 ;
      return long ;
      }
}
 // problème de syntaxe
// corriger le code pour qu'il puisse se compiler

public class TestV2 {
   public static int mediane (int ix, int iy) {
      int med  ;
      System.out.println(med) ;
       med = (ix+iy) /2 ;
      return med ;
      }
}
 // problème de syntaxe
// corriger le code pour qu'il puisse se compiler

public class TestA1 {
   public static void main(String[] args){
      int[10] array ;
      System.out.println(array.length) ;
      }
}
 // problème de syntaxe
// corriger le code pour qu'il puisse se compiler

public class TestA2 {
   public static void main(String[] args){
      int[] array ;
      System.out.println(array[0]) ;
      }
}
//
//  erreur run time  !

public class TestA3 {
   public static void main(String[] args){
      Paire[] array = new Paire[3];
      System.out.println(array[0].toString()) ;
      }
}
 // problème de syntaxe
// corriger le code pour qu'il puisse se compiler
// (difficile!)

public class TestA4 {
   public static void main(String[] args){
      String[] array ;
      array = { "shadoks", "gibis" ,     } ;
      System.out.println(array[0].toString()) ;
      }
}
//
//  (erreur run time )
public class TestA5 {
   public static void main(String[] args){
      String[] array  = { "shadoks", "gibis" ,     } ;
      System.out.println(array[array.length].toString()) ;
      }
}

classes, constructeurs, méthodes

(Pour révisions et approfondissements)

Ecrire une class MessageChat qui décrit un élément d’echange au cours d’un chat. Il s’agit d’un Data Object qui contiendra :

  • une chaîne donnant l'émetteur du message

  • un tableau de chaînes designant les destinataires

  • une chaîne contenant le message lui-même

  • un long de timestamp

Ecrire une classe EmetteurChat qui sera un simulacre (une classe qui "fait semblant" de rendre un service.

Cet EmetteurChat dispose d’une méthode void envoi(MessageChat mess) qui :

  • affichera par Sytem.out.println le message

  • l’archivera dans un tableau d’historique des messages (créér un tableau de 50 MessageChat et ne pas se préoccuper des débordement éventuels)

Propositions de corrigés :

Exercices sur les structures de contrôle

if/else (1)

Dans une classe dotée d’un simple main écrire le code suivant:

  • en utilisant java.util.Random choisir au hasard une année entre 0 et aujourd’hui.

    (On utilisera la classe java.time.Year: la méthode statique now() permet de créer un objet "année" correspondant à l’année courante. La méthode d’instance getValue() donne un entier représentant le numéro de l’année.)

  • en utilisant la méthode isLeap() de java.time.Year voir si cette année est une année bissextile.

  • afficher un message différent en fonction du résultat

if/else (2)

(Pour révisions et approfondissements)

jeu de devinette (version 1)

La classe QuelNombre vous permettra de créer un objet qui choisi un nombre au hasard entre 0 et 10 (non compris), un code utilisateur devra essayer de deviner ce nombre.

Ici nous allons introduire pour la première fois un masquage de donnée: des données contenues dans une instance de QuelNombre seront cachées aux autres code (les "codes client" qui utilisent ces instances).

Pour cela nous allons utiliser le modificateur private et le code de la classe ressemblera à ceci:

public class QuelNombre {

   private int nombreSecret =
      new java.util.Random().nextInt(10);


   public int proposition(int val) {
      // votre CODE
   }

}
  • la méthode int proposition(int) rendra 0 si le nombre proposé est celui à deviner, -1 si le nombre à deviner est inférieur à votre proposition et 1 s’il est supérieur.

  • écrire un "code client" (une classe de test avec un main) qui crée une instance de QuelNombre et tente de faire deux propositions (si le nombre secret est trouvé du premier coup ne pas faire de deuxième proposition : utiliser if/else seulement).

switch

(Pour révisions et approfondissements)

jeu de devinette (version 2)

Nous allons créer un autre "code client" pour QuelNombre.

Créer une classe Devinette : chaque instance crée à sont tour une instance de QuelNombre et utilisera sa méthode proposition.

  • créer une méthode:

    public boolean essayer(int nb)

Cette méthode va invoquer la méthode proposition sur l’instance de QuelNombre courante et va afficher un message comme "essai numéro 2 : c’est plus que 6!" (utiliser un switch).

  • Créer un main qui crée un objet Devinette et tente de faire 3 appels à essayer (si l’essai est correct abandonner les essais suivants).

Une solution : Devinette.java (remarquer pourquoi Devinette est un code distinct de QuelNombre).

while do/while

La machine à remonter le temps ( version 1)

Un code simple écrit dans un main.

  • prendre une année au hasard entre 0 et aujourd’hui. On est supposé voyager dans le passé!

  • si cette année est bissextile on peut "revenir" sinon on doit attendre la prochaine année bissextile pour "revenir" (c’est une limitation de notre machine à remonter le temps!)

  • afficher l’année d’arrivée dans le passé et l’année où votre retour se déclenche.

Note
Pour les puristes: la réalité des années bissextiles avant l'établissement du calendrier grégorien est sujette à caution. On pourrait modifier l’exercice en faisant varier les années entre 1583 et le temps présent.

La machine à remonter le temps ( version 2)

Les règles de fonctionnement de notre machine à remonter le temps sont maintenant différentes: on doit d’abord rester un an dans le passé et ensuite on peut revenir durant la première année bissextile qui se présente.

Afficher l’année d’arrivée dans le passé et l’année où votre retour se déclenche.

break

(Pour révisions et approfondissements)

jeu de devinette (version 3)

Cet exercice consiste non pas à écrire du code mais à en lire! Lire ce code:

// Cette classe SAIT qu'elle utilise un terminal

// introduction à l'algorithmique
// comment rechercher quelque chose ...

public class Devin {
        // pour faire mieux définir un constructeur pour cette classe
        // et pour QuelNombre: on fixera ainsi un limite (passer de 10 à 1000 par ex.)


        // essayer des nombres vraiment grands
        // modifier ensuite la façon de procéder un tirant au hasard
        // la valeur de séparation (ici c'est la moyenne)
        // comparez alors le nombre d'essais

        private QuelNombre devinette = new QuelNombre() ;
        private int essais = 0 ;

        public int afficherChoix(int nb) {
                essais++ ;
                int res =  devinette.proposition(nb) ;
                switch(res ) {
                        case 0 :
                                System.out.println("trouvé " + nb +" après " + this.essais + " essais") ;
                                break ;
                        case 1:
                                System.out.println("essai numéro : " + this.essais + ": c'est plus que " + nb) ;
                                break ;
                        case -1:
                                System.out.println("essai numéro : " + this.essais + ": c'est moins que " + nb) ;
                                break ;
                        default :  // LOG

                }
                return res ;
        }

        // une recherche "dichotomique"
        public void rechercher() {
                 int min = 0 ;
                 int max = 10 ; // paramétrer cette valeur pour faire évoluer le code
                while (true) {
                        int choix = (min + max)/2 ;
                        switch(afficherChoix(choix)) {
                                case 0 : return ;
                                case 1 :  min = choix ; break ;
                                case -1 :  max = choix ; break ;
                        }
                }
        }

        public static void main (String[] tb) {
                Devin gt = new Devin() ;
                gt.rechercher() ;
        }
}
  • Essayez de comprendre comment il fonctionne et pourquoi il est écrit de cette manière.

for

gestion des arguments de lancement

Il est maintenant temps d’expliquer la vraie signification de :

public static void main(String[] args){

Supposons que note main soit dans une classe de nom TestMain.

Si nous compilons le code puis lançons depuis le terminal la commande:

java TestMain arg0 arg1 arg2

et bien l’argument du main à l’exécution contient le tableau de chaîne: { "arg0", "arg1", "arg2"}.

Ce système permet de passer des arguments de lancement à la commande java.

Avec votre I.D.E. cherchez dans le documentation comment lancer le code de la classe avec des arguments de lancement.

Votre objectif: écrire une classe Addition dont la méthode main analyse les arguments de lancement du programme, les transforme en nombres entiers, les additionne et affiche le résultat.

donc:

java Addition 3 4
7
java Addition-1 7 2
8

Comme les arguments du programme sont des objets de type String on doit fabriquer des entiers à partir de leur représentation textuelle. Aller dans la documentation de la classe java.lang.Integer et chercher une méthode marquée static qui prend une chaîne en argument et rend un entier primitif.

Cette méthode sera invoquée d’une manière analogue à celle ci:

int valeur = Integer.XXXmethod(StringCourante) ;
  • une fois la méthode trouvée réalisez le code du main de Addition et testez le.

  • re-testez le avec :

    java Addition 2 3 5 -8
    java Addition 2 douze
    java Addition 1073747576 1073747576

Pour ceux qui sont en avance: reprendre le code précédent mais utiliser java.math.BigInteger au lieu de int pour représenter la valeur de la somme.

Exemples

classes, constructeurs, méthodes

/**
 * UN élément d'un echange de "tchatche" sur le réseau
 * @author pbamade
 */
public class MessageChat {
    final String expéditeur ;
    String[] destinataires ;
    final String message ;
    final long timestamp = System.currentTimeMillis();

    /**
     *
     *
     * @param expéditeur
     * @param destinataires peut être null (envoi à tous)
     * @param message
     */
    public MessageChat(String expéditeur, String[] destinataires, String message) {
        this.expéditeur = expéditeur ;
        this.destinataires = destinataires ;
        this.message = message ;
    }



    public String toString() {
        // ici penser à un objet StringBuilder
        String res = "expéditeur :" + this.expéditeur + "\n";
        res += "destinataires :" + java.util.Arrays.toString(this.destinataires) +"\n";
        res += "Message :" + this.message + "\n" ;

        return res ;
    }

}
/**
 * objet "simulacre" pour l'émission de message de tchatche.
 * @author pbamade
 */
public class EmetteurChat {

    static final int TAILLE_MAX = 50 ;

    MessageChat[] historique = new MessageChat[TAILLE_MAX ];
    int nbMessages ;

    public void envoi(MessageChat message) {
        // envoi bidon
        System.out.println(message.toString());
        this.historique[this.nbMessages % this.historique.length] = message ;
        this.nbMessages++ ;
    }

    /**
     * rend un message dans l'historique, s'il n'arrive pas à l'atteidnre
     * rend le dernier message.
     * @param rang
     * @return peut être null! (si pas de message à l'emplacement dans l'historique
     */
    public MessageChat getMessagePrécédent(int rang) {
       int index  = (rang < TAILLE_MAX) && (rang> 0) ? (nbMessages - rang)  : nbMessages - 1 ;
        return historique[index % historique.length];
    }

}
/**
 *
 * @author pbamade
 */
public class TestChat {

    public static void main(String[] args) {
        String[] destinataires = { "marie", "amélie" } ;
        MessageChat mess1 = new MessageChat("moi", destinataires, "Hello World!");
        MessageChat mess2 = new MessageChat("moi", new String[] { "jules"} , "Hello everybody!");
        MessageChat mess3 = new MessageChat("moi", null, "Bye!");

        EmetteurChat émetteur = new EmetteurChat() ;
        émetteur.envoi(mess1);
        émetteur.envoi(mess2) ;
        émetteur.envoi(mess3) ;
        System.out.println("dernier message = " + émetteur.getMessagePrécédent(1));
        System.out.println("dernier message = " + émetteur.getMessagePrécédent(2));
    }

}

Exercices sur les structures de contrôle

if/else (1)

public class VoyageDansLeTemps {

        public static void main(String[] args) {
                java.util.Random rand  = new java.util.Random() ;
                int maintenant = java.time.Year.now().getValue() ;
                int arrivée = rand.nextInt(maintenant);
                java.time.Year annéeArrivée = java.time.Year.of(arrivée) ;

                if(annéeArrivée.isLeap()) {
                        System.out.println("vous êtes parti pour l'année " + annéeArrivée +
                                         ": (bissextile!)") ;
                }
                 else{
                        System.out.println("vous êtes parti pour l'année " + annéeArrivée +
                                         ": (pas bissextile!)") ;
                 }
        }
}

if/else (2)

public class QuelNombre {

        private int nombreSecret =
                new java.util.Random().nextInt(10);


        public int proposition(int val) {
                if(nombreSecret == val) return 0 ;
                if(nombreSecret < val ) return -1 ;
                // note: ici on peut se dispenser du "else"
                return 1 ;
        }

}
public class TestDevinetteA {

        public static void main (String[] tb) {
                QuelNombre devinette = new QuelNombre() ;
                if( 0 == devinette.proposition(0) ){
                        System.out.println("trouvé! c'est 0") ;
                } else
                if( 0 == devinette.proposition(3) ){
                        System.out.println("trouvé! c'est 3") ;
                } else {
                        System.out.println("pas trouvé!") ;
                }

        }
}

switch

/**
 * NOTE TRES IMPORTANTE
 * la classe "QuelNOmbre" ne gère absolument pas les interactions
 * avec l'utilisateur!
 * elle ne doit pas le faire dans la mesure où elle peut être utilisée
 * dans des circonstances différentes (depuis une IHM, un terminal, ..)
 *
 * La présente classe SAIT qu'elle utilise un terminal ...
 *
 */
public class Devinette {

        QuelNombre devinette = new QuelNombre() ;
        int essai = 0 ;

        public boolean essayer(int nb) {
                essai++ ;
                switch(devinette.proposition(nb) ) {
                        case 0 :
                                System.out.println("bien trouvé aprés " + this.essai + " essais") ;
                                return true ;
                                // aspect très difficile ici
                                //break ; // not "reachable"
                        case 1:
                                System.out.println("essai numéro " + this.essai + ": c'est plus que " + nb) ;
                                break ;
                        case -1:
                                System.out.println("essai numéro " + this.essai + ": c'est moins que " + nb) ;
                                break ;
                        default :  // on devrait mettre une trace de log

                }
                return false ;
        }


        public static void main (String[] tb) {
                Devinette dv = new Devinette() ;
                if( ! dv.essayer(5)) {
                        if( ! dv.essayer(0) ) {
                                dv.essayer(9) ;
                        }
                }

        }
}

while do/while

public class TimeMachine1 {

    public static void main(String[] args) {
        java.util.Random rand = new java.util.Random();
        int maintenant = java.time.Year.now().getValue() ;
        int arrivée = rand.nextInt(maintenant);
        java.time.Year annéeArrivée = java.time.Year.of(arrivée) ;
        while (!annéeArrivée.isLeap()) {
            annéeArrivée = annéeArrivée.plusYears(1L);
        }

        System.out.println("parti en : " + arrivée + "; retour déclenché en : " +
                annéeArrivée);
    }
}
public class TimeMachine2 {

        public static void main(String[] args) {
                java.util.Random rand  = new java.util.Random() ;
                int maintenant = java.time.Year.now().getValue() ;
                int arrivée = rand.nextInt(maintenant);
                java.time.Year annéeArrivée = java.time.Year.of(arrivée) ;
                do {
                        annéeArrivée = annéeArrivée.plusYears(1L);
                } while(! annéeArrivée.isLeap()) ;

                System.out.println("parti en : " + arrivée + "; retour prévu en : " +
                                annéeArrivée) ;
        }
}

for

/**
   *  addition d' arguments passés au main
   * <BR>
   * <BR>
   * exécuter avec :
   *   <PRE>
   *      java Addition 2 3 5 -8
   *      java Addition 2 quelqueChose
   *      java Addition 1073747576 1073747576
   * </PRE>
   */

public class Addition {

   public static void main (String[] tbArgs) {
      int somme = 0 ;
      for (int ix = 0 ; ix < tbArgs.length; ix++ ) {
         somme += Integer.parseInt(tbArgs[ix]) ;
      }
      System.out.println( " total = " + somme ) ;
   }//End main
}
/**
   *  addition d' arguments passés au main
   * <BR>
   * <BR>
   * exécuter avec :
   *   <PRE>
   *      java AddMore 2 3 5 -8
   *      java AddMore 2 quelquechose
   *      java AddMore 1073747576 1073747576
   *      java AddMore 1073747576 1073747576 1073747576 1073747576
   * </PRE>
   */

public class AddMore {

   public static void main (String[] tbArgs) {
      java.math.BigInteger somme = java.math.BigInteger.ZERO ;
      for (String arg : tbArgs ) {
         somme = somme.add( new java.math.BigInteger(arg)) ;
      }
      System.out.println( " total = " + somme ) ;
   }//End main
}