Chapitre 6 Programmation et langages - Apprendre en ligne.net
Chapitre 6 Programmation et langages - Apprendre en ligne.net
Chapitre 6 Programmation et langages - Apprendre en ligne.net
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
L'informatique au lycée <strong>Chapitre</strong> 6<br />
http://ow.ly/2xxkI<br />
<strong>Chapitre</strong> 6<br />
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
La programmation consiste à créer une séqu<strong>en</strong>ce d'instructions pour un ordinateur afin qu'il<br />
puisse résoudre un problème ou exécuter une tâche.<br />
À partir de ce chapitre, on supposera que le lecteur maîtrise le langage Python 3.<br />
6.1. Un peu d'histoire<br />
En 1936, la publication de l'article fondateur de la sci<strong>en</strong>ce informatique On Computable<br />
Numbers with an Application to the Entscheidungsproblem, par Alan Mathison Turing, allait donner<br />
le coup d'<strong>en</strong>voi à la création de l'ordinateur programmable. Il y prés<strong>en</strong>te sa machine de Turing, le<br />
premier calculateur universel programmable, <strong>et</strong> inv<strong>en</strong>te les concepts <strong>et</strong> les termes de programmation<br />
<strong>et</strong> de programme.<br />
En 1948, Konrad Zuse publie un article sur son langage de programmation qu'il a développé<br />
<strong>en</strong>tre 1943 <strong>et</strong> 1945 : le Plankalkül. Zuse le considère comme étant le premier langage de haut<br />
niveau.<br />
C'est à partir des années 50 que l'on verra apparaître les premiers <strong>langages</strong> de programmation<br />
modernes. Voici les créateurs des <strong>langages</strong> les plus utilisés :<br />
• John Backus, inv<strong>en</strong>teur de Fortran (1954)<br />
• John McCarthy, inv<strong>en</strong>teur de LISP (1958)<br />
• Grace Hopper, surnommée « la mère langage COBOL » (1959)<br />
• John George Kem<strong>en</strong>y, concepteur du BASIC (1963)<br />
• D<strong>en</strong>nis Ritchie <strong>et</strong> K<strong>en</strong> Thompson, inv<strong>en</strong>teurs du langage C (1972)<br />
• Niklaus Wirth inv<strong>en</strong>teur de Pascal (1970) <strong>et</strong> Modula-2 (1977)<br />
• Bjarne Stroustrup, développeur de C++ (1985)<br />
• Guido van Rossum, créateur de Python (1991)<br />
• James Gosling <strong>et</strong> Patrick Naughton, créateurs de Java (1991).<br />
6.1.1. Évolution des <strong>langages</strong> informatiques<br />
On distingue aujourd'hui cinq générations de <strong>langages</strong>.<br />
La première génération est le langage machine, ou code machine. On parle aussi de langage<br />
natif. Il est composé d'instructions <strong>et</strong> de données à traiter codées <strong>en</strong> binaire. C'est le seul langage<br />
qu'un ordinateur peut traiter directem<strong>en</strong>t.<br />
Voici à quoi peut ressembler un programme <strong>en</strong> langage machine :<br />
A1 01 10 03 06 01 12 A3 01 14<br />
Il s'agit de la représ<strong>en</strong>tation hexadécimale d'un programme perm<strong>et</strong>tant d'additionner les valeurs<br />
de deux cases mémoire <strong>et</strong> de stocker le résultat dans une troisième case. On voit immédiatem<strong>en</strong>t la<br />
difficulté d'un tel langage...<br />
Didier Müller 6-1 Juin 2013
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
La deuxième génération est le langage assembleur 1 : le code devi<strong>en</strong>t lisible <strong>et</strong> compréh<strong>en</strong>sible<br />
par un plus grand nombre d'initiés. Il existe <strong>en</strong> fait un langage assembleur par type de processeur.<br />
Le programme précéd<strong>en</strong>t écrit <strong>en</strong> assembleur donnerait ceci :<br />
MOV AX, [0110]<br />
ADD AX, [0112]<br />
MOV [0114], AX<br />
Il reste utilisé dans le cadre d'optimisations, mais a été supplanté <strong>en</strong> popularité par les <strong>langages</strong><br />
plus accessibles de troisième génération.<br />
La troisième génération utilise une syntaxe proche de l'anglais. Proposés autour de 1960, ces<br />
<strong>langages</strong> ont permis un gain énorme <strong>en</strong> lisibilité <strong>et</strong> <strong>en</strong> productivité. Ils ne dép<strong>en</strong>d<strong>en</strong>t plus du<br />
processeur, comme c'était le cas des générations précéd<strong>en</strong>tes, mais d'un compilateur 2 spécifique du<br />
processeur. L'idée de portabilité 3 des programmes était lancée.<br />
La plupart des <strong>langages</strong> de programmation actuels sont de troisième génération. On trouve dans<br />
c<strong>et</strong>te catégorie tous les grands <strong>langages</strong> : Ada, Algol, Basic, Cobol, Eiffel, Fortran, C, C++, Java,<br />
Perl, Pascal, Python, Ruby, ... C<strong>et</strong>te génération couvre d'ailleurs tant de <strong>langages</strong> qu'elle est souv<strong>en</strong>t<br />
subdivisée <strong>en</strong> catégories, selon le paradigme 4 particulier des <strong>langages</strong>.<br />
Les <strong>langages</strong> de quatrième génération, abrégés L4G, souv<strong>en</strong>t associée à des bases de données,<br />
se situ<strong>en</strong>t un niveau au-dessus, <strong>en</strong> intégrant la gestion de l'interface utilisateur 5 <strong>et</strong> <strong>en</strong> proposant un<br />
langage moins technique, plus proche de la syntaxe naturelle.<br />
Ils sont conçus pour un travail spécifique : gestion de base de données (Microsoft Access, SQL),<br />
production graphique (Postscript), création d'interface (4D).<br />
La cinquième génération de <strong>langages</strong> sont des <strong>langages</strong> destinés à résoudre des problèmes à<br />
l'aide de contraintes, <strong>et</strong> non d'algorithmes écrits. Ces <strong>langages</strong> repos<strong>en</strong>t beaucoup sur la logique <strong>et</strong><br />
sont particulièrem<strong>en</strong>t utilisés <strong>en</strong> intellig<strong>en</strong>ce artificielle. Parmi les plus connus, on trouve Prolog,<br />
dont voici un exemple :<br />
frère_ou_soeur(X,Y) :- par<strong>en</strong>t(Z,X), par<strong>en</strong>t(Z,Y), X \= Y.<br />
par<strong>en</strong>t(X,Y) :- père(X,Y).<br />
par<strong>en</strong>t(X,Y) :- mère(X,Y).<br />
mère(trude, sally).<br />
père(tom, sally).<br />
père(tom, erica).<br />
père(mike, tom).<br />
Il <strong>en</strong> résulte que la demande suivante est évaluée comme vraie :<br />
- frère_ou_soeur(sally, erica).<br />
oui.<br />
Ce qui signifie que Sally <strong>et</strong> Erica sont sœurs. En eff<strong>et</strong>, Sally <strong>et</strong> Erica ont le même père (Tom).<br />
1 Pour s'initier à l'assembleur : www.comm<strong>en</strong>tcamarche.n<strong>et</strong>/cont<strong>en</strong>ts/asm/assembleur.php3<br />
2 En pratique, un compilateur sert le plus souv<strong>en</strong>t à traduire un code source écrit dans un langage de programmation <strong>en</strong> un autre langage,<br />
habituellem<strong>en</strong>t un langage assembleur ou un langage machine. Le premier compilateur, A-0 System, a été écrit <strong>en</strong> 1951 par Grace Hopper.<br />
3 En informatique, la portabilité d'un programme est caractérisée par sa capacité à fonctionner plus ou moins facilem<strong>en</strong>t dans différ<strong>en</strong>ts<br />
<strong>en</strong>vironnem<strong>en</strong>ts d'exécution<br />
4 Voir paragraphe 6.5<br />
5 L'interface utilisateur définit les moy<strong>en</strong>s <strong>et</strong> outils mis <strong>en</strong> œuvre pour qu'un humain puisse contrôler <strong>et</strong> communiquer avec une machine.<br />
Didier Müller 6-2 Juin 2013
L'informatique au lycée <strong>Chapitre</strong> 6<br />
6.1.2. Quelques <strong>langages</strong> courants<br />
Il existe <strong>en</strong>viron<br />
2500 <strong>langages</strong> de<br />
programmation,<br />
certains étant très<br />
généraux (C, Java),<br />
d'autres hyperspécialisés.<br />
Par exemple,<br />
RobotProg perm<strong>et</strong><br />
de déplacer un<br />
robot virtuel, R est<br />
un langage pour la<br />
statistique, <strong>et</strong>c.<br />
Par comparaison,<br />
on rec<strong>en</strong>se <strong>en</strong>viron<br />
6800 langues<br />
humaines parlées<br />
<strong>et</strong>/ou écrites de par<br />
le monde.<br />
Source de ce schéma : [1]<br />
Le nom Ada a été<br />
choisi <strong>en</strong> l'honneur<br />
d'Ada Lovelace, qui<br />
est supposée avoir<br />
écrit le premier<br />
programme de<br />
l'histoire.<br />
La première version<br />
d'Ada remonte à<br />
1983.<br />
6.1.3. « Hello world ! »<br />
C'est dans un memorandum interne de Brian Kernighan, Programming in C : A tutorial, écrit <strong>en</strong><br />
1974 dans les laboratoires Bell, que l'on trouve la première version d'un mini-programme affichant à<br />
l'écran « Hello World! ». Voici comm<strong>en</strong>t cela s'écrit dans divers <strong>langages</strong> 6 :<br />
Ada<br />
with Ada.Text_IO;<br />
use Ada.Text_IO;<br />
procedure Bonjour is<br />
begin -- Bonjour<br />
Put("Hello world!");<br />
<strong>en</strong>d Bonjour;<br />
6 Une liste plus complète est disponible sur Wikipédia : http://fr.wikipedia.org/wiki/Hello_world<br />
Didier Müller 6-3 Juin 2013
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
BASIC est un<br />
acronyme pour<br />
Beginner's Allpurpose<br />
Symbolic<br />
Instruction Code.<br />
Il a été conçu à la<br />
base <strong>en</strong> 1963 par<br />
John George<br />
Kem<strong>en</strong>y <strong>et</strong><br />
Thomas Eug<strong>en</strong>e<br />
Kurtz.<br />
Inv<strong>en</strong>té au début<br />
des années 1970<br />
avec UNIX, C est<br />
dev<strong>en</strong>u un des<br />
<strong>langages</strong> les plus<br />
utilisés.<br />
Bjarne Stroustrup<br />
a développé C++ au<br />
cours des années<br />
1980. Il s'agissait<br />
d'améliorer le<br />
langage C.<br />
Fortran (FORmula<br />
TRANslator) est<br />
utilisé dans les<br />
applications de<br />
calcul sci<strong>en</strong>tifique.<br />
Java a été créé par<br />
Sun Microsystems,<br />
<strong>et</strong> prés<strong>en</strong>té<br />
officiellem<strong>en</strong>t le<br />
23 mai 1995.<br />
JavaScript est un<br />
langage de<br />
programmation de<br />
scripts utilisé dans<br />
les pages web<br />
interactives .<br />
Assembleur X86 sous DOS<br />
BASIC<br />
C<br />
C++<br />
cseg segm<strong>en</strong>t<br />
assume cs:cseg, ds:cseg<br />
org 100h<br />
main proc<br />
jmp debut<br />
mess db 'Hello world!$'<br />
debut:<br />
mov dx, offs<strong>et</strong> mess<br />
mov ah, 9<br />
int 21h<br />
r<strong>et</strong><br />
main <strong>en</strong>dp<br />
cseg <strong>en</strong>ds<br />
<strong>en</strong>d main<br />
10 PRINT "Hello world!"<br />
20 END<br />
#include <br />
int main()/* ou int argc, char *argv[] */<br />
{<br />
printf("Hello world!\n");<br />
r<strong>et</strong>urn 0;<br />
}<br />
#include <br />
int main()<br />
{<br />
std::cout
L'informatique au lycée <strong>Chapitre</strong> 6<br />
6.2. La machine de Turing<br />
Une machine de Turing est une machine théorique, inv<strong>en</strong>tée par Alan Turing <strong>en</strong> 1936, pour<br />
servir de modèle idéal lors d'un calcul mathématique. Ce modèle est toujours largem<strong>en</strong>t utilisé <strong>en</strong><br />
informatique théorique, <strong>en</strong> particulier pour résoudre les problèmes de complexité algorithmique <strong>et</strong> de<br />
calculabilité.<br />
Turing Machine par Tom Dunne<br />
American Sci<strong>en</strong>tist, Mars-Avril 2002<br />
Une machine de Turing se compose des élém<strong>en</strong>ts suivants :<br />
• Un « ruban » divisé <strong>en</strong> cases adjac<strong>en</strong>tes. Chaque case conti<strong>en</strong>t un symbole parmi un<br />
alphab<strong>et</strong> fini. L'alphab<strong>et</strong> conti<strong>en</strong>t un symbole spécial « blanc » <strong>et</strong> un ou plusieurs autres<br />
symboles. Le ruban est de longueur infinie vers la gauche ou vers la droite (<strong>en</strong> d'autres<br />
termes, la machine doit toujours avoir assez de longueur de ruban pour son exécution). On<br />
considère que les cases non <strong>en</strong>core écrites du ruban conti<strong>en</strong>n<strong>en</strong>t le symbole « blanc ».<br />
• Une « tête de lecture/écriture » qui peut lire <strong>et</strong> écrire les symboles sur le ruban, <strong>et</strong> se<br />
déplacer vers la gauche ou vers la droite du ruban.<br />
• Un « registre d'état » qui mémorise l'état courant de la machine de Turing. Le nombre d'états<br />
possibles est toujours fini, <strong>et</strong> il existe un état spécial appelé « état de départ » qui est l'état<br />
initial de la machine avant son exécution.<br />
• Une « table d'actions » qui indique à la machine quel symbole écrire, comm<strong>en</strong>t déplacer la<br />
tête de lecture (« G » pour une case vers la gauche, « D » pour une case vers la droite), <strong>et</strong><br />
quel est le nouvel état, <strong>en</strong> fonction du symbole lu sur le ruban <strong>et</strong> de l'état courant de la<br />
machine. Si aucune action n'existe pour une combinaison donnée d'un symbole lu <strong>et</strong> d'un<br />
état courant, la machine s'arrête.<br />
Les machines de Turing sont une abstraction des ordinateurs :<br />
• Le ruban représ<strong>en</strong>te la mémoire de l'ordinateur. Ceci compr<strong>en</strong>d la mémoire c<strong>en</strong>trale ainsi<br />
que les mémoires externes telles les disques durs. Contrairem<strong>en</strong>t à un ordinateur, la<br />
mémoire d'une machine de Turing est infinie.<br />
• La tête de lecture/écriture représ<strong>en</strong>te le bus qui relie le microprocesseur à la mémoire. Une<br />
autre différ<strong>en</strong>ce <strong>en</strong>tre une machine de Turing <strong>et</strong> un ordinateur est que l'ordinateur peut<br />
accéder à la mémoire de manière directe, alors que la tête de lecture de la machine de<br />
Turing ne se déplace que d'une position à la fois.<br />
• Le registre d'états <strong>et</strong> la table d'actions représ<strong>en</strong>t<strong>en</strong>t le microprocesseur. Le nombre d'états est<br />
fini comme dans la réalité.<br />
Didier Müller 6-5 Juin 2013
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
Exemple<br />
La machine de Turing qui suit possède un alphab<strong>et</strong> {0, 1}, 0 étant le « blanc ». On suppose que le<br />
ruban conti<strong>en</strong>t une série de 1, <strong>et</strong> que la tête de lecture/écriture se trouve initialem<strong>en</strong>t au-dessus du 1<br />
le plus à gauche. C<strong>et</strong>te machine a pour eff<strong>et</strong> de doubler le nombre de 1, <strong>en</strong> intercalant un 0 <strong>en</strong>tre les<br />
deux séries. Par exemple, « 111 » devi<strong>en</strong>dra « 1110111 ». L'<strong>en</strong>semble d'états possibles de la machine<br />
est {e1, e2, e3, e4, e5} <strong>et</strong> l'état initial est e1. La table d'actions est la suivante :<br />
État courant Symbole lu Symbole écrit Mouvem<strong>en</strong>t Nouvel état<br />
e1<br />
e2<br />
e3<br />
e4<br />
e5<br />
0 (Arrêt)<br />
1 0 Droite e2<br />
1 1 Droite e2<br />
0 0 Droite e3<br />
1 1 Droite e3<br />
0 1 Gauche e4<br />
1 1 Gauche e4<br />
0 0 Gauche e5<br />
1 1 Gauche e5<br />
0 1 Droite e1<br />
L'exécution de c<strong>et</strong>te machine pourrait être par exemple (la position de la tête de lecture/écriture<br />
sur le ruban est inscrite <strong>en</strong> caractères gras <strong>et</strong> rouges) :<br />
Étape État Ruban<br />
1 e1 11<br />
2 e2 01<br />
3 e2 010<br />
4 e3 0100<br />
5 e4 0101<br />
6 e5 0101<br />
7 e5 0101<br />
8 e1 1101<br />
9 e2 1001<br />
10 e3 1001<br />
11 e3 10010<br />
12 e4 10011<br />
13 e4 10011<br />
14 e5 10011<br />
15 e1 11011<br />
16 (Arrêt)<br />
Le comportem<strong>en</strong>t de c<strong>et</strong>te machine peut être décrit comme une boucle :<br />
• Elle démarre son exécution dans l'état e1, remplace le premier 1 par un 0.<br />
• Puis elle utilise l'état e2 pour se déplacer vers la droite, <strong>en</strong> sautant les 1, <strong>et</strong> le premier 0<br />
qu'elle r<strong>en</strong>contre.<br />
• L'état e3 est alors utilisé pour sauter la séqu<strong>en</strong>ce suivante de 1 (initialem<strong>en</strong>t aucun) <strong>et</strong><br />
Didier Müller 6-6 Juin 2013
L'informatique au lycée <strong>Chapitre</strong> 6<br />
remplacer le premier 0 r<strong>en</strong>contré par un 1.<br />
• e4 perm<strong>et</strong> de rev<strong>en</strong>ir vers la gauche jusqu'à trouver un 0, <strong>et</strong> passer dans l'état e5.<br />
• e5 perm<strong>et</strong> <strong>en</strong>suite à nouveau de se déplacer vers la gauche jusqu'à trouver un 0, écrit au<br />
départ par l'état e1.<br />
• La machine remplace alors ce 0 par un 1, se déplace d'une case vers la droite <strong>et</strong> passe à<br />
nouveau dans l'état e1 pour une nouvelle itération de la boucle.<br />
Ce processus se répète jusqu'à ce que e1 tombe sur un 0 (c'est le 0 du milieu <strong>en</strong>tre les deux<br />
séqu<strong>en</strong>ces de 1) ; à ce mom<strong>en</strong>t, la machine s'arrête.<br />
Exercice 6.1<br />
Construisez les machines de Turing suivantes :<br />
1. Une machine qui écrit 0 1 0 1 0 1 0 ... sur un ruban blanc.<br />
2. Une machine qui multiplie par 2 son <strong>en</strong>trée binaire écrite sur le ruban.<br />
3. Une machine qui ajoute 1 à son <strong>en</strong>trée binaire écrite sur le ruban.<br />
Pour les questions 2 <strong>et</strong> 3, on suppose que la tête de lecture/écriture est positionnée sur le symbole<br />
le plus à gauche.<br />
6.3. Pseudo-code<br />
En programmation, le pseudo-code est une façon de décrire un algorithme <strong>en</strong> respectant certaines<br />
conv<strong>en</strong>tions, mais sans référ<strong>en</strong>ce à un langage de programmation <strong>en</strong> particulier. L'écriture <strong>en</strong> pseudocode<br />
perm<strong>et</strong> de développer une démarche structurée, <strong>en</strong> « oubliant » temporairem<strong>en</strong>t la syntaxe<br />
rigide d'un langage de programmation.<br />
6.3.1. Conv<strong>en</strong>tions<br />
Il n'existe pas de conv<strong>en</strong>tion universelle pour le pseudo-code. Afin de bi<strong>en</strong> se compr<strong>en</strong>dre dans la<br />
suite de ce cours, nous adopterons celle décrite ci-dessous.<br />
Nom de l'algorithme<br />
Par exemple : Calcul de la date de Pâques<br />
Données d'<strong>en</strong>trées<br />
Par exemple : Année > 1582<br />
Résultat <strong>en</strong> sortie<br />
Par exemple : Date de Pâques pour l'année donnée<br />
Bloc tant que :<br />
TANT QUE condition FAIRE<br />
instruction<br />
...<br />
FIN TANT QUE<br />
Bloc répéter jusqu'à :<br />
REPETER<br />
instruction<br />
...<br />
JUSQU'A condition<br />
Bloc pour :<br />
POUR i ALLANT DE d À f FAIRE<br />
instruction<br />
...<br />
FIN POUR<br />
Didier Müller 6-7 Juin 2013
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
Bloc si :<br />
Tableau :<br />
SI condition ALORS<br />
instruction-si-vrai<br />
...<br />
SINON<br />
instruction-si-faux<br />
...<br />
FIN SI<br />
A[i] : l'élém<strong>en</strong>t de rang i dans le tableau A, on suppose les tableaux numérotés à partir de 0.<br />
Tableau multidim<strong>en</strong>sionnel A[i,j] :<br />
Élém<strong>en</strong>t <strong>en</strong> <strong>ligne</strong> i <strong>et</strong> <strong>en</strong> colonne j du tableau A.<br />
Chaine de caractères :<br />
"string" (<strong>en</strong>tre guillem<strong>et</strong>s)<br />
Affectation :<br />
a := 10<br />
Fonction :<br />
FONCTION nom(paramètres)<br />
instruction<br />
...<br />
RETOURNER résultat<br />
Procédure :<br />
PROCEDURE nom(paramètres)<br />
instruction<br />
...<br />
résultat<br />
6.3.2. En pratique<br />
• Le pseudo-code doit être suffisamm<strong>en</strong>t précis pour que quelqu'un d'autre l'ayant lu sans<br />
connaître l'algorithme soit capable de le coder.<br />
• L'objectif est d'avoir le pseudo-code le plus simple possible, afin de le coder facilem<strong>en</strong>t <strong>et</strong><br />
sans bug. Le pseudo-code d'un p<strong>et</strong>it algorithme pr<strong>en</strong>d <strong>en</strong> général une douzaine de <strong>ligne</strong>s.<br />
Pour un problème plus complexe, il faut compter jusqu'à 20 ou 25 <strong>ligne</strong>s.<br />
• Prévoyez assez de place pour faire t<strong>en</strong>ir tout le pseudo-code sur une même page.<br />
• Lorsqu'on comm<strong>en</strong>ce à écrire le pseudo-code, on ne sait pas <strong>en</strong>core précisém<strong>en</strong>t ce qui va<br />
v<strong>en</strong>ir <strong>en</strong>suite. Il est judicieux de laisser des <strong>ligne</strong>s blanches régulièrem<strong>en</strong>t pour pouvoir<br />
ajouter des choses <strong>en</strong>suite tout <strong>en</strong> gardant quelque chose de propre.<br />
• Pour r<strong>en</strong>dre compte visuellem<strong>en</strong>t des imbrications des boucles, ind<strong>en</strong>tez vers la droite le<br />
corps des boucles <strong>et</strong> des fonctions. Sur le papier, on peut ajouter de grandes barres verticales<br />
pour faire ressortir <strong>en</strong>core plus les différ<strong>en</strong>ts blocs d'instructions.<br />
6.3.3. Exemple de pseudo-code<br />
Algorithme : Tri d'une liste de nombres<br />
Donnée : Tableau A de n nombres<br />
Résultat : Tableau A de n nombres triés par ordre croissant<br />
Didier Müller 6-8 Juin 2013
L'informatique au lycée <strong>Chapitre</strong> 6<br />
permut := 1<br />
TANT QUE permut = 1 FAIRE<br />
permut := 0<br />
POUR i ALLANT DE 0 À n-2 FAIRE<br />
SI A[i] > A[i+1] ALORS<br />
echanger A[i] <strong>et</strong> A[i+1]<br />
permut := 1<br />
FIN SI<br />
FIN POUR<br />
FIN TANT QUE<br />
6.4. Transformation du code source<br />
Le code source n'est (presque) jamais utilisable tel quel. Il est généralem<strong>en</strong>t écrit dans un langage<br />
« de haut niveau », compréh<strong>en</strong>sible pour l'homme, mais pas pour la machine. Il existe deux stratégies<br />
de traduction, ces deux stratégies étant parfois disponibles au sein du même langage.<br />
• Le langage traduit les instructions au fur <strong>et</strong> à mesure qu'elles se prés<strong>en</strong>t<strong>en</strong>t. Cela s'appelle la<br />
compilation à la volée, ou l'interprétation.<br />
• Le langage comm<strong>en</strong>ce par traduire l'<strong>en</strong>semble du programme <strong>en</strong> langage machine,<br />
constituant ainsi un deuxième programme (un deuxième fichier) distinct physiquem<strong>en</strong>t <strong>et</strong><br />
logiquem<strong>en</strong>t du premier. Ensuite, <strong>et</strong> <strong>en</strong>suite seulem<strong>en</strong>t, il exécute ce second programme.<br />
Cela s'appelle la compilation.<br />
6.4.1. Compilation<br />
Certains <strong>langages</strong> sont « compilés ». En toute généralité, la compilation est l'opération qui<br />
consiste à transformer un langage source <strong>en</strong> un langage cible. Dans le cas d'un programme, le<br />
compilateur va transformer tout le texte représ<strong>en</strong>tant le code source du programme, <strong>en</strong> code<br />
compréh<strong>en</strong>sible pour la machine, appelé code machine.<br />
Dans le cas de <strong>langages</strong> compilés, ce qui est exécuté est le résultat de la compilation. Une fois<br />
effectuée, l'exécutable obt<strong>en</strong>u peut être utilisé sans le code source.<br />
6.4.2. Interprétation<br />
D'autres <strong>langages</strong> ne nécessit<strong>en</strong>t pas de phase spéciale de compilation. La méthode employée<br />
pour exécuter le programme est alors différ<strong>en</strong>te. Le programme <strong>en</strong>tier n'est jamais compilé. Chaque<br />
<strong>ligne</strong> de code est compilée « <strong>en</strong> temps réel » par un programme. On dit de ce programme qu'il<br />
interprète le code source. Par exemple, Python est un langage interprété.<br />
Cep<strong>en</strong>dant, ce serait faux de dire que la compilation n'intervi<strong>en</strong>t pas. L'interprète produit le code<br />
machine, au fur <strong>et</strong> à mesure de l'exécution du programme, <strong>en</strong> compilant chaque <strong>ligne</strong> du code source.<br />
6.4.3. Avantages, inconvéni<strong>en</strong>ts<br />
Les avantages généralem<strong>en</strong>t r<strong>et</strong><strong>en</strong>us pour l'utilisation de <strong>langages</strong> « compilés », est qu'ils sont<br />
plus rapides à l'exécution que des <strong>langages</strong> interprétés, car l'interprète doit être lancé à chaque<br />
exécution du programme, ce qui mobilise systématiquem<strong>en</strong>t les ressources.<br />
Les <strong>langages</strong> interprétés offr<strong>en</strong>t <strong>en</strong> revanche une certaine portabilité, ainsi qu'une facilité pour<br />
l'écriture du code. En eff<strong>et</strong>, il n'est pas nécessaire de passer par la phase de compilation pour tester le<br />
code source.<br />
Didier Müller 6-9 Juin 2013
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
6.5. Paradigmes<br />
En informatique, un paradigme est une une façon de programmer, un modèle qui ori<strong>en</strong>te notre<br />
manière de p<strong>en</strong>ser pour formuler <strong>et</strong> résoudre un problème.<br />
Certains <strong>langages</strong> sont conçus pour supporter un paradigme <strong>en</strong> particulier (Smalltalk <strong>et</strong> Java<br />
support<strong>en</strong>t la programmation ori<strong>en</strong>tée obj<strong>et</strong>, tandis que Haskell est conçu pour la programmation<br />
fonctionnelle), alors que d'autres support<strong>en</strong>t des paradigmes multiples (à l'image de C++, Common<br />
Lisp, OCaml, Python, Ruby ou Scheme).<br />
6.5.1. <strong>Programmation</strong> impérative<br />
C'est le paradigme le plus anci<strong>en</strong>. Les rec<strong>et</strong>tes de cuisine <strong>et</strong> les itinéraires routiers sont deux<br />
exemples familiers qui s'appar<strong>en</strong>t<strong>en</strong>t à de la programmation impérative. La grande majorité des<br />
<strong>langages</strong> de programmation sont impératifs. Les opérations sont décrites <strong>en</strong> termes de séqu<strong>en</strong>ces<br />
d'instructions exécutées par l'ordinateur pour modifier l'état du programme.<br />
Niklaus Wirth<br />
Edsger Wybe<br />
Dijkstra<br />
6.5.2. <strong>Programmation</strong> structurée (ou procédurale)<br />
La programmation structurée constitue un sous-<strong>en</strong>semble de la programmation impérative. C'est<br />
un paradigme important de la programmation, apparu vers 1970. Elle dérive de travaux de Niklaus<br />
Wirth pour son Algol W <strong>et</strong> reçut son coup d'<strong>en</strong>voi avec l'article fondateur de Dijkstra dans<br />
Communications of the ACM intitulé GO TO statem<strong>en</strong>t considered harmful.<br />
Elle est <strong>en</strong> eff<strong>et</strong> célèbre pour son essai de suppression de l'instruction GOTO ou du moins pour la<br />
limitation de son usage.<br />
La programmation structurée est possible dans n'importe quel langage de programmation<br />
procédural, mais certains, comme le Fortran IV, s'y prêtai<strong>en</strong>t très mal. Vers 1970, la programmation<br />
structurée devint une technique populaire, <strong>et</strong> les <strong>langages</strong> de programmation procéduraux intégrèr<strong>en</strong>t<br />
des mécanismes r<strong>en</strong>dant aisée la programmation structurée. Parmi les <strong>langages</strong> de programmation les<br />
plus structurants, on trouve PL/I, Pascal <strong>et</strong>, plus tardivem<strong>en</strong>t pour les proj<strong>et</strong>s de très grande taille,<br />
Ada.<br />
Exemple<br />
Dans certains <strong>langages</strong> anci<strong>en</strong>s comme le BASIC, les <strong>ligne</strong>s de programmation port<strong>en</strong>t des<br />
numéros, <strong>et</strong> les <strong>ligne</strong>s sont exécutées par la machine dans l'ordre de ces numéros. Dans tous ces<br />
<strong>langages</strong>, il existe une instruction de branchem<strong>en</strong>t, notée « aller à » <strong>en</strong> pseudo-code, instruction qui<br />
<strong>en</strong>voie directem<strong>en</strong>t le programme à la <strong>ligne</strong> spécifiée. Inversem<strong>en</strong>t, ce type de langage ne comporte<br />
pas d'instructions comme « Fin Tant Que », ou « Fin Si », qui ferm<strong>en</strong>t un bloc.<br />
Pr<strong>en</strong>ons l'exemple d'une structure « Si … Alors … Sinon »<br />
<strong>Programmation</strong> Structurée<br />
Si condition Alors<br />
instructions 1<br />
Sinon<br />
instructions 2<br />
FinSi<br />
<strong>Programmation</strong> non structurée<br />
1000 Si condition Alors Aller En 1200<br />
1100 instruction 1<br />
1110 <strong>et</strong>c.<br />
1120 <strong>et</strong>c.<br />
1190 Aller <strong>en</strong> 1400<br />
1200 instruction 2<br />
1210 <strong>et</strong>c.<br />
1220 <strong>et</strong>c.<br />
1400 suite de l'algorithme<br />
Les programmeurs décompos<strong>en</strong>t leur code <strong>en</strong> procédures ne dépassant guère 50 <strong>ligne</strong>s, afin<br />
d'avoir le programme <strong>en</strong> <strong>en</strong>tier sous leurs yeux.<br />
Une procédure, aussi appelée routine, sous-routine, module ou fonction, conti<strong>en</strong>t une série<br />
d'étapes à réaliser. N'importe quelle procédure peut être appelée à n'importe quelle étape de<br />
l'exécution du programme, incluant d'autres procédures, voire la procédure elle-même (récursivité).<br />
Didier Müller 6-10 Juin 2013
L'informatique au lycée <strong>Chapitre</strong> 6<br />
Il n'y a que des avantages à découper un programme <strong>en</strong> procédures :<br />
• on a la possibilité de réutiliser le même code à différ<strong>en</strong>ts emplacem<strong>en</strong>ts dans le programme<br />
sans avoir à le r<strong>et</strong>aper ;<br />
• il est plus simple de suivre l'évolution du programme (la programmation procédurale perm<strong>et</strong><br />
de se passer d'instructions « GOTO ») ;<br />
• on crée un code plus modulaire <strong>et</strong> structuré ;<br />
• chaque programmeur peut développer son bout de code de son côté.<br />
6.5.3. <strong>Programmation</strong> ori<strong>en</strong>tée obj<strong>et</strong><br />
La programmation ori<strong>en</strong>tée obj<strong>et</strong> (POO) ou programmation par obj<strong>et</strong>, est un paradigme de<br />
programmation informatique qui consiste <strong>en</strong> la définition <strong>et</strong> l'assemblage de « briques logicielles »<br />
appelées obj<strong>et</strong>s. Un obj<strong>et</strong> représ<strong>en</strong>te un concept, une idée ou toute <strong>en</strong>tité du monde physique, comme<br />
une voiture, une personne ou <strong>en</strong>core une page d'un livre. Le langage Simula-67 j<strong>et</strong>te les prémisses<br />
de la programmation obj<strong>et</strong>, résultat des travaux sur la mise au point de <strong>langages</strong> de simulation<br />
informatique dans les années 1960 dont s'inspira aussi la recherche sur l'intellig<strong>en</strong>ce artificielle dans<br />
les années 1970-80. Mais c'est réellem<strong>en</strong>t par <strong>et</strong> avec Smalltalk 72 puis Smalltalk 80, inspiré <strong>en</strong><br />
partie par Simula, que la programmation par obj<strong>et</strong>s débute <strong>et</strong> que sont posés les concepts de base de<br />
celle-ci : obj<strong>et</strong>, messages, <strong>en</strong>capsulation, polymorphisme, héritage, <strong>et</strong>c.<br />
À partir des années 1980, comm<strong>en</strong>ce l'effervesc<strong>en</strong>ce des <strong>langages</strong> à obj<strong>et</strong>s : Objective C (début<br />
des années 1980), C++ (C with classes) <strong>en</strong> 1983, Eiffel <strong>en</strong> 1984, Common Lisp Object System<br />
dans les années 1980, <strong>et</strong>c. Les années 1990 voi<strong>en</strong>t l'âge d'or de l'ext<strong>en</strong>sion de la programmation par<br />
obj<strong>et</strong> dans les différ<strong>en</strong>ts secteurs du développem<strong>en</strong>t logiciel.<br />
Quelques <strong>langages</strong> à obj<strong>et</strong>s : Ada, Java, C#, Objective C, Eiffel, Python, C++, PHP,<br />
Smalltalk...<br />
6.5.4. <strong>Programmation</strong> fonctionnelle<br />
La programmation fonctionnelle est un paradigme de programmation qui considère le calcul <strong>en</strong><br />
tant qu'évaluation de fonctions mathématiques <strong>et</strong> rej<strong>et</strong>te le changem<strong>en</strong>t d'état <strong>et</strong> la mutation des<br />
données. Elle sou<strong>ligne</strong> l'application des fonctions, contrairem<strong>en</strong>t au modèle de programmation<br />
impérative qui m<strong>et</strong> <strong>en</strong> avant les changem<strong>en</strong>ts d'état.<br />
Le langage fonctionnel le plus anci<strong>en</strong> est Lisp, créé <strong>en</strong> 1958 par McCarthy. Lisp a donné<br />
naissance à des variantes telles que Scheme (1975) <strong>et</strong> Common Lisp (1984). Haskell (1987) est<br />
aussi un langage à paradigme fonctionnel. La programmation fonctionnelle s'affranchit de façon<br />
radicale des eff<strong>et</strong>s secondaires <strong>en</strong> interdisant toute opération d'affectation.<br />
Le paradigme fonctionnel n'utilise pas de machine d'états pour décrire un programme, mais un<br />
emboîtem<strong>en</strong>t de « boîtes noires » que l'on peut imbriquer les unes dans les autres. Chaque boîte<br />
possédant plusieurs paramètres <strong>en</strong> <strong>en</strong>trée mais une seule sortie, elle ne peut sortir qu'une seule valeur<br />
possible pour chaque n-upl<strong>et</strong> de valeurs prés<strong>en</strong>tées <strong>en</strong> <strong>en</strong>trée. Ainsi, les fonctions n'introduis<strong>en</strong>t pas<br />
d'eff<strong>et</strong>s de bord. Un programme est donc une application, au s<strong>en</strong>s mathématique, qui ne donne qu'un<br />
seul résultat pour chaque <strong>en</strong>semble de valeurs <strong>en</strong> <strong>en</strong>trée. C<strong>et</strong>te façon de p<strong>en</strong>ser, qui est très différ<strong>en</strong>te<br />
de la p<strong>en</strong>sée habituelle <strong>en</strong> programmation impérative, est l'une des causes principales de la difficulté<br />
qu'ont les programmeurs formés aux <strong>langages</strong> impératifs pour aborder la programmation<br />
fonctionnelle. Cep<strong>en</strong>dant, elle ne pose généralem<strong>en</strong>t pas de difficultés particulières aux débutants qui<br />
n'ont jamais été exposés à des <strong>langages</strong> impératifs.<br />
Exercice 6.2<br />
Expliquez c<strong>et</strong>te description de Python, tirée de Wikipédia :<br />
« Python est un langage de programmation interprété multi-paradigme. Il favorise la<br />
programmation impérative structurée, <strong>et</strong> ori<strong>en</strong>tée obj<strong>et</strong>. »<br />
Didier Müller 6-11 Juin 2013
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
6.6. Les notions principales de la programmation<br />
La plupart des <strong>langages</strong> de programmation ont des caractéristiques communes que nous allons<br />
passer rapidem<strong>en</strong>t <strong>en</strong> revue ici.<br />
6.6.1. L'affectation<br />
Une affectation est une opération qui perm<strong>et</strong> d'attribuer une valeur à une variable. Pour expliquer<br />
ce qui se passe lors d'une affectation, il faut imaginer qu'il existe, dans un recoin de l'ordinateur, une<br />
case mémoire appelée x. L'instruction x=t consiste à remplir la case x avec la valeur de l'expression<br />
t. Si x cont<strong>en</strong>ait déjà une valeur, celle-ci est écrasée.<br />
Exemples<br />
Après l'affectation x=3, la variable x conti<strong>en</strong>dra la valeur 3.<br />
Après y=4+x, la variable y conti<strong>en</strong>dra la valeur 7.<br />
Affectation <strong>et</strong> comparaison<br />
Il ne faut pas confondre l'affectation avec la comparaison. Par exemple, la comparaison x==3<br />
perm<strong>et</strong> de savoir si oui ou non la valeur de la variable x est 3. Dans la plupart des <strong>langages</strong>, on<br />
différ<strong>en</strong>cie ces deux opérations. En Python, l'affectation est exprimée par un « = », tandis que la<br />
comparaison est exprimée par « == ». D'autres <strong>langages</strong> (Pascal par exemple) utilis<strong>en</strong>t<br />
respectivem<strong>en</strong>t les opérateurs « := » <strong>et</strong> « = ».<br />
Incrém<strong>en</strong>tation / décrém<strong>en</strong>tation<br />
Il arrive fréquemm<strong>en</strong>t que l'on doive incrém<strong>en</strong>ter (ou décrém<strong>en</strong>ter) une variable, c'est-à-dire<br />
augm<strong>en</strong>ter (ou diminuer) sa valeur d'une ou plusieurs unités. Dans ce cas, on peut utiliser<br />
l'instruction x=x+1 7 . Voici ce qui se passe : on pr<strong>en</strong>d la valeur cont<strong>en</strong>ue dans x, on y ajoute 1, puis<br />
on rem<strong>et</strong> le nouveau résultat dans la variable x.<br />
L'instruction x=x+1 est tellem<strong>en</strong>t fréqu<strong>en</strong>te qu'il existe souv<strong>en</strong>t des raccourcis : x+=1 (Python)<br />
ou x++ (C, Mathematica).<br />
6.6.2. Les tests<br />
Un test est une instruction du g<strong>en</strong>re si...alors...sinon. La suite du programme dép<strong>en</strong>dra du résultat<br />
du test.<br />
SI Test 1 ALORS<br />
Instruction 1<br />
SINON<br />
Instruction 2<br />
FIN SI<br />
Instruction 3<br />
Par exemple, <strong>en</strong> Python, on aura :<br />
if x>=10:<br />
x=x-20<br />
else:<br />
x=x+2<br />
7 Remarquez bi<strong>en</strong> que c<strong>et</strong>te expression n'a mathématiquem<strong>en</strong>t aucun s<strong>en</strong>s<br />
Didier Müller 6-12 Juin 2013
L'informatique au lycée <strong>Chapitre</strong> 6<br />
Le même test <strong>en</strong> Java serait :<br />
if (x>=10) x=x-20 else x=x+2<br />
On peut <strong>en</strong>chaîner autant d'instructions « sinon si » que l'on veut : seule la première dont la<br />
condition sera vérifiée sera exécutée. On peut généralem<strong>en</strong>t associer une clause sinon qui ne sera<br />
exécutée que si aucune clause sinon si n'a été vérifiée.<br />
SI Test 1 ALORS<br />
Instruction 1<br />
SINON SI Test 2 ALORS<br />
Instruction 2<br />
FIN SI<br />
Instruction 3<br />
Par exemple, <strong>en</strong> Python 3 :<br />
if x==0:<br />
print("x est nul")<br />
elif x
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
heure 0 minute, 1 heure 1 minute, ... On voit qu'une première boucle parcourra les heures, tandis que<br />
la deuxième parcourra les minutes, <strong>et</strong> que l'on incrém<strong>en</strong>tera l'heure seulem<strong>en</strong>t quand 60 minutes<br />
seront passées. Voilà ce que cela donnera <strong>en</strong> Python 3 :<br />
h=0<br />
while h
L'informatique au lycée <strong>Chapitre</strong> 6<br />
En Pascal :<br />
En C :<br />
for i := depart to fin do instruction;<br />
Itérateur<br />
Un itérateur est un obj<strong>et</strong> qui perm<strong>et</strong> de réaliser une boucle parcourant tous les élém<strong>en</strong>ts cont<strong>en</strong>us<br />
dans une structure de données (par exemple une liste).<br />
POUR CHAQUE valeur DANS collection<br />
Instruction 1<br />
FIN POUR CHAQUE<br />
Instruction 2<br />
Exemple <strong>en</strong> Python :<br />
for animal in ["chat", "chi<strong>en</strong>", "poule"] :<br />
print(animal)<br />
6.6.4. Les sous-programmes<br />
Un sous-programme est un <strong>en</strong>semble d'instructions pouvant être appelé depuis plusieurs <strong>en</strong>droits<br />
du programme. Les sous-programmes sont utilisés pour améliorer la structure du programme <strong>et</strong> sa<br />
lisibilité. Ces constructions ajout<strong>en</strong>t la notion de passage de paramètres <strong>et</strong> aussi la notion de variables<br />
locales qui évite que le sous-programme ait un eff<strong>et</strong> de bord sur la routine appelante.<br />
Une fonction peut d'une part effectuer une action (par exemple afficher un résultat), <strong>et</strong> d'autre<br />
part r<strong>et</strong>ourner une valeur. Une fonction qui ne r<strong>en</strong>voie pas de valeur est appelée une procédure.<br />
Portée d'une variable<br />
En Python, une variable définie au mom<strong>en</strong>t où elle est affectée d'une valeur. Une variable définie<br />
dans le programme principal est visible de l'intérieur des fonctions, mais une variable définie dans<br />
une fonction n'est pas visible de l'extérieur (à moins d'utiliser l'instruction global). Deux variables<br />
peuv<strong>en</strong>t donc avoir le même nom mais être différ<strong>en</strong>tes selon l'<strong>en</strong>droit où elles sont définies.<br />
Dans une fonction, Python utilise une variable définie localem<strong>en</strong>t. S'il elle n'est pas définie<br />
localem<strong>en</strong>t, Python recherche la variable au niveau global, mais dans ce cas, il n'est pas possible de<br />
modifier la variable globale.<br />
Pr<strong>en</strong>ons un exemple <strong>en</strong> Python :<br />
def ecrire():<br />
n = 3<br />
print(n,<strong>en</strong>d=' ')<br />
n=5<br />
ecrire()<br />
print(n)<br />
Didier Müller 6-15 Juin 2013
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
Tous ces exemples<br />
sont très mauvais<br />
du point de vue de<br />
la lisibilité. Il faut<br />
éviter d'écrire des<br />
programmes<br />
pareils ! Ils sont<br />
juste là pour<br />
préciser le concept<br />
de portée d'une<br />
variable.<br />
Ce programme écrira 3 5. On voit bi<strong>en</strong> que les deux n sont des variables différ<strong>en</strong>tes, puisque<br />
l'instruction n=3 n'a pas modifié la valeur de l'autre n. Le n de la deuxième <strong>ligne</strong> est une variable<br />
locale à la procédure ecrire, tandis que celui de la cinquième <strong>ligne</strong> est une variable locale.<br />
Modifions légèrem<strong>en</strong>t ce programme :<br />
def ecrire():<br />
n += 3<br />
print(n,<strong>en</strong>d=' ')<br />
n=5<br />
ecrire()<br />
print(n)<br />
Ce programme produira une erreur, car le n local dans la procédure écrire n'a pas été initialisé.<br />
Pour finir avec c<strong>et</strong> exemple, le programme ci-dessous donnera comme résultat 3 3. La <strong>ligne</strong><br />
global n signale que n est la variable globale initialisée dans le programme principal. Il ne s'agit<br />
donc plus d'une variable locale. Il n'y a là plus qu'une seule variable n.<br />
def ecrire():<br />
global n<br />
n = 3<br />
print(n,<strong>en</strong>d=' ')<br />
n=5<br />
ecrire()<br />
print(n)<br />
Passage de paramètres<br />
On peut passer des paramètres à une procédure ou une fonction sous forme d'une liste de<br />
paramètres formels <strong>en</strong>tre par<strong>en</strong>thèses. A l'intérieur du corps de la procédure, les paramètres sont des<br />
variables locales.<br />
Il ne faut pas redéclarer le nom des paramètres dans la section des déclarations locales. Voici un<br />
exemple <strong>en</strong> Pascal 8 , qui calcule x n (naïvem<strong>en</strong>t) :<br />
var n : integer;<br />
function puissance(x:real; n:integer) : real;<br />
var p:real;<br />
begin<br />
p:=1;<br />
while n>0 do<br />
begin<br />
p:=p*x;<br />
n:=n-1<br />
<strong>en</strong>d;<br />
puissance:=p<br />
<strong>en</strong>d;<br />
begin<br />
n:=3;<br />
writeln('Pi au cube =',puissance(3.14159,n));<br />
writeln(n) (*la valeur de n n'a pas été modifiée*)<br />
<strong>en</strong>d.<br />
C'est la valeur du paramètre qui est passé à la procédure. Si la valeur est modifiée à l'intérieur de<br />
la procédure, la modification n'est pas répercutée à la sortie de la procédure. On appelle ce type de<br />
passage de paramètre un passage par valeur.<br />
8 En Pascal, toutes les variables doiv<strong>en</strong>t être déclarées, ce qui n'est pas le cas <strong>en</strong> Python, où les variables « vi<strong>en</strong>n<strong>en</strong>t au monde » <strong>en</strong> se voyant<br />
assigner une valeur <strong>et</strong> sont automatiquem<strong>en</strong>t détruites lorsqu'elles se r<strong>et</strong>rouv<strong>en</strong>t hors de portée.<br />
Didier Müller 6-16 Juin 2013
L'informatique au lycée <strong>Chapitre</strong> 6<br />
Dans certains <strong>langages</strong>, il est possible de passer des variables comme paramètres. On appelle cela<br />
un passage par variable ou passage par référ<strong>en</strong>ce. Toute modification du paramètre dans la fonction<br />
appelée <strong>en</strong>traîne alors la modification de la variable passée <strong>en</strong> paramètre.<br />
Voici un autre programme <strong>en</strong> Pascal, qui échange les valeurs de deux variables :<br />
var x,y : real;<br />
Remarquez bi<strong>en</strong> le<br />
mot-clef var <strong>en</strong>tre<br />
les par<strong>en</strong>thèses qui<br />
fait toute la<br />
différ<strong>en</strong>ce.<br />
procedure echanger(var a,b:real)<br />
var aux:real;<br />
begin<br />
aux:=a; a:=b; b:=aux<br />
<strong>en</strong>d;<br />
begin<br />
x:=3; y:=4;<br />
echanger(x,y);<br />
writeln(' x=',x, ', y=',y)<br />
<strong>en</strong>d.<br />
Ce programme écrira x=4, y=3.<br />
Puisque la procédure att<strong>en</strong>d des variables <strong>en</strong> paramètres, on ne peut pas appeler echanger avec<br />
des valeurs (echanger(3,4) est interdit, car 3 <strong>et</strong> 4 ne sont pas des variables : on ne peut pas les<br />
modifier).<br />
En Python, le passage des paramètres se fait toujours par référ<strong>en</strong>ce, MAIS certains types sont<br />
« immutables », c'est-à-dire non modifiables. Les règles sont les suivantes :<br />
• si un paramètre transmis à une fonction est une valeur immutable (les nombres <strong>et</strong> les<br />
chaînes de caractères), la fonction n'aura aucun moy<strong>en</strong> de modifier l'original. La valeur de<br />
départ est conservée ;<br />
• si un paramètre est une valeur mutable (les listes par exemple), la fonction pourra modifier<br />
l'original, <strong>et</strong> avoir ainsi un eff<strong>et</strong> de bord 9 (désiré ou non).<br />
Pr<strong>en</strong>ons un exemple (vicieux) :<br />
def ecrire(x):<br />
x=5<br />
print(x,<strong>en</strong>d=' ')<br />
x=0<br />
ecrire(x)<br />
print(x)<br />
Le résultat sera 5 0, alors que l'on s'att<strong>en</strong>dait plutôt à 5 5. Cela vi<strong>en</strong>t du fait que le type <strong>en</strong>tier est<br />
immutable.<br />
Par contre :<br />
def ecrire(x):<br />
x[0]=5<br />
# on modifie le 1er élém<strong>en</strong>t de la liste x<br />
print(x[0],<strong>en</strong>d=' ')<br />
x=[0,1,2,3,4]<br />
ecrire(x)<br />
print(x[0])<br />
produira 5 5, car une liste est mutable. D'une manière générale, il vaut mieux éviter les eff<strong>et</strong>s de<br />
bords, afin d'avoir un programme plus lisible.<br />
9 En informatique, une fonction est dite à eff<strong>et</strong> de bord si elle modifie un état autre que sa valeur de r<strong>et</strong>our.<br />
Didier Müller 6-17 Juin 2013
<strong>Programmation</strong> <strong>et</strong> <strong>langages</strong><br />
Sources<br />
[1] Pixel, « Diagram and history of programming languages »,<br />
<br />
[2] Wikipédia, « Langages de programmation »,<br />
<br />
[3] Wikipédia, « <strong>Programmation</strong> informatique », <br />
[4] Wikipédia, « Machine de Turing », <br />
[5] Wikipédia, « Paradigme (programmation) »,<br />
<br />
[6] Wikipédia, « Machine de Turing », <br />
Didier Müller 6-18 Juin 2013