Primitives fondamentales dalgorithmique Les oprations dun algorithmes sont

  • Slides: 61
Download presentation
Primitives fondamentales d'algorithmique • Les opérations d'un algorithmes sont habituellement exécutées une à la

Primitives fondamentales d'algorithmique • Les opérations d'un algorithmes sont habituellement exécutées une à la suite de l'autre, en séquence ordre est important. (parallélisme) • On ne peut pas arbitrairement changer cette séquence. – Affectation – Sélection – Répétition 1

 Branchement conditionnel if (condition) { instructions } else { instructions } test if

Branchement conditionnel if (condition) { instructions } else { instructions } test if (condition) instruction else instruction facultatif test_1_vrai test_2_vrai test_faux test_3_faux 2

 Branchement multiple switch (variable_énumérable) { case valeur_1 : instructions ; break; case valeur_2

Branchement multiple switch (variable_énumérable) { case valeur_1 : instructions ; break; case valeur_2 : instructions ; break; default : instructions ; } Type int Ne pas oublier Tous les autres cas Pourquoi une nouvelle sélection ? 3

Boucles indicées Contrôlée par un indice nombre d’itérations connu à l’avance (déterministe). Éxécuté 1

Boucles indicées Contrôlée par un indice nombre d’itérations connu à l’avance (déterministe). Éxécuté 1 fois Éxécuté à chaque fois for ( initialisation ; condition_de_boucle ; évolution ) { instructions; } Continue tant que condition = vrai init test corps_boucle incr for (init; test; incr) { corps_boucle; } 4

Boucles conditionnels Contrôlée par une condition nombre d’itérations inconnu par avance (indéterministe). Continue tant

Boucles conditionnels Contrôlée par une condition nombre d’itérations inconnu par avance (indéterministe). Continue tant que condition = vrai while ( condition ) { instructions; } (On peut ne pas rentrer) test corps_boucle do { instructions; } while ( condition ) (On rentre au moins une fois) while (test) { corps_boucle; } 5

Méthodologie de résolution d'un problème 1 - Définir le problème (QUOI ? ) Lire

Méthodologie de résolution d'un problème 1 - Définir le problème (QUOI ? ) Lire l’énoncé du problème, être certain de bien le comprendre, ressortir les informations pertinentes : données ? résultats ? relations entre données ? Création du cahier des charges qui définie ces notions en détails. 2 - Analyser le problème (COMMENT ? ) Réfléchir à la résolution du problème en ignorant l’existence du PC - Expliciter les données et les résultats Définir précisément leur Nature : Simple, Structure, Domaine de validité - Expliciter les relations données/résultats exploiter l’ensemble de vos connaissances et solution existantes. encore difficile ? 6 Décomposer le problème!! Analyse descendante!!

3 - Résoudre le problème Algorithme = méthode de résolution. Pour décrire l'algorithme, il

3 - Résoudre le problème Algorithme = méthode de résolution. Pour décrire l'algorithme, il faut un langage algorithmique. Le langage algorithmique peut avoir plusieurs formes mais à quelques contraintes : Langage limité et précis. Écrire formellement l’algorithme en utilisant un pseudo langage ou un organigramme Vérifier votre solution sur un exemple (preuve formelle de l’algorithme) 4 - Implémentation Transformer l'algorithme en programme Le programme sera compilé puis exécuté. 5 - Validation des résultats Tester le programme sur différents jeux de tests le jeux de tests doit être « suffisant » ne pas oublier les cas particuliers, … 7

Savoir être : – efficace : quelle méthode me permettra d’obtenir le plus vite,

Savoir être : – efficace : quelle méthode me permettra d’obtenir le plus vite, le plus clairement, le plus simplement possible les résultats attendus. – paresseux : que puis-je réutiliser? – prévoyant : s’assurer que le programme sera facilement réutilisable et extensible 8

Méthodes d’analyse Instance du problème • Exemple d’un problème: Tri d’un ensemble d’éléments –

Méthodes d’analyse Instance du problème • Exemple d’un problème: Tri d’un ensemble d’éléments – Entrée: Suite de n éléments a 1, …an – Sortie: La suite ordonnée • Instances du problème: – Suite de nombres: 475, 787, 34, 245, 56, 350 9

Analyse descendante Objectifs: Méthode pour écrire un algorithme de qualité. Principe: Abstraire: Repousser le

Analyse descendante Objectifs: Méthode pour écrire un algorithme de qualité. Principe: Abstraire: Repousser le plus loin possible l’écriture de l’algorithme. Décomposer: Décomposer la résolution en une suite de “sous-problèmes” que l’on considère comme résolus. Combiner: Résoudre le pb par combinaison des abstractions des “sous-pbs”. Pb: Afficher les nbres parfaits compris entre 1 et un nbre saisi par l’utilisateur Énoncé: Afficher les nombres parfaits (nombre égaux à la somme de leurs diviseurs) compris entre 1 et un nombre n (naturel 1) saisi par l’utilisateur. afficher. Nbs. Parfaits saisir. Borne. Max entiers est. Parfait somme. Des. Diviseurs booléen entier 10 est. Un. Diviseur booléen

Diviser pour régner • La méthode d’analyse « diviser pour régner » : –

Diviser pour régner • La méthode d’analyse « diviser pour régner » : – on conçoit un ensemble de procédures pour résoudre le problème – programmation dirigée par les traitements : on décide d’abord de la manière dont on va manipuler les données puis on conçoit les structures de données pour faciliter cette manipulation. – une procédure est un regroupement d’instructions dans un bloc que l'on pourra appeler par son nom • La méthode d’analyse « diviser pour régner » : – Ces procédures reçoivent éventuellement des variables en paramètres et effectuent des traitements sur ces variables données en paramètres ou sur des variables déclarées à l’intérieur de la procédure. – Une variable est un morceau de mémoire auquel on donne un nom et dans lequel on stocke des valeurs. 11

Apport de la démarche algorithmique • Décomposer une tâche complexe en tâches élémentaires. •

Apport de la démarche algorithmique • Décomposer une tâche complexe en tâches élémentaires. • Penser en termes d’étapes. • Vérifier la succession des opérations. • Assurer la rigueur d’écriture. 12

Récursivité • Il est parfois difficile de définir un objet: plus simple de le

Récursivité • Il est parfois difficile de définir un objet: plus simple de le définir en fonction de lui-même. • Récursion en programmation: quand une méthode s’appelle-même. • Toute méthode récursive peut-être convertie en méthode non-récursive. • Méthodes récursives plus coûteuses en espace mémoire, et parfois aussi en temps. La récursivité est un mécanisme de calcul puissant!! Résoudre un problème de taille n peut se ramener à la résolution d’un (plusieurs) sous problèmes de taille plus réduite. . . 13

 • Exemple (suite) D’après la définition précédente : «a» est une chaîne :

• Exemple (suite) D’après la définition précédente : «a» est une chaîne : un caractère ‘a’ suivi d’une chaîne vide «ab» est une chaîne : un caractère ‘a’ suivi de la chaîne « b » La récursivité est un mécanisme puissant de définition d’objets! 14

Procédure récursive • Procédure qui s’invoque elle-même Exemple: n! = n(n-1)(n-2)… 2. 1 Si

Procédure récursive • Procédure qui s’invoque elle-même Exemple: n! = n(n-1)(n-2)… 2. 1 Si n≥ 0 0! = 1 n! = n(n-1)! pour n≥ 1 5! = 5. 4! = 120 4! = 4. 3! = 24 3! = 3. 2! =6 2! = 2. 1! =2 1! = 1. 0! =1 • Toute procédure récursive doit avoir une condition d’arrêt: cas de base qui permet de ne plus invoquer la procédure. Ici, la condition d’arrêt est n=0 15

Trace pour n =3: Entrée: Entier n≥ 0 Sortie: n! Procédure factoriel (n) factoriel(3)

Trace pour n =3: Entrée: Entier n≥ 0 Sortie: n! Procédure factoriel (n) factoriel(3) Retourne: 3. factoriel(2) Si n = 0 alors factoriel(2) Retourne (1) Retourne (n. factoriel(n-1)) Fin factoriel Retourne: 2. factoriel(1) Retourne: 1. factoriel(0) 1. 1=1 Retourne: 1 3. 2=6 2. 1=2 16

Procédure itérative pour le calcul de n! Trace pour n =3 : Entrée: Entier

Procédure itérative pour le calcul de n! Trace pour n =3 : Entrée: Entier n≥ 0 Sortie: n! Procédure factoriel-iteratif (n) res = 1; courant = n; Tant que courant>0 res=1 courant=3 res=3 courant=2 res=6 courant=1 res=6 courant=0 Faire res : = res * courant; courant : = courant-1; Fin Tant que Retourne (res) Fin factoriel-iteratif 17

Nombres de Fibonacci Exemple: Un robot peu avancer par des pas de 1 ou

Nombres de Fibonacci Exemple: Un robot peu avancer par des pas de 1 ou 2 mètres. Calculer le nombre de façons différentes de parcourir une distance de n mètres Distance Suite de pas Nb de possibilités 1 1 1 2 1, 1 ou 2 2 3 1, 1, 1 ou 1, 2 ou 2, 1 3 4 1, 1, 1, 1 ou 1, 1, 2 ou 1, 2, 1 ou 2, 1, 1 ou 2, 2 5 18

 • Pas(n): Nombre de possibilités pour parcourir n mètres. • Pas(1) = 1,

• Pas(n): Nombre de possibilités pour parcourir n mètres. • Pas(1) = 1, Pas(2) = 2; • Pour n>2: – Si premier pas = 1 mètres, il reste n-1 mètres -> Pas(n-1) – Si premier pas = 2 mètres, il reste n-2 mètres -> Pas(n-2) Donc, Pas(n) = Pas(n-1)+Pas(n-2) Entrée: n Séquence de Fibonacci: Sortie: Pas(n) f 1 = 1 Procédure Pas (n) f 2 = 2 Si n=1 ou n=2 alors fn = fn-1 + fn-2 pour n>2 Retourne (n) Retourne (Pas(n-1)+Pas(n-2)) Fin Pas 19

Récursivité Vs Itération procédure Itération( ) Tantque (condition) faire Récursivité procédure Itération( ) Si

Récursivité Vs Itération procédure Itération( ) Tantque (condition) faire Récursivité procédure Itération( ) Si (condition) alors <Instructions> Itération() <Instructions> fin tantque fonction S(n) : entier S : =0 Tant que (n>0) faire S: =S+n n: =n-1 fin tant que retourner S fin si fonction S(n) : entier Si (n=0) alors S: = 0 sinon S: = S(n-1)+n fin si 20

Diviser pour résoudre Principe général : - Diviser le problème de taille n en

Diviser pour résoudre Principe général : - Diviser le problème de taille n en sous-problèmes plus petits de manière que la solution de chaque sous-problème facilite la construction du problème entier. (Analyse descendante) - Division progressive jusqu' à l'obtention d'un sous-problème de taille 1. Schéma général : DPR(x) : Si x est suffisamment petit ou simple alors Retourner A(x) Sinon Décomposer x en sous exemplaires x 1, x 2. . . xk Pour i=1, k : yi : = DPR(xi) Finpour Retourner les yi pour obtenir une solution à x Retourner y Fsi 21

Applications : Tri par fusion d'une liste L de n éléments avec n =

Applications : Tri par fusion d'une liste L de n éléments avec n = 2 k. Une technique "diviser pour résoudre" peut être la suivante: Pour trier une liste de n éléments, il faut trier deux listes de n/2 éléments chacune puis de faire l'interclassement entre ces deux listes. De la même façon, pour trier une liste de n/2 éléments il faut trier deux listes de n/4 éléments chacune puis de faire leur interclassement. Et ainsi de suite jusqu'à l'obtention de listes d'un seul élément. 22

Les Tours de Hanoi A B C Peut-on bouger les disques de A vers

Les Tours de Hanoi A B C Peut-on bouger les disques de A vers C en utilisant B. Contrainte : un disque ne peut jamais être déposé sur un disque plus petit Y a-t-il une solution ? 23

A B C 24

A B C 24

 • • Supposons qu’on ait n disques au départ Les disques sont numérotés

• • Supposons qu’on ait n disques au départ Les disques sont numérotés de 1 à n, par ordre croissant de diamètre. Algorithme : – Bouger les n-1 plus petits disques de A à B en utilisant C – Bouger le disque n de A à C – Bouger les n-1 plus petits disques de B à C en utilisant A Complexité : 2^n-1 mouvements !!! 25

Décomposition modulaire • Quelques citations : – « Pour comprendre un programme d ’un

Décomposition modulaire • Quelques citations : – « Pour comprendre un programme d ’un seul tenant, un être humain met normalement un temps qui augmente exponentiellement avec la taille du programme » Djikstra – «Pour maîtriser la complexité du problème à résoudre, diviser chacune des difficultés que j’examinerais en autant de parcelles qu’il pourrait et qu ’il serait requis pour mieux le résoudre » Descartes • stratégie "diviser pour régner » permet d’alléger le programme, de faciliter sa Maintenance, de le Structurer, d’améliorer sa Lisibilité, Extensibilité et Réutilisation. 26

Les fonctions et procédures • Les fonctions sont au plus bas niveau de la

Les fonctions et procédures • Les fonctions sont au plus bas niveau de la décomposition d’un problème. • Une fonction devrait avoir un seul but ou tâche à exécuter. • Les fonctions sont représentées dans un graphe de structure qui est une hiérarchie (fonctionnelle). • Une fonction est une abstraction parce qu’elle peut cacher les détails d’une tâche et elle réduit l’interface à des paramètres et une valeur de retour. Les procédures et les fonctions sont à la base de la programmation structurés 27

Avantages : • Les fonctions nous permettent de factoriser nos problèmes en parties gérables

Avantages : • Les fonctions nous permettent de factoriser nos problèmes en parties gérables et compréhensibles. • Facilitent la distribution du travail. • Permettent la réutilisation du code – bibliothèques et fonctions définies par les programmeurs de systèmes. • Permettent de protéger les données de chaque fonction (visibilité). • Vision très « top-down » de la programmation, tendance cartésienne analytique Attention : Danger du « Code spaghetti » 28

Déclaration et définition d’une fonction • Une fonction est déclarée avec un prototype qui

Déclaration et définition d’une fonction • Une fonction est déclarée avec un prototype qui consiste en un entête de fonction. entête • La définition du code de la fonction c’est son implémentation Type_retour Nom. Fonction (liste formelle de paramètres); corp s appe l { *définitions locales + traitement * } \ nom de la fonction Variable = Nom. Fonction(Var 1, Var 2); • Principe de la « boîte noire » Une procédure peut être assimilé à une « boîte noire » , c’est à dire un module dont on peut ne connaître que les interactions possibles avec le monde extérieur : N entrées Procédure /fonction N sorties 29

 • En C nous pouvons décomposer une grosse fonction monolithique (main) en de

• En C nous pouvons décomposer une grosse fonction monolithique (main) en de plus petites fonctions cohésives. NB: Pour pouvoir faire un programme exécutable il faut toujours une fonction « main » , c’est le point d’entrée dans le programme : le microprocesseur sait qu’il va commencer à exécuter les instructions à partir de cet endroit • Ces fonctions peuvent être misent à l’intérieur d’un seul fichier: une unité de compilation • Déclarer par des prototypes de fonctions. • Une fonction peut avoir le type void • Une fonction void ne peut pas faire partie d’une expression, elle peut seulement être un énoncé. 30

Le module C C nous fournit deux types de fichiers pour que nous puissions

Le module C C nous fournit deux types de fichiers pour que nous puissions définir nos modules – Le fichier. h – ou entête de module : Contient la déclaration des fonctions et les attributs que nous voulons que les autre modules voient. Aussi connue comme interface du module – Le fichier. c – ou corps du module : Contient la définition des fonctions qui sont déclarées dans l’entête du module et autres fonctions internes ou de soutient. Connue comme implémentation du module 31

 • Modules = fonctions (déclaration / implémentation) • Communication entre modules = appels

• Modules = fonctions (déclaration / implémentation) • Communication entre modules = appels de fonctions • Flexibilité et réutilisation par des pointeurs de fonctions • Comprendre le programme comprendre ce que fait chaque fonction. • Pour les gros programmes, il ne suffit pas seulement de décomposer un programme en fonctions. • Tout comme un édifice, un programme logiciel doit avoir une structure bien dessinée; une architecture • L’architecture d’un gros programme doit être exprimée en unités de compilation séparées • En C, ces unités de compilation sont des modules (ex. les bibliothèques de 32 modules tel que stdio, conio, …)

Masquage d’information • Le concept de masquage d’information est clef pour les concepts de

Masquage d’information • Le concept de masquage d’information est clef pour les concepts de décomposition et d’abstraction. • On cache l’information qui peut changer et on expose une interface stable qui ne changera pas. • L’information est obtenue ou changée SEULEMENT en utilisant l’interface. Type et paramètres de fonction Il y a 2 façons principales pour échanger de l’information entre les fonctions : – Variables partagées (variables globales). – Passage de paramètres, la déclaration explicite d’information nécessaire pour qu’une fonction réalise sa tâche. 33

Variables locales et passage de paramètres Utilisation d ’une procédure et passage de paramètres

Variables locales et passage de paramètres Utilisation d ’une procédure et passage de paramètres Passage par valeur 34 Passage par adresse (par référence)

– Inconvénients d'une utilisation systématique de variables globales • manque de lisibilité • risque

– Inconvénients d'une utilisation systématique de variables globales • manque de lisibilité • risque d'effets de bord si la procédure modifie les variables globales – Avantages d'une utilisation de variables locales • meilleure structuration. • diminution des erreurs de programmation. • les variables locales servent de variables intermédiaires (tampon) et sont "oubliées" (effacées de la mémoire) à la sortie de la procédure. Une procédure doit effectuer la tâche qui lui a été confiée, en ne modifiant que l'état de ses variables locales. 35

Structures de données Problème : “Comment Organiser au mieux l’information dans un Programme ?

Structures de données Problème : “Comment Organiser au mieux l’information dans un Programme ? ” Choisir la façon de représenter les données qui rendent le programme le plus efficace possible en temps, en espace etc. • Listes linéaires chaînées : – ensemble de nœuds alloués dynamiquement chaînés entre eux. – un nœud est une entité de stockage. – plus adapté aux instances de taille variable • Arbres : – structure de données hiérarchisée. • Graphe : – structure plus complexe représentant des relations entre éléments. • Hachage : transformer une donnée (par une fonction) en une adresse où sera logée la 36 donnée. (Gestion des collisions)

Abstraction • Lorsqu’on utilise une structure de données, l’important est de connaître les opérations

Abstraction • Lorsqu’on utilise une structure de données, l’important est de connaître les opérations que l’on peut effectuer sur les données. • Un type abstrait de données (TAD, ou ADT en anglais): Description d’une structure de données qui fait abstraction des détails de l’implémentation. • Modèle ou type de données abstrait : Écrire des algorithmes indépendamment de la représentation mémoire. Donc définition d'une machine abstraite pour chaque structure de données (Modèle ) avec un ensemble d'opérations • Exemple: – Créer une liste vide – Ajouter un élément (début, fin, milieu) – Retirer un élément (début, fin, milieu) – Détruire une liste – Trier les éléments d’une liste 37

Les tableaux • • • Ensemble d’objets de même type à accès direct Taille

Les tableaux • • • Ensemble d’objets de même type à accès direct Taille du tableau fixe, n’est pas modifiable, accessible par la valeur Accès aux éléments par tableau[i] Non vérification des bornes si débordement Indices débutant à 0 (en algorithmique 1) Création d’un tableau en 1 étape (2 dans d’autres langages: déclaration et instanciation) Stockage compact Taille fixe, en général Réajustement de taille coûteux en temps Insertion d’élément onéreuse en temps. 0 tableau 0 1 2 2 3 4 6 9 Tableau de 10 éléments Indices 38

Copie de tableaux de nombres ou partage Copie d’un tableau = copie des éléments

Copie de tableaux de nombres ou partage Copie d’un tableau = copie des éléments un à un (la destination doit être créée) 0 T 1 T 2 T 3 1 0 1 1 3 2 3 5 7 9 9 Situation possible en java mais pas en C (T est une constante, utilisation de pointeur) 39

Structures de données en RAM Allocation mémoire : • statique : espace alloué avant

Structures de données en RAM Allocation mémoire : • statique : espace alloué avant l'exécution du programme. • dynamique : espace alloué pendant l'exécution. • mixte : mélange des deux. Intérêts des pointeurs • Gestion de l’espace mémoire en cours d’exécution • Modifications de variables passées en paramètres de fonction • Représentation de tableaux : accès direct et indexé • en C++ d’autres utilisations 40

int* a = NULL; // Initialisation d’un pointeur à “NULL” a int* a=(int*)malloc(3*sizeof(int)); //Allocation

int* a = NULL; // Initialisation d’un pointeur à “NULL” a int* a=(int*)malloc(3*sizeof(int)); //Allocation et assignement a *a free(a); // Désallocation dynamique a *a 41

Liste chaînée : Structures Noeud Tête p_last nb_elements List_t p_first Node_t p_data p_next Data_t

Liste chaînée : Structures Noeud Tête p_last nb_elements List_t p_first Node_t p_data p_next Data_t typedef struct LIST { NODE* p_first_node_ ; NODE* p_last_node_ ; int nb_items_ ; } LIST ; typedef struct NODE { struct NODE* next_ ; void* p_item_ ; } NODE ; 42

BOOLEAN check_item( LIST* list, DATA* data ) { BOOLEAN found = LIST_Owns_Item( list, data

BOOLEAN check_item( LIST* list, DATA* data ) { BOOLEAN found = LIST_Owns_Item( list, data ); if( found ) { printf( “Item %d , %c in List”, data->index_, data->value_ ); } return found; } List_t* list_create( void ); int list_insert_item( List_t* list, Data_t* item ); Noeud Tête 43

Liste chaînée : Implantation • Choix d'une représentation mémoire et la traduction des opérations

Liste chaînée : Implantation • Choix d'une représentation mémoire et la traduction des opérations du modèle dans cette représentation. • Toujours tester la validité d’un pointeur avant de l’utiliser. • S’assurer de ne jamais perdre l’adresse d’une zone allouée dynamiquement. • Dans un programme, toute allocation par malloc ou calloc doit être suivie d’une désallocation par free. 44

Liste chaînée : Pile et File Pile, ou Tas (Stack) : structure LIFO void

Liste chaînée : Pile et File Pile, ou Tas (Stack) : structure LIFO void push(Data_t*) Data_t* pop(void) File, ou queue : structure FIFO void push(Data_t*) Data_t* pop(void) 45

Arbres: Structure de données Tree. Node_t p_parent p_first_child p_data p_next Data_t 46

Arbres: Structure de données Tree. Node_t p_parent p_first_child p_data p_next Data_t 46

Langage de programmation Programmer, c’est plus que simplement écrire du code. • Comment les

Langage de programmation Programmer, c’est plus que simplement écrire du code. • Comment les langages de programmation diffèrent-ils des langages naturels? • Qu’est-ce qu’un bon programmeur? • Un programmeur devrait-il connaître plus d’un langages de programmation? • Pourquoi étudier les langages de programmation? 47

Structure d’un système informatique Applications s r u te a il OS p C

Structure d’un système informatique Applications s r u te a il OS p C om Ed ite urs Langage machine Dispositifs physiques Interpréteurs 48

Niveau de complexité et d’abstraction • Langages de bas niveau (langage machine, assembleur). •

Niveau de complexité et d’abstraction • Langages de bas niveau (langage machine, assembleur). • Langages de haut niveau (les langages les plus utilisés : C, C++, …). • Langages de très haut niveau (Prolog, langages spécialises, SQL, …). • Au delà des langages de programmation : Environnements de programmation et outils de développement logiciel (J 2 EE, . NET) 49

Historique des Langages de programmation 1954 FORTRAN (John Backus) 1959 LISP (Mc. Carthy) 1960

Historique des Langages de programmation 1954 FORTRAN (John Backus) 1959 LISP (Mc. Carthy) 1960 COBOL (Grace Hopper) 1960 BASIC (Kemeny, Kurtz) 1971 Pascal (Niklaus Wirth, Kathleen Jensen) 1972 C (Brian W. Kernighan, Dennis Ritchie) 1975 Prolog (Colmerauer et. al. ) 1980 Ada 1983 Objective C (Obj. C) (Brad Cox) 1983 C++ (Bjarne Stroustrup) 1987 Perl (Larry Wall) 1988 Tcl (John Ousterhout) 1991 Python (Guido van Rossum) 1995 Delphi 1995 Java (Sun Microsystems) 1997 PHP (Rasmus Lerdorf), Java. Script 2001 C# (Microsoft dans le cadre de. NET) 2002 Visual Basic. NET 2003 Delphi. NET 50

Les différent types de langages • Différent langages permettent de résoudre différent problèmes de

Les différent types de langages • Différent langages permettent de résoudre différent problèmes de façon différentes. • Une opération peut être exprimée dans différent langages, puis exécuté sur la même machine. Langages à usage général : la plupart des langages que vous connaissez. Langages impératifs : permettent au programmeur d’attribuer des valeurs a des espaces mémoire, afin de décrire explicitement comment résoudre le problème. (Java, C++, Pascal) Langages déclaratifs : permettent au programmeur de déclarer diverse entités et relations. Le programme pourra ensuite utiliser ces declarations pour résoudre le problème. (Prolog, Lisp) Langages spécialises : ex: matlab (mathématiques), Cobol (Gestion), SQL (langage assertionnel pour BD), Perl (langage script). 51

Langages Impératifs • Programmation procédurale: Le programme est divisé en blocs pouvant contenir des

Langages Impératifs • Programmation procédurale: Le programme est divisé en blocs pouvant contenir des variables locales, ainsi que d’autres blocs. (C, Fortran, Pascal) • Programmation orientée-objet: Des objets se rapportant au problème sont définis, avec leurs attributs et leur façon de réagir à différent événements. Le problème est résolu grâce a l’interaction entre ces objets. (Java, C++, …) Langages Déclaratifs • Programmation fonctionnelle: Un programme consiste en la déclaration de fonctions. Un appel a une fonction est fait et retournera un élément qui dépendra de la valeur de ses paramètres qui peuvent, eux même, être des appels a des fonctions. (Lisp) • Programmation logique: Un programme consiste en la déclaration d’une série d ’axiomes et de règles de déduction, et la présentation d’un théorème à prouver. Le programme répond si le théorème peut être prouvé ou non 52 à partir des déclarations. (Prolog)

Critères d’un langage de programmation • Abstraction : abstraction procédurale et l’abstraction des données

Critères d’un langage de programmation • Abstraction : abstraction procédurale et l’abstraction des données permettent la généralité des programmes. • Absence d’ambiguïtés. • Simplicité : C et Pascal sont simple, C++ et Java? • Modularité : présence d’outils de modularisation et la capacité d’être incorporé dans un environnement de programmation intégré. • Fiabilité : Vérification des types, traitement des exceptions et erreurs, l’absence d’ambiguïtés (et en générale la lisibilité et l’aptitude à l’écriture). • Coût associées à l’utilisation du langage : – Temps nécessaire au développement (facilité de programmation, disponibilité de code, de librairies et de documentation). – Facilité d’implémentation. – Portabilité et standardisation. 53

Implémentation de langage de programmation Processeur de langage : Dispositif (logiciel ou matériel (hardware))

Implémentation de langage de programmation Processeur de langage : Dispositif (logiciel ou matériel (hardware)) capable d’exécuter des instructions du langage. La traduction est le processus qui transforme un programme d’un langage à un autre, tout en préservant son sens et sa fonctionnalité. Le langage cible peut être directement exécutable sur l’ordinateur, ou (plus souvent) devra à nouveau être traduit en un langage de niveau inférieur. Machine virtuelle : c’est une réalisation logicielle (simulation) d’un processeur de langage. Il est difficile de programmer directement pour le hardware—le hardware est donc généralement « enveloppé » de plusieurs couches logicielles. Une couche peut être partagé par plusieurs processeurs de langage, chacun ayant sa propre machine virtuelle au dessus de cette couche. 54

Modèles d’implémentation Compilation : Un compilateur a pour rôle de transformer tout programme écrit

Modèles d’implémentation Compilation : Un compilateur a pour rôle de transformer tout programme écrit dans un langage source en un programme réellement exécuté par la machine. Le code résultant sera exécuté plus tard. Interprétation : Divise le programme en petit fragments (représentant des éléments de syntaxe). Une boucle traduit et exécute immédiatement les fragments. • On désigne un processeur de langage comme interpréteur s’il ressemble plus à un interpréteur, et comme compilateur, s’il ressemble plus à un compilateur. • L’implémentation des langages de programmation utilise souvent un mélange des deux (ex. Java est compilé en « bytecode » , puis celui-ci est interprété). 55

Les compilateurs Phases d’un compilateur : La compilation d'un programme passe par plusieurs phases

Les compilateurs Phases d’un compilateur : La compilation d'un programme passe par plusieurs phases : – Analyse lexicale – Analyse syntaxique – Analyse sémantique – Interprétation ou génération de code – Lorsqu'on passe par la phase de génération de code on parle de compilateur. – Lorsqu'on passe par la phase d'interprétation on parle d'interpréteur. 56

Analyse lexicale : Analyse microscopique des éléments formant un programme. Ces éléments, appelés unité

Analyse lexicale : Analyse microscopique des éléments formant un programme. Ces éléments, appelés unité lexicales, sont les mots réservés du langage, les identificateurs utilisateurs, les caractères spéciaux, les constantes, etc. Un analyseur lexical élimine tout ce qui n'est pas utile pour la phase suivante qui est l'analyse syntaxique. Il ignore ainsi les commentaires et les blancs. Analyse syntaxique : Analyse macroscopique. Derrière tout langage de programmation il y a une grammaire formée de l'ensemble des règles utilisées pour l’écriture des programmes. 57

Analyse sémantique : Donne un sens aux différentes instructions du programme. Facilite l’étape de

Analyse sémantique : Donne un sens aux différentes instructions du programme. Facilite l’étape de génération de code ou d'interprétation. Forme interne = Découpage du programme en un ensemble d'opérations élémentaires directement interprétées dans un autre langage de programmation ou traduites en code objet. Génération de code : Consiste à associer à chaque élément de la forme interne l’équivalent en code objet. Interprétation : Consiste à associer à chaque élément de la forme interne l’équivalent dans le langage d'interprétation. 58

Compilation et exécution Programme source Compilateur Analyse lexicale (scaning) Séquence d’unités lexicales Table de

Compilation et exécution Programme source Compilateur Analyse lexicale (scaning) Séquence d’unités lexicales Table de symboles Optimisation du code Programme abstrait (code intermédiaire) Analyse syntaxique (parsing) Arbre syntaxique Analyse sémantique Programme abstrait (optimisé) Génération du code Code exécutable (object code) Chargeur/Éditeur de liens (Loader/Linker) Programme résultant Données d’entré Ordinateur Données de sortie 59

Etapes d'exécution d’un langage compilé : cas C Fichier de code Compilation Librairies Code

Etapes d'exécution d’un langage compilé : cas C Fichier de code Compilation Librairies Code objet Edition de liens Programme exécutable Autres code objet Fichier d'entête 60

Compilateur/interpréteur • Compilateur: traduire le programme entier une fois pour toutes exemple. c fichier

Compilateur/interpréteur • Compilateur: traduire le programme entier une fois pour toutes exemple. c fichier source Compilateur exemple exécution fichier exécutable – + plus rapide à l’exécution – + sécurité du code source – - il faut recompiler à chaque modification • Interpréteur: traduire au fur et à mesure les instructions du programme à chaque exécution exemple. bas fichier source Interprétation+exécution – + exécution instantanée appréciable pour les débutants – - exécution lente par rapport à la compilation 61