Title: Algorithmique Proc
1Algorithmique Procédurale
- IUP GMI 1ère année
- Denis Robilliard
2Sommaire
- 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
3- 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- 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- 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- 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
7Introduction
- 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, ...
9Historique
- 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.
11La 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
ltq, sgt ltq , s , pgt - 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
...
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 ltq0, 0gt
ltq1, 1, dgt
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
- ltq0, 0gt ltq10, 0, dgt
- ltq0, 1gt ltq11, 1, dgt
- ltq10, 0gt ltq20, 0, dgt
- ltq10, 1gt ltq21, 1, dgt
- ltq11, 0gt ltq21, 0, dgt
- ltq11, 1gt ltq22, 1, dgt
- ltq20, 0gt ltqF, 0, dgt
- ltq21, 0gt ltq311, 1, dgt
- ltq311, 0gt ltqF, 1, dgt
- ltq22, 0gt ltq321, 1, dgt
- ltq321, 0gt ltq422, 1, dgt
- ltq422, 0gt ltq523, 1, dgt
- ltq523, 0gt ltqF, 1, dgt
- 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...
17Langages 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
18Arbres 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 1.000.000 de lignes...
21Syntaxe, 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.
23Premier programme
bonjour nb entier
seq
demander nombre
afficher nombre
saluer
sortir("le nombre est ") sortir(nb)
sortir("bonjour")
24Premier 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
25Instructions
- 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
26Commentaires
- 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.
27Variables, 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- 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
29Types 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 102 123.0
30- caractère (Ada character) 'A', 'b', '?', ...
- booléen (Ada boolean) valant Vrai ou Faux
(Ada True, False)
31Opé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
33Entré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(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é.
36Inclure 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
40Conversions 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
41Structures 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.
42Structure 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.
43Structure 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
44Expressions 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
- lt, lt, gt, gt, , /
- et (and), ou (or), non (not)
- ou exclusif (xor)
- et alors (and then), ou sinon (or else)
- dans (in), dehors (not in)
45Structure de cas AP
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.
47Structure de cas ADA
- case expr is
- when \ expr interv_discr others \ gt
statement -
- end case
- Exemple
- case nb is -- nb est une variable entiere
- when 1 2 3 gt put("1,2 ou 3) new-line
- when 5..10 gt put("entre 5 et 10") new_line
- when others gt null -- instruction vide
- end case
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)
49Expression 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é !
50Phases 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
51Structure de boucle AP
- Le bloc d instruction est exécuté tant que la
condition est vraie.
52Structure de boucle ADA
- while condition loop
- bloc_instr
- end loop
- Exemple
- while (nb lt 12) loop
- put(nb)
- nb nb 1
- end loop
53Boucle  pour AP
variable de boucle
variable dans envers a..b
intervalle
facultatif
- 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
- 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 lt a, l intervalle est vide, on ne le
parcourt pas ! - Si on souhaite parcourir l intervalle Ã
l envers, utiliser le mot-clé  envers .
55Boucle  pour ADA
- for variable in reverse intervalle loop
- bloc_instr
- end loop
for i in 1..10 loop put(i) end loop
for i in character'('A')..character'('Z')
loop put(i) end loop
56- -- n affiche rien !
- for i in 10..1 loop
- put(i)
- end loop
- -- affiche de 10 Ã 1
- for i in reverse 1..10 loop
- put(i)
- end loop
-- affiche 1 Ã 10, puis 3 ! i 3 for i in
1..10 loop put(i) end loop put(i) -- ne
compile pas ! for i in 1..10 loop i i
1 end loop
57Boucle avec sortie
- loop
- instr
-
- exit when condition -- facultatif
- instr
-
- 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
- end loop
60Ré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
61Bloc 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
62Bloc déclaratif ADA
- id declare
- declarative_item
- begin
- handled_statement
- end id
- handled_statement
- statement
- exception_handler
63- 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
-
64Types 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.
65Tableaux AP
- Représentation d'un tableau à 1 dimension
indices
temperatures
nom du tableau
variables
temperatures(1)
temperatures(6)
- 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
66Tableaux 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- 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.
68Exemple sur les tableaux
seq
pour
seq
Sortir(max)
Comparer avec tous
Entrer(tab(i))
pour
max tab(1)
max tab(i)
69 -- comparer avec tous for i in 2..Taille
loop if max lt tab(i) then max
tab(i) end if end loop -- afficher
max put("le max est ") put(max) new_line en
d 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)
-
70Rè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- 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 (lt, gt, lt, gt)
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)
72Les 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
73Les 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 gt 1, others gt 0)
- t TABLE'(4..7 gt 2, 8..9 gt 3)
- end
74Les 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.
75Les 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)
76Entrées/sorties sur les chaînes
- Entré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). - Sortie
- put(ch1)
- put_line(ch1) -- passe à la ligne suivante
- -- !!! Put_line ne fonctionne qu'avec des
chaînes !!!
77Attributs 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
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'
78Les 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
- m1(1,1,1) m2(1,1,10)
- get(m1(i,j,k))
- Agrégats
- t TAB_2D'((1,1), (2,2), (3,4), (4,5), (5,5))
- t TAB_2D'((1,1), (2,2), others gt (3,3))
- t TAB_2D'(1 3 gt (1,1), others gt (0,0 )
- t TAB_2D'(others gt (-1 gt 1, others gt 0))
- t TAB_2D'(others gt (others gt 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.
81Les 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
- (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 ...
83Un sous-programme est exécuté à chaque appelLors
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
85Position 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.
86Dé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.
87Paramè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
- get(n)
- end loop
- s tmp -- on a seulement le droit d'ecrire
dans s - end
91Paramè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.
92Porté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 123 65 49 124
12 12 - end portee_visibilite
95Ré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
-- conjecture de syracuse get(N) put(syracuse1(N)
)
98- 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.
99Retour sur les types
- Type / Sous-type
- une déclaration de type est statique
- type mon_entier is range 1..100 -- 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 1..100
- 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 1..100
- put(n 2) -- raise CONSTRAINT_ERROR si pas
dans 1..100 - 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
- 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/10N - On peut limiter l'intervalle des valeurs
possibles - type REEL is digits 6
- type VOLTAGE is digits 5 range 0.0 .. 1.0E9
- 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
- tableaux 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 ltgt) 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 ltgt) 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 gt 14, an gt 1789, mois gt 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 gt Rayon Integer
- when un_carre gt Coin_Inf_Droit Point
- when others gt null
- end case
- end record
- F Figure (un_point, (10,15))
- F (un_cercle, position gt (20, 25), rayon
gt 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.