Tp 1 correction Structures de données (IF2) Remarque générale : compilez et exécutez le code au-fur-et-à mesure de son écriture. Il est plus facile de corriger une petite portion de code délimitée que de faire tout le travail à la fois... Exercice 1 Rappel sur la structure d un programme Java 1. ce programme affiche «bonjour» si on l appelle sans argument, et «bonjour» suivi du premier argument sinon. > java Bonjour Bonjour > java Bonjour Jean-Jacques Bonjour Jean-Jacques > java Bonjour Jean Jacques Bonjour Jean 2. import permet d utiliser des classes provenants d autres bibliothèques. Ici, il ne sert à rien, vu que l on n utilise rien venant de la classe Deug. Par convention, java ne permet pas de donner un autre nom à la classe que le nom du fichier. La méthode main est la méthode éxécutée lors de l appel du programme. void signifie que cette fonction ne renvoie rien (oubliez static et public pour l instant). String args[] désigne les arguments passés dans la ligne de commande (Jean-Jacques (1 argument) et Jean Jacques (2 arguments) dans les exemples ci-dessus). Les commentaires peuvent s écrire : // tout ce qui est sur le reste de la ligne est alors un commentaire /* ceci est un commentaire */ Les point-virgules sont placés après les instructions et également à la fin d un import. On en met aussi après les déclarations de propriétés. Les parenthèses servent à passer des arguments à une méthode. Ligne 11, en l absence d arguments, les parenthèses sont nécéssaire pour indiquer qu il s agit bien d une méthode, et non pas une propriété. = est l opérateur d affectation. == est l opérateur mathématique qui teste l égalité des deux termes. 3. Il y a deux étapes : on compile à l aide de la commande javac javac Bonjour.java Ceci crée le fichier Bonjour.class écrit en bytecode ou code intermédiaire. on éxécute ce code à l aide de la machine virtuelle java, à l aide de la commande. java Bonjour Déjà traité ci-dessus. 1
Exercice 2 Équations 1. On se place dans le fichier Equation.java import java.lang.*; class Equation double a, b, c, delta, r1, r2; Ces propriétés sont suffisantes mais pas nécessaires : les 2 équations x 2 + x + 1 = 0 et 2x 2 + 2x + 2 = 0 sont en effet les mêmes. Il y a une redondance dans le fait de se donner a, b et c, et encore plus si l on se donne delta, r1 et r2 que l on peut calculer à partir des précédents. En fait, une des façons les plus compactes de décrire toutes les équations du second ordre serait de fixer a à 1 et de se donner b et c deux rééls. 2. Notre classe ressemble maintenant à ça : class Equation double a, b, c, delta, r1, r2; Equation(double _a, double _b, double _c) a=_a; b=_b; c=_c; Notez qu un constructeur porte toujours le même nom que sa classe, et ne retourne aucune valeur (il initialise seulement un objet). Nous venons d écrire un constructeur qui sera appelé lorque l on créera une instance d Equation avec new. Par exemple si quelquepart on a : Equation e = new Equation(1, 2, 3); e est alors une référence vers un objet Equation dont les coefficients sont 1, 2 et 3. 3. On rajoute le membre suivant à la classe. void calculerracines() delta=b*b-4*a*c; r1=(-b-math.sqrt(delta))/(2*a); r2=(-b+math.sqrt(delta))/(2*a); Si on veut ajouter un drapeau (ou flag) indiquant la validité des racines stockées, notre code va devenir le suivant : class Equation double a, b, c, delta, r1, r2; boolean racinescalculees; Equation(double _a, double _b, double _c) 2
racinescalculees = false; //au départ, les racines ne sont pas à jour a=_a; b=_b; c=_c; void calculerracines() if (!racinescalculees) //pas la peine de les recalculer! delta=b*b-4*a*c; r1=(-b-math.sqrt(delta))/(2*a); r2=(-b+math.sqrt(delta))/(2*a); racinescalculees = true; //maintenant, elles sont à jour 4. String tostring() if (!racinescalculees) return "Equation "+a+"*x^2+"+b+"*x+"+c+"=0"; return "Equation "+a+"*x^2+"+b+"*x+"+c+" = 0. Racines "+r1+" et "+r2; // on pourrait gérer les racines doubles aussi return "Equation "+a+"*x^2+"+b+"*x+"+c+"=0. Pas de racine reelle."; Exercice supplémentaire : modifier le code pour qu il n y ait pas d horreurs du genre x 2 + 2x + 2. 5. Le fichier Probleme.java ressemble à ça : class Probleme public static void main(string argd[]) Equation monequation=new Equation(1, 2, 1); monequation.calculerracines(); Remarque : java va automatiquement chercher le membre tostring() dans une classe pour convertir une instance de cette classe en chaine de caractère. Ainsi, on peut se contenter de mettre : au lieu de Deug.println(monEquation.toString()); 6. On a donc ceci : 3
7. class Probleme public static void main(string argd[]) Equation monequation=new Equation(1, 2, 1); monequation.calculerracines(); monequation.a=0; Le résultat n est plus valide : on a modifié un coefficient sans modifier les valeurs du discriminant et des racines! Dans le cas présent, c est encore pire, on n a même plus une équation du second degré. En fait on voudrait empêcher l utilisateur de faire n importe quoi avec les propriétés d une équation (comme mettre a à 0 ou bien afficher avant d avoir recalculé les racines). class Equation private double a, b, c, delta, r1, r2; private boolean racinescalculees; public Equation(double _a, double _b, double _c) racinescalculees = false; a=_a; b=_b; c=_c; void public calculerracines() racinescalculees = true; delta=b*b-4*a*c; r1=(-b-math.sqrt(delta))/(2*a); r2=(-b+math.sqrt(delta))/(2*a); public String tostring() if (!racinescalculees) return "Equation "+a+"*x^2+"+b+"*x+"+c+"=0"; return "Equation "+a+"*x^2+"+b+"*x+"+c+" = 0. Racines "+r1+" et "+r2; return "Equation "+a+"*x^2+"+b+"*x+"+c+"=0. Pas de racine reelle."; Un utilisateur extérieur à la classe ne peut plus accéder à ses propriétés. En revanche, les fonctions membres de la classes peuvent le faire, sinon, on ne pourrait rien faire du tout! 4
Remarquez les mots-clef public facultatifs rajoutés pour insister sur le fait que les méthodes écrites sont accessibles pour un utilisateur. Si on reprend le code de problème : class Probleme public static void main(string argd[]) Equation monequation=new Equation(1, 2, 1); monequation.calculerracines(); monequation.a=0; on aura une erreur ligne 5. Si on enlève cette ligne, tout se passe bien. 8. Si on voulait que l utilisateur ne fasse pas n importe quoi, on avait néanmoins envie qu il puisse accéder aux propriétés d une instance de la classe. On définit donc des accesseurs et modifieurs public pour les propriétés dont on souhaite qu elles soient accessibles et/ou modifiables. public double geta() return a; public double getb() return B; public double getc() return c; public double getdelta() return delta; public double getr1() return r1; public double getr2() return r2; public boolean getracinescalculees() return racinescalculees; public void seta(double x) if (x!=0) 5
a=x; //sinon on pourrait par exemple renvoyer un message d erreur. //ici, on choisit de ne rien faire racinescalculees=false; public void setb(double x) b=x; racinescalculees=false; public void setc(double x) c=x; racinescalculees=false; On n a pas envie que l utilisateur puisse modifier directement delta, r1, r2 ou racinescalculees. Si l utilisateur modifie directement les coefficients, le flag racinescalculees est remis à faux, ce qui empéchera d afficher des résultats faux en utilisant tostring(). On peut maintenant écrire ce genre de choses dans main : class Probleme public static void main(string argd[]) Equation monequation=new Equation(1, 2, 1); // une instance d Equation monequation.calculerracines(); //affiche : Equation 1.0*x^2+2.0*x+1.0 = 0. Racines -1.0 et -1.0 monequation.seta(3); //affiche : Equation 3.0*x^2+2.0*x+1.0 = 0. Equation monequation2=new Equation(3, 2., 4); // une autre instance d Equation /*... */ if (monequation2.getracinescalculees()) Deug.println(monEquation2.getDelta()); monequation2.calculerracines(); Deug.println(monEquation2.getDelta()); 6
Exercice 3 Nombres complexes Le fichier Complexe.java import java.lang.*; class Complexe private double re; private double im; public Complexe() re=0; im=0; public Complexe(double _re, double _im) re=_re; im=_im; public double getre() return re; public double getim() return im; public void setre(double _re) re=_re; public void setim(double _im) im=_im; public String tostring() return re+" + i "+im; public void additionner(complexe c) re+=c.re; im+=c.im; public void multiplier(complexe c) 7
double new_re=re*c.re-im*c.im; double new_im=re*c.im+im*c.re; re=new_re; im=new_im; public void rotation(double theta) Complexe c=new Complexe(Math.cos(theta), Math.sin(theta)); multiplier(c); Un TestComplexe.java possible : public class TestComplexe public static void main (String args[]) Complexe premier, deuxieme, troisieme; premier=new Complexe(); deuxieme=new Complexe(1, 2); troisieme=deuxieme; Deug.println("deuxieme "+deuxieme); Deug.println("troisieme "+troisieme); premier.setre(3); deuxieme.setre(4); Deug.println("deuxieme "+deuxieme); Deug.println("troisieme "+troisieme); premier.additionner(deuxieme); premier.multiplier(deuxieme); premier.rotation(math.pi/2); 8