I21 Algorithmique et programmation II David Gross-Amblard, Joël Savelli IEM-uB GFDL 1.2 v2.2
i IEM / uB GFDL L'équipe enseignante ● David Gross-Amblard (responsable, CM-TD-TP) – MdC Le2i : Bases de données (théorie / sécurité / application Web/musique) – Contact : david.gross-amblard sur u-bourgogne.fr, sujet [i21] – Avec modération ● Damien Leprovost (TP), doctorant (bases de données, Web social) ● Joël Savelli (TD-TP) – MdC Le2i : Modélisation ● Hakim Soussi (TP), doctorant (modélisation)
i IEM / uB GFDL Déroulement du semestre ● Cours : questions libres à la fin (même si pas de rapport avec le cours du jour) ● Vous devez : – Lire votre mél université régulièrement (et le renvoyer vers votre compte favori, votre téléphone,...) – Consultez le site du cours régulièrement
i IEM / uB GFDL Déroulement ● Début des Tds : semaine prochaine ● Début des Tps : semaine suivante ● 1 partiel / 1 examen final (coef. 1,5 et 3) – Attention : sans document ● 1 projet commun avec i22 (coef 1,5 pour i21) – Modalités précises (rapport/pré-rapport/ soutenance/etc.) – Binômes sauf exception – Commencer dès la distribution du sujet !
i IEM / uB GFDL Plan du cours I.Rappels sur Java – types, instructions, procédures, fonctions... II.Programmation par objets - classe, composition, héritage, initiation à la modélisation III.Algorithmes (et types de données) – algorithmes de tri, algorithmes récursifs, listes, piles, files, arbres
i IEM / uB GFDL Dosage de l'effort scalaires impératif récursif affectation déclaration séquence test boucle entrée/sortie syntaxe sémantique expression état valeur exécution fonction procédure référence paramètre passage par valeur Passage par référence Effet de bord Variable globale portée surcharge Ordre d'évaluation Expression comme instruction semi-compilation Machine virtuelle récurrence terminaison complexité espace temps O() Typage fort Typage faible polymorphisme enregistrement Type produit classe instance allocation Glaneur de cellulesurcharge constructeur accesseur partage Type enveloppé tableaux référenceRéférence nulle Types disjonctifs piles files exceptions Typage statique/dynamique transtypage
i IEM / uB GFDL I Rappels sur Java 1.Programmation impérative 2.Noyau impératif 3.Procédures et fonctions
i IEM / uB GFDL Programmation impérative ● Mode de programmation historique ● Matériel : mémoire(s) / processeur ● Données / programme ● Le processeur exécute le programme pour faire évoluer l'état mémoire ● (≠ programmation fonctionnelle : récriture de termes, ex. : Ocaml, Haskell) ● (≠ programmation logique : résolution, ex. : Prolog)
i IEM / uB GFDL Langage machine ● Mémoire : tableau de mots-mémoire (32 bits) ● Instructions machine : manipulation élémentaire des mots mémoire (arithmétique, déplacement, test) ● Avantage : très rapide ● Inconvénient : beaucoup de cerveau pour rien ● ex. : copier le mot binaire , soit 65 en décimal, dans la carte graphique pour écrire « A »
i IEM / uB GFDL Afficher « AB » 12 load reg move reg add reg move reg stop
i IEM / uB GFDL Programmation impérative de haut niveau : compilation ● Abstraire la mémoire et les instructions pour se concentrer sur le plus utile ● Compilation (compilateur) : traduire le programme écrit dans un langage de haut niveau en instructions machine ● Inconvénient : exécution un peu plus lente (négligeable) ● Avantage : cerveau mieux utilisé ● Changement d'architecture (processeur, langage machine) : recompiler
i IEM / uB GFDL Afficher « AB » System.out.println(« AB »);
i IEM / uB GFDL Semi-compilation ● Abstraire le processeur : machine virtuelle ● Semi-compilation : convertir le programme en langage pour la machine virtuelle ● Avoir une machine virtuelle pour chaque processeur réel ● Inconvénient : exécution encore un peu plus lente (négligeable en général) ● Avantage : pas de recompilation, le même programme pour toute architecture / portabilité du code semi- compilé
i IEM / uB GFDL Java ● Machine virtuelle (JVM : Java virtual machine) ● Programme : fichier.java ● Semi-compilateur : javac – javac Main.java -> Main.class ● Exécuteur de la machine virtuelle : – java Main (sous entendu, Main.class) ● Portabilité : le même Main.class fonctionne sur toute architecture (c'est l'exécuteur qui change)
i IEM / uB GFDL Conventions et programme minimal en Java class Main { public static void main(String arg[]){ } ● Nom du fichier :.java ● Beaucoup de notions (class, static, public, void...) pour plus tard
i IEM / uB GFDL Noyau impératif ● Déclaration ● Mise en séquence ● Affectation ● Test ● Boucle (ici en Java, mais presque pareil en C, C++, ADA, Pascal, Python, PHP,...)
i IEM / uB GFDL Syntaxe/sémantique ● Syntaxe (de Java) : ensemble de règles définissant les programmes bien formés ● Sémantique (de Java) : ensemble de règles définissant, pour les programmes syntaxiquement corrects, leurs effets sur l'état mémoire, le processeur, et leur conditions de validité
i IEM / uB GFDL Noyau impératif ● Déclaration – Instruction de déclaration de variables – Types de base – Modèle mémoire associé – Déclaration de constantes
i IEM / uB GFDL Instruction 1 : déclaration ● Syntaxe : (notation BNF Backus-Naur form) ● ex. : int toto; ● Identificateur : nom unique (suite de caractères, _, nombres, commence par un caractère, sensible à la casse) ● Types : types de bases (ex. int), types composites, types déclarés ● Ex. d'erreur de syntaxe : int 09toto;
i IEM / uB GFDL Types de bases ● Scalaires – Entier : byte, short, int, long (de plus en plus de bits pour représenter le nombre entier, plus grands nombres) – Flottants : float, double (de plus en plus de bits pour représenter le nombre flottant, meilleure précision) ● Autre – Booléens : boolean (true, false) – Caractères : char ('A', 'B',...)
i IEM / uB GFDL Variables/constantes ● Variable : zone mémoire identifiée pouvant être modifiée ● Constante : zone mémoire identifiée ne pouvant être modifiée après initialisation – Syntaxe : final – Ex : final float PI; – Une fois la valeur de PI fixée, ne pourra être modifiée
i IEM / uB GFDL Modèle mémoire ● int x; ● Une case mémoire porte le nom x, et contient une valeur de type int ● boolean b; ● Une case mémoire porte le nom b, et contient une valeur de type boolean
i IEM / uB GFDL Déclaration ● Bonne pratique : utiliser des identificateurs significatifs ● Ex : int longueurTableau; ● Contre-ex. : int lt; ● Bonne pratique : choisir une convention de nommage et s'y tenir (convention Java : premier mot en minuscule, séparation avec des majuscules, constantes en MAJUSCULES)
i IEM / uB GFDL Instruction 2 : mise en séquence ● Mettre plusieurs instruction l'une à la suite de l'autre Etat 0→(instr. 1)→Etat 1→(instr. 2)→Etat 2... ● Ex : int x; int y; ● En Java, C, C++ : « ; » est un terminateur (il y a toujours un « ; » à la fin d'une instruction) ● Dans d'autres langages : séparateur (Ocaml, Pascal)
i IEM / uB GFDL Bloc d'instructions ● Bloc : suite d'instructions entre accolades ● Ex : public static void main(String argv[]){ Int x; {int y; int z; { int q; int t; }
i IEM / uB GFDL Portée des identificateurs ● Un identificateur est défini pour le bloc courant et ses sous-blocs ● Une redéclaration d'un identificateur dans le même bloc est interdite ● Servira plus tard...
i IEM / uB GFDL Portée des identificateurs ● Ex : int x;// accessible : x { int y;// accessibles : x,y int z;// accessibles : x,y,z int x; // interdit : x déjà défini } // accessibles : x int x; // interdit : x défini dans ce même bloc
i IEM / uB GFDL Instruction 3 : affectation ● Syntaxe : = ● Ex. : int x=3; ● Expression : ce qui a une valeur ● Types de bases munis d'opérateurs internes : – Scalaires ● Entiers positifs : +, *, -, / (quotient), % (reste) ● Entiers négatifs : +, *, -, / (division arrondie en défaut), % ● Flottants : +, *, -, / – Autres ● Booléens : && (et), || (ou), ! (non)
i IEM / uB GFDL Booléens ● George Boole ( ), logicien, mathématicien et philosophe britannique ● Fondements de la logique moderne, basés sur une structure algébrique et sémantique (algèbre de Boole)
i IEM / uB GFDL Expressions ● Par combinaison de : – valeurs de types de bases (littéraux) ● ex. 3, ''Toto'' – expression expression ● ex. 3+2, 1-5*3 – expression ● ex. -1 – Parenthèses ● ex. -(1+3)*5+2
i IEM / uB GFDL Expressions : priorité des opérateurs ● Priorités usuelles – Parenthèses > - unaire > * > + ● ex. -(3+5)*2+8 – ! > && > || ● ex. !true && false || true
i IEM / uB GFDL Instruction 3 : affectation ● Si constante, une et une seule affectation final float PI; PI= ; final int THECANTROPE; THECANTROPE=1; THECANTROPE=2; // erreur sémantique
i IEM / uB GFDL Expressions : opérateurs logiques ● Test d'égalité – ==, != : test l'égalité/l'inégalité de valeurs ● Comparateurs (types ordonnés) –, >=
i IEM / uB GFDL Instruction 3 : affectation ● Sémantique de l'affectation : – Calcul de la valeur de l'expression – Modification de la case mémoire indentifiée à cette valeur int x ; x=3+5*(2+8); boolean b; b=true || true; ● Modèle mémoire : – La case nommée x contient la valeur 53 – La case nommée b contient la valeur true
i IEM / uB GFDL Typage ● Une expression peut combiner des types ● Un calcul (de type) est réalisé pour vérifier la cohérence des types ● ex d'erreur sémantique : int x=true; (syntaxe ok) ● Ex : int x=(3*2)+(5/2)-(3+2.5); (erreur) ● Ex : boolean b=(3>5)&&( ==8.0); (ok) ● Il existe un programme qui vérifie automatiquement si les types d'un programme Java sont corrects
i IEM / uB GFDL Types ● Ex: javac ● Java est un langage à typage statique pour les types de base : après compilation, il ne peut y avoir d'erreur de type (autre exemple : C++) ● => Pour Ariane (plus stricte encore : ADA) ● Autres langages : pas de déclaration, typage dynamique (à l'exécution, les variables changent de type, ex. PHP) ● => Pour faire vite, plus risqué
i IEM / uB GFDL Instructions 1 et 3 combinées int x; (x vaut la valeur par défaut des int, 0) x=3; → int x=3; (x ne vaut jamais 0) ● Bonne pratique : initialiser les variables immédiatement (signalé par le compilateur)
i IEM / uB GFDL Types de base manipulés par références ● Tableau : tableau d'éléments de même type ● Déclaration : int[] t; (t de type tableau d'entiers) ● Variante (déconseillée): int t[]; ● Modèle mémoire : t ne contient pas une valeur, mais une référence vers un élément ● Dans ce cas : référence par défaut : null (rien)
i IEM / uB GFDL Instanciation d'un tableau ● Instanciation : opération d'allocation mémoire associée à un type / expression ayant pour valeur une référence ● Syntaxe pour l'instanciation d'un tableau : new [ ] ● Alloue un tableau de n éléments de type, initialisés à une valeur par défaut (0 pour scalaires, etc.) ● Ex. : instanciation d'un tableau de 10 int : new int[10];
i IEM / uB GFDL Tableau à plusieurs dimensions ● ex. : int[][] t=new int[10][3]; ● Accès aux éléments : t[1][1] ● Littéraux de type tableau : Int[] t={1,2,3,4}; String[] s={''toto'', ''tutu''};
i IEM / uB GFDL Modèle mémoire int[] t=new int[10]; ● t contient une référence vers le tableau instancié. Le tableau contient 10 valeur 0 ● Accès aux éléments par l'indice, débute à 0 ● Expression t[0], t[1],... ● Partage de référence : Int[] t1=new int[10]; Int[] t2=t1; ● t1 et t2 référencent le même tableau !
i IEM / uB GFDL Partage de références ● t1[1]=55; ● t2[1]=60; ● t1[1] est modifié. ● Attention : test d'égalité t1==t2 ● Compare la valeur de t1 à celle de t2 ● Mais la valeur de t1 et de t2 sont des références
i IEM / uB GFDL Test d'égalité et références ● Pour les types manipulés par référence, l'opérateur d'égalité teste si les références sont égales, et ne compare par le contenu ● Grande source d'erreur ● Idem pour les chaînes ● Comparer le contenu de 2 tableaux : tester les éléments un par un ● Comparer le contenu de 2 chaînes : s.equals(s2), mais on verra plus tard
i IEM / uB GFDL Types de bases manipulés par références ● Chaînes de caractère : String ● Constantes : ''tata'' ● String toto=''tata''; ● String tutu=toto; ● Tutu référence la même chaîne que toto ● Effet de : tutu=''bob'' ? ● En Java : impossibilité de modifier un élément String (alors qu'en C, en C++,...)
i IEM / uB GFDL Instruction 4 : test ● Correspond à la notion – « Si ceci est vrai, alors exécuter cela, (et sinon ceci) » if ( ) else ● Ex. : if (32+5>22 && (true || 1==1)) x=1;
i IEM / uB GFDL Instruction 4 : test ● Si plus d'une instruction à réaliser, en faire un bloc d'instruction (entre accolades) If (x) { y=3; z=5; } else { y=1; z=2; } ● Bonne pratique : indentation et alignement du code
i IEM / uB GFDL Instruction 4 : test ● Tests multiples : if ( ) instr.1 else if ( ) instr. 2 else if ( ) instr. 3...
i IEM / uB GFDL switch/case switch( ){ case : ;... default : ; }
i IEM / uB GFDL switch/case ● Instruction break : quitter le bloc courant (ici, le switch)
i IEM / uB GFDL switch/case int x=2; String reponse; switch(x){ case 2: case 4: case 8:reponse= ''c'est 2, 4 ou 8''; break; case 1: reponse= ''c'est 1''; default : reponse= ''c'est pas''; }
i IEM / uB GFDL Instruction 5 : boucle ● Pour, tant que-faire, faire-tant que ● Tant que (condition) faire instruction – Tant que la condition est vraie, exécuter la/les instruction(s)
i IEM / uB GFDL boucle ● Objectif : éviter les répétitions de code / faire varier un indice de boucle ● T[0]=0; t[1]=1; t[2]=2; ● i=0; Tant que(i<3) – T[i]=i; – i=i+1; ● while( ) do ● Int i=0; while(i<3){ T[i]=i;i=i+1; ● Attention : expression vérifiée avant l'entrée dans la boucle ● x=11; While (x<10) do x=x+1;
i IEM / uB GFDL Instruction 5 : boucle ● Question de la terminaison ● int x=1; while (x>0) do x=x+1; ● La terminaison d'un programme est en général indécidable (il n'existe pas de programme qui vérifie qu'un programme P passé en paramètre termine toujours) ● « On Computable Numbers with an Application to the Entscheidungsproblem » [Turing, 1936]
i IEM / uB GFDL Alan Mathison Turing ( ) ● Mathématicien britannique ● Machine de Turing ● Test de Turing ● Code Enigma ● Médaille de Turing
i IEM / uB GFDL Instruction 5 : boucle ● do while ( ); ● Test de la condition à la fin : exécute au moins une fois l'instruction
i IEM / uB GFDL Instruction 5 : boucle ● for( ; ; ) – ● Correspond à – Exécuter I1; – Tant que (E est vraie) ● Exécuter I3 ● Exécuter I2
i IEM / uB GFDL Boucles : break/continue ● break : sortie du bloc courant (donc de la boucle) ● continue : passer au tour de boucle suivant (pour le for, faire l'étape I2);
i IEM / uB GFDL Procédures et fonctions ● Procédures prédéfinies ● Motivation pour leur utilisation ● Déclaration de procédures ● Déclaration de fonctions ● Fonctions et opérateurs ● Surcharge ● Fonctions comme instructions
i IEM / uB GFDL Procédures prédéfinies ● Entrées / sorties : – System.out.println(); // sauter une ligne – System.out.println( ); ● Affiche la valeur de l'expression et saut de ligne (si référence, une adresse de la mémoire de la machine virtuelle, comme – System.out.print( ); ● Idem, sans saut de ligne
i IEM / uB GFDL Fonctions prédéfinies ● Calculs – ex. float f=Math.sin(12); ● Entrées / sorties : – Entrées en Java, complexes – Fichier Lire.java pour vous simplifier la vie, disponible sur le site ● ex. : int x=Lire.i(); ● ex. : float f=Lire.f(); ● etc.
i IEM / uB GFDL Procédures déclarées : motivation ● Ex : afficher « Bonjour et sauter 2 lignes après une délicate frise », pour Clément et Eliana
i IEM / uB GFDL Motivation ● System.out.println(« Bonjour Clément »); ● System.out.println(« ============= »); ● System.out.println(); ● System.out.println(« Bonjour Eliana »); ● System.out.println(« ============= »); ● System.out.println();
i IEM / uB GFDL Motivation ● Objectif : éviter les redondances de code / factoriser du code ● « Mais je peux faire du copier/coller ! » ● Oui, mais si il faut changer le message, la frise, il faut (penser à) corriger à plusieurs endroits (éventuellement éloignés) ● Bonne pratique : Lorsque deux traitements sont identiques aux paramètres près, en faire une procédure
i IEM / uB GFDL Motivation ● // déclaration ● void message(String nom){ – System.out.println(« Bonjour » +nom); – System.out.println(« ============= »); – System.out.println(); ● } ● Message(« Clément »); // programme principal ● message(« Eliana »);
i IEM / uB GFDL On peut faire mieux ● Redondance des sauts de ligne ● La frise peut servir autre part ● Bonne pratique : si un traitement peut servir dans plusieurs contextes, en faire une procédure
i IEM / uB GFDL Factorisation de code ● Void afficheFrise(){ – System.out.println(« ============= »); ● } ● Void sauteDeuxLignes(){ – System.out.println(); ● }
i IEM / uB GFDL Factorisation de code ● void message(String nom){ – System.out.println(« Bonjour » +nom); – AfficheFrise(); – SauteDeuxLignes(); ● } ● message(« Clément »); // programme principal ● message(« Eliana »);
i IEM / uB GFDL Avantages ● Écrire moins ● Modifications se propagent partout (ex. frise avec des « # ») ● Faciliter la compréhension (programmation en équipe...binômes) ● Découpage et distribution du travail (lundi AfficheFrise, mardi sauteDeuxLigne, etc.)
i IEM / uB GFDL Vocabulaire ● Déclaration de procédure ou fonction ● Appel de procédure ou fonction
i IEM / uB GFDL Déclaration de procédures ● Identificateur de procédure (son nom) – Convention Java : commence par une minuscule, majuscule comme séparateur – ex. afficheLigne et pas Affiche_Ligne ● Bonne pratique : choisir une convention et s'y tenir (pourquoi pas celle de Java ?)
i IEM / uB GFDL Déclarations des paramètre formels ● Déclaration des paramètres formels (ou arguments formels) : ● void (,,etc.) ● void message(String nom)... ● Nb de paramètre : arité de la procédure ● Paramètres disponibles comme variables dans le corps de la proc. ou fonction ● Corps : bloc
i IEM / uB GFDL Appel de procédures ● Appel : respecter l'arité, l'ordre des paramètres et leur type ● ex. message(« Eliana »); ● Contre-ex. : message(); ● valeur « Eliana » : paramètre (argument) réel
i IEM / uB GFDL Sémantique de l'appel void afficheNombre(int nombre){ System.out.println(« Le nombre est » +nombre); } int n= 12; afficheNombre(n+1); ● La valeur des expressions fournies comme paramètre est calculée (ici, 13) ● Les valeurs résultantes sont copiées comme valeur des paramètres formels ● Valeur de nombre dans afficheNombre: 13
i IEM / uB GFDL Passage de paramètres ● Passage par recopie ● Attention : void afficheNombre(int nombre){ System.out.println(« Le nombre est » +nombre); nombre=nombre+1; } int n= 12; afficheNombre(n); ● Aucun rapport entre nombre et n : n est inchangé par l'appel
i IEM / uB GFDL Passage de paramètres ● Même dans le cas suivant : void afficheNombre(int nombre){ System.out.println(« Le nombre est » +nombre); nombre=nombre+1; } int nombre= 12; afficheNombre(nombre); ● Deux identificateurs nombre, différenciés par le contexte
i IEM / uB GFDL Autres langages ● Possibilité de passage par adresse (ou référence) : C, C++ ● Complique les choses
i IEM / uB GFDL Attention : paramètre réel référence ● En Java, certains types sont manipulés par référence ● Tableau, chaînes, etc. ● int[10] t; // t est une référence au tableau Void affichePremierElement(int[10] tab){ System.out.println(« premier element » + tab[0]); } ● La valeur de t est seulement copiée, mais le ● Tableau est accessible en écriture (tab référence le même tableau)