algorithmique et programmation - cours en ligne de … · 2 mic 2 informatique : algorithmique et...
Post on 14-Sep-2018
227 Views
Preview:
TRANSCRIPT
2
MIC
1
Algorithmique et Programmation
Support de Cours MIC2
Année 2016-2017 esquirol@insa-toulouse.fr
2
MIC
2
Informatique :Algorithmique et Programmation
Groupes A&B&C : Patrick Esquirol, DGEI colette.merce@insa-toulouse.fr
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Ce que vous savez faire (1/2)
� Sur le plan algorithmique� Utiliser à bon escient les structures de contrôle
� Séquence
� Répétitions (boucles) � Structure « for … loop … end loop»
� Structure « while … loop … end loop»
� Structures de choix� Alternative : « if … then … else …end if »
� Choix multiple : « case … when … end case »
� Ecrire des algorithmes « classiques »� Parcourir(pour Affecter/Afficher) un tableau
� Chercher la valeur min[max] du tableau (indiquer la 1ere place qui le contient)
� Ecrire des sous-programmes déjà spécifiés� La fonctionnalité du sous-programme est définie
� Les paramètres du sous-programme sont fixés
3G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Ce que vous savez faire (2/2 )
� Sur le plan des structures de données� Utiliser des types simples� Utiliser des types composés
� Tableaux (array)
� Articles (record)
� Naviguer dans des structures composées� Tableaux d’articles, Articles contenant des tableaux,
� Matrices
� Tableaux de tableaux
� …
� Sur le plan de la mise au point de programmes (en T P)� Utiliser l’environnement de programmation (Linux, Emacs, Gnat)� Mettre en œuvre une méthodologie de développement progressive
� écriture d’un sous-programme + sous-programmes de test
4G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Objectifs du module (1/2)
� Sur le plan algorithmique, vous serez capable de :
� Concevoir et formaliser des algorithmes complexes selon la méthode de l’analyse descendante
� Maîtriser la spécification et le développement de sous-programmes� Ecrire des algorithmes « classiques »
� Recherche du min (ou du max) dans un tableau ou une liste
� Recherche d’une valeur dans un tableau ou une liste
� Tri croissant ou décroissant d’un tableau (différents algorithmes)
� Mettre en œuvre une analyse récursive et concevoir des sous-programmes récursifs
� Travailler sur des structures de données dynamiques (listes basées sur des pointeurs)
� Insérer[Supprimer] un élément en tête[fin] de liste
5G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Objectifs du module (2/2)
� Sur le plan des structures de données, vous serez ca pable de :
� Maîtriser la déclaration et l’utilisation de tableaux notamment leur dimensionnement
� Définir des structures de données dynamiques en utilisant des pointeurs
� Choisir et concevoir les structures de données les mieux adaptées à un problème donné (suite au module du semestre 2)
� Sur le plan du développement de programmes en TP, v ous serez capable de :
� Mettre au point progressivement un programme répondant à un cahier des charges (analyse, conception, codage et tests)
� Réaliser les tests unitaires et fonctionnels
� Intégrer des données dans un programme à partir de saisies ou de fichiers textes.
� Travailler en autonomie et développer le programme complet
6G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
7
Organisation et plan du cours
� Organisation� Cours : 5 séances de 1h15� TD : 10 séances de 1h15� TP : 5 séances de 2h45 (en binôme ou monôme)
� Contrôles : 1 évaluation individuelle� 1 Contrôle sur machine (sans documents)
� Plan du cours (prévisionnel)� Cours 1 Analyse descendante et rappels sur les sous-programmes� Cours 2 Tableaux et problèmes de dimensionnement� Cours 3 Récursivité� Cours 4 Pointeurs � Cours 5 Pointeurs et Conclusion
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
8
Bibliographie et logiciels
� Bibliographie� « Programmation Séquentielle avec Ada95 »
P. Breguet – L. Zaffalon
Presses Polytechniques et Universitaires Romandes
� « Programmer avec Ada95 »J. Barnes, Adison Wesley
� Pour faire de l’ADA � Compilateur gratuit et IDE
� Windows : Gnat et Adagide/Emacs
� Linux : Gnat et Emacs
� Mac : http://www.macada.org/
� Manuel officiel� Ada95 Reference Manual
� http://www.adahome.com/rm95/
� Sites internet : www.adapower.com/ www.ada-france.org/
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
9
Forme générale d’un programme avec S/P
-- Entête du programmeWITH ... ; USE ……. ;PROCEDURE Nom_Programme IS
-- Déclarations des constantes, types et sous-types…….
-- Spécifications et corps des S.-P.…….…….
-- Déclarations des variables du programme principal…….
BEGIN-- Instructions (dont appels aux S.-P.)…….
END Nom_Programme ;G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
11
Chap 1 – SP - Pourquoi faire des S/P?
� Améliorer � La lisibilité des programmes réalisés
� Programmes moins longs et plus clairs (1 page chacun au plus)
� La fiabilité et la maintenance des programmes� 1 fois le S.-P. écrit et testé, plus besoin d’y revenir
� Développer plus rapidement
� Réutiliser les S.-P. existants� Trouvés sur Internet, déjà développés au sein de l’entreprise,…
� Partager le développement entre équipes� Chaque équipe a en charge un ou plusieurs S.-P.
� Attention à la conception
� Comment décomposer en sous-programmes ?
� Quels paramètres ?
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
12
Chap. 1 : SP - Concepts de base
� Deux catégories de sous-programmes� Fonction
� Retourne 1 résultat unique
� Appel de fonction ≈ Expression
� Procédure� Effectue une action qui peut générer 0, 1 ou plusieurs résultats
� Appel de procédure ≈ Instruction
� Concepts de base
� Déclaration d’un S.-P. / Appel d’un S.-P.
� Echanges d’informations entre S.-P. et programme appelant� Paramètres formels / Arguments d’appel
� Portée des variables� Variables locales / variables globales
� Imbrication de sous-programmes
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
13
Chap. 1 : SP - Déclaration et appel d’une fonction
� Déclaration d’une fonction
� Appels de fonction, exemples :
function Nom_de_Fonction ( Parametres_Formels ) return Type_Resultat is
-- Déclaration de constantes, types, ss-types et variables locales
begin-- instructions….
return Expression ; -- de type Type_Resultatend Nom_de_Fonction;
Variable := Nom_de_Fonction ( Parametres_D_Appel ) ;
Put ( Nom_De_Fonction ( Parametres_D_Appel ) ) ;
if Nom_de_Fonction ( Parametres_D_Appel ) then
Ne pas oublier
Ou rien !
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
14
Chap. 1 : SP - Exemple d’une fonction Calculer_Somm e
Corps du sous-programme-- calcule la somme des valeurs rangées dans un tableau
function Calculer_Somme (T : in Tab_Entier) return Integer is
S : Integer; -- variable locale résultat
begin
S := 0;
for I in T’range loop
S := S + T(I) ;
end loop ;
return S;
end Calculer_Somme;
---------------------------------------------------------------------
Appel du sous-programme
….Resu := Calculer_Somme( Mon_Tableau );
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
15
Chap. 1 : SP - Exemple de déclaration d’une procédur e
� Spécification d’un sous-programme de facturation � Ecrire un sous-programme qui à partir
� Du prix unitaire d’un article
� Du nombre d’articles achetés
� Du taux de TVA appliqué
� Retourne� Le prix HT et le prix TTC
procedure Facture(PU : in float; N : in natural; TVA : in Float ;
PHT : out Float ; PTTC : out Float ) isbegin
PHT := PU*Float(N) ;
PTTC := PHT + PHT*TVA ;
end Facture ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
16
Chap. 1 : SP - Exemples d’appel de la procédure
PROCEDURE Toto IS
-- Declaration du sous-programme
procedure Facture(Pu : in float; N : in natural; TVA : in Float ; Pht , Pttc : out Float) is
…begin
…end Facture ;
-------------------------------------------------------------------------- Declarations des variables du programme principal (juste avant le begin)P1 : Float := 23.45 ;Montant_HT, Montant_TTC, X, Y : Float ;
begin…. --Pu N TVA Pht PttcFacture (P1 , 100 , 0.20, Montant_HT , Montant_TTC ) ;Facture ( 99.9 , 50 , 0.5, X, Y );….
end Toto ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
17
Chap. 1 : SP – Décl. et appel d’une procédure : form e générale
� Déclaration d’une procédure
� Appel de la procédure ( ≈ instruction)
procedure Nom_de_procedure ( Parametres_Formels ) is
-- Partie déclarative
begin
-- instructions….
end Nom_de_procedure;
Nom_de_procedure ( Parametres_D_Appel ) ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
18
Chap. 1 : SP - Paramètres formels et paramètres d’ap pel
� Paramètres formels
� Matérialisent les échanges d’information entre S.-P. et programme d’appel
� Permettent de décrire le traitement effectué par le S.-P.
� Paramètres d’appel (valeurs ou variables figurant d ans l’appel)
� Valeurs ou variables échangées au moment de l’appel
� Sens des échanges (modes de passage) (page 29)
� in : valeur reçue par le S.-P. Le paramètre se comporte comme une constante dans le S.-P. (il ne peut pas modifier sa valeur)
� out : valeur uniquement fixée par le S.-P. Le paramètre se comporte comme une variable affectée par le S.-P. La valeur précédant l’appel du S.-P. est inutilisée et de toutes façons écrasée par la valeur fixée par le S.-P.
� in out : valeur modifiée par le S.-P. Le paramètre se comporte comme une variable dont la valeur est transmise au S.-P. puis modifiée par lui.
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
19
Chap. 1 : SP – Exemples de spécification de SP
� Si le mode de passage n’est pas spécifié � c’est le mode IN par défaut
� Si le S.-P. est une fonction, TOUS les paramètres formels sont
� Obligatoirement en mode IN
� Exemples : donner la spécifications d’un sous-progr amme qui
� affiche à l’écran le contenu d’une variable de type Tab
� fait le tri d’un tableau de type Tab
� permute les valeurs contenues dans 2 variables entières
� lit des valeurs fournies au clavier et les range dans un tableau
� Calcule le produit scalaire de 2 vecteurs
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 1 : SP - Portée d’un objet ( variable ou sous- programme)
� Définition� Portée d’un objet dans un programme = zone du programme dans laquelle
l’objet est vu (et donc utilisable)� La portée d’un objet
� Commence à la déclaration de cet objet� Se termine au « end » du bloc dans lequel l’objet est déclaré
� Exemple
20
procedure Mon_Prog is
A , X : Integer ;
procedure Toto is
I, X : Float ;begin
end Toto;
begin
end Mon_Prog ;
Portée de I et X (2)
Portée de A et X (1)
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 1 : SP - Effet de bord (exemple) 1/2
21
procedure Exemple isA, B : Integer ;
------------------------------------------------procedure Permuter(X, Y : in out Integer ) is
Aux : Integer;begin
Aux := X; X := Y; Y := Aux;
end Permuter ; ----------------------------------------------------begin
A:=10 ; B :=20 ;Permuter (A, B) ; put (« A = ") ; put (A) ; put (« B = ") ; put (B) ;
end Exemple ;
procedure Exemple isA, B : Integer ;
------------------------------------------------procedure Permuter is
Aux : Integer;begin
Aux := A; A := B; B := Aux;
end Permuter ; ------------------------------------------------begin
A:=10 ; B :=20 ;Permuter ; put (« A = ") ; put (A) ; put (« B = ") ; put (B) ;
end Exemple ;
Effets de bord
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 1 : SP - Effet de bord (exemple) 2/2
22
procedure Exemple is
procedure Permuter(X, Y : in out Integer ) isAux : Integer;
beginAux := X; X := Y; Y := Aux;
end Permuter ; ---------------------------------
A, B : Integer ;
beginA:=10 ; B :=20 ;Permuter (A, B) ;
put (A) ; put (B) ; end Exemple ;
procedure Exemple is
procedure Permuter isAux : Integer;
beginAux := A; A := B; B := Aux;
end Permuter ; ------------------------
A, B : Integer ;
beginA:=10 ; B :=20 ;Permuter ; put (A) ; put (B) ;
end Exemple ;
INCORRECT
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
23
Chap. 1 : SP - Emboîtement de S/P
G.AURIOL, C. MERCE, P. ESQUIROL
Variables et S.-P. visibles
procedure PRINCIPALE isToto : Integer ; procedure SP1(Params1 ….) is
Toto1 : Integer ;begin --SP1
-- Instructionsend SP1 ;procedure SP2(Params2 ….) is
Toto2 : integer;procedure SP2_1(Params21) is
Toto21 : Integer ;begin -- SP2_1
-- Instructionsend SP2_1;
begin --SP2-- Instructions
end SP2 ;begin -- PRINCIPALE
-- Instructionsend PRINCIPALE ;
Toto, Params1, Toto1SP1
Toto, Params2, Toto2Params21, Toto21,SP1, SP2_1
Toto, Params2, Toto2 SP1, SP2
Toto,SP1, SP2
2
MIC
G.AURIOL, C. MERCE, P. ESQUIROL
26
Chapitre 2
Analyse descendante et méthodologie de développement d’un programme
2
MIC
Chap. 2 : Méthodologie de développement d’un progra mme
� Analyse et Conception � Analyse et compréhension du cahier des charges
� identifier les données d’entrée du programme, les fonctionnalités à développer et les résultats attendus
� Choix des structures de données adaptées aux besoins� Elaboration de l’algorithme principal
� Décomposition en fonctionnalités
� Implémentation de certaines fonctionnalités par app el à des sous-programmes (abstraction).
� Spécification de ces sous-programmes (? Nom, Paramètres formels ?)
� Identification des jeux de tests afin de valider le bon fonctionnement du programme final lorsqu’il sera terminé
� Elaboration de l’algorithme de chaque sous-programme
� Codage et mise au point� Codage de chaque sous-programme et tests unitaires
� Décomposition en s.-p. (etc)
� Codage de l’algorithme principal et tests fonctionnels
27G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
28
Chap. 2 : Analyse descendante - mise en œuvre sur un exemple
� Cahier
des charges
Mon_Programme
Saisir une nouvelle suitede10 éléments
Calculer la somme des éléments de la suite
Calculer la moyenne des éléments de la suite
Afficher la suite
� Pour une suite donnée, l’utilisateur du programme pourra choisir l’action qu’il souhaite exécuter à partir d’un menu qui s’affichera à l’écran
� Plusieurs suites pourront être traitées séquentiellement
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 2 : Analyse descendante - mise en œuvre sur un exemple
� Phase d’analyse et de conception � Analyse du cahier des charges
� identifier les données d’entrée du programme, les fonctionnalités à développer et les résultats attendus
� Pour cet exemple simple :� Données d’entrée du programme
� 10 valeurs fournies par l’utilisateur (saisies au clavier)
� Résultats attendus (� affichés à l’écran)� La somme des valeurs
� La moyenne des valeurs
� Fonctionnalités � Acquisition et stockage des 10 valeurs fournies dans un tableau
� Calcul de la somme d’un tableau
� Calcul de la moyenne d’un tableau
29G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 2 : Analyse descendante - mise en œuvre sur un exemple
� Analyse et Conception � Analyse du cahier des charges
� identifier les données d’entrée du programme, les fonctionnalités à développer et les résultats attendus
� Choix des structures de données adaptées aux besoins� Elaboration de l’algorithme principal
� Décomposition en fonctionnalités
� Implémentation de ces fonctionnalités par des sous-programmes.
� Spécification de ces sous-programmes
30G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 2 : Analyse descendante - mise en œuvre sur un exemple
Structures de données et variables
Mon_Tableau : tableau de 10 composantes entières
Arret_Demande : booléen
Algorithme
Arret_Demandé false Saisie_Faite false
Tant que Arret_Demandé = false répéter
afficher le menu des actions possibles
lire (saisir) l’action souhaitée par l’utilisateur
en fonction de l’action souhaitée
lire (saisir) une suite des 10 valeurs fournies par l’utilisateur
Saisie_Faite true
afficher la suite à l’écran (si Saisie_Faite)
afficher la somme des valeurs (si Saisie_Faite)
afficher la moyenne des valeurs (si Saisie_Faite)
arrêter le programme :
Fin tant que
31
Arret_Demandé true
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 2 : Analyse descendante - mise en œuvre sur un exemple
Structures de données et variables
Mon_Tableau : tableau de 10 composantes
Arret_Demande : booleen
Algo
Arret_demandé false
Tant que Arret_Demandé = false répéter
afficher le menu
lire (saisir) l’action souhaitée par l’utilisateur
en fonction de l’action souhaitée
saisir et enregistrer la suite de valeurs
Saisie_Faite true
afficher la suite à l’écran
afficher (la somme des valeurs)
afficher (la moyenne des valeurs)
Arret_Demandé true
Fin tant que
32
� Appel à un sous-programme Afficher_menu
� Appel à un s-p Afficher_Suite
� Appel à un s-p Calculer_Somme
� Appel à un s-p Calculer_Moyenne
� Appel à un s-p Saisir_Suite
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
33
Chap. 2 : Spécification des sous-programmes
� Spécifier un sous-programme c’est définir
� Le Nom et l’objectif du sous-programme
� Les informations qu’il va utiliser (paramètres en entrée)
� Les informations qu’il va générer (paramètres en sortie)
� Les informations qu’il va modifier (paramètres en entrée-sortie)
� Bonnes pratiques
� Un seul traitement par sous-programme
� Ne pas mélanger entrées/sorties (interface utilisateur) et traitement
� Choisir des noms de sous-programmes représentatifs
� Écrire le corps du sous-programme revient à écrire l’algorithme correspondant au traitement que doit faire le sous- programme
� Si l’algorithme est complexe, on applique à nouveau une analyse descendante
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 2 : Spécification des sous-programmes de l’ex emple
� Afficher_Menu� Objectif : afficher les différentes actions offertes à l’utilisateur� Données d’entrée : aucune� Résultats générés : aucun
� Saisir_Suite� Objectif : saisir un tableau de valeurs � Données d’entrée : aucune (les donnée sont fournies par l’utilisateur via le
clavier) � Résultats générés : le tableau de valeurs
� Calculer_Somme� Objectif : calculer la somme des éléments d’‘un tableau� Données d’entrée : le tableau de valeurs� Résultats générés : la somme
� Remarque : � Algorithmes associés très simples � pas de décomposition supplémentaire
34G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 2 : Analyse descendante - mise en œuvre sur un exemple
� Phase d’analyse
� Globalement indépendante du langage support
� Codage et tests
� Développer PROGRESSIVEMENT chaque sous-programme
� Ecrire pour chaque sous-programme développé un sous-programme de test qui
� Définit et initialise les variables qui servent au test
� Affiche le résultat attendu pour ces valeurs
� Appelle le sous-programme
� Affiche les valeurs obtenues
35G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
G.AURIOL, C. MERCE, P. ESQUIROL
38
Chapitre 3
Types Tableaux Non Contraints Algorithme de recherche dans un tableau
2
MIC
Chap. 3 - Type tableau contraint ou non contraint
� Un tableau permet de regrouper des éléments de même nature
� Pour déclarer un type tableau, on précise� Le type de l’indice qui permet de le parcourir (plusieurs dim. possibles)� Le type des éléments contenus dans le tableau (les composantes)
� 2 possibilités pour déclarer un type tableau� Déclaration d’un type contraint
� �on fixe définitivement la taille de ce type de tableaux
� Déclaration d’un type non contraint � �on ne fixe pas une taille unique à la déclaration du type. Des tableaux
distincts pourront avec des tailles différentes
39
type Nom_Du_Type is array (type_de_l’indice ) of type_des_composantes ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
40
Chap. 3 - Type tableau contraint
� Déclaration : Le nombre de composantes est fixé à l a déclaration du type
� Déclaration des variables
� Bien adapté lorsque toutes les variables de type tableau ont toujours le même dimensionnement et la dimension est connue avant l’ exécution du programme
� Lourdeur si ce n’est pas le cas
type Un_Tab_contraint is array (Integer range 1..20) of Float ;
type Un_Autre_Tab_Contraint is array (Character range ‘A’..’Z’) of Float ;
A, B : Un_Tab_contraint ; -- A et B de même taille : 20 float chacun
X,Y : Un_Autre_Tab_Contraint ; -- X et Y de même taille : 26 character chacun
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
41
Chap. 3 - Type tableau non contraint (NC)
� Déclaration du type
� Exemples
� Caractéristiques importantes
� Les paramètres formels d’un ss-programme peuvent être non contraints� Comment écrire ce sous-programme ?
� Une variable d’un type tableau doit être dimensionnée lors de sa déclaration
� pb du dimensionnement
type identificateur_du_type is array (type_indice range <>) of type_composantes ;
type Un_Vecteur is array (Integer range <>) of Integer ;type Un_Tab is array (Character range <>) of Float ;
Vec1 : Un_Vecteur(0..9); Vec2 : Un_Vecteur(1..1000);
Tab1 : Un_Tab(‘a’ ..’z’); Tab2 : Un_Tab(‘A’..’E’);
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 3 – Sous-programmes et types tab non contraint (1/2)
42
procedure Exemple is
type Un_Vecteur is array (Integer range <>) of Integer ;
function Indice_Du_Min (De : in Un_Vecteur ) return Integer is-- retourne l’indice du min du vecteur De
begin…
end Indice_Du_Min ;
X : Un_Vecteur ( 1..10) ;Y : Un_Vecteur ( 0..100) ;
begin --Exemple-- Saisie de X et de Y
…-- afficher l’indice du min de X ?
Put(Indice_Du_Min(X)) ;
-- afficher l’indice du min de Y ?Put(Indice_Du_Min(Y)) ;
-- afficher l’indice du min dans la portion (tranche) 20..50 de YPut(Indice_Du_Min(Y(20..50))) ;
end Exemple ;
Exemple : SP qui retourne l’indice de la valeur minimum d’un tableau de type non contraint
1- spécification du SP et exemples d’appel
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 3 – Sous-programmes et types tab non contraint (2/2)
43
procedure Exemple istype Un_Vecteur is array (Integer range <>) of Integer ;
function Indice_Du_Min (De : in Un_ Vecteur ) return Integer is-- retourne l’indice du min du vecteur De
…..
end Indice_Du_Min ;X : Un_Vecteur (1..10) ;Y : Un_Vecteur (0..100) ;
begin…
end Exemple ;
Exemple : SP qui retourne l’indice de la valeur minimum d’un tableau de type non contraint
1- spécification du SP et exemples d’appel
2- écriture du SP
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap3 - Problème du dimensionnement d’une variable t ableau (1/5)
� Différentes situations� On connait la dimension du tableau lorsqu’on écrit le programme
� pas de problème
� On ne connait pas la dimension du tableau lorsqu’on écrit le programme� on ne peut déclarer la variable de type tableau
il faut d’abord déterminer la dimension de ce tableau
44
procedure Exemple istype Un_Vecteur is array (Integer range <>) of Integer ;…
X : Un_Vecteur (1..10) ;Y : Un_Vecteur (0..100) ;
begin…
end Exemple ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap3 - Problème du dimensionnement d’une variable t ableau (2/5)
45
procedure Exemple istype Un_Vecteur is array (Integer range <>) of Integer ;
procedure Saisir (T : out Un_Vecteur) is
…end Saisir ;function Indice_Du_Min (De : in Un_Vecteur ) return Integer is
…end Indice_Du_Min ;Dim : Integer ;Mon_Tab : Un_Vecteur (1..Dim ) ;
beginput (« entrez la dimension »);Get (Dim ) ;
…Saisir(Mon_Tab) ;
…put(Indice_Du_Min(Mon_Tab));
…end Exemple ;
valeur ???
1ère tentative :
La dimension du tableau est fournie par l’utilisateur en début d’exécution
=> échec
G.AURIOL, C. MERCE, P. ESQUIROL
C’est trop tard ! Mon_Tab a été créé avec une taille indéterminée …
2
MIC
Chap3 - Problème du dimensionnement d’une variable t ableau (3/5)
46
procedure Exemple istype Un_Vecteur is array (Integer range <>) of Integer ;
procedure Saisir (T : out Un_Vecteur) is
…end Saisir ;function Indice_Du_Min (De : in Un_Vecteur ) return Integer is
…end Indice_Du_Min ;Dim : Integer;
beginput (« entrez la dimension »);Get (Dim);declare
Mon_Tab : Un_Vecteur(1..Dim ); begin
Saisir(Mon_Tab) ;…
put(Indice_Du_Min(Mon_Tab));…
end ;end Exemple ;
2ème tentative :
La dimension est fixée avant la déclaration
� Utiliser un bloc declare
…� begin
…� end;
=> Ok
G.AURIOL, C. MERCE, P. ESQUIROL
Mon_Tab est déclaré APRES
On fixe d’abord Dim
2
MIC
Chap3 - Problème du dimensionnement d’une variable t ableau (4/5)
47
procedure Exemple istype Un_Vecteur is array (Integer range <>) of Integer ;
procedure Saisir (T : out Un_Vecteur) is
end Saisir ;function Indice_Du_Min (De : in Un_Vecteur ) return Integer isend Indice_Du_Min ;
function Donne_La_Dimension return Integer isD: integer;
beginput (« entrez la dimension »);Get(D);
return D;end Donne_La_Dimension ;
Mon_Tab : Un_Vecteur (1.. Donne_La_Dimension ) ;
beginSaisir(Mon_Tab) ;
…put(Indice_Du_Min(Mon_Tab));
…end Exemple ;
3ème tentative :
La dimension est fixée par une fonction
� Avantage : ne nécessite pas le bloc
declare…begin…end;
=> Ok
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap3 - Problème du dimensionnement d’une variable t ableau (5/5)
48
procedure Exemple istype Un_Vecteur is array (Integer range <>) of Integer ;
function Donne_La_Dimension return Integer is…
end Donne_La_Dimension ;
function Saisir return Un_Vecteur is-- retourne un vecteur dont la dimension et -- les valeurs sont saisies au clavier
V : Un_Vecteur (1..Donne_La_Dimension );begin
put("Saisir " & integer’image(V’last) & " entiers : " );for I in V’range loop
get(V(I));end loop;
return V;end Saisir ;MonTab : Un_vecteur := Saisir ;
begin… put(Indice_Du_Min(Mon_Tab));…
end Exemple;
4ème tentative :
La dimension ET le tableau sont fixés par des fonctions
=> Ok
G.AURIOL, C. MERCE, P. ESQUIROL
Mon_Tab est dimensionné par l’affectation du tableau retourné par Saisir
2
MIC
49
Chap. 3 : À retenir (1/2)
� Souplesse des types « tableau non contraint »� Algorithmes généraux basés sur les attributs ‘first, ‘last, ‘range, ‘length� Possibilité de manipuler des « tranches de tableaux »
� Intérêt à utiliser des paramètres formels de S/P d’ un type tableau non contraint � Intérêt : réutilisabilité (s’adapte) à des tableaux de toute dimension
=> généralisation de l’algorithme
� Attention, les variables (en particulier les paramè tres d’appel du S/P) sont obligatoirement contraintes lors de leur déclaratio n.
procedure Exemple istype Un_Vecteur is array (Integer range <>) of Integer ;
X : Un_Vecteur (1..10) ;Y : Un_Vecteur (0..100) ;
beginY( 50..55 ) := X( 3..8) ; -- 6 éléments copiésif X (1..4) < Y (5..8) then … -- 4 éléments comparés…
end Exemple ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
50
Chap. 3 - À retenir (2/2)
� Toute variable doit être contrainte lors de sa décl aration
� Plusieurs solutions pour « contraindre » une variable de type tableau n on contraint
� Technique 1 : Utiliser un bloc DECLARE dans le programme principal pour déclarer la variable après avoir déterminé sa dimension.
� Technique 2 : Utiliser une fonction de dimensionnement au moment de la déclaration, ex : Var : Un_Vecteur(1 .. Donner_Dimension);
� Technique 3 : Utiliser une déclaration+affectation à l’aide d’une fonctiond’initialisation, du type Var : Un_Vecteur := Saisir; La fonction d’initialisation peut elle-même utiliser une fonction de dimensionnement
� Un Type prédéfini non contraint important : le type STRING
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
51
Chap. 3 - Type prédéfini String ( chaîne de caractèr es)
� Déclarations� Le type String est un type non contraint prédéfini (connu du langage)
� Littéraux (valeurs de) chaînes de caractères �
� Déclarations de variables (il faut TOUJOURS que la dimension soit connue !)
"c'est une chaine" -- C'est une valeur de type string"s" -- C'est aussi une valeur de type string
type String is array ( Positive range <> ) of Character ;
Ch : String (1 .. 4) ;
Mess : String (1 .. 7) := "bonjour ";Texte1 : String := " ça va ?" ;Texte2 : String := Mess & Texte1;Faux : String ; -- erreur !!
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
52
Chap. 3 - Type prédéfini String ( chaîne de caractèr es)
� Opérations sur les String
(identiques à celles disponibles sur des tableaux à 1 dimension)� Attributs
� first , last , length , range
� Image , value
� AffectationRemarque : même longueur de part et d'autre de l'affectation
Integer'Image(123) = " 123"Integer'Value(" -123") = -123
type Couleur is (rouge, jaune, vert, bleu);Couleur'Image(rouge) = " ROUGE"
Ch : String (1 .. 5) ;Mess : String (1 .. 7) := "bonjour";
beginCh := "salut" ;Mess := "salut--" ;Ch := Mess(1.. 4) ; --erreur !!
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
53
Chap. 3 - Type prédéfini String (chaîne de caractère s)
� Opérations sur les String � Égalité
� Il faut des chaînes de même longueur de part et d’autre de l’égalité
� Ordre lexicographique� Chaînes quelconques
� Concaténation
"ABC" > "AB" ;"ABC" < "CD" ;
Mess : String (1 .. 7) := ("bonjour") ;Texte : String := (" ca va?") ;
beginPut_Line (Mess & Texte);Put_Line (Mess & '!');Put_line('A '& 'B');
end Exemple;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
54
Chap. 3 – Le paquetage Ada.Text_IO
procedure Put(Item : in Character); -- affichage d’un caractèreprocedure Put(Item : in String); -- affichage d’un stringprocedure Put_Line(Item : in String) ; -- affichage puis retour-ligne
procedure New_Line(spacing : in positive_count := 1) ;-- spacing retours-ligne (par défaut : 1)
procedure Get(Item : out Character) ; -- lecture d’un caractèreprocedure Get(Item : out String) ; -- lecture d’un string -- il faut fournir autant de caractères que la longueur de Itemprocedure Get_Line(Item : out String ; Last : out Natural) ;-- lit les caractères fournis jusqu'à ce qu’une fin de ligne soit rencontrée-- ou que la longueur de Item soit atteinte.-- Last donne l'indice dans la chaîne du dernier caractère lu
procedure Skip_Line; -- « saute » tous les caractères jusqu’au retour-ligneG.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 3 - Algorithmique : recherche d’une valeur dan s un tableau
� Problème : � On souhaite écrire un sous-programme qui détermine si une valeur donnée
figure dans un tableau. � Si oui, on veut connaitre l’indice de la première occurrence de cette valeur
dans le tableau.� Spécification du sous-programme
� Données en entrée� La valeur cherchée
� Le tableau de valeurs
� Résultats en sortie� Un booléen qui indique si la valeur a été trouvée
� L’indice de la 1ère occurrence de la valeur cherchée
55G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 3 - Recherche d’une valeur dans un tableau -1 ere version
56
type Un_Vecteur is array (Integer range <>) of Integer ;
procedure Chercher ( Val : in Integer ; Vec : in Un_Vecteur;Trouve : out Boolean ; Pos : out Integer ) is
-- cherche Val dans le tableau Vec-- Trouve est True si Val appartient à Vec ; Pos est l’indice de Val dans Vec
beginTrouve := FALSE;for I in Vec’range loop
if Vec(I) = Val thenTrouve := TRUE;Pos := I;
end if;end loop;
end Chercher;
Commentaires: cet algorithme fournit en réalité l’i ndice de la dernière occurrence de Val car le parcours de Vec continue même après avoir trouvé la valeur.
G.AURIOL, C. MERCE, P. ESQUIROL
Algorithme incorrect !!
2
MIC
Chap. 3 - Recherche d’une valeur dans un tableau - 2 ème version
57
type Un_Vecteur is array (Integer range <>) of Integer ;
procedure Chercher ( Val : in Integer ; Vec : in Un_Vecteur;Trouve : out Boolean ; Pos : out Integer ) is
-- cherche Val dans le tableau Vec; -- Trouve est True si Val appartient à Vec ; Pos est l’indice de Val dans Vec
beginI := Vec’first ;while Vec(I) /= Val loop
I := I+1 ;end loop;...
end Chercher;
Que se passe t-il si Val ne se trouve pas dans le vecteur Vec??
Algorithme incorrect !!
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 3 - Recherche d’une valeur dans un tableau - 3 ème version
58
type Un_Vecteur is array (Integer range <>) of Integer ;
procedure Chercher ( Val : in Integer ; Vec : in Un_Vecteur;Trouve : out Boolean ; Pos : out Integer ) is
-- cherche Val dans le tableau Dans ; -- Trouve est True si Val appartient à Vec ; Pos est l’indice de Val dans Vec
beginI := Vec’first ;while I <= Vec’last and then Vec(I) /= Val loop
I := I+1 ;end loop ;if I > Vec’last then
Trouve := False ; else
Trouve := True; Pos := I;end if ;
end Chercher;
Algorithme correct … maisspécifique à ADA !!
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 3 - Recherche d’une valeur dans un tableau - 4 ème version
59
type Un_Vecteur is array (Integer range <>) of Integer ;
procedure Chercher ( Val : in Integer ; Vec : in Un_Vecteur;Trouve : out Boolean ; Pos : out Integer ) is
-- cherche Val dans le tableau Vec ; -- Trouve est True si Val appartient à Vec ; Pos est l’indice de Val dans Vec
beginI := Vec’first ; Trouve := false ;while I <= Vec’last and not trouve loop
if Vec(I) = Val thenTrouve := True;Pos := I ;
elseI := I+1;
end if ;end loop ;
end Chercher ;
AlgorithmeA RETENIR !
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
63
Chap. 4 : Récursivité - Introduction
� Définition récursive� "Un sous-programme récursif est un sous-programme récursif"
� Définition plus sérieuse� Un sous-programme est dit récursif lorsqu'il fait appel à lui-même
� Vous connaissez déjà!
Exemple en math : calcul de factorielle n� Définition de n! : n! = n × (n-1)!
0! = 1� Exemple 4! = 4 × 3!
3! = 3 × 2!
2! = 2 × 1!
1! = 1 × 0!
0! = 1
Cas trivial
La dimension change
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
64
Chap. 4 : Récursivité - 1 er exemple
� Écriture récursive de factorielle
procedure Test_Facto is
function Facto (N: in Natural) return Positive is…end Facto ;
Nb : natural; -- nombre lu
beginput ("entrer un nombre positif ou nul");get ( Nb ); put ( Nb ); put( " ! = " ); put (Facto(Nb) );
end Test_Facto;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
65
Chap. 4 : Récursivité - 1 er exemple
� Écriture récursive de factorielle
function Facto (n: in Natural) return Positive isResu : Positive ;
begin
return Resu;end Facto;
-- 0! = 1
-- n! = n×(n-1)!
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
66
Chap. 4 : Récursivité - Principe d’un fonctionnemen t récursif
� Un sous-programme récursif a le même fonctionnement qu’un sous-programme non récursif.
� Principe de fonctionnement� Exécution du sous-programme récursif(version 1)
� Appel récursif � interruption de la version en cours
� Le système sauvegarde dans une pile l'environnement du ss-prgme� Adresse de retour
� Valeur des paramètres de mode in de la version en cours
� Valeur des variables locales de la version en cours
� Une nouvelle version du sous-prgme (version 2) s’exécute avec une nouvelle version des paramètres formels in (leur valeur est celle spécifiée dans l’appel) ;
� Fin d'exécution de cette nouvelle version (version 2) ; retour des valeurs des paramètres de mode out et in out . ou du résultat de la fonction
� Reprise de la version appelante (version 1) là où elle s'était interrompue au moment de l’appel avec son environnement restauré tel qu’elle l’avait laissé
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
67
Chap. 4 : Récursivité - Fonctionnement de la Pile
� Qu’est ce que la pile ?� Zone mémoire particulière réservée à chaque programme
� Rôle� Stocker les valeurs des variables locales et des paramètres d'un s-p et
l’adresse de retour avant tout appel à un autre sous-programme� Gestion transparente pour l'utilisateur
� S/P récursif : à chaque appel récursif, toutes les variables locales sont stockées dans la pile (empilées) autant de fois qu' il y a d'appels récursifs
� En fin d’exécution d’une version, les variables son t « dépilées » pour que l’on retrouve l’environnement de la version précéde nte
� Attention au "débordement de pile" : Exception « Sto rage_Error »
C’est la manifestation d’une récursion infinie :
- l’arrêt de la récursion est mal défini
- l’appel récursif est erroné
…
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
68
Chap. 4 : Récursivité - Arbre d’appel de Facto pour N=3
Facto(3)
Facto(2)
Facto(1)
Facto(0)
function Facto (N: in Natural) return Positive isResu : Positive;
beginif N=0 then
Resu := 1;else
Resu := N * Facto (N-1);end if;return Resu;
end Facto;
beginput (Facto (3) ) ;
end Test_facto;
N (0) = 3Resu (0) =
3xResu (1) =3*2 =6
Programme Principal
G.AURIOL, C. MERCE, P. ESQUIROL
N (1) = 2Resu (1) =
2xResu (2) = 2*1 =2
N (2) = 1Resu (2) =
1xResu (3) =1*1 =1
N (3) = 0
Resu (3) = 1
2
MIC
69
Chap. 4 : Récursivité - version itérative / version récursive
� Pour des problèmes simples, il existe une version i térative simple
� Comparer version itérative et version récursive
function Facto ( N : in Natural) return Positive isResu : Positive := 1;
beginfor J in 1..N loop
Resu := J * Resu ;end loop;return Resu;
end Facto;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
G.AURIOL, C. MERCE, P. ESQUIROL
70
Chap. 4 : Récursivité – Exemples
� Qu’affiche la procédure?
procedure Test_Toto2 is
procedure Toto (N: in Integer) isbegin
if N > 0 thenToto ( N-1);
end if ;put ( N , 5);
end Toto ;
beginToto ( 4 ) ;
end Test_Toto2;
procedure Test_Toto3 is
procedure Toto (N: in out Natural) isbegin
if N > 0 thenN := N-1;Toto (N);
end if ;put (N, 5);
end Toto ;
X: Integer :=4;
beginToto (X) ; put ( X ) ;
end Test_Toto3;
2
MIC
71
Chap. 4 : Récursivité - Analyse récursive d'un probl ème
� Quand envisager une conception récursive?� Lorsque l’algo itératif n’est pas évident� Lorsqu'il est facile de décomposer le problème en un ou plusieurs sous-
problèmes de même nature mais de taille plus petite � Une conception récursive comprend souvent 3 étapes non forcément
séquentielles� Décomposition du problème (la taille doit diminuer!)� Paramétrage (la taille est un paramètre)� Identification du (des) cas trivial(aux)
� Forme générale d'un algorithme récursif
� Il faut qu'un algorithme récursif se termine. Il fa ut montrer que
� la décomposition simplifie le problème et converge vers le cas trivial !
if cas trivial thenCalcul direct
else Appels récursifs
end if ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
72
Chap. 4 : Récursivité - Exemple : Inversion d’un vec teur (1/6)
� Quel est le problème?
� On a
� On veut
� Une analyse récursive comprend souvent 3 étapes non forcément séquentielles� Paramétrage du S/P
� Le vecteur à inverser� Rmq. : la taille d’un vecteur est intrinsèque à celui-ci � ce n’est pas
un paramètre
� Identification du (des) cas trivial(aux)� Vecteur de taille nulle ou de taille 1.
� Décomposition en ss-pbs de plus petite taille
10 30 20 15 40
40 15 20 30 10
X
Y
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
73
Chap. 4 : Récursivité - Exemple : Inversion d’un vec teur (2/6)
� Structure de données
� Obligatoirement un tableau non contraint car le S/P va manipuler des vecteurs de tailles dégressives
� Paramétrage du sous-programme� Lié au besoin : on va manipuler le vecteur initial et le vecteur inversé� Si procédure
� Si fonction
type Vecteur is array (Integer range <>) of Integer ;
procedure Inversion ( V : in out Vecteur ) ;
function Inversion ( V : in Vecteur ) return Vecteur ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
74
Chap. 4 : Récursivité - Exemple : Inversion d’un vec teur (3/6)
type Vecteur is array ( Integer range <> ) of Integer;
function Inversion ( V : in Vecteur ) return Vecteur is
begin-- cas trivialif … then
…else -- appels récursifs
……
end if;return W;end Inversion;
Fonction récursive
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
75
Chap. 4 : Récursivité - Exemple : Inversion d’un vec teur (4/6)
procedure Test_Inversion isX,Y : Vecteur (1..5);begin
X := (10, 30, 20, 15, 40) ;put ( " attendu apres inversion : 40 15 20 30 10 " ); Y := Inversion ( X ) ;-- affichage du vecteur inverséput ( " obtenu apres inversion : " ) ; for I in Y'range loop
put ( Y(I) ) ;end loop;
end Test_Inversion;
Test de la fonction récursive
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
76
Chap. 4 : Récursivité - Exemple : Inversion d’un vec teur (5/6)
procedure Inversion ( V : in out Vecteur ) is
Temp : Integer ;
begin
if V'length = 0 then
null ;
else
Temp := V (V'last) ;
V (V'last) := V (V'first) ;
V (V'First) := temp ;
Inversion ( V ( V'first+ 1 .. V'last- 1) ) ;
end if ;
end Inversion;
Procédure récursive
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
77
Chap. 4 : Récursivité - Exemple : Inversion d’un vec teur (6/6)
procedure Test_Inversion isX : Vecteur (1..5);
beginX := (10, 30, 20, 15, 40) ;put ( " attendu apres inversion : 40 15 20 30 10 " ); Inversion ( X ) ;-- affichage du vecteur inverséput ( " obtenu apres inversion : " ) ; for I in X'range loop
put ( X(I) ) ;end loop;
end Test_Inversion;
Test de la procedurerécursive
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
78
Chap. 4 : Récursivité - Exemple : Les tours de Hanoi
� La fin du monde!� Une légende asiatique raconte que dans un temple se trouvent trois
poteaux sur lesquels s'empilent 64 disques d'or. Les prêtresdéplacent continuellement les disques selon les règles édictées ci-après. D'après cette même légende, le dernier déplacement dedisque marquera la fin du monde
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
79
Chap. 4 : Récursivité - Exemple : Les tours de Hano i
� Règles de déplacement
� On ne déplace qu'un seul disque à la fois
� On ne peut déplacer que le disque situé au sommet d'un poteau
� On ne peut poser un disque que sur un poteau vide ou sur un poteau contenant des disques plus grands
� On souhaite écrire un programme qui écrit la suite des déplacements à effectuer
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
80
Chap. 4 : Récursivité - Les tours de Hanoi avec 1 di sque
� Exemple : déplacer 1 disque du socle ‘A’ vers le so cle ‘B’
� Liste des déplacements :
A � B
Socle A Socle B Socle C Socle A Socle B Socle C
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
81
Chap. 4 : Récursivité - Les tours de Hanoi avec 2 di sques
� Exemple : déplacer 2 disques du socle ‘A’ vers le s ocle ‘B’ (en utilisant ‘C’ comme socle intermédiaire)
� Déplacements:
A � C
A � B
C � B
A B C
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
82
Chap. 4 : Récursivité - Les tours de Hanoi avec 3 d isques !
� Exemple avec 3 disques
A B C
� DéplacementsA � BA � CB � CA � B
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
83
Chap. 4 : Récursivité - Les tours de Hanoi avec 3 disques !
A B C
C � AC � BA � B
� DéplacementsA � BA � CB � CA � B
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 4 : Récursivité - Les tours de Hanoi : analys e récursive
� Une analyse récursive comprend souvent 3 étapes non forcément séquentielles
� Identification du (des) cas trivial(aux)
� Tour n’ayant aucun disque ! (il n’y a rien à faire)
� Paramétrage du S/P
� Le nombre de disques à déplacer � N
� Le nom des socles
� Socle de départ � Dep
� Socle d’arrivée � Arr
� Socle intermédiaire � Int
� Décomposition du problème initial en sous-problèmes de même nature mais de plus petite taille
84G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
85
Chap. 4 : Récursivité - Les tours de Hanoi : décompo sition récursive
Pour déplacer N disques d’un socle de départ Dep vers un socle d’arrivée Arren utilisant un socle intermédiaire Int , il faut
- Déplacer N-1 disques de Dep vers Int en utilisant Arr comme socle intermédiaire
- Déplacer un disque de Dep vers Arr
- Déplacer N-1 disques de Int vers Arr en utilisant Dep comme socle intermédiaire
Dep Arr Int
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
86
Chap. 4 : Récursivité - Les tours de Hanoi
procedure Test_Hanoi is
procedure Hanoi (N : in Natural; Dep, Arr, Int : in Character) isbegin
if N /= 0 thenHanoi( N-1, Dep, Int, Arr);put (" déplacer un disque de "); put (Dep);put(" vers "); put (Arr); new_line;Hanoi( N-1, Int, Arr, Dep);
end if;end Hanoi;
Nb: natural;
beginput (" Nombre de disques ? "); get (Nb) ; Hanoi (Nb, 'A', 'B', 'C');
end Test_Hanoi;
Dép Arr Int.
Dép Arr Int
Dép Arr Int
Dép Arr Int.
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
87
Chap. 4 : Récursivité - Les tours de Hanoi : arbre d ’appel
3, A, B, C
2, A, C, B 2, C, B, A
1, B,C,A1, A, B, C
0, C, B, A0, A, C,B Ecriture d'un déplacement
1
Affichages :de A vers B (1)de A vers C (2)de B vers C (3)de A vers B (4)de C vers A (5)de C vers B (6)
de A vers B (7)
1
2
3
4
Socle A
Socle B
Socle C
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
Chap. 4 : Récursivité - Les tours de Hanoi et la fin du monde !
88
� Calcul du nombre de déplacements à effectuer pour n disquesND(n) = 2 × ND (n-1) +1ND(0) = 0
Ce qui donne en « dérécursivisant »ND(1) = 1ND(2) = 2 × ND (1) + 1 = 2 + 1ND(3) = 2 × ND (2) + 1 = 22 + 2 + 1
ND(n) = 2n-1 + … + 2 + 1 = ∑ 2� =2� − 1����
� Calcul du temps mis pour déplacer 64 disques� On suppose 1 déplacement = 1 sec� Temps total ≈ 264 sec ≈ 0,2 × 1020 sec
� 1 année = 31 536 000 sec ≈ 0.3 × 108 sec
� 1 siècle ≈ 0.3 × 1010 sec
� Il faudra ≈ 1010 siècles pour déplacer les tours � De la marge avant la fin du monde !!
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
91
Chap. 5 : Les pointeurs - Introduction
� Les variables manipulées jusqu’à présent sont dites statiques
� Statiques car explicitement déclarées� Déclarées en précisant
� Leur nom
� Leur type � Réservation figée d'un espace mémoire
� Exemple avec des tableaux
Type Un_Tab_Contraint is array (Integer range 1..5) of Float ;
Type Un_Tab_NON_Contraint is array (Integer range <>) of Float ;
X : Un_Tab_Contraint ;
Y : Un_Tab_Non_Contraint (1..10) ;
� Attention : une fois déclarées, X et Y ne peuvent pas « grandir » ou « diminuer » � LIMITATION
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
92
Chap. 5 : Les pointeurs – Exemple de liste
� Gérer la liste des personnes s'inscrivant pour une course à pieds et maintenir l’ordre alphabétique de la liste� On ne sait pas a priori combien de personnes vont participer à cette
course� Des nouveaux participants peuvent arriver à tout moment
� Des participants peuvent annuler à tout moment
� Difficile dans ces conditions de dimensionner une variable de type tableau
� � Besoin : on veut pouvoir créer des variables au fur et à mesure des besoins en cours d’exécution du programme � variables dynamiques
� � La notion de pointeur répond à ce besoin
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
93
Chap. 5 : Les pointeurs - Allocation dynamique
� Allocation dynamique� Mécanisme permettant de réserver « dynamiquement » de la mémoire
c’est à dire de créer « dynamiquement » une variable� Dynamiquement � en cours d’exécution du programme (au fur et à mesure
des besoins)� La réservation se fait dans une zone mémoire particulière de la machine
(appelée tas)� Les variables créées dynamiquement n’ont pas de nom puisqu’elles sont
créées en dehors des parties déclaratives des programmes� Les variables de cette zone mémoire ne sont accessib les que par
l’intermédiaire leur adresse (par des pointeurs)
� Définition� Pointeur : variable contenant l’adresse d’une autre variable (ou d’un sous
programme- hors contexte de ce module) ;� Elle « pointe » sur une autre variable
� Exemple : liste des coureurs
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
94
Chap. 5 : Les pointeurs – Utilisation de variables d ynamiques
� Rappels : utilisation de variables statiques (ex. t ableau)� Déclaration d’un type
� Déclaration d’une variable de ce type
� Accès à la variable par son nom
� Pointeurs et variables dynamiques� Déclaration d’un type « pointeur » ?� Déclaration d’une variable de type « pointeur » ?� Création d’une variable dynamique (Allocation de place mémoire) ?� Accès à la variable dynamique ?� Libération espace mémoire (Dé-allocation d’un pointeur) ?
type Un_Vect is array (Integer range 1..10) of Integer ;
Mon_Vecteur : Un_Vect ;
Mon_Vecteur ( 1 ) := 8 ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
95
� Déclaration d’un type pointeur
� Forme générale
� Exemples
� Déclaration d’une variable d'un type pointeur
� Par défaut, en ADA, la valeur d’une variable de typ e pointeur est « null » lors de la déclaration
� Le pointeur pointe sur « rien »
� Il n’y a pas eu de réservation mémoire
Chap. 5 : Les pointeurs : déclarations
type Ptr_Int is access Integer ;
type Tab is array (1..6) of Boolean ;type Ptr_Tab is access Tab ;
type NomType is access TypePointé ;
P : Ptr_Int ;
M : Ptr_Tab ;
P : Ptr_Int := null ;
M : Ptr_Tab := null ;
Type pointeur
Obligatoire
P
M
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
96
Chap. 5 : Les pointeurs : Allocation mémoire (1/3)
� Création d’une variable dynamique � réservation mémoire
� Forme générale
La variable dynamique créée n’a pas de nom et
n’est accessible que via la variable NomPointeur
de type pointeur ( NomType )
type NomType is access TypePointé ;
NomPointeur : NomType ;
begin
NomPointeur := new TypePointé ;
-- accès à la variable
NomPointeur.all := xxxx ;
New = « Allocateur »- Cherche une zone mémoire disponible dans le tas- Réserve cette zone- Retourne l’adresse de la zone
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
97
Chap. 5 : Les pointeurs : Allocation mémoire (2/3)
� Exemple de création d’une variable dynamique non in itialisée
(ou Allocation d’un pointeur)
type Un_Ptr_Int is access Integer ;
type Tab is array (1..6) of Boolean ;
type Un_Ptr_Tab is access Tab ;
P : Un_Ptr_Int ; M : Un_Ptr_Tab ;
beginP := new Integer ;M := new Tab ;
P M?
?
?
?
?
?
?
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
98
Chap. 5 : Les pointeurs : Allocation mémoire (3/3)
� Création d’une variable dynamique initialisée
beginP := new Integer'(23) ;M := new Tab'(others => true) ;
P
M
23
true true true true true true
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
99
Chap. 5 : Les pointeurs : Accès à la variable dynam ique (1/4)
� Utilisation des pointeurs : accès aux variables dyn amiques� Forme générale
� Exemple
beginP.all := 23 -- variable pointée par P (dont l’adresse est dans P)M.all(2) := False : -- variable pointée par M (c’est un tableau)
NomPointeur.all « zone pointée » par NomPointeur
P 23
P.all (variable pointée par P ; contient 23)
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
100
Chap. 5 : Les pointeurs : Accès à la variable dynam ique(2/4)
� Réservation mémoire et initialisation de la zone mém oire réservée
type Ptr_Int is access Integer ;
P : Ptr_Int ; begin
P := new Integer'(23) ;
type Ptr_Int is access Integer ;
P : Ptr_Int ; begin
P := new Integer ;P.all := 23 ;
P 23 P ?23
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
101
Chap. 5 : Les pointeurs : Accès à la variable dynam ique (3/4)
� variables dynamiques d’un type composé (tableau ou structure)
type Tab is array (1..8) of Boolean ;
type Ptr_Tab is access Tab ;
M : Ptr_Tab := null ;
beginM := new Tab'(others => True) ;for i in Tab'range loop
if M.all(i) then….
end if ;end loop;
type Tab is array (1..8) of Boolean ;type Ptr_Tab is access Tab ;
M : Ptr_Tab := null ;
beginM := new Tab'(others => True) ;for i in Tab'range loop
if M(i) then….
end if ;end loop ; Omission de « .all »
M null ;
M true true true true true true
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
102
Chap. 5 : Les pointeurs : Accès aux variables dynam iques (4/4)
� Accès aux variables dynamiques d’un type composé (s uite)
type Tab is array (1..8) of Boolean ;type Ptr_Tab is access Tab ;
M : Ptr_Tab := null ;
beginM := new Tab'(others => True) ;for i in M.all' range loop
if M.all(i) then…
end if ;end loop;
type Tab is array (1..8) of Boolean ;type Ptr_Tab is access Tab ;
M : Ptr_Tab := null ;
beginM := new Tab'(others => True) ;
for i in M'range loopif M(i) then
…end if ;
end loop ;
Attribut classique de la variable M.all ( qui est de type Tab)
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
103
Chap. 5 : Les pointeurs : pointeur vs. variable dyn amique (1/3)
� Ne pas confondre pointeur et la variable pointée
� Que se passe-t-il à l’exécution ?
type Ptr_Int is access Integer ;
P : Ptr_Int ; begin
P := new Integer'(23) ;put ( P ) ;
type Ptr_Int is access Integer ;
P : Ptr_Int ; begin
P := new Integer'(23) ;put ( P.all ) ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
104
Chap. 5 : Les pointeurs : pointeur vs. variable dyn amique (2/3)
� Contenu de P1 et P2 après exécution ? Contenu de P1 .all et P2.all ?
� Dessiner les boîtes !
type Ptr_Int is access Integer ;
P1, P2 : Ptr_Int; begin
P1 := new Integer’(23) ; P2 := P1;put ( P1.all ) ;put ( P2.all ) ;
type Ptr_Int is access Integer ;
P1, P2 : Ptr_Int; begin
P1 := new Integer’(23) ; P2 := P1 ;P2.all := 21 ;put ( P1.all ) ;put ( P2.all ) ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
105
Chap. 5 : Les pointeurs : pointeur ou variable dyna mique (3/3)
� Contenu de P1 et P2 après exécution dans chaque cas ? Contenu de P1.all et P2.all ?
� Dessiner les boîtes !
type Ptr_Int is access Integer ;
P1, P2 : Ptr_Int;
beginP1 := new Integer’(23) ;P2 := new integer’(21);P2.all := P1.all ;put ( P1.all ) ;put ( P2.all ) ;
type Ptr_Int is access Integer ;
P1, P2 : Ptr_Int;
beginP1 := new Integer’(23) ;P2 := new integer’(21);P2 := P1 ;put ( P1.all ) ;put ( P2.all ) ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
106
Chap. 5 : Les pointeurs : Egalité entre ptrs ou entr e var. pointées
type Ptr_Int is access Integer ;
P1, P2 : Ptr_Int; begin
P1 := new Integer’(23) ;P2 := new integer;P2.all := P1.all;-- P1 = P2 ?? -- P1.all=P2.all ??
type Ptr_Int is access Integer ;
P1, P2 : Ptr_Int; begin
P1 := new Integer’(23) ; P2 := P1;-- P1 = P2 ?? -- P1.all=P2.all ??
L’expression P1 = P2 vaut TRUE si P1 et P2 contie nnent la même adresse (ie pointent sur la même variable dynamique ou pointent tous les deux sur null )
L’expression P1.all = P2.all prend la valeur TRUE si P1 et P2 pointent sur des variables contenant la même valeur
P1 23
P2 23
P1
23
P2
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
107
Chap. 5 : Les pointeurs : utilisation
� Structures de données dynamiques
� Listes � à travers des exemples
� Arbres, graphes –cf. module suivant
� Dimensionnement dynamique de tableaux (sans bloc d eclare)
� En fin de chapitre
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
108
Chap. 5 : Les pointeurs - Structure de liste
� Gérer la liste des personnes s'inscrivant pour une course à pieds� On ne sait pas a priori combien de personnes vont participer à cette
course� Des nouveaux participants peuvent arriver à tout moment
� Des participants peuvent annuler à tout moment
� Pour chaque coureur� Nom� Numéro de dossard
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
109
Chap. 5 : Les pointeurs : structure de liste
� Structure de données � Déclarations des types
subtype Chaine3 is String(1..3);
type Un_Coureur;type Un_Ptr_Coureur is access Un_Coureur;
type Un_Coureur is recordNom : Chaine3 := (others => ' ');Dossard : Natural;Suivant : Un_Ptr_Coureur;
end record;
Déclaration de la liste : une seule variable quel que soit le nombre d’éléments
Deb_Liste : Un_Ptr_Coureur;
� Gestion de la liste : algorithmes classiques� Parcours de la liste (par exemple pour afficher tous les éléments)� Rechercher si un élément appartient à la liste� Insérer / Supprimer un élément� …
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
110
Chap. 5 : Les pointeurs : Affichage de la liste
� version itérative
procedure Afficher_Coureurs (L : in Un_Ptr_Coureur) isAux : Un_Ptr_Coureur := L;
beginPut_Line(" la liste des coureurs est : ");while Aux /= null loop
Put (" ") ;Put ( Aux.all.Nom );Put( Aux.all.Dossard) ;New_Line;Aux := Aux.all.Suivant;
end loop;end Afficher_Coureurs;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
111
Chap. 5 : Les pointeurs : Affichage de la liste
� version récursive
procedure Afficher_Coureurs (L : in Un_Ptr_Coureur) isbegin
if L /= null then-- affichage du 1er coureurPut (" ");Put (L.all.Nom);Put (L.all.Dossard,4);New_Line;-- affichage de la suiteAfficher_Coureurs (L.all.suiv);
end if;end Afficher_Coureurs;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
112
Chap. 5 : Les pointeurs : affichage d’une liste
� Que fait ce sous-programme ?
procedure Afficher_Coureurs (L : in Un_Ptr_Coureur) isbegin
if L /= null then-- affichage de la suiteAfficher_Coureurs (L.all.suiv);-- affichage du 1er coureurPut (" ");Put (L.all.Nom);Put (L.all.Dossard,4);New_Line;
end if;end Afficher_Coureurs;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
113
Chap. 5 : Les pointeurs - Recherche d’un élément dan s une liste
� Le coureur est identifié par son nom
function Chercher_Coureur ( Le_Nom : in chaine3 ; Dans : in Un_Ptr_Coureur ) return Boolean is
Aux : Un_Ptr_Coureur;Trouve : boolean :=false;
BeginAux := Dans;while Aux/=null and not Trouve loop
If Aux.all.nom = Le_Nom thenTrouve := True;
else -- on avance dans la listeAux := Aux.all.suiv;
end if;end loop;return Trouve;
end Ajouter_Coureur;
Remarque 1 : on pourrait retourner le pointeur sur l’élément recherché
Remarque 3 : version récursive ?
Remarque 2 : algo proche de celui de la recherche dans un tableau
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
114
Chap. 5 : Les pointeurs - Ajout d’un élément en débu t de liste
� Le nom et le num de dossard sont donnés
procedure Ajouter_Coureur ( L : ?? Un_Ptr_Coureur ; Le_Nom : in chaine3 ; Le_Num : in Natural) is
Aux : Un_Ptr_Coureur ;begin
-- réservation mémoireAux : = new Un_Coureur;-- actualisation des informations Aux.all.Nom := Le_Nom; Aux.all.Num := Le_Num;-- réalisation des chaînagesAux.all.suiv:= L;L:=Aux;
end Ajouter_Coureur; Mode de passage de L?
-- réservation mémoire-- actualisation des informations -- réalisation des chaînagesL := new Un_Coureur’(Le_Nom,Le_Num,L) ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
115
Chap. 5 : Les pointeurs - Structure de liste
� Ajout d’un élément en début d’une liste
� Démarche générale
� 1- Faire la réservation mémoire
� 2- Actualiser les informations
� 3- Trouver l’endroit d’insertion
� Algo de recherche
� Est ce possible si on pointe sur l’élément qui suivra celui que l’on veut insérer ?
� � On a besoin d’avoir un pointeur sur l’élément qui précède
� 4- Réaliser les chaînages
� Attention aux cas particuliers
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
116
Chap. 5 : Les pointeurs – Suppression du 1 er coureur de la liste
procedure Sup_1er_Coureur ( L : ?? Un_Ptr_Coureur) isbegin
if L= null then-- il n’y a aucun coureur dans la liste
Raise Suppression_Impossible;else
L : = L.all.suiv ;-- liberer l’espace inutilisé � cf module suivant
end Sup_1er_Coureur ;
Mode de passage de L ?
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
117
Chap. 5 : Les pointeurs – Structure de liste
� Suppression d’’un coureur dont le nom est fourni
� Démarche
� 1- chercher le coureur à supprimer
� Algo de recherche
� On a besoin d’avoir un pointeur sur l’élément qui précède
� 2- Modifier les chaînages
� Attention au cas particuliers
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
118
Chap. 5 : Les pointeurs - Utilisations de pointeurs
� Structures de données dynamiques � Listes � vues à travers un exemple� Arbres, graphes � cf. module suivant
� Dimensionnement dynamique de tableaux
� Déclarer un tableau dont la dimension est fournie par l’utilisateur en début de programme
� 2 solutions � Bloc declare (cf. chapitre types tableaux non contraints)
� Avec pointeur
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
119
Chap. 5 : Les pointeurs - Dimensionnement dynamique de tableaux
beginput ("nombre de composantes ? ");get (Nbre_Comp) ;declareMon_Tab : Un_Tab (1..Nbre_Comp);
beginfor I in Mon_Tab’range loop
Mon_Tab(I) :=0.0;end loop;
end ;end Exemple ;
type Un_Ptr_Sur_Tab is access Un_Tab ;P_Mon_Tab : Un_Ptr_Sur_Tab;begin
put ("nombre de composantes ? ");get (Nbre_Comp) ;
P_Mon_Tab:=new Un_Tab (1..Nbre_Comp);
for I in P_Mon_Tab.all’range loopP_Mon_Tab.all (I) :=0.0;
end loop;
end Exemple;
procedure Exemple istype Un_Tab is array (Integer range <>) of Float ;
Nbre_Comp : Natural ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
120
Chap. 5 : Les pointeurs - Dimensionnement dynamique de String
� Exemple
type Ref_String is access String ;
S : Ref_String ;
beginS := new String (1..8) ;S := new String’("bonjour!") ;S.all := "salut---" ;S := new string(1..20) ;
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
123
Conclusion - A retenir de ce cours (1/3)
� Problèmes algorithmiques� Réflexion indépendante de tout langage� Algorithmes écrits en notation algorithmique (proche du langage naturel) ou
en Ada (très proche de la notation algorithmique)� Séquences - Choix – Répétitions -
� Gestion de la complexité : Approche par décompositi on � Sous-programme correspond à un « traitement » logique� But du sous-programme ? Paramétrage ? � Corps du sous-programme � pb algorithmiqueMême démarche quel que soit le langage
� Récursivité � facilité d’écriture de certains algorithmes� Décomposition d’un pb en 1 ou plusieurs pbs de même nature mais de taille
plus petite� La « taille » est un des paramètres� Identification de cas triviaux (résolution directe)Attention à la finitude � on atteint un cas trivial
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
124
Conclusion - A retenir de ce cours (2/3)
� Choix de la structure de données en fonction du pro blème
� Regroupement de données de types différents � « record »
� Regroupement de données de mêmes types � « tableau » ? « liste chaînée » ?
Dépend des caractéristiques du pb notamment de la connaissance de la dimension
� Si celle-ci est connue quand on écrit le programme� Tableau contraint ou non contraint
� Si elle est fournie par l’utilisateur en début de programme� Tableau non contraint avec bloc « DECLARE »
� Pointeur sur un tableau non contraint (sans bloc « DECLARE »)
� Si l’utilisateur ne maîtrise pas la dimension� Liste
� Pointeur sur le début de la liste
� 1 seule variable déclarée (le pointeur sur le 1er élément) quelle que soit la longueur de la liste
� Éventuellement, un pointeur aussi sur le dernier élément de la liste
G.AURIOL, C. MERCE, P. ESQUIROL
2
MIC
125
Conclusion - A retenir de ce cours (3/3)
� Dans un tableau, les composantes sont les unes à la suite des autres en mémoire� Accès à une composante par son indice �T(I) � Accès à la composante suivante : I := I+1
� Dans une liste, on ne maîtrise pas le positionnemen t des éléments dans la mémoire� Accès à un élément par son adresse � P.all � Accès à la composante suivante : P := P.all.suiv ;
� Certains algorithmes classiques ont la même « forme » pour un tableau ou une liste� Parcours� Recherche si une valeur se trouve dans le tableau ou dans la liste
� Algorithmes spécifiques� Insertion d’un élément dans une liste � Suppression d’un élément dans une liste
G.AURIOL, C. MERCE, P. ESQUIROL
top related