ALGORITHMIQUE
ALGORITHMIQUE
ALGORITHMIQUE
EPIGRAPHE
AVANT PROPOS
Le présent support a été élaboré après plusieurs tours d’horizon sur
différent cours d’algorithmique ou logique de programmation de premier
niveau en sciences informatiques. Ce tour d’horizon nous a amenés, à une
étude minutieuse, à connaître les besoins réel des étudiants en matière de
raisonnement informatique.
BUT DU COURS
Le but de ce cours et de permettre aux étudiants de premier graduat
d’exprimer les instructions résolvant un problème donné indépendamment
des particularités de tel ou tel langage de programmation.
OBJECTIFS DU COURS
Ce cours a pour objectif de :
Rendre le contact avec le monde de l’informatique plus doux et plus
agréable ;
Doter les étudiants des reflexes d’informaticien, reflexes sans les quels
la résolution des problèmes informatique ne serait pas possible.
METHODOLOGIE D’ENSEIGNEMENT
Dans ce cours nous utiliserons la méthodologie participative, c'est-à-
dire que les étudiants auront droit à un jeu des questions et réponses afin de
bien assoir la matière.
PLAN DU COURS
0. INTRODUCTION
A. TABLEAUX UNIDIMENSIONNELS
B. TABLEAUX MULTIDIMENSIONNELS
0. INTRODUCTION
0. 1. Préambule
L’algorithmique est un terme d’origine arabe, comme algèbre, amiral
ou zénith. Ainsi, l’algo n’est pas " rythmique ", à la différence du bon rock’n
roll. L’algo n’est pas non plus " l’agglo ".
du point de vue) est que justement, si le touriste vous demande son chemin,
c’est qu’il ne le connaît pas. Donc, si on n’est pas un goujat intégral, il ne
sert à rien de lui dire de le trouver tout seul. De même les modes d’emploi
contiennent généralement (mais pas toujours) un peu plus d’informations
que " débrouillez vous pour que ça marche ". Pour fonctionner, un
algorithme doit donc contenir uniquement des instructions
compréhensibles par celui qui devra l’exécuter. C’est d’ailleurs l’un des
points délicats pour les rédacteurs de modes d’emploi : les références
culturelles, ou lexicales, des utilisateurs, étant variées, un même mode
d’emploi peut être très clair pour certains et parfaitement abscons pour
d’autres. En informatique, heureusement, il n’y a pas ce problème : les
choses auxquelles ont doit donner des instructions sont les ordinateurs, et
ceux-ci ont le bon goût d’être tous strictement aussi idiots les uns que les
autres.
Il faut être rigoureux. Car chaque fois qu’on écrit une série d’instructions
qu’on croit justes, il faut se mettre à la place de la machine qui va les
exécuter, pour vérifier si le résultat obtenu est bien celui que l’on voulait.
Mais cette opération ne requiert pas la moindre once d’intelligence,
uniquement d’être méthodique.
Il faut avoir une certaine intuition, car aucune recette ne permet de
savoir a priori quelles instructions permettront d’obtenir le résultat
voulu. C’est là, si l’on y tient, qu’intervient la forme " d’intelligence "
requise pour l’algorithmique. Alors, c’est certain, il y a des gens qui ont
au départ davantage cette intuition que les autres. Mais d’une part, les
réflexes, cela s’acquiert, et l’expérience finit par compenser largement
0.5. L’ADN
1. L’affectation de variables
2. La lecture / écriture
3. Les tests
4. Les boucles
Pour employer une image, une variable est une boîte, repérée par une
étiquette. Pour avoir accès au contenu de la boîte, il suffit de la désigner par
son étiquette.
Tous les langages, quels qu’ils soient offrent un " bouquet " de types
numériques, dont le détail est susceptible de varier légèrement d’un langage
à l’autre. Grosso modo, on retrouve cependant les types suivants :
Nous n’emploierons pas ces types ici, mais vous ne manquerez pas de
les rencontrer en programmation proprement dite.
Fort heureusement, les boîtes que sont les variables peuvent contenir
bien d’autres informations que des nombres. Sans cela, on serait un peu
embêté dès que l’on devrait stocker un nom de famille, par exemple.
I. 2. L’instruction d’affectation
I. 2. 1. Syntaxe et signification
La seule chose qu’on puisse vraiment faire avec une variable, c’est de
l’affecter, c’est-à-dire lui attribuer une valeur. En algorithmique, cette
instruction se note avec le signe .
Ainsi :
Phigo 24
Fabi Phigo
Fabi Phigo + 4
Fabi Fabi + 1
Pour revenir à présent sur le rôle des guillemets dans les chaînes de
caractères et sur la confusion numéro 2 signalée plus haut, comparons
maintenant deux algorithmes suivants :
Dans l'exemple n°1, ce que l'on affecte à la variable Fabi, c'est la suite
de caractères P – h – i – g – o. Et à la fin de l’algorithme, le contenu de la
variable Fabi est donc « Phigo ».
Ceci est une simple illustration. Mais elle résume l’ensemble des
problèmes qui surviennent lorsqu’on oublie la règle des guillemets aux
chaînes de caractères.
Il va de soi que l’ordre dans lequel les instructions sont écrites va jouer
un rôle essentiel dans le résultat final. Considérons les deux algorithmes
suivant (notez que ce sont les premiers algorithmes complets que nous
examinerons, comme quoi on avance) :
Il est clair que dans le premier cas la valeur finale de A est 12, dans
l’autre elle est 34.
Il est tout aussi clair que ceci ne doit pas nous étonner. Lorsqu’on
indique le chemin à quelqu’un, dire " prenez tout droit sur 1km, puis à
droite " n’envoie pas les gens au même endroit que si l’on dit " prenez à
droite puis tout droit pendant 1 km ".
Enfin, il est également clair que si l’on met de côté leur vertu
pédagogique, les deux algorithmes ci-dessus sont parfaitement idiots ; à tout
le moins ils contiennent une incohérence. Il n’y a aucun intérêt à affecter
une variable pour l’affecter différemment juste après. En l’occurrence, on
aurait tout aussi bien atteint le même résultat en écrivant simplement :
Début Début
A 12 A 34
Fin Fin
Tous les éléments sont maintenant en votre possession pour que ce soit à
vous de jouer maintenant !
Applications
Variables A, B en Entier
Début
A←1
B←A+3
A←3
Fin
Variables A, B, C en Entier
Début
A←5
B←3
C←A+B
A←2
C←B–A
Fin
Variables A, B en Entier
Début
A←5
B←A+4
A←A+1
B←A–4
Fin
7
5+4
123-45+844
Phigo-12+5-Fabi
Elles sont toutes des expressions valides, pour peu que Phigo et Fabi
soient bien des nombres. Car dans le cas contraire, la quatrième expression
n’a pas de sens. En l’occurrence, les opérateurs que j’ai employés sont
l’addition (+) et la soustraction (-).
Opérateurs numériques :
+ Addition
- soustraction
* multiplication
/ division
Exemple
Variables A, B, C en Caractère
Début
A "Bien"
B "Phil"
C A&B
Fin
La valeur de C à la fin de l’algorithme est "BienPhil"
Opérateurs de comparaison
> Supérieur
< Inférieur
= Egale
<> Différent
=< Inférieur ou égale
>= Supérieur ou égale
Noter que ces opérateurs de comparaison s’emploient tout à fait avec
des caractères. Ceux-ci sont codés par la machine dans l’ordre alphabétique,
les majuscules étant systématiquement placées avant les minuscules. Ainsi
on a :
Exercice 1.8
Exercice 1.9
Applications
1. 3. REMARQUES
Maintenant que nous avons fait connaissance des variables et que
nous les manipulons les yeux fermés (mais les neurones en éveil, toutefois),
j’attire votre attention sur la trompeuse similitude de vocabulaire entre les
mathématiques et l’informatique.
Exemple
Variable A en Numérique
Début
A 12^2
Fin
Lire Brian
Dès lors, aussitôt que la touche Entrée (Enter) a été frappée, l’exécution
reprend. Dans le sens inverse, pour écrire quelque chose à l’écran, c’est aussi
simple que :
Ecrire Phigo
Avant de Lire une variable, il est très fortement conseillé d’écrire des libellés
à l’écran, afin de prévenir l’utilisateur de ce qu’il doit introduire comme valeur ou
frapper au clavier (sinon, le pauvre utilisateur passe son temps à se demander ce
que l’ordinateur attend de lui et c’est très désagréable !) :
APPLICATION
Toujours est-il que la structure d’un test est relativement claire. Arrivé
à la première ligne (Si…Alors) la machine examine la valeur du booléen. Si ce
booléen a pour valeur " Vrai ", elle exécute la série d’instructions 1. Cette
série d’instructions peut être très brève comme très longue, cela n’a aucune
importance. A la fin de cette série d’instructions, au moment où elle arrive
au mot " Sinon ", la machine sautera directement à la première instruction
située après le " Finsi ". De même, au cas où le booléen avait comme valeur
" Faux ", la machine saute directement à la première ligne située après le
" Sinon " et exécute l’ensemble des " instructions 2 ".
La forme simplifiée correspond au cas où l’une des deux " branches "
du Si est vide. Dès lors, plutôt qu’écrire " sinon ne rien faire du tout ", il est
plus simple de ne rien écrire.
Exemple
• Une valeur
• Un opérateur de comparaison
• Une autre valeur
non une, mais deux conditions. Car elle revient à dire que " Phigo est
supérieur à 5 et Phigo est inférieur à 8 ". Il y a donc bien là deux conditions,
reliées par ce qu’on appelle un opérateur logique, le mot ET.
C1 et C2 C2 Vrai C2 Faux
C1 Vrai Vrai Faux
C1 Faux Faux Faux
C1 ou C2 C2 Vrai C2 Faux
C1 Vrai Vrai Vrai
C1 Faux Vrai Faux
Non C1
C1 Vrai Faux
C1 Faux Vrai
Quelques mots pour finir là-dessus. L’opérateur NON, lui, inverse une
condition :
Exemple
Exemple
inférieure à zéro, celui-ci écrit dorénavant " C’est de la glace " et passe
directement à la fin, sans être ralenti par l’examen d’autres possibilités (qui
sont forcément fausses). Cette deuxième version n’est donc pas seulement
plus simple à écrire et plus lisible, elle est également plus performante à
l’exécution.
Cette citation n’apporte peut-être pas grand chose à cet exposé, mais
je l’aime bien, alors c’était le moment ou jamais.
Mais dans certains cas, ce ne sont pas deux voies qu’il nous faut, mais
trois, ou même plus. Dans le cas de l’état de l’eau, il nous faut trois voies
pour notre « train », puisque l’eau peut être solide, liquide ou gazeuse. Alors,
nous n’avons pas eu le choix : pour deux voies, il nous fallait un aiguillage,
pour trois voies il nous en faut deux, imbriqués l’un dans l’autre.
Devient :
Variable Fabi en Entier
Début
Ecrire "Entrez la température de l’eau :"
Lire Fabi
Si Fabi =< 0 Alors
Ecrire "C’est de la glace"
Jusqu’ici, nous avons utilisé uniquement des conditions pour faire des
choix. Mais vous vous rappelez qu’il existe un type de variables (les
booléennes) susceptibles de stocker les valeurs VRAI ou FAUX. En fait, on
peut donc entrer des conditions dans ces variables, et tester ensuite la
valeur de ces variables.
Finsi
Finsi
Fin
• Une variable booléenne n’a besoin que d’un seul bit pour être stockée.
L’alourdissement de ce point de vue n’est donc pas considérable.
• Dans certains cas, notamment celui de conditions composées très
lourdes (avec plein de ET et de OU tout partout) cette technique peut
faciliter le travail du programmeur. Les variables booléennes peuvent
également s’avérer très utiles pour servir de flag, technique dont on
reparlera plus loin (rassurez-vous, rien à voir avec le flagrant délit des
policiers).
Exemple
Variables A, B, C, D, E en Booléen
Variable X en Entier
Début
Lire X
A ← X > 12
B←X>2
C←X<6
D ← (A ET B) OU C
E ← A ET (B OU C)
Ecrire D, E
Fin
S’il n’y a dans une condition que des ET, ou que des OU, en revanche,
les parenthèses ne changent strictement rien.
Dans une condition composée employant à la fois des opérateurs ET et
des opérateurs OU, la présence de parenthèses possède une influence sur le
résultat, tout comme dans le cas d’une expression numérique comportant
des multiplications et des additions.
On en arrive à une autre propriété des ET et des OU, bien plus
intéressante.
Spontanément, on pense souvent que ET et OU s’excluent
mutuellement, au sens où un problème donné s’exprime soit avec un ET,
soit avec un OU. Pourtant, ce n’est pas si évident.
Quand faut-il ouvrir la fenêtre de la salle ? Uniquement si les
conditions l’imposent, à savoir :
Si il fait trop chaud ET il ne pleut pas Alors
Ouvrir la fenêtre
Sinon
Fermer la fenêtre
Finsi
Cette petite règle pourrait tout aussi bien être formulée comme suit :
Si il ne fait pas trop chaud OU il pleut Alors
Fermer la fenêtre
Sinon
Ouvrir la fenêtre
Finsi
Ces deux formulations sont strictement équivalentes. Ce qui nous
amène à la conclusion suivante :
Toute structure de test requérant une condition composée faisant
intervenir l’opérateur ET peut être exprimée de manière équivalente avec un
opérateur OU, et réciproquement.
Ceci est moins surprenant qu’il n’y paraît au premier abord. Jetez
pour vous en convaincre un œil sur les tables de vérité, et vous noterez la
symétrie entre celle du ET et celle du OU. Dans les deux tables, il y a trois
cas sur quatre qui mènent à un résultat, et un sur quatre qui mène au
sur les tests pour affronter n'importe quelle situation. Non, ce n'est pas de la
démagogie.
Malheureusement, nous ne sommes pas tout à fait au bout de nos
peines ; il reste une dernière structure logique à examiner, et pas des
moindres.
Applications
A vue de nez, on pourrait essayer avec un SI. Voyons voir ce que ça donne :
TantQue booléen
...
Instructions
...
FinTantQue
Equivaut à :
Dans cet exemple, le programme écrira une fois "il est passé par ici"
puis six fois de suite "il repassera par là", et ceci quinze fois en tout. A la fin,
il y aura donc eu 15 x 6 = 90 passages dans la deuxième boucle (celle du
milieu). Notez la différence marquante avec cette structure :
Ici, il y aura quinze écritures consécutives du message "il est passé par
ici", puis six écritures consécutives du message "il repassera par là" , et ce
sera tout. Si des boucles peuvent être imbriquées (cas n°1) ou successives
(cas n°2), elles ne peuvent jamais, au grand jamais, être croisées. Cela
n’aurait aucun sens logique, et de plus, bien peu de langages vous
autoriseraient ne serait-ce qu’à écrire cette structure aberrante.
Instructions
Trac Suivant
Vous remarquerez que nous faisons ici gérer " en double " la variable
Truc, ces deux gestions étant contradictoires. D’une part, la ligne " Pour… "
augmente la valeur de Truc de 1 à chaque passage. D’autre part la ligne
" Truc Truc * 2 " double la valeur de Truc à chaque passage. Il va sans dire
que de telles manipulations perturbent complètement le déroulement normal
de la boucle, et sont sources d’exécutions erratiques.
A. TABLEAUX UNIDIMENSIONNELS
Cerise sur le gâteau, pour peu que l’on ne puisse savoir d’avance
combien il y aura de valeurs à traiter, là on est carrément cuits.
Dans notre exemple, nous créerons donc un tableau appelé Note (ou
N, si on veut aller plus vite). Et chaque note individuelle sera désignée
Note(1), Note(2), etc.
En nous calquant sur les choix les plus fréquents dans les langages de
programmations, nous déciderons ici arbitrairement et une bonne fois pour
toutes que :
• Les "cases" sont numérotées à partir de zéro, autrement dit que le plus
petit indice est zéro.
Remarque générale : l’indice qui sert à désigner les éléments d’un tableau
peut être exprimé directement comme un nombre en clair, mais il peut être
aussi une variable, ou une expression calculée.
Dans un tableau, la valeur d’un indice doit toujours :
A. 3. Tableaux dynamiques
Il arrive fréquemment que l’on ne connaisse pas à l’avance le nombre
d’éléments que devra comporter un tableau. Bien sûr, une solution
consisterait à déclarer un tableau gigantesque (10 000 éléments, pourquoi
pas) pour être sûr que « ça rentre ». Mais d’une part, on n’en sera jamais
parfaitement sûr, d’autre part, en raison de l’immensité de la place mémoire
réservée et la plupart du temps non utilisée, c’est un gâchis préjudiciable à
la rapidité, voire à la viabilité, de notre algorithme.
Notez que tant qu’on n’a pas précisé le nombre d’éléments d’un
tableau, d’une manière ou d’une autre, ce tableau est inutilisable.
Exemple : on veut faire saisir des notes pour un calcul de moyenne, mais on
ne sait pas combien il y aura de notes à saisir. Le début de l’algorithme
sera quelque chose du genre :
Cette technique n’a rien de sorcier, mais elle fait partie de l’arsenal de
base de la programmation en gestion.
45 122 12 3 21 78 64 53 89 28 84 46
nombre 3), et on l’échange alors avec le premier élément (le nombre 45). Le
tableau devient ainsi :
3 122 12 45 21 78 64 53 89 28 84 46
3 12 122 45 21 78 64 53 89 28 84 46
3 12 21 45 122 78 64 53 89 28 84 46
Mais tout cela serait bien aride et sans saveur, si nous nous privions du
spectacle assez étonnant de cet algorithme permettant d’effectuer cette tâche
est le suivant :
Pour i ← 0 à 10
mini = t(i)
posmini ← i
on examine tous les éléments suivants
Pour j ← i + 1 à 11
Si t(j) < t(posmini) Alors
posmini ← j
Finsi
j suivant
A cet endroit, on sait maintenant où est le plus petit élément. Il ne reste plus
qu'à effectuer la permutation.
temp ← t(posmini)
t(posmini) ← t(i)
t(i) ← temp
On a placé correctement l'élément numéro i, on passe à présent au suivant.
i suivant
Tout ceci peut vous sembler un peu fumeux, mais cela devrait
s’éclairer à l’aide d’un exemple extrêmement fréquent : la recherche de
l’occurrence d’une valeur dans un tableau. On en profitera au passage pour
corriger une erreur particulièrement fréquente chez le programmeur
débutant.
i suivant
Fin
Il ne nous reste plus qu'à gérer la variable Trouvé. Ceci se fait en deux
étapes.
qu'elle soit différente de toutes les valeurs de Tab pour qu'elle n'en fasse pas
partie.
Voilà la raison qui nous oblige à passer par une variable booléenne, un
« drapeau » qui peut se lever, mais ne jamais se rabaisser. Et cette technique
de flag (que nous pourrions élégamment surnommer « gestion asymétrique
de variable booléenne ») doit être mise en œuvre chaque fois que l’on se
trouve devant pareille situation.
• Lui attribuer la valeur Vrai dès qu’une seule permutation a été faite (il
suffit qu’il y en ait eu une seule pour que l’on soit obligé de tout
recommencer encore une fois).
• La remettre à Faux à chaque tour de la boucle principale (quand on
recommence un nouveau tour général de bulles, il n’y a pas encore eu
d’éléments échangés),
• Dernier point, il ne faut pas oublier de lancer la boucle principale, et
pour cela de donner la valeur Vrai au flag au tout départ de
l’algorithme.
A. 5. La recherche dichotomique
Nous allons terminer ce point migraineux par une technique célèbre de
recherche, qui révèle toute son utilité lorsque le nombre d'éléments est très
élevé.
Par exemple, imaginons que nous ayons un programme qui doit
vérifier si un mot existe dans le dictionnaire. Nous pouvons supposer que le
dictionnaire a été préalablement entré dans un tableau (à raison d'un mot
par emplacement). Ceci peut nous mener à, disons à la louche, 40 000 mots.
B. TABLEAUX MULTIDIMENSIONNELS
« Le vrai problème n’est pas de savoir si les machines pensent, mais de
savoir si les hommes pensent » - B.F. Skinner
Avec les outils que nous avons abordés jusque là, le plus simple serait
évidemment de modéliser le damier sous la forme d’un tableau. Chaque case
est un emplacement du tableau, qui contient par exemple 0 si elle est vide,
et 1 s’il y a un pion. On attribue comme indices aux cases les numéros 1 à 8
pour la première ligne, 9 à 16 pour la deuxième ligne, et ainsi de suite
jusqu’à 64.
B. 3. Tableaux à n dimensions
Si vous avez compris le principe des tableaux à deux dimensions, sur
le fond, il n’y a aucun problème à passer au maniement de tableaux à trois,
quatre, ou pourquoi pas neuf dimensions. C’est exactement la même chose.
Si je déclare un tableau Titi (2, 4, 3, 3), il s’agit d’un espace mémoire
contenant 3 x 5 x 4 x 4 = 240 valeurs. Chaque valeur y est repérée par
quatre coordonnées.
A ← Sin(35)
L’EXERCICE DE LA JOURNEE
Tous les langages, je dis bien tous, proposent peu ou prou les
fonctions suivantes, même si le nom et la syntaxe peuvent varier d’un
langage à l’autre :
Exemples :
Il existe aussi dans tous les langages une fonction qui renvoie le
caractère correspondant à un code Ascii donné (fonction Asc), et Lycée de
Versailles (fonction Chr) :
Modulo
Cette fonction peut paraître un peu bizarre, est réservée aux seuls
matheux. Mais vous aurez là aussi l’occasion de voir dans les exercices à
venir que ce n’est pas le cas.
Une autre fonction classique, mais très utile, est celle qui génère un
nombre choisi au hasard.
Mais il n’y a pas que les jeux qui ont besoin de générer des nombres
aléatoires. La modélisation (physique, géographique, économique, etc.) a
parfois recours à des modèles dits stochastiques. Ce sont des modèles dans
lesquels les variables se déduisent les unes des autres par des relations
déterministes (autrement dit des calculs), mais où l’on simule la part
d’incertitude par une « fourchette » de hasard.
En fait, on se rend compte avec un tout petit peu de pratique que cette
fonction Aléa peut nous servir pour générer n’importe quel nombre compris
dans n’importe quelle fourchette. Je sais bien que mes lecteurs ne sont
guère matheux, mais là, on reste franchement en deçà du niveau de feu le
BEPC :
Toto aura bien une valeur comprise entre 1,35 et 1,65. Et le tour est
joué.
dans des variables de type caractère. Jusque là, pas de scoop me direz-vous,
à juste titre vous répondrai-je, mais attendez donc la suite.
Parce qu'il y a des situations où on n'a pas le choix. Nous allons voir
dès le chapitre suivant un mode de stockage (les fichiers textes) où toutes les
informations, quelles qu'elles soient, sont obligatoirement stockées sous
forme de caractères. Dès lors, si l'on veut pouvoir récupérer des nombres et
faire des opérations dessus, il va bien falloir être capable de convertir ces
chaînes en numériques.
VII. 1. Sous-procédures
Une application, surtout si elle est longue, a toutes les chances de
devoir procéder aux mêmes traitements, ou à des traitements similaires, à
plusieurs endroits de son déroulement. Par exemple, la saisie (et le contrôle
qu’elle implique) d’une réponse par oui ou par non, peuvent être répétés dix
fois à des moments différents de la même application. La manière la plus
immédiate – et la moins habile – de résoudre la question est bien entendu de
répéter le code correspondant autant de fois que nécessaire. Ainsi, la
structure peut paraître simple. Mais elle est inutilement lourdingue, et en
réalité, pour peu que le programme soit joufflu, il peut devenir parfaitement
illisible. Il faut donc opter pour une autre stratégie, qui consiste à séparer ce
traitement du corps du programme et à appeler ces instructions (qui ne
figurent donc plus qu’en un seul exemplaire) à chaque fois qu’on en a
besoin. Le corps du programme s’appelle alors la procédure principale, et
ces groupes d’instructions auxquels on a recours s’appellent des sous-
procédures. Reprenons cet exemple de question à laquelle l’utilisateur doit
répondre par oui ou par non.
Mauvaise Structure
...
Ecrire "Etes-vous marié ?"
Rep = ""
TantQue Rep <> " Oui" et Rep <> "Non"
Ecrire "Tapez Oui ou Non"
Lire Rep
FinTantQue
Ecrire "Avez-vous des enfants ?"
Rep = ""
TantQue Rep <> "Oui" et Rep <> "Non"
Ecrire "Tapez Oui ou Non"
Lire Rep
FinTantQue
Bonne Structure
• la procédure doit être " prévenue " qu’elle recevra un message, et être
capable de le récupérer pour l’afficher.
technique, c’est que la variable Rep doit pouvoir conserver son contenu en
voyageant d’une procédure à l’autre. On en reparlera plus loin mais ce genre
de variable est extrêmement gourmand en mémoire vive. Donc, si on appelle
comme cela plusieurs procédures, avec plein de variables qu’on veut
récupérer, cela risque de coincer sérieusement à l’exécution. La solution la
plus économique en ressources consiste à transmettre la valeur de la
variable Rep de la sous-procédure vers la procédure principale, exactement
comme on transmettait jusque là la valeur de la variable Msg de la procédure
principale vers la sous-procédure. On introduit donc un second
paramètre, mais qui est maintenant un paramètre en sortie. La déclaration
de la procédure devient :
La manière dont ces déclarations doivent être faites est évidemment fonction
de chaque langage de programmation. En pseudo-code algorithmique, vous
Petit retour sur une notion très rapidement survolée plus haut : celle
de " programmation structurée ". En fait, nous avons jusqu’à présent, tels
Monsieur Jourdain, fait de la programmation structurée sans le savoir.
Aussi, plutôt qu’expliquer longuement en quoi cela consiste, je préfère
passer directement à raconter en quoi cela ne consiste pas.
Programmation Structurée
Si condition Alors
instructions 1
Sinon
instructions 2
FinSi
Nous avions programmé cela aussi sec avec une boucle Pour, et roule
Raoul. Mais une autre manière de voir les choses, ni plus juste, ni moins
juste, serait de dire que quel que soit le nombre n :
n ! = n x (n-1) !
Si l’on doit programmer cela, on peut alors imaginer une fonction Fact,
chargée de calculer la factorielle. Cette fonction effectue la multiplication du
nombre passé en argument par la factorielle du nombre précédent. Et cette
factorielle du nombre précédent va bien entendu être elle-même calculée par
la fonction Fact.
Autrement dit, on va créer une fonction qui pour fournir son résultat,
va s’appeler elle-même un certain nombre de fois. C’est cela, la récursivité.
Toutefois, il nous manque une chose pour finir : quand ces auto-appels de la
fonction Fact vont-ils s’arrêter ? Cela n’aura-t-il donc jamais de fin ? Si, bien
BIBLIOGRAPHIE