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 IUP GMI 1ère année Denis Robilliard.

Présentations similaires


Présentation au sujet: "Algorithmique Procédurale IUP GMI 1ère année Denis Robilliard."— Transcription de la présentation:

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

2 Sommaire zIntroduction yHistorique yLa machine de Turing yLangages de programmation yArbres programmatiques et Ada ySyntaxe, expressions régulières zPremier programme yPremier programme en Ada yInstructions

3 yCommentaires yVariables, affectations yTypes de base yOpérations arithmétiques de base yEntrées/sorties sur les types de base yInclure des bibliothèques yConversions de types zStructures de contrôle du flux d instructions yStructure d'alternative AP / ADA yExpressions booléennes, opérateurs relationnels

4 yStructure de cas AP / ADA yExpression statique ou dynamique yPhases d'écriture d'un programme yStructure de boucle AP /ADA yBoucle "pour" AP / ADA yBoucle avec sortie yRésumé des différentes structures de boucle en ADA yBloc déclaratif AP /ADA zTypes tableaux yTableaux AP / ADA

5 yExemple sur les tableaux yRègles, opérations et attributs de tableaux yLes tranches yLes agrégats yLes chaînes de caractères AP / ADA yEntrées / sorties sur les chaînes yAttributs relatifs aux chaînes et aux caractères yLes tableaux à plusieurs dimensions zLes sous-programmes : procédures et fonctions yParamètres et valeur de retour

6 yParamètres par défaut yPosition des procédures et des fonctions yDéclarations préliminaires yPortée et visibilité zRécursivité zRetour sur les types, enregistrements

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

8 zAlgo 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. zIl existe d autres formes d algo : parallèle, objet, fonctionnelle, déclarative,...

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

10 zPremière personne à programmer : Lady Ada Lovelace, "assistante" de Babbage. zThé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". zPremiers ordinateurs électroniques mis au point pendant la 2nde guerre mondiale.

11 La machine de Turing zUn "ordinateur" de papier : yune bande de papier, finie mais aussi longue qu on le souhaite, divisée en cases qui peuvent contenir les symbole 0 ou 1 yune "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 y… (voir page suivante)

12 y un programme, composé de règles de la forme : ~ x 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 x {s, s } dans {0,1} les symboles que l on peut écrire sur la bande x 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 zReprésentation de la machine de Turing Tête de lecture dans la configuration de départ... q Position de la tête de lecture et état de la bande après application de la règle : ~... q1

14 zExemple de programme yObjectif : 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. yNote : 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 zLe programme : ~ zNote : yq0 est l état initial de la machine y qF est l état final : quand la machine passe dans l état qF elle s arrête

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

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

18 Arbres Programmatiques et Ada zNous utiliserons 2 langages : yUn langage pédagogique, en partie graphique, noté AP : les Arbres Programmatiques. Note : ce ne sont pas des organigrammes. yUn 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 zPourquoi les arbres programmatiques ? yC est une notation "papier" (nous n exécuterons pas un AP sur machine). Nous nous permettrons une syntaxe plus souple. yLes APs forcent le programmeur à une approche hiérarchique, descendante du problème. zC est la "programmation structurée" : yOn part des idées générales et on va progressivement de plus en plus dans le détail. yLes 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 zLa programmation procédurale structurée marche très bien pour concevoir de petites applications (- de 5000 lignes). zD autres approches, notamment la conception objet, seront vues plus tard dans le cursus pour les applis plus importantes. yNote : le code de la navette spatiale américaine fait plus de de lignes...

21 Syntaxe, expressions régulières zPas de langage sans syntaxe (ou orthographe) yNous utiliserons une forme restreinte des « expressions régulières » pour définir précisément la syntaxe autorisée, particulièrement en Ada. yExemple : identifiant ::= lettre { [ _ ] / lettre | chiffre / } yCe 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 zSymboles formant les expressions rationnelles y ::= introduit l expression rationnelle qui définit la syntaxe associée au concept; y [ ] délimitent une sous-expression facultative; y { } délimitent un motif qui peut être répété; y … désigne un terme identique au terme précédent; y | (barre verticale) "ou bien" dans une énumération; y \ \ délimitent une série d'option d'options parmi lesquelles il faut choisir une; y en_gras dénote un mot réservé (mot clé) de ADA ou un symbole à prendre littéralement.

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

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 zUn programme est composé d instructions. Une instruction peut elle-même contenir d autres instructions. zPar défaut, les instructions s'exécutent en séquence. zEn Ada les instructions sont terminées par un point virgule (facultatif en AP). zUne instruction peut s étendre sur plusieurs lignes. zPas de différence entre majuscules et minuscules

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

27 Variables, affectation zChaque donnée (nombre, caractère, …) que l on veut réutiliser ultérieurement doit être stockée dans un emplacement mémoire appelé "variable". zLes 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 zLes 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. zL affectation est une instruction. Elle sera noté := en AP et en ADA. ynb := 2; -- range la valeur 2 dans nb

29 Types de base zNous utiliserons 4 types de base yentier (Ada : integer) : nombres sans virgule yflottant (Ada : float) : nombres avec virgule. Un flottant s'écrit toujours :flottant ::= chiffre+ "." chiffre+ xex : xctr-ex : yNotation exponentielle pour les flottants x1.23e2 = 1.23E2 = 1.23 * 10 ^2 = 123.0

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

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

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

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

34 zEcriture (ou sortie) d une donnée yAP : sortir (variable | donnée ) yAda : put (variable | donnée ); xAda permet de donner un format à la donnée : nombre de chiffres, … xentiers : put (variable | donnée, nb_chiffres); xflottants : put (variable | donnée, nb_chiffres_avant_virg, nb_chiffres_apres_virg, nb_chiffres_exposant);

35 zExemples de sorties yput(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é. yput( ); -- écrit E2 yput( , 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 zEn 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. yText_io : saisie et sortie de caractères yInteger_text_io : d entiers yFloat_text_io : de flottants zNote : d'autres constructions peuvent nécessiter d'inclure d'autres bibliothèques...

37 zInclusion de biblis : ywith bibli_1, bibli_2; yles 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 zSi 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 zPourquoi devoir préfixer par défaut ? Utile si 2 biblis apportent des instructions de même nom bibli1 mon_put bibli2 mon_put programme with bibli1, bibli2;... mon_put(123);... lequel est-ce ?

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

41 Structures de contrôle du flux d'instructions zIl est souvent nécessaire que l'état d'un programme (contenu des variables, …) puisse influer sur l'ordre d'exécution des intructions. zC'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 zLes instructions du bloc "si" ne sont exécutées que si la condition est vérifiée. zLes instructions du bloc "sinon" sont exécutées seulement dans le cas contraire. si condition bloc "sinon" instructions bloc "si" instructions

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

44 Expressions booléennes, opérateurs relationnels zUne condition est une expression booléenne. zElle est vérifiée si elle vaut vrai (true). zOpérateurs relationnels : y, >=, =, /= yet (and), ou (or), non (not) you exclusif (xor) yet alors (and then), ou sinon (or else) ydans (in), dehors (not in)

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

46 zLa valeur de expression doit correspondre à une et une seule des valeurs données dans les losanges. zSeul le bloc situé sous la bonne valeur est exécuté. zAprè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; zExemple : 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 end case;

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

49 Expression statique ou dynamique zUne expression "statique" est une expression dont la valeur peut être calculée lors de la compilation du programme. zUne expression "dynamique" dépend, à priori, de l'exécution du programme. zEx : 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 zÉcriture du source zCompilation : traduction du source en objet yPréprocesseur (nettoie le source) yCompilateur (traduit en assembleur) yAssembleur (traduit en code machine) zÉditeur de liens : traduction de l'objet en exécutable, regroupement en un seul fichier des différents modules qui constituent le programme zChargeur : installe l'exécutable en mémoire, puis l'exécute

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

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

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

54 zLa variable de boucle : yNe doit pas être déclarée. yMasque toute autre variable déjà déclarée de même nom, dans tout le sous-arbre du bloc d'instruction. yContient la valeur courante dans l intervalle. yEst considérée comme une constante dans le bloc d instruction : on ne peut pas la modifier. zAttention : ySi b < a, l intervalle est vide, on ne le parcourt pas ! ySi 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; for i in character'('A')..character'('Z') loop put(i); end loop; for i in loop put(i); end loop; zExemples :

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

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

58 zExemple : -- 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 zDe 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 z[id:] [while bool_expr | for id in [reverse] discrete_range] loop statement {…} end loop [id]; zexit [loop_id] [when bool_expr];

61 Bloc déclaratif AP zIl 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. zEn AP : nom_bloc var1, var2 : type1; var3, var4, var5 : type2; bloc_instr

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

63 zLe "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. zExemple de bloc déclaratif : declare tmp : integer; begin tmp := A; A := B; B := tmp; end;

64 Types tableaux zDe 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, … zOn 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. zOn accède à une donnée en rappelant le nom du tableau et son ou ses indices.

65 Tableaux AP zReprésentation d'un tableau à 1 dimension : temperatures nom du tableau indices variablestemperatures(1)temperatures(6) zUne 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 zOn peut les déclarer comme des variables : tab1 : array(1..8) of integer; tab2 : array(1..8) of integer; zAttention, tab1 et tab2 sont considérés comme étant de types différents : ypas d'affectation possible au niveau tableau sans une conversion. ypas de possibilité de les passer en paramètre à une fonction ou à une procédure (voir plus loin).

67 zEn 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; zPas de problème d'affectation, ni de passage en paramétre. zLes déclarations de types se placent dans la partie déclarative d'une unité de compilation ou d'un bloc déclaratif. zNous 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; saisie déterminer_max afficher_max i dans 2..taille i dans 1..taille pourseq pour seq Comparer avec tous initialiser Entrer(tab(i)) max := tab(1) Sortir(max) max := tab(i) max < tab(i) si

69 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); -- 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;

70 Règles, opérations et attributs de tableaux zun tableau ne peut contenir qu'un seul type d'éléments; zon ne peut pas utiliser un indice en dehors des bornes définies à la déclaration du tableau, sous peine de "plantage"; zon 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 zUn tableau connaît yses bornes : a'first, a'last yl'intervalle des indices corrects : a'range (équivalent à a'first..a'last) yla longueur de cet intervalle : a'length zOn peut comparer des tableaux (, =) selon le principe de l'ordre lexicographique yquand tout est égal, un tableau plus court est considéré comme plus "petit" ou "avant" dans l'ordre. z On peut concaténer des tableaux avec & a(1..10) := b(1..5) & c(2..6);

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

73 Les agrégats zPermettent 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 zLes chaînes de caractères sont des données très utilisées : il existe un type chaine prédéfini. zLe 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é zAttention, 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 zEn ADA, on dispose du type STRING : ch1, ch2 : string(1..8); -- conseillé ch3 : array(1..8) of character; -- déconseillé zComme 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. zAccès : ch1(1) := ch2(8); ch1(1..5) := ch2(1..2) & ch2(2..4);

76 Entrées/sorties sur les chaînes zEntrée : 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). zSortie : 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 zImage : renvoie la représentation d'un type sous forme de chaîne. zValue : renvoie la "valeur" d'une chaine. zPred, Succ : le précédent et le suivant. zPos, Val : la position et son inverse Character'pred('2') = '1' Character'succ('A') = 'B' Character'pos('0') = 48 Character'val(48) = '0' Integer'image(300) = "300" Character'image('z') = "z" Integer'value("300") = 300 Character'value(" 'z' ") = 'z'

78 Les tableaux à plusieurs dimensions zArray_type_def ::= array (discrete_range {, …}) of type zExemple : 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 zAccès : ym1(1,1,1) := m2(1,1,10); yget(m1(i,j,k)); zAgrégats : yt := TAB_2D'((1,1), (2,2), (3,4), (4,5), (5,5)); yt := TAB_2D'((1,1), (2,2), others => (3,3)); yt := TAB_2D'(1 | 3 => (1,1), others => (0,0 ); yt := TAB_2D'(others => (-1 => 1, others => 0)); yt := TAB_2D'(others => (others => 0));

80 zAttributs : yfirst(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) = yfirst(1), last(1), range(1), length(1) se notent aussi first, last, range, length.

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

82 zFormals ::= (id {, id} : [in | in out | out] subtype_name [:= expr] {; …}) zExemples : 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 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; Flux des instructions Appels de sous-programme Paramètre effectif Paramètre formel zUn sous-programme est exécuté à chaque appel Lors de l'appel, le paramètre formel prend la valeur du paramètre effectif Spécification de sous-programme

84 zLes sous-programmes servent : yà éviter les répétitions inutiles de code, lorsqu'un ensemble d'instructions sert à plusieurs endroits. yà 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. zLes sous-programmes doivent : yé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. yconserver une taille raisonnable pour pouvoir être compris et mis au point sans pb : au maximum 60 lignes

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

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

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

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

89 zLes modes des paramètres : yin : lecture seule (comme une constante) yout : écriture seule yin out : lecture / écriture (comme une variable) zSi on n'indique pas de mode, c'est le mode "in" par défaut. zUne fonction a toujours ses paramètres en mode "in". zAttention, 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; get(n); end loop; s := tmp; -- on a seulement le droit d'ecrire dans s end;

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

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

93 zToute entité déclarée dans la partie déclarative d'un sous-programme ou d'un bloc "declare" : yn'est visible que dans ce sous-programme ou ce bloc. ydisparaî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é zUn 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 zCE QU'IL FAUT COMPRENDRE : zchaque niveau d'appel récursif crée sa propre copie des paramètres formels et des variables locales. zlors 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 !) zdans 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 zPlusieurs sous-programmes peuvent s'appeler les uns les autres : -- 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; 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;

98 yAttention, dans l'exemple précédent on a besoin de déclarations préliminaires pour compiler. zComment aborder un problème récursif ? yIl 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… yIl faut déterminer sur quelle "variable" (ex: N) on fait la récurrence. yIl faut avoir une solution d'arrêt de la récursivité (quand N est petit). ySupposant avoir la solution au rang N-1, trouver ce qu'il faut faire pour passer au rang N.

99 Retour sur les types zType / Sous-type yune 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 !!! yune 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 zTypes 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 zTypes é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 zAttributs pour types énumérés yjour'first # LUNDI yjour'last # DIMANCHE yjour'succ(LUNDI) # MARDI yjour'pred(MARDI) # LUNDI yjour'pos(LUNDI) # 0 yjour'val(0) # LUNDI yjour'value("LUNDI") # LUNDI yjour'image(LUNDI) # "LUNDI"

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

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

105 yIntérêt des tableaux non contraints xQuand 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 … xOn utilise les attributs de tableau pour connaître l'intervalle des indices. yRappel : les chaînes de caractères xEn fait le type STRING est simplement un type tableau de caractères non contraint : type STRING is array(integer range <>) of character;

106 zType Article / Enregistrement (record) ySi 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. yLes différentes variables de l'article s'appellent des champs. yLa 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 yExemple : 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; end record; F : Figure := (un_point, (10,15)); F := (un_cercle, position => (20, 25), rayon => 50);

109 yPartie variante : comment ça marche ? xEntre 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. xDans 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. xOn 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 IUP GMI 1ère année Denis Robilliard."

Présentations similaires


Annonces Google