MethodeAnalyse2.ppt

Download Report

Transcript MethodeAnalyse2.ppt

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 (condition)
instruction
else
instruction
facultatif
test_1
test_1_vrai
test_2
test_2_vrai
test_vrai
test_faux
test_3_faux
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 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 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 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 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, 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
– Entrée: Suite de n éléments a1,…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 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.
afficherNbsParfaits
saisirBorneMax
entier
entier
entier
estParfait
sommeDesDiviseurs
booléen
entier
10
entiers
estUnDiviseur
booléen
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.
• 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 définir en fonction
de lui-même.
• Récursion en programmation: quand une méthode s’appelle elle-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 :
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 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)
Retourne: 3.factoriel(2)
Si n = 0 alors
factoriel(2)
Retourne (1)
Retourne (n.factoriel(n-1))
Fin factoriel
Retourne: 2.factoriel(1)
factoriel(1)
Retourne: 1.factoriel(0)
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 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 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(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)
f1 = 1
Procédure Pas (n)
f2 = 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
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 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 x1,x2...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 = 2k.
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 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
A
B
C
A
B
C
24
•
•
•
•
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 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 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 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 consiste en un entête de
fonction.
entête
• La définition du code de la fonction c’est son implémentation
Type_retour NomFonction (liste formelle de paramètres);
{
\*définitions locales + traitement *\
} \\ nom de la fonction
Variable = NomFonction(Var1,Var2);
• 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 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 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 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
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
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 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 ?”
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 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 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.
Indices
0
tableau
0
1
2
2
3
4
6
9
Tableau de 10 éléments
38
Copie de tableaux de nombres ou partage
Copie d’un tableau = copie des éléments un à un (la destination doit être créée)
0
T1
1
1
3
2
3
5
7
2
3
5
7
9
T2
0
T3
1
1
3
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 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 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
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 );
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 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 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
TreeNode_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 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
OS
Langage machine
Dispositifs
physiques
Interpréteurs
48
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 (J2EE, .NET)
49
Historique des Langages de programmation
1954 FORTRAN (John Backus)
1959 LISP (McCarthy)
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 (ObjC) (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), JavaScript
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 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 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
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))
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 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 :
– 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é 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 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 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
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 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