1.11k likes | 1.29k Views
Algorithmique Procédurale. IUP GMI 1ère année Denis Robilliard. Sommaire. Introduction Historique La machine de Turing Langages de programmation Arbres programmatiques et Ada Syntaxe, expressions régulières Premier programme Premier programme en Ada Instructions. Commentaires
E N D
Algorithmique Procédurale IUP GMI 1ère année Denis Robilliard
Sommaire • Introduction • Historique • La machine de Turing • Langages de programmation • Arbres programmatiques et Ada • Syntaxe, expressions régulières • Premier programme • Premier programme en Ada • 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
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
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
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
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.
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, ...
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.
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.
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)
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
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 q0 • Représentation de la machine de Turing ... Tête de lecture dans la configuration de départ ... 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
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.
Le programme : <q0, 0> ~ <q10, 0, d> <q0, 1> ~ <q11, 1, d> <q10, 0> ~ <q20, 0, d> <q10, 1> ~ <q21, 1, d> <q11, 0> ~ <q21, 0, d> <q11, 1> ~ <q22, 1, 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
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...
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
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.
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).
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 1.000.000 de lignes...
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é".
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.
Nom de l ’unité/programme Déclaration de variable Connecteur séquence d ’instructions sortir("entrer votre nombre : ") entrer(nb) Nom de bloc d ’instructions instruction Bloc d ’instructions Premier programme bonjour nb : entier seq demander nombre afficher nombre saluer sortir("le nombre est : ") sortir(nb) sortir("bonjour")
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
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
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.
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, …)
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
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 : 0.0 0.5 123.45 • ctr-ex : .0 3 324. • Notation exponentielle pour les flottants • 1.23e2 = 1.23E2 = 1.23 * 10^2 = 123.0
caractère (Ada : character) : 'A', 'b', '?', ... • booléen (Ada : boolean) : valant Vrai ou Faux (Ada : True, False)
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
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
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.
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);
Exemples de sorties • put(123); put(12345678); put(123,2); put('A'); put('A'); -- écrit 123 12345678123AA Note : le format par défaut des entiers est 8 caractères de large. Un format trop petit est ignoré. • put(123.456); -- écrit 1.23456E2 • put(123.456, 2, 2, 0); -- écrit 123.45 Note : par défaut les flottants sont écrits en notation scientifique. Si la mantisse est trop grande, le format est partiellement ignoré.
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...
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;
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'); …
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
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
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.
bloc "si" bloc "sinon" si condition instructions instructions Structure d'alternative AP • 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.
Structure d'alternative ADA if condition_1 then bloc instr. elsif condition_2 then bloc instr. elsif condition_3 then bloc instr. ... else -- facultatif bloc instr. end if; if condition then bloc instr. else -- facultatif bloc instr. end if;
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)
cas : expression expr_1 expr_2 défaut expr_n ... bloc_1 bloc_2 bloc_n instructions bloc_défaut instructions instructions instructions Structure de cas AP
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.
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 5..10 => put("entre 5 et 10"); new_line; when others => null; -- instruction vide end case;
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)
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é !
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