La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Algorithmique Procédurale

Présentations similaires


Présentation au sujet: "Algorithmique Procédurale"— Transcription de la présentation:

1 Algorithmique Procédurale
IUP GMI 1ère année Denis Robilliard

2 Sommaire Introduction Premier programme Historique
La machine de Turing Langages de programmation Arbres programmatiques et Ada Syntaxe, expressions régulières Premier programme Premier programme en Ada Instructions

3 Structures de contrôle du flux d ’instructions
Commentaires Variables, affectations Types de base Opérations arithmétiques de base Entrées/sorties sur les types de base Inclure des bibliothèques Conversions de types Structures de contrôle du flux d ’instructions Structure d'alternative AP / ADA Expressions booléennes, opérateurs relationnels

4 Types tableaux Structure de cas AP / ADA
Expression statique ou dynamique Phases d'écriture d'un programme Structure de boucle AP /ADA Boucle "pour" AP / ADA Boucle avec sortie Résumé des différentes structures de boucle en ADA Bloc déclaratif AP /ADA Types tableaux Tableaux AP / ADA

5 Les sous-programmes : procédures et fonctions
Exemple sur les tableaux Règles, opérations et attributs de tableaux Les tranches Les agrégats Les chaînes de caractères AP / ADA Entrées / sorties sur les chaînes Attributs relatifs aux chaînes et aux caractères Les tableaux à plusieurs dimensions Les sous-programmes : procédures et fonctions Paramètres et valeur de retour

6 Retour sur les types, enregistrements
Paramètres par défaut Position des procédures et des fonctions Déclarations préliminaires Portée et visibilité Récursivité Retour sur les types, enregistrements

7 Introduction Algorithmique : "art" d ’écrire des algorithmes ou programmes. Synonyme : programmation. Algorithme : procédé opératoire qui permet, à partir de données, d ’obtenir un résultat précis. Ex : algo de l ’addition de deux nombres.

8 Algo procédurale (ou encore impérative) : les programmes sont conçus comme une liste d ’ordres / instructions, qui doivent s ’exécuter un par un, dans un ordre chronologique défini à l ’avance. Il existe d ’autres formes d ’algo : parallèle, objet, fonctionnelle, déclarative, ...

9 Historique Premiers algorithmes dès l ’Antiquité : Euclide, Eratosthène, … Premières machines à calcul : Pascal, Descartes (17ème), algorithme "codé" par des engrenages. Premier véritable ordinateur : la machine de Babbage (19ème), non achevée. Nouveauté : elle est programmable.

10 Première personne à programmer : Lady Ada Lovelace, "assistante" de Babbage.
Théorisation : Turing, Church (années 30), définition de la notion mathématique de "fonction calculable" = ce qui peut être réalisé par un "ordinateur universel". Premiers ordinateurs électroniques mis au point pendant la 2nde guerre mondiale.

11 La machine de Turing Un "ordinateur" de papier :
une bande de papier, finie mais aussi longue qu ’on le souhaite, divisée en cases qui peuvent contenir les symbole 0 ou 1 une "tête" de lecture/écriture qui pointe sur une case, qui peut lire ou écrire un 0 ou un 1 dans la case, et qui peut se déplacer d ’une case à droite ou à gauche … (voir page suivante)

12 un programme, composé de règles de la forme : <q, s> ~ <q ’, s ’, p>
avec {q, q ’} des états de la machine de Turing, dont le nombre, toujours fini, est dépendant du programme que l ’on exécute {s, s ’} dans {0,1} les symboles que l ’on peut écrire sur la bande p dans {g,d} une direction indiquant vers quelle case voisine (gauche ou droite) se déplace la tête de lecture pour exécuter la prochaine instruction

13 Représentation de la machine de Turing
... q0 Tête de lecture dans la configuration de départ 1 ... Position de la tête de lecture et état de la bande après application de la règle : <q0, 0> ~ <q1, 1, d> q1

14 Exemple de programme Objectif : le programme va lire un nombre en base 1 composé de 2 chiffres au plus. Il va écrire le double de ce nombre, en base 1, plus loin sur la bande. Note : la bande sera donc divisée (virtuellement) en une zone de données de deux cases suivie d ’une zone de résultat. La donnée en entrée est écrite sur la bande par l ’utilisateur.

15 Le programme : Note : <q0, 0> ~ <q10, 0, d>
<q20, 0> ~ <qF, 0, d> <q21, 0> ~ <q311, 1, d> <q311, 0> ~ <qF, 1, d> <q22, 0> ~ <q321, 1, d> <q321, 0> ~ <q422, 1, d> <q422, 0> ~ <q523, 1, d> <q523, 0> ~ <qF, 1, d> Note : q0 est l ’état initial de la machine qF est l ’état final : quand la machine passe dans l ’état qF elle s ’arrête

16 Tout ce qui peut être calculé par une machine de Turing = ensemble des fonctions calculables
Tous les ordinateurs actuels sont des machines de Turing, à la restriction près que leur mémoire est finie. Il existe des fonctions non calculables !!! Un ordinateur ne peut pas tout faire...

17 Langages de programmation
Pour communiquer l ’idée d ’un algo, à une personne ou à un ordinateur, nécessité d ’un langage. En général les langages informatiques sont universels (ils permettent de coder tous les programmes possibles). Cependant, ils favorisent souvent une certaine approche des problèmes : Pascal, C : programmation procédurale Smalltalk, Eiffel, Java : programmation objet Prolog : programmation déclarative

18 Arbres Programmatiques et Ada
Nous utiliserons 2 langages : Un langage pédagogique, en partie graphique, noté AP : les Arbres Programmatiques. Note : ce ne sont pas des organigrammes. Un langage "de la vraie vie" : ADA. C ’est un langage de programmation procédurale, créé en 1983 sur appel d ’offre du Département de la Défense américain. Il possède, depuis 1995, des extensions objets, que nous n ’utiliserons pas.

19 Pourquoi les arbres programmatiques ?
C ’est une notation "papier" (nous n ’exécuterons pas un AP sur machine). Nous nous permettrons une syntaxe plus souple. Les APs forcent le programmeur à une approche hiérarchique, descendante du problème. C ’est la "programmation structurée" : On part des idées générales et on va progressivement de plus en plus dans le détail. Les branches d'un arbre programmatique sont assez indépendantes les unes des autres (au moins en ce qui concerne le déroulement des instructions).

20 La programmation procédurale structurée marche très bien pour concevoir de petites applications (- de 5000 lignes). D ’autres approches, notamment la conception objet, seront vues plus tard dans le cursus pour les applis plus importantes. Note : le code de la navette spatiale américaine fait plus de de lignes...

21 Syntaxe, expressions régulières
Pas de langage sans syntaxe (ou orthographe) Nous utiliserons une forme restreinte des « expressions régulières » pour définir précisément la syntaxe autorisée, particulièrement en Ada. Exemple : identifiant ::= lettre { [ _ ] / lettre | chiffre / } Ce qui signifie qu ’un identifiant commence forcément par une lettre et se continue par une suite, éventuellement vide, de lettres et/ou chiffres, qui peuvent chacun être précédé d'un "blanc souligné".

22 Symboles formant les expressions rationnelles
::= introduit l ’expression rationnelle qui définit la syntaxe associée au concept;  [ ] délimitent une sous-expression facultative; { } délimitent un motif qui peut être répété; … désigne un terme identique au terme précédent; | (barre verticale) "ou bien" dans une énumération; \ \ délimitent une série d'option d'options parmi lesquelles il faut choisir une; en_gras dénote un mot réservé (mot clé) de ADA ou un symbole à prendre littéralement.

23 Premier programme Nom de l ’unité/programme bonjour Déclaration de
nb : entier Déclaration de variable Connecteur séquence d ’instructions seq saluer demander nombre afficher nombre Nom de bloc d ’instructions sortir("entrer votre nombre : ") entrer(nb) sortir("bonjour") sortir("le nombre est : ") sortir(nb) instruction Bloc d ’instructions

24 Premier programme en Ada
with text_io, integer_text_io; use text_io, integer_text_io; procedure bonjour is nb : integer; begin -- saluer put_line("bonjour"); -- demander nombre put("entrez votre nombre : "); get(nb); -- afficher nombre put("le nombre est : "); put(nb); end bonjour; -- le rappel du nom d'unité est facultatif

25 Instructions Un programme est composé d ’instructions. Une instruction peut elle-même contenir d ’autres instructions. Par défaut, les instructions s'exécutent en séquence. En Ada les instructions sont terminées par un point virgule (facultatif en AP). Une instruction peut s ’étendre sur plusieurs lignes. Pas de différence entre majuscules et minuscules

26 Commentaires Les commentaires ont pour objectif de faciliter la compréhension du programme. Les noms de bloc d ’instructions AP seront toujours reportés comme commentaires en Ada. Des commentaires supplémentaires seront évidemment les bienvenus. Les commentaires débutent par -- et se poursuivent jusque la fin de ligne.

27 Variables, affectation
Chaque donnée (nombre, caractère, …) que l ’on veut réutiliser ultérieurement doit être stockée dans un emplacement mémoire appelé "variable". Les 2 langages, AP et ADA, sont "fortement typés" : une variable ne peut contenir qu ’une seule sorte ou "type" de données (soit un caractère, soit un nombre entier, …)

28 L ’affectation est une instruction. Elle sera noté := en AP et en ADA.
Les variables utilisées par un programme doivent être "déclarées" avant leur utilisation : on précise leur nom et l ’unique type de valeur qu ’elles peuvent contenir. L ’affectation est une instruction. Elle sera noté := en AP et en ADA. nb := 2; -- range la valeur 2 dans nb

29 Types de base Nous utiliserons 4 types de base
entier (Ada : integer) : nombres sans virgule flottant (Ada : float) : nombres avec virgule. Un flottant s'écrit toujours :flottant ::= chiffre+ "." chiffre+ ex : ctr-ex : Notation exponentielle pour les flottants 1.23e2 = 1.23E2 = 1.23 * 10^2 = 123.0

30 caractère (Ada : character) : 'A', 'b', '?', ...
booléen (Ada : boolean) : valant Vrai ou Faux (Ada : True, False)

31 Opérations arithmétiques de base
Les 4 opérations + - * / Attention, sur des entiers le résultat est arrondi à l ’entier le plus proche nb := 3 / 2; -- nb contient 1 Il est interdit de mélanger des types différents dans une opération quelconque nbf := 3.0 / 2; -- erreur de compilation nbf := 3.0 / 2.0; -- ok, nb vaut 1.5

32 Reste et modulo de la division entière de 2 nombres : rem, mod
nb := 3 rem 2; -- nb vaut 1 nb := 10 mod 5; -- nb vaut 0 Exponentiation (entiers et flottants) : ** nb := 3 ** 2; -- nb vaut 9 fonctionne aussi sur les flottants Valeur absolue (entiers et flottants) : abs() nb := abs(-3); -- nb vaut 3

33 Entrées/sorties sur les types de base
Lecture (ou saisie) d ’une donnée AP : entrer (nom_de_variable) Ada : get (nom_de_variable); Ada permet de spécifier le nombre maximum de caractères (largeur de champ) à prendre en compte : get (nom_variable, largeur_champ) Le programme s ’arrête, l ’utilisateur tape une donnée au clavier suivie d ’un retour chariot. Une donnée est toujours saisie dans une variable.

34 Ecriture (ou sortie) d ’une donnée
AP : sortir (variable | donnée ) Ada : put (variable | donnée ); Ada permet de donner un format à la donnée : nombre de chiffres, … entiers : put (variable | donnée , nb_chiffres); flottants : put (variable | donnée, nb_chiffres_avant_virg , nb_chiffres_apres_virg , nb_chiffres_exposant);

35 Exemples de sorties put(123); put( ); put(123,2); put('A'); put('A'); -- écrit AA Note : le format par défaut des entiers est 8 caractères de large. Un format trop petit est ignoré. put( ); -- écrit E2 put( , 2, 2, 0); -- écrit Note : par défaut les flottants sont écrits en notation scientifique. Si la mantisse est trop grande, le format est partiellement ignoré.

36 Inclure des bibliothèques
En Ada, les entrées/sorties ne sont pas intégrées au langage : il est nécessaire d ’inclure les bibliothèques spécifiques qui contiennent ces instructions optionnelles. Text_io : saisie et sortie de caractères Integer_text_io : d ’entiers Float_text_io : de flottants Note : d'autres constructions peuvent nécessiter d'inclure d'autres bibliothèques...

37 Inclusion de biblis : with bibli_1, bibli_2;
les instructions contenues dans la bibli sont accessible en les préfixant du nom de la bibli: with text_io; procedure aaa is begin text_io.put('A'); end aaa;

38 Si on utilise fréquemment une instruction en provenance d'une bibli, le préfixage devient vite fatiguant, on le supprime avec "use" : with text_io; use text_io; put('A');

39 Pourquoi devoir préfixer par défaut ?
Utile si 2 biblis apportent des instructions de même nom bibli1 programme mon_put with bibli1, bibli2; ... mon_put(123); lequel est-ce ? bibli2 mon_put

40 Conversions de types AP et Ada sont fortement typés : on ne peut pas mélanger des données de types différents dans une même expression. Il est nécessaire de pouvoir convertir des données d ’un type dans un autre : conversion de type (ou changement de type ou transtypage). conversion_de_type ::= nom_de_type ( donnée | variable ) nb := integer(3.5); -- nb vaut 3

41 Structures de contrôle du flux d'instructions
Il est souvent nécessaire que l'état d'un programme (contenu des variables, …) puisse influer sur l'ordre d'exécution des intructions. C'est le rôle des structures de contrôle de préciser comment et à quelles conditions l'ordre d'exécution des instructions peut varier.

42 Structure d'alternative AP
si condition bloc "si" instructions bloc "sinon" instructions Les instructions du bloc "si" ne sont exécutées que si la condition est vérifiée. Les instructions du bloc "sinon" sont exécutées seulement dans le cas contraire.

43 Structure d'alternative ADA
if condition then bloc instr. else -- facultatif end if; if condition_1 then bloc instr. elsif condition_2 then elsif condition_3 then ... else -- facultatif end if;

44 Expressions booléennes, opérateurs relationnels
Une condition est une expression booléenne. Elle est vérifiée si elle vaut vrai (true). Opérateurs relationnels : <, <=, >, >=, =, /= et (and), ou (or), non (not) ou exclusif (xor) et alors (and then), ou sinon (or else) dans (in), dehors (not in)

45 Structure de cas AP cas : expression expr_1 expr_2 ... expr_n défaut
bloc_1 instructions bloc_2 instructions bloc_n instructions bloc_défaut instructions

46 La valeur de expression doit correspondre à une et une seule des valeurs données dans les losanges.
Seul le bloc situé sous la bonne valeur est exécuté. Après exécution de ce bloc, on sort de la structure de cas, les autres blocs sont ignorés.

47 Structure de cas ADA case expr is
when \ expr | interv_discr | others \ {| …} => statement {…} {…} end case; Exemple : case nb is -- nb est une variable entiere when 1 | 2 | 3 => put("1,2 ou 3); new-line; when => put("entre 5 et 10"); new_line; when others => null; -- instruction vide

48 3 règles à retenir pour l'ensemble des choix :
il doit être exhaustif (d'où l'utilisation fréquente de others) il ne doit pas y avoir de répétitions les choix doivent être "statiques" (c'est à dire évaluables lors de la compilation)

49 Expression statique ou dynamique
Une expression "statique" est une expression dont la valeur peut être calculée lors de la compilation du programme. Une expression "dynamique" dépend, à priori, de l'exécution du programme. Ex : le contenu d'une variable est susceptible de changer lors de l'exécution d'un programme (par définition…). Par conséquent, toute expression qui comporte une variable est considérée comme dynamique, même si l'auteur du programme sait que le contenu de la variable en question ne sera pas changé !

50 Phases d'écriture d'un programme
Écriture du source Compilation : traduction du source en objet Préprocesseur (nettoie le source) Compilateur (traduit en assembleur) Assembleur (traduit en code machine) Éditeur de liens : traduction de l'objet en exécutable, regroupement en un seul fichier des différents modules qui constituent le programme Chargeur : installe l'exécutable en mémoire, puis l'exécute

51 Structure de boucle AP tantque condition nom_bloc instructions Le bloc d ’instruction est exécuté tant que la condition est vraie.

52 Structure de boucle ADA
while condition loop bloc_instr end loop; Exemple : while (nb < 12) loop put(nb); nb := nb + 1;

53 Boucle « pour » AP pour variable de boucle nom_bloc variable dans
envers a..b instructions facultatif intervalle Le bloc d ’instruction est exécuté autant de fois que d'éléments dans l ’intervalle discret [a..b]. La boucle "pour" n'est à utiliser que si on connait à l'avance le nombre de tours à effectuer.

54 La variable de boucle : Attention : Ne doit pas être déclarée.
Masque toute autre variable déjà déclarée de même nom, dans tout le sous-arbre du bloc d'instruction. Contient la valeur courante dans l ’intervalle. Est considérée comme une constante dans le bloc d ’instruction : on ne peut pas la modifier. Attention : Si b < a, l ’intervalle est vide, on ne le parcourt pas ! Si on souhaite parcourir l ’intervalle à l ’envers, utiliser le mot-clé « envers ».

55 Boucle « pour » ADA for variable in reverse intervalle loop bloc_instr
end loop; Exemples : for i in loop put(i); end loop; for i in character'('A')..character'('Z') loop put(i); end loop;

56 -- n ’affiche rien ! for i in loop put(i); end loop; -- affiche de 10 à 1 for i in reverse loop -- affiche 1 à 10, puis 3 ! i := 3; for i in loop put(i); end loop; -- ne compile pas ! i := i + 1;

57 Boucle avec sortie loop instr {…} exit when condition; -- facultatif
end loop;

58 Exemple : -- compte une séquence de nombres terminée par 0
-- nb et compteur sont des variables entières put("Entrez vos nombres, terminez par 0"); new_line; loop get(nb); exit when nb = 0; compteur := compteur + 1; end loop; put("Decompte = "); put (compteur); new_line;

59 De plus, les boucles ADA peuvent recevoir un identifiant de boucle, qui peut se combiner avec l'instruction exit. Bcl1: loop {…} Bcl2: loop exit Bcl1; end loop;

60 Résumé des différentes structures de boucle en ADA
[id:] [while bool_expr | for id in [reverse] discrete_range] loop statement {…} end loop [id]; exit [loop_id] [when bool_expr];

61 Bloc déclaratif AP Il peut être utile de déclarer des variables pour un usage momentané : leur portée peut être réduite au bloc d'instruction où elles servent. En AP : nom_bloc var1, var2 : type1; var3, var4, var5 : type2; bloc_instr

62 Bloc déclaratif ADA [id:] declare declarative_item begin
handled_statement end [id]; handled_statement ::= statement {…} [exception_handler]

63 Exemple de bloc déclaratif :
Le "handled_statement" est un simple bloc d'instructions, qui se termine par un traitant d'exceptions : des instructions servant à rattraper d'éventuelles erreurs lors de l'exécution. Exemple de bloc déclaratif : declare tmp : integer; begin tmp := A; A := B; B := tmp; end;

64 Types tableaux De nombreuses applications nécessitent de mémoriser des séries de variables : composantes de vecteurs ou de matrices, tables de température ou de pression, … On peut stocker ces données dans une structure simple appelée tableau, à l'intérieur de laquelle chaque donnée est associée à un ou plusieurs numéros appelé indices. On accède à une donnée en rappelant le nom du tableau et son ou ses indices.

65 Tableaux AP Représentation d'un tableau à 1 dimension :
indices 16 14 13 12 1 2 3 4 5 6 7 8 temperatures nom du tableau temperatures(1) temperatures(6) variables Une variable de type tableau doit être déclarée, en précisant le type unique des valeurs contenues dans le tableau et les bornes du tableau : temperatures : tableau (1..8) d'entiers;

66 Tableaux ADA On peut les déclarer comme des variables :
tab1 : array(1..8) of integer; tab2 : array(1..8) of integer; Attention, tab1 et tab2 sont considérés comme étant de types différents : pas d'affectation possible au niveau tableau sans une conversion. pas de possibilité de les passer en paramètre à une fonction ou à une procédure (voir plus loin).

67 Pas de problème d'affectation, ni de passage en paramétre.
En général, on déclare un type tableau avant de déclarer les variables : type tab_int_8 is array(1..8) of integer; tab1, tab2 : tab_int_8; Pas de problème d'affectation, ni de passage en paramétre. Les déclarations de types se placent dans la partie déclarative d'une unité de compilation ou d'un bloc déclaratif. Nous utiliserons la même convention en AP.

68 Exemple sur les tableaux
max_tab max : entier type tab20int est tableau(1..20) d'entiers tab : tab20int; seq saisie déterminer_max afficher_max pour seq Sortir(max) i dans 1..taille Entrer(tab(i)) initialiser Comparer avec tous pour max := tab(1) i dans 2..taille si max < tab(i) max := tab(i)

69 -- comparer avec tous for i in 2..Taille loop if max < tab(i) then max := tab(i); end if; end loop; -- afficher max put("le max est :"); put(max); new_line; end max_tab; Procedure max_tab is Taille : constant := 20; type Tab20Int is array(1..Taille) of integers; max : integer; tab : Tab20Int; begin -- saisie put_line("entrez le tableau"); for i in 1..Taille loop get(tab(i)); end loop; -- determiner max -- initialiser max := tab(1);

70 Règles, opérations et attributs de tableaux
un tableau ne peut contenir qu'un seul type d'éléments; on ne peut pas utiliser un indice en dehors des bornes définies à la déclaration du tableau, sous peine de "plantage"; on peut affecter un tableau à un autre tableau s'ils sont compatibles : même taille, même type d'éléments (une conversion de type peut être nécessaire) : a, b : tab_int; a := b;

71 On peut concaténer des tableaux avec &
Un tableau connaît ses bornes : a'first, a'last l'intervalle des indices corrects : a'range (équivalent à a'first..a'last) la longueur de cet intervalle : a'length On peut comparer des tableaux (<, >, <=, >=) selon le principe de l'ordre lexicographique quand tout est égal, un tableau plus court est considéré comme plus "petit" ou "avant" dans l'ordre. On peut concaténer des tableaux avec & a(1..10) := b(1..5) & c(2..6);

72 Les tranches On peut extraire un "morceau" de tableau, il suffit que les indices soient contigus : a, b : tab_int; a(1..5) := b(6..10); Attention lors d'une telle affectation à vérifier que les 2 tranches soient de même taille. Les tranches peuvent se superposer : a(1..5) := a(2..6) -- décale la tranche 2..6 d'une case

73 Les agrégats Permettent d'initialiser les tableaux : declare
type TABLE is array(4..9) of integer; t : TABLE := (1, 2, 3, 4, 5, 6); begin t := TABLE'(4 | 6 => 1, others => 0); t := TABLE'(4..7 => 2, 8..9 => 3); end;

74 Les chaînes de caractères AP
Les chaînes de caractères sont des données très utilisées : il existe un type chaine prédéfini. Le type chaine est un en fait un tableau de caractère, avec une syntaxe raccourcie : ch1, ch2 : chaine(1..8); -- conseillé ch3 : tableau(1..8) de caractères; -- déconseillé Attention, dans l'exemple précédent ch1 et ch2 sont de même type, mais pas ch3, bien que ces 3 objets soient représentés de manière identique en mémoire.

75 Les chaînes de caractères ADA
En ADA, on dispose du type STRING : ch1, ch2 : string(1..8); -- conseillé ch3 : array(1..8) of character; -- déconseillé Comme en AP, ch1 et ch2 sont de même type, mais pas ch3, bien que ces 3 objets soient représentés de manière identique en mémoire. Accès : ch1(1) := ch2(8); ch1(1..5) := ch2(1..2) & ch2(2..4);

76 Entrées/sorties sur les chaînes
get(ch1); -- attention, taper exatement 8 caractères!!! get_line(ch1, lng1); -- le nombre de cars tapés sera -- rangé dans lng1, qu'il faut déclarer (var. entière). Sortie : put(ch1); put_line(ch1); -- passe à la ligne suivante -- !!! Put_line ne fonctionne qu'avec des chaînes !!!

77 Attributs relatifs aux chaînes et aux caractères
Image : renvoie la représentation d'un type sous forme de chaîne. Value : renvoie la "valeur" d'une chaine. Pred, Succ : le précédent et le suivant. Pos, Val : la position et son inverse Integer'image(300) = "300" Character'image('z') = "z" Integer'value("300") = 300 Character'value(" 'z' ") = 'z' Character'pred('2') = '1' Character'succ('A') = 'B' Character'pos('0') = 48 Character'val(48) = '0'

78 Les tableaux à plusieurs dimensions
Array_type_def ::= array (discrete_range {, …}) of type Exemple : type MATRICE is array(1..10, 1..10, 1..10) of float; type TAB_2D is array(1..5, -1..0) of integer; m1, m2 : MATRICE; t : TAB_2D;

79 Accès : Agrégats : m1(1,1,1) := m2(1,1,10); get(m1(i,j,k));
t := TAB_2D'((1,1), (2,2), (3,4), (4,5), (5,5)); t := TAB_2D'((1,1), (2,2), others => (3,3)); t := TAB_2D'(1 | 3 => (1,1), others => (0,0 ); t := TAB_2D'(others => (-1 => 1, others => 0)); t := TAB_2D'(others => (others => 0));

80 Attributs : first(i), last(i), range(i), length(i) où i est le numéro de la dimension : t'first(1) = 5 t'first(2) = -1 t'range(1) = 1..5 t'range(2) = -1..0 first(1), last(1), range(1), length(1) se notent aussi first, last, range, length.

81 Les sous-programmes : procédures et fonctions
Subprogram_body ::= subprogram_spec is {declarative_item} begin handled_statement end; Subprogram_spec ::= procedure [parent_name.]id [formals] | function [parent_name.]id [formals] return subtype_name

82 Formals ::= Exemples : (id {, id} : [in | in out | out] subtype_name
[:= expr] {; …}) Exemples : procedure efface_ecran is … procedure passe_lignes (x : integer) is … function lire_entier return integer is … function perimetre (rayon : float) return float is … procedure peri_surf (rayon : in float; perimetre, surface : out float) is ...

83 Un sous-programme est exécuté à chaque appel Lors de l'appel, le paramètre formel prend la valeur du paramètre effectif Paramètre effectif Paramètre formel Flux des instructions procedure exemple is begin passe_lignes(2); N := 10; passe_lignes(N); end exemple; procedure passe_lignes(X : integer) is begin for cpt in 1..X loop new_line; end loop; end passe_lignes; Spécification de sous-programme Appels de sous-programme

84 Les sous-programmes servent :
à éviter les répétitions inutiles de code, lorsqu'un ensemble d'instructions sert à plusieurs endroits. à structurer le programme en isolant des fonctionnalités spécifiques dans des sous-programmes séparés : c'est comme si on ajoutait de nouvelles instructions de base. Les sous-programmes doivent : éviter au maximum d'utiliser des variables déclarées en dehors d'eux-mêmes : utiliser les paramètres pour communiquer les données. conserver une taille raisonnable pour pouvoir être compris et mis au point sans pb : au maximum 60 lignes

85 Position des procédures et fonctions
1) Dans des fichiers séparés, un par procédure/fonction : On les inclus dans le programme principal avec "with nom_proc" (le fichier doit avoir le même nom). La clause "use" n'est pas nécessaire. Elles ne connaissent pas les types/variables du programme principal ! 2) Dans la procédure principale, dans la section déclarative (là où on place les déclarations de types, de variables, …) Elles connaissent les déclarations placées avant.

86 Déclarations préliminaires
Une procédure ne peut en appeler une autre qui soit déclarée après : C'est génant, obligation de bouger le morceau de code à la bonne place. C'est parfois inextricable : si p1 appelle p2 et p2 appelle p1, bouger le code n'est pas la solution. On recourt à une déclaration préliminaire, que l'on place le plus haut possible : Même syntaxe qu'une déclaration ordinaire, sauf qu'on s'arrête au "is", qui est remplacé par ";" procedure lire_somme (s : out integer) ; -- decl. prelim.

87 Paramètres et valeur de retour
Les paramètres des sous-programmes et la valeur de retour des fonctions servent à échanger des données avec le programme appelant. dans la déclaration du ss-prog : paramètres formels dans l'appel au ss-prog : paramètres effectifs Une procédure ne retourne pas de valeur, mais elle peut prendre des paramètres qui peuvent être modifiés. Une fonction retourne obligatoirement une unique valeur. Ses paramètres ne peuvent être modifiés (penser aux fonctions mathématiques).

88 La valeur d'une fonction est retournée par l'instruction : return expression;
Si le flux d'instruction atteint le "end" final d'une fonction sans rencontrer de "return", l'exception "program_error" est levée. On peut utiliser return ; dans une procédure : on quitte la procédure en cours et on revient à l'appelant (rien n'est retourné).

89 Les modes des paramètres :
in : lecture seule (comme une constante) out : écriture seule in out : lecture / écriture (comme une variable) Si on n'indique pas de mode, c'est le mode "in" par défaut. Une fonction a toujours ses paramètres en mode "in". Attention, en mode "out" on ne peut pas consulter (lire) la valeur du paramètre, ce qui peut être déconcertant.

90 Procedure lire_somme (s : out integer) is
-- met dans s la somme des entiers saisis par l'utilisateur n, tmp : integer := 0; begin put_line("entrer vos entiers (terminer par -1)"); get(n); while n /= -1 loop -- s := s + tmp; est interdit (car mode "out") tmp := tmp + n; end loop; s := tmp; -- on a seulement le droit d'ecrire dans s end;

91 Paramètres par défaut Les paramètres peuvent recevoir une valeur par défaut : on n'est alors pas obligé de les fournir. Dans text_io, "new_line" est déclaré ainsi : procedure new_line (spacing : positive := 1) is … On peut appeler new_line sans paramètre, dans ce cas new_line passe 1 seule ligne.

92 Portée et visibilité Portée d'une entité (type, variable, constante…) : partie du code où sa déclaration est effective, c'est à dire où l'entité existe. Visibilité d'une entité : partie du code où l'entité est accessible. La visibilité est toujours incluse dans la portée : on ne peut accéder qu'à une entité qui existe. La visibilité est souvent plus réduite que la portée : masquages temporaires par des entités portant le même nom et plus locales.

93 Toute entité déclarée dans la partie déclarative d'un sous-programme ou d'un bloc "declare" :
n'est visible que dans ce sous-programme ou ce bloc. disparaît une fois le sous-programme ou le bloc terminé.

94 With … ; use … ; Procedure portee_visibilite is A : constant := 123; B : integer := A + 1; -- debut de la visibilite de A C : integer := 12; -- debut de la visibilite de B function f (B : character := integer'image(C)(2)) -- debut visibilite C return integer is C : integer := 0; -- debut de la visibilite de B de f begin -- debut de la visibilite de C de f return character'pos(B) + C; end; begin -- retour de la visibilite de B et C après masquage dans f put(A); put(f('A')); put(f); put (B); put(C); put(integer'image(C)); -- affiche : end portee_visibilite;

95 Récursivité Un sous-programme peut s'appeler lui-même :
function factorielle(N : integer) return integer is begin if N = 0 then return 1; -- condition d'arrêt else return N * factorielle(N - 1); -- appel récursif end if; end factorielle;

96 CE QU'IL FAUT COMPRENDRE :
chaque niveau d'appel récursif crée sa propre copie des paramètres formels et des variables locales. lors du retour d'un appel récursif on retrouve donc intactes les valeurs des paramètres et des variables (sauf si elles ont été passées récursivement en mode "out", bien entendu !) dans le code du sous-programme, il doit y avoir une alternative où on ne relance pas un appel révursif, sinon la récursion est infinie (concrètement ça plante après avoir saturé la mémoire de la machine).

97 Plusieurs sous-programmes peuvent s'appeler les uns les autres :
function syracuse1(N : integer) return integer is begin if N /= 1 and N % 2 = 0 then return syracuse1(N / 2); elsif N /= 1 then return syracuse2(N); else return N; end if; end; -- conjecture de syracuse get(N); put(syracuse1(N)); function syracuse2(N : integer) return integer is begin if N /= 1 and N % 2 /= 0 then return syracuse2(3 * N + 1); else return syracuse1(N); end if; end;

98 Comment aborder un problème récursif ?
Attention, dans l'exemple précédent on a besoin de déclarations préliminaires pour compiler. Comment aborder un problème récursif ? Il faut avoir l'intuition qu'il se traite récursivement. Si on ne sait pas le traiter de manière classique, ça ne coûte rien de se poser la question… Il faut déterminer sur quelle "variable" (ex: N) on fait la récurrence. Il faut avoir une solution d'arrêt de la récursivité (quand N est petit). Supposant avoir la solution au rang N-1, trouver ce qu'il faut faire pour passer au rang N.

99 Retour sur les types Type / Sous-type
une déclaration de type est statique type mon_entier is range ; -- ok N : integer := 100; -- variable, non statique type mon_entier2 is range 1..N; -- interdit !!! une déclaration de sous-type peut être dynamique, elle s ’appuie sur un type pré-existant N : integer := 100; -- variable subtype mon_entier3 is integer range 1..N;

100 Types entiers with ada.text_io; use ada.text_io;
procedure test_instanciation is type mon_entier is range ; package mon_entier_io is new ada.text_io.integer_io(mon_entier); use mon_entier_io; -- autorise les E/S sur ce nouveau type n : mon_entier; begin put("entrer un entier : "); get(n); -- raise DATA_ERROR si pas dans put(n * 2); -- raise CONSTRAINT_ERROR si pas dans end;

101 Types énumératifs with ada.text_io, ada.integer_text_io;
use ada.text_io, ada.integer_text_io; procedure test_type_enumere is type JOUR is (LUNDI, MARDI, MERCREDI, JEUDI, VENDREDI, SAMEDI, DIMANCHE); package jour_io is new ada.text_io.enumeration_io(jour); use jour_io; n : integer; begin put("entrer un entier : "); get(n); put(JOUR'VAL(n mod 7)); end;

102 Attributs pour types énumérés
jour'first # LUNDI jour'last # DIMANCHE jour'succ(LUNDI) # MARDI jour'pred(MARDI) # LUNDI jour'pos(LUNDI) # 0 jour'val(0) # LUNDI jour'value("LUNDI") # LUNDI jour'image(LUNDI) # "LUNDI"

103 Type booléen Types flottants
type boolean is (FALSE, TRUE); -- type énuméré Types flottants On peut préciser le nombre de chiffres significatifs : digits N = précision au 1/10^N On peut limiter l'intervalle des valeurs possibles type REEL is digits 6; type VOLTAGE is digits 5 range E+9; Attributs type FL is digits D range I..S FL'digits # D FL'first # I FL'last # S E/S : instancier ada.text_io.float_io(nom_type)

104 Types tableaux contraints / non contraints
type vecteur1 is array(1..10) of float; v1, v2 : vecteur1; toutes les variables de type vecteur1 ont mêmes dimensions tableaux non contraints type vecteur2 is array(integer range <>) of float; v1 : vecteur2(1..10); v2 : vecteur2(-5..15); v1 et v2 sont de même type, mais de dimensions différentes on doit fournir les bornes lors d'une déclaration de variable de type vecteur2

105 Intérêt des tableaux non contraints
Quand ils apparaissent en tant que paramètres formels, il n'est pas nécessaire de préciser leur taille (car ce n'est pas une déclaration de variable) : Procedure truc(v : in out vecteur2) is … On utilise les attributs de tableau pour connaître l'intervalle des indices. Rappel : les chaînes de caractères En fait le type STRING est simplement un type tableau de caractères non contraint : type STRING is array(integer range <>) of character;

106 Type Article / Enregistrement (record)
Si un tableau est une collection de variables de même type accessibles via leur numéro, un article est une collection de variables de types qui peuvent être différents, accessibles par leur nom. Les différentes variables de l'article s'appellent des champs. La variable de type article possède son propre nom, on accède à ses champs par la notation pointée : nom_d_article.nom_de_champ

107 Exemple : type MOIS is (Janvier, Fevrier, …, Decembre); type DATE is record jour : integer range 1..31; mois : MOIS; an : integer; end record; d : DATE; d := (14, Juillet, 1789); d := (jour => 14, an => 1789, mois => Juillet); d.mois := Mars; d.jour := 12; d.an := d.an + 1;

108 Type Article avec partie variante
type Genre_Figure is (un_cercle, un_point, un_carre); type Point is record X, Y : Integer; end record; type Figure (Sorte : Genre_Figure := un_point) is record Position : Point; case Sorte is when un_cercle => Rayon : Integer; when un_carre => Coin_Inf_Droit : Point; when others => null; end case; F : Figure := (un_point, (10,15)); F := (un_cercle, position => (20, 25), rayon => 50);

109 Partie variante : comment ça marche ?
Entre les différents contructions rendues possibles dans la partie variante, le compilateur calcule celle qui occupe le plus de place et alloue cette place à la variable. Dans l'exemple, c'est le carré qui prend le plus de place. Si on charge la variable avec un point ou un cercle, une partie de la mémoire reste inutilisée, tout simplement. On ne peut changer le discriminant (variable qui sélectionne la partie variante) que si on change tout le reste de l'article.


Télécharger ppt "Algorithmique Procédurale"

Présentations similaires


Annonces Google