Introduction au codage binaire
Introduction au codage binaire
Préambule : Le Codage
« L’information n’est pas le savoir. Le savoir n’est pas la sagesse. La sagesse n’est pas la
beauté. La beauté n’est pas l’amour. L’amour n’est pas la musique, et la musique, c’est ce
qu’il y a de mieux. » - Frank Zappa
« Les ordinateurs sont comme les dieux de l’Ancien Testament : avec beaucoup de règles, et
sans pitié. » - Joseph Campbell
« Compter en octal, c’est comme compter en décimal, si on n’utilise pas ses pouces » - Tom
Lehrer
« Il y a 10 sortes de gens au monde : ceux qui connaissent le binaire et les autres » -
Anonyme
C’est bien connu, les ordinateurs sont comme le gros rock qui tâche : ils sont binaires.
Mais ce qui est moins connu, c’est ce que ce qualificatif de « binaire » recouvre exactement,
et ce qu’il implique. Aussi, avant de nous plonger dans les arcanes de l’algorithmique
proprement dite, ferons-nous un détour par la notion de codage binaire. Contrairement aux
apparences, nous ne sommes pas éloignés de notre sujet principal. Tout au contraire, ce que
nous allons voir à présent constitue un ensemble de notions indispensables à l’écriture de
programmes. Car pour parler à une machine, mieux vaut connaître son vocabulaire…
60, c’est 6 x 10, parce que le 6 est le deuxième chiffre en partant de la droite
2, c’est 2 x 1, parce que le 2 est le premier chiffre en partant de la droite
On peut encore écrire ce même nombre d’une manière légèrement différente. Au lieu de :
9 562 = 9 x 1 000 + 5 x 100 + 6 x 10 + 2,
On écrit que :
9 562 = (9 x 10 x 10 x 10) + (5 x 10 x 10) + (6 x 10) + (2)
Arrivés à ce stade de la compétition, je prie les allergiques de m’excuser, mais il nous faut
employer un petit peu de jargon mathématique. Ce n’est pas grand-chose, et on touche au but.
Alors, courage ! En fait, ce jargon se résume au fait que les matheux notent la ligne ci-dessus
à l’aide du symbole de « puissance ». Cela donne :
9 562 = 9 x 103 + 5 x 102 + 6 x 101 + 2 x 100
Et voilà, nous y sommes. Nous avons dégagé le mécanisme général de la représentation par
numérotation de position en base décimale.
Alors, nous en savons assez pour conclure sur les conséquences du choix de la base décimale.
Il y en a deux, qui n’en forment en fin de compte qu’une seule :
parce que nous sommes en base décimale, nous utilisons un alphabet numérique de dix
symboles. Nous nous servons de dix chiffres, pas un de plus, pas un de moins.
toujours parce nous sommes en base décimale, la position d’un de ces dix chiffres
dans un nombre désigne la puissance de dix par laquelle ce chiffre doit être multiplié
pour reconstituer le nombre. Si je trouve un 7 en cinquième position à partir de la
droite, ce 7 ne représente pas 7 mais 7 fois 104, soit 70 000.
Un dernier mot concernant le choix de la base dix. Pourquoi celle-là et pas une autre ? Après
tout, la base dix n’était pas le seul choix possible. Les babyloniens, qui furent de brillants
mathématiciens, avaient en leur temps adopté la base 60 (dite sexagésimale). Cette base 60
impliquait certes d’utiliser un assez lourd alphabet numérique de 60 chiffres. Mais c’était
somme toute un inconvénient mineur, et en retour, elle possédait certains avantages non
négligeables. 60 étant un nombre divisible par beaucoup d’autres (c’est pour cette raison qu’il
avait été choisi), on pouvait, rien qu’en regardant le dernier chiffre, savoir si un nombre était
divisible par 2, 3, 4, 5, 6, 10, 12, 15, 20 et 30. Alors qu’en base 10, nous ne pouvons
immédiatement répondre à la même question que pour les diviseurs 2 et 5. La base
sexagésimale a certes disparu en tant que système de notation des nombres. Mais Babylone
nous a laissé en héritage sa base sexagésimale dans la division du cercle en soixante parties
(pour compter le temps en minutes et secondes), et celle en 6 x 60 parties (pour les degrés de
la géométrie et de l’astronomie).
Alors, pourquoi avons-nous adopté la base décimale, moins pratique à bien des égards ? Nul
doute que cela tienne au dispositif matériel grâce auquel tout être humain normalement
constitué stocke spontanément une information numérique : ses doigts !
Profitons-en pour remarquer que le professeur Shadoko avait inventé exactement le même
système, la seule différence étant qu'il avait choisi la base 4 (normal, les shadoks n'avaient
que 4 mots). Regardez donc cette video - ou comment faire rigoler les gens en ne disant
(presque) que des choses vraies :
J'ajoute que c'est l'ensemble des videos des shadoks, et en particulier celles traitant de la
logique et des mathématiques, qui vaut son pesant de cacahuètes interstellaires. Mais hélas
cela nous éloignerait un peu trop de notre propos (c'est pas grave, on y reviendra à la
prochaine pause).
4. Le codage hexadécimal
Pour en finir avec ce préambule (sinon, cela deviendrait de la gourmandise) , on va évoquer
un dernier type de codage, qui constitue une alternative pratique au codage binaire. Il s’agit du
codage hexadécimal, autrement dit en base seize.
Pourquoi ce choix bizarre ? Tout d’abord, parce que le codage binaire, ce n’est tout de même
pas très économique, ni très lisible. Pas très économique : pour représenter un nombre entre 1
et 256, il faut utiliser systématiquement huit chiffres. Pas très lisible : parce que
d’interminables suites de 1 et de 0, on a déjà vu plus folichon.
Alors, une alternative toute naturelle, c’était de représenter l’octet non comme huit bits (ce
que nous avons fait jusque là), mais comme deux paquets de 4 bits (les quatre de gauche, et
les quatre de droite). Voyons voir cela de plus près.
Avec 4 bits, nous pouvons coder 2 x 2 x 2 x 2 = 16 nombres différents. En base seize, 16
nombres différents se représentent avec un seul chiffre (de même qu’en base 10, dix nombres
se représentent avec un seul chiffre).
Quels symboles choisir pour les chiffres ? Pour les dix premiers, on n’a pas été chercher bien
loin : on a recyclé les dix chiffres de la base décimale. Les dix premiers nombres de la base
seize s’écrivent donc tout bêtement 0, 1, 2, 3, 4, 5, 6, 7, 8, et 9. Là, il nous manque encore 6
chiffres, pour représenter les nombres que nous écrivons en décimal 10, 11, 12, 13, 14 et 15.
Plutôt qu’inventer de nouveaux symboles (ce qu’on aurait très bien pu faire), on a recyclé les
premières lettres de l’alphabet. Ainsi, par convention, A vaut 10, B vaut 11, etc. jusqu’à F qui
vaut 15.
Or, on s’aperçoit que cette base hexadécimale permet une représentation très simple des octets
du binaire. Prenons un octet au hasard :
10011110
Pour convertir ce nombre en hexadécimal, il y a deux méthodes : l’une consiste à faire un
grand détour, en repassant par la base décimale. C’est un peu plus long, mais on y arrive.
L’autre méthode consiste à faire le voyage direct du binaire vers l’hexadécimal. Avec
l’habitude, c’est nettement plus rapide !
Première méthode :
On retombe sur un raisonnement déjà abordé. Cet octet représente en base dix :
1 x 27 + 0 x 26 + 0 x 25 + 1 x 24 + 1 x 23 + 1 x 22 + 1 x 21 + 0 x 20 =
1 x 128 + 1 x 16 + 1 x 8 + 1 x 4 + 1 x 2 + 0 x 1 =
128 + 16 + 8 + 4 + 2 =
158
De là, il faut repartir vers la base hexadécimale.
Dans 158, on trouve 9 x 16, c’est-à-dire 9 x 161. Je retranche 144 de 158 et j’obtiens 14.
Dans 14, on trouve 14 x 1, c’est-à-dire 14 x 160. On y est.
Le nombre s’écrit donc en hexadécimal : 9E
Deuxième méthode :
Divisons 1 0 0 1 1 1 1 0 en 1 0 0 1 (partie gauche) et 1 1 1 0 (partie droite).
1 0 0 1, c’est 8 + 1, donc 9
1 1 1 0, c’est 8 + 4 + 2 donc 14
Le nombre s’écrit donc en hexadécimal : 9E. C’est la même conclusion qu’avec la première
méthode. Encore heureux !
Le codage hexadécimal est très souvent utilisé quand on a besoin de représenter les octets
individuellement, car dans ce codage, tout octet correspond à seulement deux signes.
Allez, assez bavardé, on passe aux choses sérieuses : les arcanes de l’algorithmique…
Introduction a l’Algorithmique
« Un langage de programmation est une convention pour donner des ordres à un ordinateur.
Ce n’est pas censé être obscur, bizarre et plein de pièges subtils. Ca, ce sont les
caractéristiques de la magie. » - Dave Small
L’algorithmique est un terme d’origine arabe, comme algèbre, amiral ou zénith. Ce n’est pas
une excuse pour massacrer son orthographe, ou sa prononciation.
Ainsi, l’algo n’est pas « rythmique », à la différence du bon rock’n roll. L’algo n’est pas non
plus « l’agglo ».
Alors, ne confondez pas l’algorithmique avec l’agglo rythmique, qui consiste à poser des
parpaings en cadence.
1. Qu’est-ce que l’algomachin ?
Avez-vous déjà ouvert un livre de recettes de cuisine ? Avez vous déjà déchiffré un mode
d’emploi traduit directement du coréen pour faire fonctionner un magnétoscope ou un
répondeur téléphonique réticent ? Si oui, sans le savoir, vous avez déjà exécuté des
algorithmes.
Plus fort : avez-vous déjà indiqué un chemin à un touriste égaré ? Avez vous fait chercher un
objet à quelqu’un par téléphone ? Ecrit une lettre anonyme stipulant comment procéder à une
remise de rançon ? Si oui, vous avez déjà fabriqué – et fait exécuter – des algorithmes.
Comme quoi, l’algorithmique n’est pas un savoir ésotérique réservé à quelques rares initiés
touchés par la grâce divine, mais une aptitude partagée par la totalité de l’humanité. Donc, pas
d’excuses…
Un algorithme, c’est une suite d’instructions, qui une fois exécutée correctement, conduit à un
résultat donné. Si l’algorithme est juste, le résultat est le résultat voulu, et le touriste se
retrouve là où il voulait aller. Si l’algorithme est faux, le résultat est, disons, aléatoire, et
décidément, cette saloperie de répondeur ne veut rien savoir.
Complétons toutefois cette définition. Après tout, en effet, si l’algorithme, comme on vient de
le dire, n’est qu’une suite d’instructions menant celui qui l’exécute à résoudre un problème,
pourquoi ne pas donner comme instruction unique : « résous le problème », et laisser
l’interlocuteur se débrouiller avec ça ? A ce tarif, n’importe qui serait champion
d’algorithmique sans faire aucun effort. Pas de ça Lisette, ce serait trop facile.
Le malheur (ou le bonheur, tout dépend 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 variables, 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.
2. Faut-il être matheux pour être bon en algorithmique ?
Je consacre quelques lignes à cette question, car cette opinion aussi fortement affirmée que
faiblement fondée sert régulièrement d’excuse : « moi, de toute façon, je suis mauvais(e) en
algo, j’ai jamais rien pigé aux maths ». Faut-il être « bon en maths » pour expliquer
correctement son chemin à quelqu’un ? Je vous laisse juge.
La maîtrise de l’algorithmique requiert deux qualités, très complémentaires d’ailleurs :
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 possèdent au départ davantage cette intuition que les
autres. Cependant, et j’insiste sur ce point, les réflexes, cela s’acquiert. Et ce qu’on
appelle l’intuition n’est finalement que de l’expérience tellement répétée que le
raisonnement, au départ laborieux, finit par devenir « spontané ».
il faut être méthodique et rigoureux. En effet, chaque fois qu’on écrit une série
d’instructions qu’on croit justes, il faut systématiquement se mettre mentalement à la
place de la machine qui va les exécuter, armé d'un papier et d'un crayon, afin de
vérifier si le résultat obtenu est bien celui que l’on voulait. Cette opération ne requiert
pas la moindre once d’intelligence. Mais elle reste néanmoins indispensable, si l’on ne
veut pas écrire à l’aveuglette.
Et petit à petit, à force de pratique, vous verrez que vous pourrez faire de plus en plus souvent
l’économie de cette dernière étape : l’expérience fera que vous « verrez » le résultat produit
par vos instructions, au fur et à mesure que vous les écrirez. Naturellement, cet apprentissage
est long, et demande des heures de travail patient. Aussi, dans un premier temps, évitez de
sauter les étapes : la vérification méthodique, pas à pas, de chacun de vos algorithmes
représente plus de la moitié du travail à accomplir... et le gage de vos progrès.
les tests
les boucles
Un algorithme informatique se ramène donc toujours au bout du compte à la combinaison de
ces quatre petites briques de base. Il peut y en avoir quelques unes, quelques dizaines, et
jusqu’à plusieurs centaines de milliers dans certains programmes de gestion. Rassurez-vous,
dans le cadre de ce cours, nous n’irons pas jusque là (cependant, la taille d’un algorithme ne
conditionne pas en soi sa complexité : de longs algorithmes peuvent être finalement assez
simples, et de petits très compliqués).
4. Algorithmique et programmation
Pourquoi apprendre l’algorithmique pour apprendre à programmer ? En quoi a-t-on besoin
d’un langage spécial, distinct des langages de programmation compréhensibles par les
ordinateurs ?
Parce que l’algorithmique exprime les instructions résolvant un problème donné
indépendamment des particularités de tel ou tel langage. Pour prendre une image, si un
programme était une dissertation, l’algorithmique serait le plan, une fois mis de côté la
rédaction et l’orthographe. Or, vous savez qu’il vaut mieux faire d’abord le plan et rédiger
ensuite que l’inverse…
Apprendre l’algorithmique, c’est apprendre à manier la structure logique d’un programme
informatique. Cette dimension est présente quelle que soit le langage de programmation ;
mais lorsqu’on programme dans un langage (en C, en Visual Basic, etc.) on doit en plus se
colleter les problèmes de syntaxe, ou de types d’instructions, propres à ce langage. Apprendre
l’algorithmique de manière séparée, c’est donc sérier les difficultés pour mieux les vaincre.
A cela, il faut ajouter que des générations de programmeurs, souvent autodidactes (mais pas
toujours, hélas !), ayant directement appris à programmer dans tel ou tel langage, ne font pas
mentalement clairement la différence entre ce qui relève de la structure logique générale de
toute programmation (les règles fondamentales de l’algorithmique) et ce qui relève du langage
particulier qu’ils ont appris. Ces programmeurs, non seulement ont beaucoup plus de mal à
passer ensuite à un langage différent, mais encore écrivent bien souvent des programmes qui
même s’ils sont justes, restent laborieux. Car on n’ignore pas impunément les règles
fondamentales de l’algorithmique… Alors, autant l’apprendre en tant que telle !
Bon, maintenant que j’ai bien fait l’article pour vendre ma marchandise, on va presque
pouvoir passer au vif du sujet…
« A l’origine de toute erreur attribuée à l’ordinateur, vous trouverez au moins deux erreurs
humaines. Dont celle consistant à attribuer l’erreur à l’ordinateur. » - Anonyme
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 dans ce cours ; mais je les signale, car vous ne manquerez
pas de les rencontrer en programmation proprement dite.
Il est vrai qu'il n'est pas à proprement parler indispensable, et qu'on pourrait écrire à peu près
n’importe quel programme en l'ignorant complètement. Pourtant, si le type booléen est mis à
disposition des programmeurs dans tous les langages, ce n'est pas pour rien. Le recours aux
variables booléennes s'avère très souvent un puissant instrument de lisibilité des algorithmes :
il peut faciliter la vie de celui qui écrit l'algorithme, comme de celui qui le relit pour le
corriger.
3. L’instruction d’affectation
3.1 Syntaxe et signification
Ouf, après tout ce baratin préliminaire, on aborde enfin nos premières véritables
manipulations d’algorithmique. Pas trop tôt, certes, mais pas moyen de faire autrement !
En fait, la variable (la boîte) n'est pas un outil bien sorcier à manipuler. A la différence du
couteau suisse ou du superbe robot ménager vendu sur Télé Boutique Achat, on ne peut pas
faire trente-six mille choses avec une variable, mais seulement une et une seule.
Cette seule chose qu’on puisse faire avec une variable, c’est l’affecter, c’est-à-dire lui
attribuer une valeur. Pour poursuivre la superbe métaphore filée déjà employée, on peut
remplir la boîte.
En pseudo-code, l'instruction d'affectation se note avec le signe ←
Ainsi :
Toto ← 24
Attribue la valeur 24 à la variable Toto.
Ceci, soit dit en passant, sous-entend impérativement que Toto soit une variable de type
numérique. Si Toto a été défini dans un autre type, il faut bien comprendre que cette
instruction provoquera une erreur. C’est un peu comme si, en donnant un ordre à quelqu’un,
on accolait un verbe et un complément incompatibles, du genre « Epluchez la casserole ».
Même dotée de la meilleure volonté du monde, la ménagère lisant cette phrase ne pourrait
qu’interrompre dubitativement sa tâche. Alors, un ordinateur, vous pensez bien…
On peut en revanche sans aucun problème attribuer à une variable la valeur d’une autre
variable, telle quelle ou modifiée. Par exemple :
Tutu ← Toto
Signifie que la valeur de Tutu est maintenant celle de Toto.
Notez bien que cette instruction n’a en rien modifié la valeur de Toto : une instruction
d’affectation ne modifie que ce qui est situé à gauche de la flèche.
Tutu ← Toto + 4
Si Toto contenait 12, Tutu vaut maintenant 16. De même que précédemment, Toto vaut
toujours 12.
Tutu ← Tutu + 1
Si Tutu valait 6, il vaut maintenant 7. La valeur de Tutu est modifiée, puisque Tutu est la
variable située à gauche de la flèche.
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 :
Exemple n°1
Début
Riri ← "Loulou"
Fifi ← "Riri"
Fin
Exemple n°2
Début
Riri ← "Loulou"
Fifi ← Riri
Fin
La seule différence entre les deux algorithmes consiste dans la présence ou dans l’absence des
guillemets lors de la seconde affectation. Et l'on voit que cela change tout !
Dans l'exemple n°1, ce que l'on affecte à la variable Fifi, c'est la suite de caractères R – i – r -
i. Et à la fin de l’algorithme, le contenu de la variable Fifi est donc « Riri ».
Dans l'exemple n°2, en revanche, Riri étant dépourvu de guillemets, n'est pas considéré
comme une suite de caractères, mais comme un nom de variable. Le sens de la ligne devient
donc : « affecte à la variable Fifi le contenu de la variable Riri ». A la fin de l’algorithme n°2,
la valeur de la variable Fifi est donc « Loulou ». Ici, l’oubli des guillemets conduit certes à un
résultat, mais à un résultat différent.
A noter, car c’est un cas très fréquent, que généralement, lorsqu’on oublie les guillemets lors
d’une affectation de chaîne, ce qui se trouve à droite du signe d’affectation ne correspond à
aucune variable précédemment déclarée et affectée. Dans ce cas, l’oubli des guillemets se
solde immédiatement par une erreur d’exécution.
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.
Exemple 2
Variable A en Numérique
Début
A ← 12
A ← 34
Fin
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 :
Exemple 1
Variable A en Numérique
Début
A ← 12
Fin
Exemple 2
Variable A en Numérique
Début
A ← 34
Fin
Tous les éléments sont maintenant en votre possession pour que ce soit à vous de jouer !
Exercice 1.1
Quelles seront les valeurs des variables A et B après exécution des instructions suivantes ?
Variables A, B en Entier
Début
A←1
B←A+3
A←3
Fin
Exercice 1.2
Quelles seront les valeurs des variables A, B et C après exécution des instructions suivantes ?
Variables A, B, C en Entier
Début
A←5
B←3
C←A+B
A←2
C←B–A
Fin
Exercice 1.3
Quelles seront les valeurs des variables A et B après exécution des instructions suivantes ?
Variables A, B en Entier
Début
A←5
B←A+4
A←A+1
B←A–4
Fin
Exercice 1.4
Quelles seront les valeurs des variables A, B et C après exécution des instructions suivantes ?
Variables A, B, C en Entier
Début
A←3
B ← 10
C←A+B
B←A+B
A←C
Fin
Exercice 1.5
Quelles seront les valeurs des variables A et B après exécution des instructions suivantes ?
Variables A, B en Entier
Début
A←5
B←2
A←B
B←A
Fin
Moralité : les deux dernières instructions permettent-elles d’échanger les deux valeurs de B et
A ? Si l’on inverse les deux dernières instructions, cela change-t-il quelque chose ?
Les deux dernières instructions ne permettent donc pas d’échanger les deux valeurs de B et A,
puisque l’une des deux valeurs (celle de A) est ici écrasée.
Si l’on inverse les deux dernières instructions, cela ne changera rien du tout, hormis le fait que cette
fois c’est la valeur de B qui sera écrasée.
Exercice 1.6
Plus difficile, mais c’est un classique absolu, qu’il faut absolument maîtriser : écrire un
algorithme permettant d’échanger les valeurs de deux variables A et B, et ce quel que soit leur
contenu préalable.
On est obligé de passer par une variable dite temporaire (la variable C).
Exercice 1.7
Une variante du précédent : on dispose de trois variables A, B et C. Ecrivez un algorithme
transférant à B la valeur de A, à C la valeur de B et à A la valeur de C (toujours quels que
soient les contenus préalables de ces variables).
Début
…
D←C
C←B
B←A
A←D
Fin
En fait, quel que soit le nombre de variables, une seule variable temporaire suffit…
4. Expressions et opérateurs
Si on fait le point, on s’aperçoit que dans une instruction d’affectation, on trouve :
à gauche de la flèche, un nom de variable, et uniquement cela. En ce monde empli de
doutes qu’est celui de l’algorithmique, c’est une des rares règles d’or qui marche à
tous les coups : si on voit à gauche d’une flèche d’affectation autre chose qu’un nom
de variable, on peut être certain à 100% qu’il s’agit d’une erreur.
à droite de la flèche, ce qu’on appelle une expression. Voilà encore un mot qui est
trompeur ; en effet, ce mot existe dans le langage courant, où il revêt bien des
significations. Mais en informatique, le terme d’expression ne désigne qu’une seule
chose, et qui plus est une chose très précise :
Une expression est un ensemble de valeurs, reliées par des opérateurs, et équivalent à une
seule valeur
Cette définition vous paraît peut-être obscure. Mais réfléchissez-y quelques minutes, et vous
verrez qu’elle recouvre quelque chose d’assez simple sur le fond. Par exemple, voyons
quelques expressions de type numérique. Ainsi :
7
5+4
123-45+844
Toto-12+5-Riri
…sont toutes des expressions valides, pour peu que Toto et Riri 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 (-).
Revenons pour le moment sur l’affectation. Une condition supplémentaire (en plus des deux
précédentes) de validité d’une instruction d’affectation est que :
l’expression située à droite de la flèche soit du même type que la variable située à
gauche. C’est très logique : on ne peut pas ranger convenablement des outils dans un
sac à provision, ni des légumes dans une trousse à outils… sauf à provoquer un
résultat catastrophique.
Si l’un des trois points énumérés ci-dessus n’est pas respecté, la machine sera incapable
d’exécuter l’affectation, et déclenchera une erreur (est-il besoin de dire que si aucun de ces
points n’est respecté, il y aura aussi erreur !)
On va maintenant détailler ce que l’on entend par le terme d’ opérateur.
Un opérateur est un signe qui relie deux valeurs, pour produire un résultat.
Les opérateurs possibles dépendent du type des valeurs qui sont en jeu. Allons-y, faisons le
tour, c’est un peu fastidieux, mais comme dit le sage au petit scarabée, quand c’est fait, c’est
plus à faire.
Exercice 1.8
Que produit l’algorithme suivant ?
Variables A, B, C en Caractères
Début
A ← "423"
B ← "12"
C←A+B
Fin
Il ne peut produire qu’une erreur d’exécution, puisqu’on ne peut pas additionner des caractères.
Exercice 1.9
Que produit l’algorithme suivant ?
Variables A, B, C en Caractères
Début
A ← "423"
B ← "12"
C←A&B
Fin
1. De quoi parle-t-on ?
Trifouiller des variables en mémoire vive par un chouette programme, c’est vrai que c’est très
marrant, et d’ailleurs on a tous bien rigolé au chapitre précédent. Cela dit, à la fin de la foire,
on peut tout de même se demander à quoi ça sert.
En effet. Imaginons que nous ayons fait un programme pour calculer le carré d’un nombre,
mettons 12. Si on a fait au plus simple, on a écrit un truc du genre :
Variable A en Numérique
Début
A ← 12^2
Fin
D’une part, ce programme nous donne le carré de 12. C’est très gentil à lui. Mais si l’on veut
le carré d’un autre nombre que 12, il faut réécrire le programme. Bof.
D’autre part, le résultat est indubitablement calculé par la machine. Mais elle le garde
soigneusement pour elle, et le pauvre utilisateur qui fait exécuter ce programme, lui, ne saura
jamais quel est le carré de 12. Re-bof.
C’est pourquoi, heureusement, il existe des d’instructions pour permettre à la machine de
dialoguer avec l’utilisateur (et Lycée de Versailles, eût ajouté l’estimé Pierre Dac, qui en
précurseur méconnu de l’algorithmique, affirmait tout aussi profondément que « rien ne sert
de penser, il faut réfléchir avant »).
Dans un sens, ces instructions permettent à l’utilisateur de rentrer des valeurs au clavier pour
qu’elles soient utilisées par le programme. Cette opération est la lecture.
Dans l’autre sens, d’autres instructions permettent au programme de communiquer des
valeurs à l’utilisateur en les affichant à l’écran. Cette opération est l’écriture.
Remarque essentielle : A première vue, on peut avoir l’impression que les informaticiens
étaient beurrés comme des petits lus lorsqu’ils ont baptisé ces opérations ; puisque quand
l’utilisateur doit écrire au clavier, on appelle ça la lecture, et quand il doit lire sur l’écran on
appelle çà l’écriture. Mais avant d’agonir d’insultes une digne corporation, il faut réfléchir un
peu plus loin. Un algorithme, c’est une suite d’instructions qui programme la machine, pas
l’utilisateur ! Donc quand on dit à la machine de lire une valeur, cela implique que
l’utilisateur va devoir écrire cette valeur. Et quand on demande à la machine d’écrire une
valeur, c’est pour que l’utilisateur puisse la lire. Lecture et écriture sont donc des termes qui
comme toujours en programmation, doivent être compris du point de vue de la machine qui
sera chargée de les exécuter. Et là, tout devient parfaitement logique. Et toc.
Exercice 2.1
Quel résultat produit le programme suivant ?
Variables val, double numériques
Début
Val ← 231
Double ← Val * 2
Ecrire Val
Ecrire Double
Fin
Exercice 2.2
Ecrire un programme qui demande un nombre à l’utilisateur, puis qui calcule et affiche le
carré de ce nombre.
Equivalent javascipt :
var nb=0 ;
var carr=0 ;
nb = prompt("Entrez un nombre : ", "") ;
carr = nb * nb ;
alert("Son carré est :"+carr ) ;
Exercice 2.3
Ecrire un programme qui lit le prix HT d’un article, le nombre d’articles et le taux de TVA, et
qui fournit le prix total TTC correspondant. Faire en sorte que des libellés apparaissent
clairement.
Equivalent javascipt :
var nb=0 ;
var pht =0 ;
var ttva =0 ;
var pttc =0 ;
Exercice 2.4
Ecrire un algorithme utilisant des variables de type chaîne de caractères, et affichant quatre
variantes possibles de la célèbre « belle marquise, vos beaux yeux me font mourir d’amour ».
On ne se soucie pas de la ponctuation, ni des majuscules.
Equivalent javascipt :
t1 = "belle Marquise" ;
t2 = "vos beaux yeux" ;
t3 = "me font mourir" ;
t4 = "d’amour" ;
alert (t1 + " " + t2 + " " + t3 + " " + t4) ;
alert( t3 + " " + t2 + " " + t4 + " " + t1) ;
alert (t2 + " " + t3 + " " + t1 + " " + t4) ;
alert (t4 + " " + t1 + " " + t2 + " " + t3) ;
Partie 3
Les Tests
« Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore
bien plus dur quand on est convaincu que le code est juste. » - Steve McConnell
« Il n’existe pas, et il n’existera jamais, de langage dans lequel il soit un tant soit peu difficile
d’écrire de mauvais programmes ». - Anonyme
« Si le déboguage est l’art d’enlever les bogues, alors la programmation doit être l’art de les
créer. » - Anonyme
Je vous avais dit que l’algorithmique, c’est la combinaison de quatre structures élémentaires.
Nous en avons déjà vu deux, voici la troisième. Autrement dit, on a quasiment fini le
programme.
Mais non, je rigole.
1. De quoi s’agit-il ?
Reprenons le cas de notre « programmation algorithmique du touriste égaré ». Normalement,
l’algorithme ressemblera à quelque chose comme : « Allez tout droit jusqu’au prochain
carrefour, puis prenez à droite et ensuite la deuxième à gauche, et vous y êtes ».
Mais en cas de doute légitime de votre part, cela pourrait devenir : « Allez tout droit jusqu’au
prochain carrefour et là regardez à droite. Si la rue est autorisée à la circulation, alors
prenez la et ensuite c’est la deuxième à gauche. Mais si en revanche elle est en sens interdit,
alors continuez jusqu’à la prochaine à droite, prenez celle-là, et ensuite la première à
droite ».
Ce deuxième algorithme a ceci de supérieur au premier qu’il prévoit, en fonction d’une
situation pouvant se présenter de deux façons différentes, deux façons différentes d’agir. Cela
suppose que l’interlocuteur (le touriste) sache analyser la condition que nous avons fixée à
son comportement (« la rue est-elle en sens interdit ? ») pour effectuer la série d’actions
correspondante.
Eh bien, croyez le ou non, mais les ordinateurs possèdent cette aptitude, sans laquelle
d’ailleurs nous aurions bien du mal à les programmer. Nous allons donc pouvoir parler à notre
ordinateur comme à notre touriste, et lui donner des séries d’instructions à effectuer selon que
la situation se présente d’une manière ou d’une autre. Cette structure logique répond au doux
nom de test. Toutefois, ceux qui tiennent absolument à briller en société parleront également
de structure alternative.
Nous reviendrons dans quelques instants sur ce qu’est une condition en informatique.
Toujours est-il que la structure d’un test est relativement claire. Dans la forme la plus simple,
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. Cette série d’instructions peut être
très brève comme très longue, cela n’a aucune importance. En revanche, dans le cas où le
booléen est faux, l'ordinateur saute directement aux instructions situées après le FinSi.
Dans le cas de la structure complète, c'est à peine plus compliqué. Dans le cas où le booléen
est VRAI, et après avoir exécuté la série d'instructions 1, au moment où elle arrive au mot
« Sinon », la machine saute directement à la première instruction située après le « Finsi ». De
même, au cas où le booléen a 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 ». Dans
tous les cas, les instructions situées juste après le FinSi seront exécutées normalement.
En fait, 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. Et
laisser un Si... complet, avec une des deux branches vides, est considéré comme une très
grosse maladresse pour un programmeur, même si cela ne constitue pas à proprement parler
une faute.
Exprimé sous forme de pseudo-code, la programmation de notre touriste de tout à l’heure
donnerait donc quelque chose du genre :
Allez tout droit jusqu’au prochain carrefour
Si la rue à droite est autorisée à la circulation Alors
Tournez à droite
Avancez
Prenez la deuxième à gauche
Sinon
Continuez jusqu’à la prochaine rue à droite
Prenez cette rue
Prenez la première à droite
Finsi
L’ensemble des trois éléments constituant la condition constitue donc, si l’on veut, une
affirmation, qui a un moment donné est VRAIE ou FAUSSE.
A noter que ces opérateurs de comparaison peuvent tout à fait s’employer avec des caractères.
Ceux-ci sont codés par la machine dans l’ordre alphabétique (rappelez vous le code ASCII vu
dans le préambule), les majuscules étant systématiquement placées avant les minuscules.
Ainsi on a :
“t” < “w” VRAI
“Maman” > “Papa“ FAUX
“maman” > “Papa” VRAI
Remarque très importante
Exercice 3.1
Ecrire un algorithme qui demande un nombre à l’utilisateur, et l’informe ensuite si ce nombre est
positif ou négatif (on laisse de côté le cas où le nombre vaut zéro).
Variable n en Entier
Début
Ecrire "Entrez un nombre : "
Lire n
Si n > 0 Alors
Ecrire "Ce nombre est positif”
Sinon
Ecrire "Ce nombre est négatif"
Finsi
Fin
Equivalent javascript :
var n=0 ;
} else {
4. Conditions composées
Certains problèmes exigent parfois de formuler des conditions qui ne peuvent pas être
exprimées sous la forme simple exposée ci-dessus. Reprenons le cas « Toto est inclus entre 5
et 8 ». En fait cette phrase cache non une, mais deux conditions. Car elle revient à dire que
« Toto est supérieur à 5 et Toto 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.
Comme on l’a évoqué plus haut, l’informatique met à notre disposition quatre opérateurs
logiques : ET, OU, NON, et XOR.
Le ET a le même sens en informatique que dans le langage courant. Pour que
"Condition1 ET Condition2" soit VRAI, il faut impérativement que Condition1 soit
VRAI et que Condition2 soit VRAI. Dans tous les autres cas, "Condition 1 et
Condition2" sera faux.
Il faut se méfier un peu plus du OU. Pour que "Condition1 OU Condition2" soit
VRAI, il suffit que Condition1 soit VRAIE ou que Condition2 soit VRAIE. Le point
important est que si Condition1 est VRAIE et que Condition2 est VRAIE aussi,
Condition1 OU Condition2 reste VRAIE. Le OU informatique ne veut donc pas dire «
ou bien »
Le XOR (ou OU exclusif) fonctionne de la manière suivante. Pour que "Condition1
XOR Condition2" soit VRAI, il faut que soit Condition1 soit VRAI, soit que
Condition2 soit VRAI. Si toutes les deux sont fausses, ou que toutes les deux sont
VRAI, alors le résultat global est considéré comme FAUX. Le XOR est donc
l'équivalent du "ou bien" du langage courant.
J’insiste toutefois sur le fait que le XOR est une rareté, dont il n’est pas strictement
indispensable de s’encombrer en programmation.
Enfin, le NON inverse une condition : NON(Condition1)est VRAI si Condition1 est
FAUX, et il sera FAUX si Condition1 est VRAI. C'est l'équivalent pour les booléens
du signe "moins" que l'on place devant les nombres.
Alors, vous vous demandez peut-être à quoi sert ce NON. Après tout, plutôt qu’écrire
NON(Prix > 20), il serait plus simple d’écrire tout bonnement Prix=<20. Dans ce cas
précis, c’est évident qu’on se complique inutilement la vie avec le NON. Mais si le
NON n'est jamais indispensable, il y a tout de même des situations dans lesquelles il
s'avère bien utile.
On représente fréquemment tout ceci dans des tables de vérité (C1 et C2 représentent deux
conditions, et on envisage à chaque fois les quatre cas possibles)
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
LE GAG DE LA JOURNÉE...
...Consiste à formuler dans un test une condition qui ne pourra jamais être vraie, ou
jamais être fausse. Si ce n’est pas fait exprès, c’est assez rigolo. Si c’est fait exprès, c’est
encore plus drôle, car une condition dont on sait d’avance qu’elle sera toujours fausse n’est
pas une condition. Dans tous les cas, cela veut dire qu’on a écrit un test qui n’en est pas un, et
qui fonctionne comme s’il n’y en avait pas.
Cela peut être par exemple : Si Toto < 10 ET Toto > 15 Alors… (il est très difficile de trouver
un nombre qui soit à la fois inférieur à 10 et supérieur à 15 !)
Bon, ça, c’est un motif immédiat pour payer une tournée générale, et je sens qu’on ne restera
pas longtemps le gosier sec.
Exercice 3.2
Ecrire un algorithme qui demande deux nombres à l’utilisateur et l’informe ensuite si leur produit est
négatif ou positif (on laisse de côté le cas où le produit est nul). Attention toutefois : on ne doit pas
calculer le produit des deux nombres.
Variables m, n en Entier
Début
Ecrire "Entrez deux nombres : "
Lire m, n
Si (m > 0 ET n > 0) OU (m < 0 ET n < 0) Alors
Ecrire "Leur produit est positif"
Sinon
Ecrire "Leur produit est négatif"
Finsi
Fin
Equivalent javascript :
var m=0 ;
var n=0 ;
Exercice 3.3
Ecrire un algorithme qui demande trois noms à l’utilisateur et l’informe ensuite s’ils sont
rangés ou non dans l’ordre alphabétique.
Variables a, b, c en Caractère
Début
Ecrire "Entrez successivement trois noms : "
Lire a, b, c
Si a < b ET b < c Alors
Ecrire "Ces noms sont classés alphabétiquement"
Sinon
Ecrire "Ces noms ne sont pas classés"
Finsi
Fin
Equivalent javascript :
var a="" ;
var b="" ;
var c="" ;
a = prompt("Entrez un nom : ", "") ;
b = prompt("Entrez un nom : ", "") ;
c = prompt("Entrez un nom : ", "") ;
Else {
5. Tests imbriqués
Graphiquement, on peut très facilement représenter un SI comme un aiguillage de chemin de
fer (ou un aiguillage de train électrique, c’est moins lourd à porter). Un SI ouvre donc deux
voies, correspondant à deux traitements différents. Mais il y a des tas de situations où deux
voies ne suffisent pas. Par exemple, un programme devant donner l’état de l’eau selon sa
température doit pouvoir choisir entre trois réponses possibles (solide, liquide ou gazeuse).
Une première solution serait la suivante :
Variable Temp en Entier
Début
Ecrire "Entrez la température de l’eau :"
Lire Temp
Si Temp =< 0 Alors
Ecrire "C’est de la glace"
FinSi
Si Temp > 0 Et Temp < 100 Alors
Ecrire "C’est du liquide"
Finsi
Si Temp > 100 Alors
Ecrire "C’est de la vapeur"
Finsi
Fin
Vous constaterez que c’est un peu laborieux. Les conditions se ressemblent plus ou moins, et
surtout on oblige la machine à examiner trois tests successifs alors que tous portent sur une
même chose, la température de l'eau (la valeur de la variable Temp). Il serait ainsi bien plus
rationnel d’imbriquer les tests de cette manière :
Variable Temp en Entier
Début
Ecrire "Entrez la température de l’eau :"
Lire Temp
Si Temp =< 0 Alors
Ecrire "C’est de la glace"
Sinon
Si Temp < 100 Alors
Ecrire "C’est du liquide"
Sinon
Ecrire "C’est de la vapeur"
Finsi
Finsi
Fin
Nous avons fait des économies : au lieu de devoir taper trois conditions, dont une composée,
nous n’avons plus que deux conditions simples. Mais aussi, et surtout, nous avons fait des
économies sur le temps d’exécution de l’ordinateur. Si la température est 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.
Les structures de tests imbriqués sont donc un outil indispensable à la simplification et à
l’optimisation des algorithmes.
Exercice 3.4
Ecrire un algorithme qui demande un nombre à l’utilisateur, et l’informe ensuite si ce nombre est
positif ou négatif (on inclut cette fois le traitement du cas où le nombre vaut zéro).
Variable n en Entier
Début
Ecrire "Entrez un nombre : "
Lire n
Si n < 0 Alors
Ecrire "Ce nombre est négatif"
SinonSi n = 0 Alors
Ecrire "Ce nombre est nul"
Sinon
Ecrire "Ce nombre est positif"
Finsi
Fin
Equivalent javascript
var n=0 ;
n = prompt("Entrez un nombre : ", "") ;
if (n < 0) {
alert("Ce nombre est négatif") ;
}
Else if (n == 0) {
alert("Ce nombre est nul") ;
}
Else {
alert("Ce nombre est positif ") ;
}
Exercice 3.5
Ecrire un algorithme qui demande deux nombres à l’utilisateur et l’informe ensuite si le
produit est négatif ou positif (on inclut cette fois le traitement du cas où le produit peut être
nul). Attention toutefois, on ne doit pas calculer le produit !
Variables m, n en Entier
Début
Ecrire "Entrez deux nombres : "
Lire m, n
Si m = 0 OU n = 0 Alors
Ecrire "Le produit est nul"
SinonSi (m < 0 ET n < 0) OU (m > 0 ET n > 0) Alors
Ecrire "Le produit est positif"
Sinon
Ecrire "Le produit est négatif"
Finsi
Fin
Si on souhaite simplifier l’écriture de la condition lourde du SinonSi, on peut toujours passer
par des variables booléennes intermédiaires. Une astuce de sioux consiste également à
employer un Xor (c'est l'un des rares cas dans lesquels il est pertinent)
Equivalent javascript
var m=0 ;
var n=0 ;
if (m == 0 || n == 0) {
alert("Le produit est nul ") ;
}
Else if ((m < 0 && n < 0) || (m > 0 && n > 0)) {
alert("Le produit est positif ") ;
}
Else {
alert("Le produit est négatif ") ;
}
Exercice 3.6
Ecrire un algorithme qui demande l’âge d’un enfant à l’utilisateur. Ensuite, il l’informe de sa
catégorie :
"Poussin" de 6 à 7 ans
"Pupille" de 8 à 9 ans
"Minime" de 10 à 11 ans
"Cadet" après 12 ans
Equivalent javascript
var age=0 ;
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.
Cette structure (telle que nous l’avons programmée à la page précédente) devrait être
schématisée comme suit :
Soyons bien clairs : cette structure est la seule possible du point de vue logique (même si on
peut toujours mettre le bas en haut et le haut en bas). Mais du point de vue de l’écriture, le
pseudo-code algorithmique admet une simplification supplémentaire. Ainsi, il est possible
(mais non obligatoire, que l’algorithme initial :
Variable Temp en Entier
Début
Ecrire "Entrez la température de l’eau :"
Lire Temp
Si Temp =< 0 Alors
Ecrire "C'est de la glace"
Sinon
Si Temp < 100 Alors
Ecrire "C’est du liquide"
Sinon
Ecrire "C’est de la vapeur"
Finsi
Finsi
Fin
devienne :
Variable Temp en Entier
Début
Ecrire "Entrez la température de l’eau :"
Lire Temp
Si Temp =< 0 Alors
Ecrire "C’est de la glace"
SinonSi Temp < 100 Alors
Ecrire "C’est du liquide"
Sinon
Ecrire "C’est de la vapeur"
Finsi
Fin
Dans le cas de tests imbriqués, le Sinon et le Si peuvent être fusionnés en un SinonSi. On
considère alors qu’il s’agit d’un seul bloc de test, conclu par un seul FinSi
Le SinonSi permet en quelque sorte de créer (en réalité, de simuler) des aiguillages à plus de
deux branches. On peut ainsi enchaîner les SinonSi les uns derrière les autres pour simuler un
aiguillage à autant de branches que l’on souhaite.
7. Variables Booléennes
Jusqu’ici, pour écrire nos des tests, nous avons utilisé uniquement des conditions. 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.
Reprenons l’exemple de l’eau. On pourrait le réécrire ainsi :
Variable Temp en Entier
Variables A, B en Booléen
Début
Ecrire "Entrez la température de l’eau :"
Lire Temp
A ← Temp =< 0
B ← Temp < 100
Si A Alors
Ecrire "C’est de la glace"
SinonSi B Alors
Ecrire "C’est du liquide"
Sinon
Ecrire "C’est de la vapeur"
Finsi
Fin
A priori, cette technique ne présente guère d’intérêt : on a alourdi plutôt qu’allégé
l’algorithme de départ, en ayant recours à deux variables supplémentaires.
Mais souvenons-nous : une variable booléenne n’a besoin que d’un seul bit pour être
stockée. De ce point de vue, l’alourdissement 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,
en améliorant nettement la lisibilité de l’algorithme. 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).
Partie 4
Encore de la Logique
« La programmation peut être un plaisir ; de même que la cryptographie. Toutefois, il faut
éviter de combiner les deux. » - Kreitzberg et Sneidermann
équivaut à :
Cette règle porte le nom de transformation de Morgan, du nom du mathématicien anglais qui
l'a formulée.
Exercice 4.1
Formulez un algorithme équivalent à l’algorithme suivant :
Si Tutu > Toto + 4 OU Tata = "OK" Alors
Tutu ← Tutu + 1
Sinon
Tutu ← Tutu – 1
Finsi
Equivalent javascript :
Variables h, m en Numérique
Début
Ecrire "Entrez les heures, puis les minutes : "
Lire h, m
m←m+1
Si m = 60 Alors
m←0
h←h+1
FinSi
Si h = 24 Alors
h←0
FinSi
Ecrire "Dans une minute il sera ", h, "heure(s) ", m, "minute(s)"
Fin
Equivalent javascript :
var h=0 ;
var m=0 ;
m=m+1;
if (m == 60) {
m = 0;
h = h + 1;
}
if (h == 24) {
h = 0;
}
Alert("Dans une minute il sera "+ h + "heure(s) " + m + "minute(s)");
Exercice 4.3
De même que le précédent, cet algorithme doit demander une heure et en afficher une autre.
Mais cette fois, il doit gérer également les secondes, et afficher l'heure qu'il sera une seconde
plus tard.
Par exemple, si l'utilisateur tape 21, puis 32, puis 8, l'algorithme doit répondre : "Dans une
seconde, il sera 21 heure(s), 32 minute(s) et 9 seconde(s)".
NB : là encore, on suppose que l'utilisateur entre une date valide.
Variables h, m, s en Numérique
Début
Ecrire "Entrez les heures, puis les minutes, puis les secondes : "
Lire h, m, s
s←s+1
Si s = 60 Alors
s←0
m←m+1
FinSi
Si m = 60 Alors
m←0
h←h+1
FinSi
Si h = 24 Alors
h←0
FinSi
Ecrire "Dans une seconde il sera ", h, "h", m, "m et ", s, "s"
Fin
Equivalent javascript :
var h=0 ;
var m=0 ;
var s=0 ;
s=s+1;
if (s == 60) {
s = 0;
m = m + 1;
}
if (m == 60) {
m = 0;
h = h + 1;
}
if (h == 24) {
h = 0;
}
Alert("Dans une seconde il sera "+ h+ "h"+ m+ "m et "+ s+ "s");
Exercice 4.4
Un magasin de reprographie facture 0,10 E les dix premières photocopies, 0,09 E les vingt
suivantes et 0,08 E au-delà. Ecrivez un algorithme qui demande à l’utilisateur le nombre de
photocopies effectuées et qui affiche la facture correspondante.
Variables n, p en Numérique
Début
Ecrire "Nombre de photocopies : "
Lire n
Si n <= 10 Alors
p ← n * 0,1
SinonSi n <= 30 Alors
p ← 10 * 0,1 + (n – 10) * 0,09
Sinon
p ← 10 * 0,1 + 20 * 0,09 + (n – 30) * 0,08
FinSi
Ecrire "Le prix total est: ", p
Fin
Equivalent javascript :
var n=0 ;
var p=0 ;
Exercice 4.5
Equivalent javascript :
var sex="" ;
var age=0 ;
if ((sex = "M" && age > 20) || (sex = "F" && (age > 18 && age < 35))) {
alert("Imposable");
}
Else {
alert("Non Imposable");
}
Exercice 4.6
Les élections législatives, en Guignolerie Septentrionale, obéissent à la règle suivante :
lorsque l'un des candidats obtient plus de 50% des suffrages, il est élu dès le premier
tour.
en cas de deuxième tour, peuvent participer uniquement les candidats ayant obtenu au
moins 12,5% des voix au premier tour.
Vous devez écrire un algorithme qui permette la saisie des scores de quatre candidats au
premier tour. Cet algorithme traitera ensuite le candidat numéro 1 (et uniquement lui) : il dira
s'il est élu, battu, s'il se trouve en ballottage favorable (il participe au second tour en étant
arrivé en tête à l'issue du premier tour) ou défavorable (il participe au second tour sans avoir
été en tête au premier tour).
Cet exercice, du pur point de vue algorithmique, n'est pas très méchant. En revanche, il
représente dignement la catégorie des énoncés piégés.
En effet, rien de plus facile que d'écrire : si le candidat a plus de 50%, il est élu, sinon s'il a
plus de 12,5 %, il est au deuxième tour, sinon il est éliminé. Hé hé hé... mais il ne faut pas
oublier que le candidat peut très bien avoir eu 20 % mais être tout de même éliminé, tout
simplement parce que l'un des autres a fait plus de 50 % et donc qu'il n'y a pas de deuxième
tour !...
Moralité : ne jamais se jeter sur la programmation avant d'avoir soigneusement mené l'analyse
du problème à traiter.
Variables A, B, C, D en Numérique
Début
Ecrire "Entrez les scores des quatre prétendants :"
Lire A, B, C, D
C1 ← A > 50
C2 ← B > 50 ou C > 50 ou D > 50
C3 ← A >= B et A >= C et A >= D
C4 ← A >= 12,5
Si C1 Alors
Ecrire “Elu au premier tour"
Sinonsi C2 ou Non(C4) Alors
Ecrire “Battu, éliminé, sorti !!!”
SinonSi C3 Alors
Ecrire "Ballotage favorable"
Sinon
Ecrire "Ballotage défavorable"
FinSi
Fin
Equivalent javascript :
var A=0 ;
var B=0 ;
var C=0 ;
var D=0 ;
if (A > 50){
alert("Elu au premier tour ");
}
Else if ((B > 50 || C > 50 || D > 50) || !(A >= 12,5)) {
alert("Battu, éliminé, sorti !!!”);
}
Else if (A >= B && A >= C && A >= D) {
alert("Ballotage favorable ”);
}
Else {
alert("Ballotage défavorable ”);
}
Exercice 4.7
Une compagnie d'assurance automobile propose à ses clients quatre familles de tarifs
identifiables par une couleur, du moins au plus onéreux : tarifs bleu, vert, orange et rouge. Le
tarif dépend de la situation du conducteur :
un conducteur de moins de 25 ans et titulaire du permis depuis moins de deux ans, se
voit attribuer le tarif rouge, si toutefois il n'a jamais été responsable d'accident. Sinon,
la compagnie refuse de l'assurer.
un conducteur de moins de 25 ans et titulaire du permis depuis plus de deux ans, ou de
plus de 25 ans mais titulaire du permis depuis moins de deux ans a le droit au tarif
orange s'il n'a jamais provoqué d'accident, au tarif rouge pour un accident, sinon il est
refusé.
un conducteur de plus de 25 ans titulaire du permis depuis plus de deux ans bénéficie
du tarif vert s'il n'est à l'origine d'aucun accident et du tarif orange pour un accident, du
tarif rouge pour deux accidents, et refusé au-delà
De plus, pour encourager la fidélité des clients acceptés, la compagnie propose un
contrat de la couleur immédiatement la plus avantageuse s'il est entré dans la maison
depuis plus d'un an.
Ecrire l'algorithme permettant de saisir les données nécessaires (sans contrôle de saisie) et de
traiter ce problème. Avant de se lancer à corps perdu dans cet exercice, on pourra réfléchir un
peu et s'apercevoir qu'il est plus simple qu'il n'en a l'air (cela s'appelle faire une analyse !)
Là encore, on illustre l'utilité d'une bonne analyse. Je propose deux corrigés différents. Le
premier suit l'énoncé pas à pas. C'est juste, mais c'est vraiment lourd. La deuxième version
s'appuie sur une vraie compréhension d'une situation pas si embrouillée qu'elle n'en a l'air.
Dans les deux cas, un recours aux variables booléennes aère sérieusement l'écriture.
Donc, premier corrigé, on suit le texte de l'énoncé pas à pas :
Variables age, perm, acc, assur en Numérique
Variables C1, C2, C3 en Booléen
Variable situ en Caractère
Début
Ecrire "Entrez l’âge: "
Lire age
Ecrire "Entrez le nombre d'années de permis: "
Lire perm
Ecrire "Entrez le nombre d'accidents: "
Lire acc
Ecrire "Entrez le nombre d'années d'assurance: "
Lire assur
C1 ← age >= 25
C2 ← perm >= 2
C3 ← assur > 1
Si Non(C1) et Non(C2) Alors
Si acc = 0 Alors
situ ← "Rouge"
Sinon
situ ← "Refusé"
FinSi
Sinonsi ((Non(C1) et C2) ou (C1 et Non(C2)) Alors
Si acc = 0 Alors
situ ← "Orange"
SinonSi acc = 1 Alors
situ ← "Rouge"
Sinon
situ ← "Refusé"
FinSi
Sinon
Si acc = 0 Alors
situ ← "Vert"
SinonSi acc = 1 Alors
situ ← "Orange"
SinonSi acc = 2 Alors
situ ← "Rouge"
Sinon
situ ← "Refusé"
FinSi
FinSi
Si C3 Alors
Si situ = "Rouge" Alors
situ ← "Orange"
SinonSi situ = "Orange" Alors
situ ← "Orange"
SinonSi situ = "Vert" Alors
situ ← "Bleu"
FinSi
FinSi
Ecrire "Votre situation : ", situ
Fin
Vous trouvez cela compliqué ? Oh, certes oui, ça l'est ! Et d'autant plus qu'en lisant entre les
lignes, on pouvait s'apercevoir que ce galimatias de tarifs recouvre en fait une logique très
simple : un système à points. Et il suffit de comptabiliser les points pour que tout s'éclaire...
Reprenons juste après l'affectation des trois variables booléennes C1, C2, et C3. On écrit :
P←0
Si Non(C1) Alors
P←P+1
FinSi
Si Non(C2) Alors
P←P+1
FinSi
P ← P + acc
Si P < 3 et C3 Alors
P←P-1
FinSi
Si P = -1 Alors
situ ← "Bleu"
SinonSi P = 0 Alors
situ ← "Vert"
SinonSi P = 1 Alors
situ ← "Orange"
SinonSi P = 2 Alors
situ ← "Rouge"
Sinon
situ ← "Refusé"
FinSi
Ecrire "Votre situation : ", situ
Fin
Cool, non ?
Exercice 4.8
Ecrivez un algorithme qui a près avoir demandé un numéro de jour, de mois et d'année à
l'utilisateur, renvoie s'il s'agit ou non d'une date valide.
Cet exercice est certes d’un manque d’originalité affligeant, mais après tout, en algorithmique
comme ailleurs, il faut connaître ses classiques ! Et quand on a fait cela une fois dans sa vie,
on apprécie pleinement l’existence d’un type numérique « date » dans certains langages…).
Il n'est sans doute pas inutile de rappeler rapidement que le mois de février compte 28 jours,
sauf si l’année est bissextile, auquel cas il en compte 29. L’année est bissextile si elle est
divisible par quatre. Toutefois, les années divisibles par 100 ne sont pas bissextiles, mais les
années divisibles par 400 le sont. Ouf !
Un dernier petit détail : vous ne savez pas, pour l’instant, exprimer correctement en pseudo-
code l’idée qu’un nombre A est divisible par un nombre B. Aussi, vous vous contenterez
d’écrire en bons télégraphistes que A divisible par B se dit « A dp B ».
Exercice 4.8
En ce qui concerne le début de cet algorithme, il n’y a aucune difficulté. C’est de la saisie bête
et même pas méchante:
Variables J, M, A, JMax en Numérique
Variables VJ, VM, B en Booleen
Début
Ecrire "Entrez le numéro du jour"
Lire J
Ecrire "Entrez le numéro du mois"
Lire M
Ecrire "Entrez l'année"
Lire A
C'est évidemment ensuite que les ennuis commencent… La première manière d'aborder la
chose consiste à se dire que fondamentalement, la structure logique de ce problème est très
simple. Si nous créons deux variables booléennes VJ et VM, représentant respectivement la
validité du jour et du mois entrés, la fin de l'algorithme sera d'une simplicité biblique (l’année
est valide par définition, si on évacue le débat byzantin concernant l’existence de l’année
zéro) :
Si VJ et VM alors
Ecrire "La date est valide"
Sinon
Ecrire "La date n'est pas valide"
FinSi
Toute la difficulté consiste à affecter correctement les variables VJ et VM, selon les valeurs
des variables J, M et A. Dans l'absolu, VJ et VM pourraient être les objets d'une affectation
monstrueuse, avec des conditions atrocement composées. Mais franchement, écrire ces
conditions en une seule fois est un travail de bénédictin sans grand intérêt. Pour éviter d'en
arriver à une telle extrémité, on peut sérier la difficulté en créant deux variables
supplémentaires :
Une approche différente consisterait à limiter les conditions composées, quitte à le payer par
une structure beaucoup plus exigeante de tests imbriqués. Là encore, on évite de jouer les
extrémistes et l'on s'autorise quelques conditions composées lorsque cela nous simplifie
l'existence. On pourrait aussi dire que la solution précédente "part de la fin" du problème (la
date est elle valide ou non ?), alors que celle qui suit "part du début" (quelles sont les données
entrées au clavier ?) :
Si M < 1 ou M > 12 Alors
Ecrire "Date Invalide"
SinonSi M = 2 Alors
Si A dp 400 Alors
Si J < 1 ou J > 29 Alors
Ecrire "Date Invalide"
Sinon
Ecrire "Date Valide"
FinSi
SinonSi A dp 100 Alors
Si J < 1 ou J > 28 Alors
Ecrire "Date Invalide"
Sinon
Ecrire "Date Valide"
FinSi
SinonSi A dp 4 Alors
Si J < 1 ou J > 28 Alors
Ecrire "Date Invalide"
Sinon
Ecrire "Date Valide"
FinSi
Sinon
Si J < 1 ou J > 28 Alors
Ecrire "Date Invalide"
Sinon
Ecrire "Date Valide"
FinSi
FinSi
SinonSi M = 4 ou M = 6 ou M = 9 ou M = 11 Alors
Si J < 1 ou J > 30 Alors
Ecrire "Date Invalide"
Sinon
Ecrire "Date Valide"
FinSi
Sinon
Si J < 1 ou J > 31 Alors
Ecrire "Date Invalide"
Sinon
Ecrire "Date Valide"
FinSi
FinSi
On voit que dans ce cas, l'alternative finale (Date valide ou invalide) se trouve répétée un
grand nombre de fois. Ce n'est en soi ni une bonne, ni une mauvaise chose. C'est simplement
une question de choix stylistique.
Personnellement, j'avoue préférer assez nettement la première solution, qui fait ressortir
beaucoup plus clairement la structure logique du problème (il n'y a qu'une seule alternative,
autant que cette alternative ne soit écrite qu'une seule fois).
Il convient enfin de citer une solution très simple et élégante, un peu plus difficile peut-être à
imaginer du premier coup, mais qui avec le recul apparaît comme très immédiate. Sur le fond,
cela consiste à dire qu'il y a quatre cas pour qu'une date soit valide : celui d'un jour compris
entre 1 et 31 dans un mois à 31 jours, celui d'un jour compris entre 1 et 30 dans un mois à 30
jours, celui d'un jour compris entre 1 et 29 en février d'une année bissextile, et celui d'un jour
de février compris entre 1 et 28. Ainsi :
B ← (A dp 4 et Non(A dp 100)) ou A dp 400
K1 ← (m=1 ou m=3 ou m=5 ou m=7 ou m=8 ou m=10 ou m=12) et (J>=1 et J=<31)
K2 ← (m=4 ou m=6 ou m=9 ou m=11) et (J>=1 et J=<30)
K3 ← m=2 et B et J>=1 et J=<29
K4 ← m=2 et J>=1 et J=<28
Si K1 ou K2 ou K3 ou K4 Alors
Ecrire "Date valide"
Sinon
Ecrire "Date non valide"
FinSi
Fin
Tout est alors réglé avec quelques variables booléennes et quelques conditions composées, en
un minimum de lignes de code.
La morale de ce long exercice - et non moins long corrigé, c'est qu'un problème de test un peu
compliqué admet une pléiade de solutions justes...
...Mais que certaines sont plus astucieuses que d'autres !
Si vous avez compris ce qui précède, et que l'exercice de la date ne vous pose plus aucun
problème, alors vous savez tout ce qu'il y a à savoir 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…
Partie 5
Les Boucles
« Les premiers 90% du code prennent les premiers 90% du temps de développement. Les 10%
restants prennent les autres 90% du temps de développement » - Tom Cargill
Exercice 5.1
Ecrire un algorithme qui demande à l’utilisateur un nombre compris entre 1 et 3 jusqu’à ce
que la réponse convienne.
Variable N en Entier
Debut
N←0
Ecrire "Entrez un nombre entre 1 et 3"
TantQue N < 1 ou N > 3
Lire N
Si N < 1 ou N > 3 Alors
Ecrire "Saisie erronée. Recommencez”
FinSi
FinTantQue
Fin
Equivalent javascript :
var n = 0 ;
while (n != 2) {
n = prompt("Entrez un nombre entre 1 et 3") ;
if (n <1 || n > 3) {
Alert("Saisie erronée. Recommencez”) ;
}
}
Exercice 5.2
Ecrire un algorithme qui demande un nombre compris entre 10 et 20, jusqu’à ce que la
réponse convienne. En cas de réponse supérieure à 20, on fera apparaître un message : « Plus
petit ! », et inversement, « Plus grand ! » si le nombre est inférieur à 10.
Corrigé Exercice 5.2
Variable N en Entier
Debut
N←0
Ecrire "Entrez un nombre entre 10 et 20"
TantQue N < 10 ou N > 20
Lire N
Si N < 10 Alors
Ecrire "Plus grand !"
SinonSi N > 20 Alors
Ecrire "Plus petit !"
FinSi
FinTantQue
Fin
Equivalent javascript :
var n = 0 ;
var reponse = 1 ;
while (reponse != 0) {
n = prompt("Entrez un nombre entre 10 et 20") ;
if (n <10) {
Alert("Plus grand”) ;
}
Else if (n > 20) {
Alert("Plus petit !”) ;
}
Else {
reponse= 0 ;
}
}
Exercice 5.3
Ecrire un algorithme qui demande un nombre de départ, et qui ensuite affiche les dix nombres
suivants. Par exemple, si l'utilisateur entre le nombre 17, le programme affichera les nombres
de 18 à 27.
Variables N, i en Entier
Debut
Ecrire "Entrez un nombre : "
Lire N
Ecrire "Les 10 nombres suivants sont : "
Pour i ← N + 1 à N + 10
Ecrire i
i Suivant
Fin
Equivalent javascript :
var N = 0 ;
Les structures Pour sont employées dans les situations où l’on doit procéder à un traitement
systématique sur les éléments d’un ensemble dont le programmeur connaît d’avance la
quantité.
Nous verrons dans les chapitres suivants des séries d’éléments appelés tableaux (parties 7 et
8) et chaînes de caractères (partie 9). Selon les cas, le balayage systématique des éléments de
ces séries pourra être effectué par un Pour ou par un TantQue : tout dépend si la quantité
d’éléments à balayer (donc le nombre de tours de boucles nécessaires) peut être dénombrée à
l’avance par le programmeur ou non.
Exercice 5.4
Ecrire un algorithme qui demande un nombre de départ, et qui ensuite écrit la table de
multiplication de ce nombre, présentée comme suit (cas où l'utilisateur entre le nombre 7) :
Table de 7 :
7x1=7
7 x 2 = 14
7 x 3 = 21
…
7 x 10 = 70
Variables N, i en Entier
Debut
Ecrire "Entrez un nombre : "
Lire N
Ecrire "La table de multiplication de ce nombre est : "
Pour i ← 1 à 10
Ecrire N, " x ", i, " = ", n*i
i Suivant
Fin
Equivalent javascript :
var N = 0 ;
Exercice 5.5
Ecrire un algorithme qui demande un nombre de départ, et qui calcule la somme des entiers
jusqu’à ce nombre. Par exemple, si l’on entre 5, le programme doit calculer :
1 + 2 + 3 + 4 + 5 = 15
NB : on souhaite afficher uniquement le résultat, pas la décomposition du calcul.
Equivalent javascript :
var N = 0 ;
var Som = 0 ;
Exercice 5.6
Ecrire un algorithme qui demande un nombre de départ, et qui calcule sa factorielle.
NB : la factorielle de 8, notée 8 !, vaut
1x2x3x4x5x6x7x8
Variables N, i, F en Entier
Debut
Ecrire "Entrez un nombre : "
Lire N
F←1
Pour i ← 2 à N
F←F*i
i Suivant
Ecrire "La factorielle est : ", F
Fin
Equivalent javascript :
var N = 0 ;
var F = 0 ;
Exercice 5.7
Ecrire un algorithme qui demande successivement 20 nombres à l’utilisateur, et qui lui dise
ensuite quel était le plus grand parmi ces 20 nombres :
Entrez le nombre numéro 1 : 12
Entrez le nombre numéro 2 : 14
etc.
Entrez le nombre numéro 20 : 6
Le plus grand de ces nombres est : 14
Modifiez ensuite l’algorithme pour que le programme affiche de surcroît en quelle position
avait été saisie ce nombre :
C’était le nombre numéro 2
Variables N, i, PG en Entier
Debut
PG ← 0
Pour i ← 1 à 20
Ecrire "Entrez un nombre : "
Lire N
Si i = 1 ou N > PG Alors
PG ← N
FinSi
i Suivant
Ecrire "Le nombre le plus grand était : ", PG
Fin
En ligne 3, on peut mettre n’importe quoi dans PG, il suffit que cette variable soit affectée
pour que le premier passage en ligne 7 ne provoque pas d'erreur.
Exercice 5.8
Réécrire l’algorithme précédent, mais cette fois-ci on ne connaît pas d’avance combien l’utilisateur
souhaite saisir de nombres. La saisie des nombres s’arrête lorsque l’utilisateur entre un zéro.
Exercice 5.9
Lire la suite des prix (en euros entiers et terminée par zéro) des achats d’un client. Calculer la somme
qu’il doit, lire la somme qu’il paye, et simuler la remise de la monnaie en affichant les textes "10
Euros", "5 Euros" et "1 Euro" autant de fois qu’il y a de coupures de chaque sorte à rendre.
Exercice 5.10
Écrire un algorithme qui permette de connaître ses chances de gagner au tiercé, quarté, quinté et
autres impôts volontaires.
On demande à l’utilisateur le nombre de chevaux partants, et le nombre de chevaux joués. Les deux
messages affichés devront être :
X et Y nous sont donnés par la formule suivante, si n est le nombre de chevaux partants et p le
nombre de chevaux joués (on rappelle que le signe ! signifie "factorielle", comme dans l'exercice 5.6
ci-dessus) :
X = n ! / (n - p) !
Y = n ! / (p ! * (n – p) !)
NB : cet algorithme peut être écrit d’une manière simple, mais relativement peu performante. Ses
performances peuvent être singulièrement augmentées par une petite astuce. Vous commencerez
par écrire la manière la plus simple, puis vous identifierez le problème, et écrirez une deuxième
version permettant de le résoudre.
Corrigé Exercice 5.10
La première, et la plus grave, concerne la manière dont elle calcule le résultat final. Celui-ci
est le quotient d'un nombre par un autre ; or, ces nombres auront rapidement tendance à être
très grands. En calculant, comme on le fait ici, d'abord le numérateur, puis ensuite le
dénominateur, on prend le risque de demander à la machine de stocker des nombres trop
grands pour qu'elle soit capable de les coder (cf. le préambule). C'est d'autant plus bête que
rien ne nous oblige à procéder ainsi : on n'est pas obligé de passer par la division de deux très
grands nombres pour obtenir le résultat voulu.
La deuxième remarque est qu'on a programmé ici trois boucles successives. Or, en y regardant
bien, on peut voir qu'après simplification de la formule, ces trois boucles comportent le même
nombre de tours ! (si vous ne me croyez pas, écrivez un exemple de calcul et biffez les
nombres identiques au numérateur et au dénominateur). Ce triple calcul (ces trois boucles)
peut donc être ramené(es) à un(e) seul(e). Et voilà le travail, qui est non seulement bien plus
court, mais aussi plus performant :
Variables N, P, i, O, F en Entier
Debut
Ecrire "Entrez le nombre de chevaux partants : "
Lire N
Ecrire "Entrez le nombre de chevaux joués : "
Lire P
A←1
B←1
Pour i ← 1 à P
A ← A * (i + N - P)
B←B*i
i Suivant
Ecrire "Dans l’ordre, une chance sur ", A
Ecrire "Dans le désordre, une chance sur ", A / B
Fin
Partie 6
Les Tableaux
Bonne nouvelle ! Je vous avais annoncé qu’il y a avait en tout et pour tout quatre structures logiques
dans la programmation. Eh bien, ça y est, on les a toutes passées en revue.
Mauvaise nouvelle, il vous reste tout de même quelques petites choses à apprendre…
Imaginons que dans un programme, nous ayons besoin simultanément de 12 valeurs (par exemple,
des notes pour calculer une moyenne). Evidemment, la seule solution dont nous disposons à l’heure
actuelle consiste à déclarer douze variables, appelées par exemple Notea, Noteb, Notec, etc. Bien
sûr, on peut opter pour une notation un peu simplifiée, par exemple N1, N2, N3, etc. Mais cela ne
change pas fondamentalement notre problème, car arrivé au calcul, et après une succession de
douze instructions « Lire » distinctes, cela donnera obligatoirement une atrocité du genre :
Moy ← (N1+N2+N3+N4+N5+N6+N7+N8+N9+N10+N11+N12)/12
Ouf ! C’est tout de même bigrement laborieux. Et pour un peu que nous soyons dans un programme
de gestion avec quelques centaines ou quelques milliers de valeurs à traiter, alors là c’est le suicide
direct.
Cerise sur le gâteau, si en plus on est dans une situation on l’on ne peut pas savoir d’avance combien
il y aura de valeurs à traiter, là on est carrément cuits.
C’est pourquoi la programmation nous permet de rassembler toutes ces variables en une seule, au
sein de laquelle chaque valeur sera désignée par un numéro. En bon français, cela donnerait donc
quelque chose du genre « la note numéro 1 », « la note numéro 2 », « la note numéro 8 ». C’est
largement plus pratique, vous vous en doutez.
Un ensemble de valeurs portant le même nom de variable et repérées par un nombre, s’appelle un
tableau, ou encore une variable indicée.
Le nombre qui, au sein d’un tableau, sert à repérer chaque valeur s’appelle – ô surprise – l’indice.
Chaque fois que l’on doit désigner un élément du tableau, on fait figurer le nom du tableau, suivi de
l’indice de l’élément, entre parenthèses.
Un tableau doit être déclaré comme tel, en précisant le nombre et le type de valeurs qu’il contiendra
(la déclaration des tableaux est susceptible de varier d'un langage à l'autre. Certains langages
réclament le nombre d'éléments, d'autre le plus grand indice... C'est donc une affaire de
conventions).
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.
lors de la déclaration d'un tableau, on précise la plus grande valeur de l'indice (différente,
donc, du nombre de cases du tableau, puisque si on veut 12 emplacements, le plus grand
indice sera 11). Au début, ça déroute, mais vous verrez, avec le temps, on se fait à tout,
même au pire.
L’énorme avantage des tableaux, c’est qu’on va pouvoir les traiter en faisant des boucles. Par
exemple, pour effectuer notre calcul de moyenne, cela donnera par exemple :
NB : On a fait deux boucles successives pour plus de lisibilité, mais on aurait tout aussi bien pu n’en
écrire qu’une seule dans laquelle on aurait tout fait d’un seul coup.
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.
Je le re-re-répète, si l’on est dans un langage où les indices commencent à zéro, il faut en tenir
compte à la déclaration :
Tableau Note(13) en Numérique
...créera un tableau de 14 éléments, le plus petit indice étant 0 et le plus grand 13.
LE GAG DE LA JOURNEE
Il consiste à confondre, dans sa tête et / ou dans un algorithme, l’indice d’un élément d’un tableau
avec le contenu de cet élément. La troisième maison de la rue n’a pas forcément trois habitants, et la
vingtième vingt habitants. En notation algorithmique, il n’y a aucun rapport entre i et truc(i).
Exercice 6.1
Ecrire un algorithme qui déclare et remplisse un tableau de 7 valeurs numériques en les
mettant toutes à zéro.
Equivalent javascript :
var Truc = new array() ;
Ecrire un algorithme qui déclare et remplisse un tableau contenant les six voyelles de l’alphabet latin.
Equivalent javascript :
var Truc = new array() ;
Truc[0] = "a" ;
Truc[1] = "e" ;
Truc[2] = "i" ;
Truc[3] = "o" ;
Truc[4] = "u" ;
Truc[5] = "y" ;
Exercice 6.3
Ecrire un algorithme qui déclare un tableau de 9 notes, dont on fait ensuite saisir les valeurs
par l’utilisateur.
Equivalent javascript :
var Notes = new array() ;
var num=0 ;
for (var i=0 ;i<9 ;i++) {
num = i + 1 ;
Notes [i] = prompt("Entrez la note numéro "+ num, "") ;
}
Exercice 6.4
Exercice 6.5
Cet algorithme remplit un tableau avec les sept valeurs : 1, 3, 5, 7, 9, 11, 13.
Il les écrit ensuite à l’écran. Simplification :
Tableau N(6) en Numérique
Variables i, k en Numérique
Début
N(0) ← 1
Ecrire N(0)
Pour k ← 1 à 6
N(k) ← N(k-1) + 2
Ecrire N(k)
k Suivant
Fin
Exercice 6.6
Exercice 6.7
Ecrivez la fin de l’algorithme 6.3 afin que le calcul de la moyenne des notes soit effectué et affiché à
l’écran.
Corrigé Exercice 6.7
Variable S en Numérique
Tableau Notes(8) en Numérique
Debut
s←0
Pour i ← 0 à 8
Ecrire "Entrez la note n° ", i + 1
Lire Notes(i)
s ← s + Notes(i)
i Suivant
Ecrire "Moyenne :", s/9
Fin
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, au diable les varices) 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.
Aussi, pour parer à ce genre de situation, a-t-on la possibilité de déclarer le tableau sans préciser au
départ son nombre d’éléments. Ce n’est que dans un second temps, au cours du programme, que
l’on va fixer ce nombre via une instruction de redimensionnement : Redim.
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.
Exercice 6.8
Ecrivez un algorithme permettant à l’utilisateur de saisir un nombre quelconque de valeurs, qui
devront être stockées dans un tableau. L’utilisateur doit donc commencer par entrer le nombre de
valeurs qu’il compte saisir. Il effectuera ensuite cette saisie. Enfin, une fois la saisie terminée, le
programme affichera le nombre de valeurs négatives et le nombre de valeurs positives.
Exercice 6.9
Ecrivez un algorithme calculant la somme des valeurs d’un tableau (on suppose que le tableau a été
préalablement saisi).
… (on ne programme pas la saisie du tableau, dont on suppose qu’il compte N éléments)
Redim T(N-1)
…
Som ← 0
Pour i ← 0 à N - 1
Som ← Som + T(i)
i Suivant
Ecrire "Somme des éléments du tableau : ", Som
Fin
Exercice 6.10
Tableau 1 :
4 8 7 9 1 5 4 6
Tableau 2 :
7 6 5 2 1 3 7 4
Tableau à constituer :
11 14 12 11 2 8 11 10
Variables i, N en Numérique
Tableaux T1(), T2(), T3() en Numérique
Debut
Redim T3(N-1)
…
Pour i ← 0 à N - 1
T3(i) ← T1(i) + T2(i)
i Suivant
Fin
Exercice 6.11
Toujours à partir de deux tableaux précédemment saisis, écrivez un algorithme qui calcule le
schtroumpf des deux tableaux. Pour calculer le schtroumpf, il faut multiplier chaque élément du
tableau 1 par chaque élément du tableau 2, et additionner le tout. Par exemple si l'on a :
Tableau 1 :
4 8 7 12
Tableau 2 :
3 6
Le Schtroumpf sera :
3 * 4 + 3 * 8 + 3 * 7 + 3 * 12 + 6 * 4 + 6 * 8 + 6 * 7 + 6 * 12 = 279
…
S←0
Pour i ← 0 à N1 – 1
Pour j ← 0 à N2 – 1
S ← S + T1(i) * T2(j)
j Suivant
i Suivant
Ecrire "Le schtroumpf est : ", S
Fin
Exercice 6.12
Ecrivez un algorithme qui permette la saisie d’un nombre quelconque de valeurs, sur le principe de
l’ex 6.8. Toutes les valeurs doivent être ensuite augmentées de 1, et le nouveau tableau sera affiché à
l’écran.
Exercice 6.13
Ecrivez un algorithme permettant, toujours sur le même principe, à l’utilisateur de saisir un nombre
déterminé de valeurs. Le programme, une fois la saisie terminée, renvoie la plus grande valeur en
précisant quelle position elle occupe dans le tableau. On prendra soin d’effectuer la saisie dans un
premier temps, et la recherche de la plus grande valeur du tableau dans un second temps.
Toujours et encore sur le même principe, écrivez un algorithme permettant, à l’utilisateur de saisir
les notes d'une classe. Le programme, une fois la saisie terminée, renvoie le nombre de ces notes
supérieures à la moyenne de la classe.