Algorithmique & Programmation Orientée Objet Semestre 2 ST Introduction
Ajouts à la syntaxe Java Les programmes Java donnés à titre d'exemples dans le cours et de solutions aux exercices de TP sont écrits en accord avec les éléments de syntaxe présentés aux paragraphes ci-dessous. Initialisation d'une variable au cours de sa déclaration Déclaration de la variable int v et affectation initiale de la valeur 1 à cette variable: int v = 1; Remplacement avantageux des deux lignes int v; v = 1; Utilisable sur tous les types de variable Remarque: marche aussi en PDL pour les déclarations de variable (utilisation du signe de l'affectation : <-) Exemple
/* Type agrégé de stockage d'une position */ /* dans un espace à deux dimensions réelles */ static class Position2D { double x; double y; }; /* Fonction de saisie clavier d'une Position2D */ static Position2D saisirPosition2D() { Position2D p = new Position2D(); Ecran.afficherln("Saisir l'abscisse puis l'ordonnée"); p.x = Clavier.saisirDouble(); p.y = Clavier.saisirDouble(); return p; } /* Programme principal */ public static void main(String [] args) { /* Initialisation lors de la déclaration */ /* Appel directe d'une fonction de saisie */ /* clavier pour la variable de type agrégé */ int v1 = 10; Position2D p1 = saisirPosition2D(); /* Déclaration et initialisation classiques */ int v2; v2 = 10; Position2D p2 = new Position2D(); p2 = saisirPosition2D(); /* Affichages de vérification */ /* des initialisations */ Ecran.sautDeLigne(); Ecran.afficherln(v1," ",v2); Ecran.sautDeLigne(); Ecran.afficherln(p1.x," ",p1.y); Ecran.afficherln(p2.x," ",p2.y); }
ExempleInitialisationVariable.java - Exemple d'exécution
Incrémentation et décrémentation de 1 aux variables de type numérique ou assimilé v++ : Incrémentation de 1 de la variable v v : Variable de type byte, short, int, long, float, double ou char Equivalent à v = v+1 v-- : Décrémentation de 1 de la variable v v : Variable de type byte, short, int, long, float, double ou char Equivalent à v = v-1 Exemple
/* Programme principal */ public static void main(String [] args) { int i; char c; double d; /* Utilisation des opérateurs addition */ /* et soustraction classiques */ for ( i = 0 ; i < 10 ; i = i+1 ) { Ecran.formater("%3d",i); } Ecran.sautDeLigne(); for ( i = 9 ; i >= 0 ; i = i-1 ) { Ecran.formater("%3d",i); } Ecran.sautDeLigne(); Ecran.sautDeLigne(); /* Utilisation du ++ et du -- */ for ( i = 0 ; i < 10 ; i++ ) { Ecran.formater("%3d",i); } Ecran.sautDeLigne(); for ( i = 9 ; i >= 0 ; i-- ) { Ecran.formater("%3d",i); } Ecran.sautDeLigne(); Ecran.sautDeLigne(); /* Utilisation du ++ sur une variable */ /* de type caractere */ c = 'a'; Ecran.afficher(c," "); c++; Ecran.afficherln(c); /* Utilisation du ++ sur une variable */ /* de type flottant */ d = 1.0; Ecran.afficher(d," "); d++; Ecran.afficherln(d); }
ExempleIncrementation.java - Exemple d'exécution
Opérations mathématiques simples (+, -, *, /, %) sur une variable v += val: Somme de la valeur val et de la variable v avec affectation du résultat du calcul à v v -= val: Soustraction de la valeur val à la variable v avec affectation du résultat du calcul à v v *= val: Multiplication de la variable v par la valeur val avec affectation du résultat du calcul à v v /= val: Division de la variable v par la valeur val avec affectation du résultat du calcul à v v %= val: Modulo de la variable v par la valeur val avec affectation du résultat du calcul à v Exemple
/* Programme principal */ public static void main(String [] args) { int vi; double vd; /* Utilisation des opérateurs mathématiques */ /* classiques */ vi = 5; vd = 4.5; vi = vi+2; vi = vi*3; vd = vd-1.5; vd = vd/5.0; Ecran.formater("vi : %d, vd : %f\n\n",vi,vd); /* Utilisation du +=, du -=, du *= et du /= */ vi = 5; vd = 4.5; vi += 2; vi *= 3; vd -= 1.5; vd /= 5.0; Ecran.formater("vi : %d, vd : %f\n",vi,vd); }
ExempleOperationMathematiqueSimple.java - Exemple d'exécution
Déclaration dans l'instruction for de la variable compteur d'itération Utilisation fréquente d'une variable dédiée comme compteur de boucle for Variable utilisée pour l'instruction for elle-même et très fréquemment dans la séquence d'instructions du for Variable pas utilisée avant le for Variable plus utilisée après le for Ne pas déclarer cette variable avec les autres variables juste après l'entête, mais "dans" le for et donc uniquement pour lui Pas d'existence de cette variable avant le for -> Pas possible de l'utiliser Plus d'existence de cette variable après le for -> Plus possible de l'utiliser Exemple
/* Fonction d'affichage avec utilisation */ /* de variables compteurs globales */ /* à la fonction */ static void affichage1() { int i; int j; for ( i = 0 ; i < 3 ; i = i+1 ) { for ( j = 0 ; j < 10 ; j = j+1 ) { Ecran.formater("%3d",i+j); } Ecran.sautDeLigne(); } } /* Fonction d'affichage avec utilisation */ /* de variables compteurs locales aux for */ static void affichage2() { for ( int i = 0 ; i < 3 ; i = i+1 ) { for ( int j = 0 ; j < 10 ; j = j+1 ) { Ecran.formater("%3d",i+j); } Ecran.sautDeLigne(); } } /* Programme principal */ public static void main(String [] args) { affichage1(); Ecran.sautDeLigne(); affichage2(); }
ExempleCompteurLocalFor.java - Exemple d'exécution
Avantage: Localisation de cette variable là et uniquement là où elle est utilisée -> Plus propre, plus sûr Omission des accolades dans les séquences d'instructions réduites à une seule instruction Optionnellement, possibilité de ne pas placer entre accolades les séquences d'instructions réduites à une seule instruction Applicable à toutes les instructions de structuration: for, while, do while, if et case Présente le risque d'oublier de mettre les accolades si, dans un second temps, on ajoute une (ou des) instruction à la séquence
/* Fonction d'affichage avec utilisation */ /* systématique des accolades */ static void affichage1() { int i; int j; for ( i = 0 ; i < 3 ; i = i+1 ) { for ( j = 0 ; j < 10 ; j = j+1 ) { if ( j%2 == 0 ) { Ecran.formater("%3d",i+j); } else { Ecran.formater("%3d",i-j); } } Ecran.sautDeLigne(); } } /* Fonction d'affichage avec suppression */ /* des accolades optionnelles */ static void affichage2() { int i; int j; for ( i = 0 ; i < 3 ; i = i+1 ) { for ( j = 0 ; j < 10 ; j = j+1 ) if ( j%2 == 0 ) Ecran.formater("%3d",i+j); else Ecran.formater("%3d",i-j); Ecran.sautDeLigne(); } } /* Programme principal */ public static void main(String [] args) { affichage1(); Ecran.sautDeLigne(); affichage2(); }
ExempleBlocUneInstructionSansAccolades.java - Exemple d'exécution
Return sur autre chose qu'une variable Possibilité d'appeler l'instruction return de fin de fonction sur autre chose qu'une variable utilisée à cette fin: - constante - constante littérale - expression arithmétique ou booléenne - appel de fonction Ce sur quoi porte le return doit obligatoirement être du type défini comme retourné par la fonction.
/* Fonction de conversion valeur en radians */ /* vers valeur en degrés */ /* Utilisation d'une variable locale */ /* pour la valeur retournée */ static double radiansToDegres1(double rdn) { double dgr; dgr = rdn/Math.PI*180.0; return dgr; } /* Fonction de conversion valeur en radians */ /* vers valeur en degrés */ /* Pas d'utilisation d'une variable locale */ /* pour la valeur retournée */ /* Retour direct du résultat d'évaluation */ /* d'une expression arithmétique */ static double radiansToDegres2(double rdn) { return rdn/Math.PI*180.0; } /* Programme principal */ public static void main(String [] args) { Ecran.afficherln(radiansToDegres1(1.0)); Ecran.sautDeLigne(); Ecran.afficherln(radiansToDegres2(1.0)); }
ExempleReturnSurExpression.java - Exemple d'exécution
Return ailleurs qu'en dernière instruction et returns multiples Possibilité d'utiliser l'instruction return ailleurs qu'en dernière instruction de fonction -> Interruption immédiate de la fonction avec comme valeur retournée la valeur sur laquelle le return est effectué Possibilité d'avoir plusieurs returns pour peu qu'ils s'excluent mutuellement algorithmiquement Vérification par le compilateur qu'une fonction qui doit retourner une valeur ne pourra pas se finir autrement que sur un return
/* Test si une annee est bissextile */ /* Un seul return, en fin de fonction */ static boolean estBissextile(int annee) { boolean res; if ( annee%400 == 0 ) { res = true; } else { if ( annee%100 == 0 ) { res = false; } else { if ( annee%4 == 0 ) { res = true; } else { res = false; } } } return res; } /* Test si une annee est bissextile */ /* Autant de return que de possibilités */ /* dans le test bissextilité */ /* Conservation d'un return en fin de fonction */ static boolean estBissextile1(int annee) { if ( annee%400 == 0 ) { return true; } else { if ( annee%100 == 0 ) { return false; } else { if ( annee%4 == 0 ) { return true; } } } return false; } /* Test si une annee est bissextile */ /* Autant de return que de possibilités */ /* dans le test bissextilité */ /* Tous les return sont dans les if imbriqués */ /* -> Plus de return en fin de fonction */ static boolean estBissextile2(int annee) { if ( annee%400 == 0 ) { return true; } else { if ( annee%100 == 0 ) { return false; } else { if ( annee%4 == 0 ) { return true; } else { return false; } } } } /* Programme principal */ public static void main(String [] args) { int annee; annee = 2000; Ecran.formater("%5d : %5b %5b %5b\n",annee, estBissextile(annee), estBissextile1(annee), estBissextile2(annee)); annee = 1900; Ecran.formater("%5d : %5b %5b %5b\n",annee, estBissextile(annee), estBissextile1(annee), estBissextile2(annee)); annee = 1904; Ecran.formater("%5d : %5b %5b %5b\n",annee, estBissextile(annee), estBissextile1(annee), estBissextile2(annee)); annee = 2017; Ecran.formater("%5d : %5b %5b %5b\n",annee, estBissextile(annee), estBissextile1(annee), estBissextile2(annee)); }
ExempleReturnEnCoursDeFonction.java - Exemple d'exécution
Return dans une fonction void Possibilité d'utiliser l'instruction return dans une fonction void si pas de valeur indiquée après le return -> Interruption immédiate de la fonction
/* Type agrégé de stockage d'une direction */ /* en deux dimensions */ static class Direction2D { double x = 0.0; double y = 0.0; }; /* Normalisation d'une Direction2D */ /* Interruption de la fonction par return */ /* si la direction est le vecteur nul */ static void normalisation1(Direction2D d) { double dist = d.x*d.x+d.y*d.y; if ( dist == 0.0 ) { return; } dist = Math.sqrt(dist); d.x = d.x/dist; d.y = d.y/dist; } /* Normalisation d'une Direction2D */ static void normalisation2(Direction2D d) { double dist = d.x*d.x+d.y*d.y; if ( dist != 0.0 ) { dist = Math.sqrt(dist); d.x = d.x/dist; d.y = d.y/dist; } } /* Programme principal */ public static void main(String [] args) { Direction2D da = new Direction2D(); Direction2D db = new Direction2D(); Direction2D dc = new Direction2D(); Direction2D dd = new Direction2D(); dc.x = 3.0; dc.y = 4.0; dd.x = 3.0; dd.y = 4.0; normalisation1(da); normalisation2(db); normalisation2(dc); normalisation2(dd); Ecran.formater("%f %f\n",da.x,da.y); Ecran.formater("%f %f\n",db.x,db.y); Ecran.formater("%f %f\n",dc.x,dc.y); Ecran.formater("%f %f\n",dd.x,dd.y); }
ExempleReturnDansFonctionVoid.java - Exemple d'exécution
Utilisation comme variable des paramètres d'entête passés en "Entrées" stricte Détournement possible des paramètres d'entête passés en "Entrèes" stricte pour les utiliser en tant que variables locales Pas de problème pour les paramètres d'entête de type prédéfini qui sont transmis en valeur A utiliser de façon très très prudente sur les paramètres d'entête de type agrégé.
/* Type agrege de stockage du cosinus, */ /* du sinus et de la tangente d'un angle */ static class CosSinTan { double cos = 1.0; double sin = 0.0; double tan = 0.0; }; /* Calcul du cosinus, du sinus */ /* et de la tangente */ /* d'un angle donne en degres */ static CosSinTan calculCosSinTan1(double angle) { double a; CosSinTan res = new CosSinTan(); a = angle*Math.PI/180.0; res.cos = Math.cos(a); res.sin = Math.sin(a); res.tan = Math.tan(a); return res; } /* Calcul du cosinus, du sinus */ /* et de la tangente d'un angle */ /* donne en degres */ /* Détournement du paramètre d'entête angle */ /* utilisé comme une variable locale */ static CosSinTan calculCosSinTan2(double angle) { CosSinTan res = new CosSinTan(); angle = angle*Math.PI/180.0; res.cos = Math.cos(angle); res.sin = Math.sin(angle); res.tan = Math.tan(angle); return res; } /* Programme principal */ public static void main(String [] args) { double angle; CosSinTan cst; Ecran.afficher("SVP, l'angle : "); angle = Clavier.saisirDouble(); cst = calculCosSinTan1(angle); Ecran.formater("sin(%f) = %f\n",angle,cst.sin); Ecran.formater("cos(%f) = %f\n",angle,cst.cos); Ecran.formater("tan(%f) = %f\n",angle,cst.tan); Ecran.sautDeLigne(); cst = calculCosSinTan2(angle); Ecran.formater("sin(%f) = %f\n",angle,cst.sin); Ecran.formater("cos(%f) = %f\n",angle,cst.cos); Ecran.formater("tan(%f) = %f\n",angle,cst.tan); }
ExempleParametresEnteteCommeVariables.java - Exemple d'exécution
Localisation des variables Possibilité de déclarer une variable au moment de sa première utilisation -> Variable non définie jusqu'à sa déclaration Possibilité de déclarer une variable dans une séquence d'instructions -> Existence de cette variable uniquement jusqu'à l'accolade fermante de la séquence d'instructions -> Plus d'existence de cette variable après l'accolade fermante de la séquence d'instructions
/* Calcul et affichage des coordonnées */ /* de 10 points régulièrement placés */ /* sur un cercle 2D de rayon 5.0 */ /* centré sur l'origine */ /* Localisation dans le for */ /* des variables de calcul */ /* Déclaration de variables différentes */ /* mais portant les mêmes noms que des variables */ /* déclarées dans le for */ public class ExempleLocalisationVariables { /* Programme principal */ public static void main(String [] args) { int i; Ecran.afficherln("n° rad deg x y"); for ( i = 0 ; i < 10 ; i++ ) { Ecran.formater("%2d",i); double angle = i*2.0*Math.PI/10; Ecran.formater("%7.4f",angle); double a = i*36.0; Ecran.formater("%9.4f",a); double x = 5.0*Math.cos(angle); double y = 5.0*Math.sin(angle); Ecran.formater("%9.5f %9.5f\n",x,y); } double x = 0.0; double y = 0.0; Ecran.afficherln(x," ",y); } }
ExempleLocalisationVariables.java - Exemple d'exécution
Initialisation automatique des champs des variables de type agrégé avec autre chose que 0 Possibilité de déclarer une valeur d'initalisation différente de "zéro" pour tout champ de type agrégé Très pratique pour ne pas avoir à le faire par programme Syntaxe: static class nomTypeAgrege { type nomChamp1 = valeurChamp1; type nomChamp2 = valeurChamp2; ... type nomChampN = valeurChampN; }; Utilisable sur tous les types de champs Marche aussi en langage algorithmique en utilisant la même syntaxe mais avec le signe <- pour l'affectation
/* Test de types agrégés déclarés */ /* sans et avec initialisation */ public class ExempleTypeDateSansEtAvecInitialisation { /* Stockage d'une date sans initialisation */ /* explicite des champs */ /* -> initialisation implicite à 0 */ static class DateSansInit { int jour; int mois; int annee; }; /* Stockage d'une date avec initialisation */ /* explicite des champs */ static class DateAvecInit { int jour = 1; int mois = 1; int annee = 1901; }; /* Programme principal */ public static void main(String [] args) { DateSansInit d1 = new DateSansInit(); DateAvecInit d2 = new DateAvecInit(); Ecran.afficher("Date 1 : "); Ecran.afficherln(d1.jour,":", d1.mois,":", d1.annee); Ecran.afficher("Date 2 : "); Ecran.afficherln(d2.jour,":", d2.mois,":", d2.annee); } }
ExempleTypeDateSansEtAvecInitialisation.java - Exemple d'exécution
Fichier zip du sitee