Cours Algorithmique (Génie Logiciel)
Cours Algorithmique (Génie Logiciel)
UE : Programmation Structurée
1. Notions élémentaires
■ Informatique
L'informatique est la science du traitement automatique de l'information. Elle traite de deux
aspects complémentaires
les programmes ou logiciels (software) qui décrivent un traitement à réaliser,
les machines ou le matériel (hardware) qui exécute ce traitement.
■ Hardware
C'est l'ensemble des éléments physiques (microprocesseur, mémoire, disques durs, ...)
utilisés pour traiter les informations.
■ Software
C'est un programme (ou ensemble de programmes) décrivant un traitement d'informations
à réaliser par un matériel informatique.
■ Algorithme
La notion d'algorithme est à la base de toute la programmation informatique. La
définition la plus simple que l'on peut associer à cette notion est qu'un algorithme est une
suite ordonnée d'instructions qui indique la démarche à suivre pour résoudre un problème
ou effectuer une tâche. Le mot algorithme vient du nom latinisé du mathématicien perse
AlKhawarizmi, surnommé« le père de l'algèbre».
Exemple : Appel téléphonique
a. Ouvrir son téléphone,
b. Chercher/Composer le numéro du destinataire,
c. Appuyer sur le bouton« Appel».
Ce mode d'emploi précise comment faire un appel téléphonique. Il est composé d'une suite
ordonnée d'instructions (ouvrir, chercher/composez, appuyer) qui manipulent des données
(téléphone, numéro, bouton) pour réaliser la tâche d'appel.
3. L'algorithmique
3.1. Définition
L'algorithmique est la science des algorithmes. Elle s'intéresse à l'art de construire des
algorithmes ainsi qu'à déterminer leur validité, leur robustesse, leur réutilisabilité, leur
complexité ou leur efficacité [3]. L'algorithmique permet ainsi de passer d'un problème à
résoudre à un algorithme qui décrit la démarche de résolution du problème. Par conséquent,
la programmation consiste à traduire un algorithme dans un langage« compréhensible» par
l'ordinateur afin qu'il puisse être exécuté automatiquement.
problème
algoritb.JJÜqu,e
algonthrn.e
pm·Qg:i·amma.tion
code source
La figure 1 ci-dessus illustre les deux phases nécessaires pour obtenir un code source
■ Phase d'algorithmique qui implique la recherche et l'écriture d'un algorithme;
■ Phase de programmation qui consiste à traduire l'algorithme obtenu en un
programme à l'aide d'un langage de programmation (C, Java, Python, ...).
Dans la première phase, on doit définir les données qu'on dispose et les objectifs qu'on
souhaite atteindre, ainsi que prévoir des réponses à tous les cas possibles.
2
Exemple : résolution d'une équation de second degré ax +bx+c =0
- Les données sont a, b et c
- Les sorties sont x1 et x2
- Les cas : a=0 et b#0, a = 0 et b = 0, a #0 , ......
3.2. Principe général
Le traitement automatique de l'information consiste à exécuter des instructions (opérations
élémentaires et complexes) sur des données d'entrée afin de générer d'autres informations
appelées résultats ou données de sortie.
Supposons qu'on doit calculer la moyenne d'un étudiant pour un ensemble de matières.
Donc, on doit :
i. Définir le nombre des matières concernées ainsi que les notes et les coefficients ;
ii. Réaliser les opérations suivantes :
Multiplier chaque note d'une matière par son coefficient,
Calculer la somme des résultats des multiplications,
Diviser la somme obtenue par le total des coefficients,
iii. Afficher le la moyenne de l'étudiant (résultat final).
Remarque:
Lorsqu'on écrit un algorithme, les questions suivantes doivent être considérées :
✓ Quel est le résultat attendu?
✓ Quelles sont les données nécessaires (informations requises)?
✓ Comment faire (le traitement à réaliser)?
Partie déclarative : appelée aussi entête de l'algorithme, elle contient généralement les
déclarations (des constantes, des variables, etc.).
Partie corps de l'algorithme : constituée d 'une ou plusieurs séquences
d'instructions faisant appel à des opérations de base à exécuter par l'ordinateur.
Syntaxe:
Algorithme nom_de_l'algorithme ;
} Partie déclarative (Entête)
< Liste de variables/constantes>;
Début
< Séquence d'instructions>; Partie corps de l'algorithme
Fin }
L'élément unitaire de stockage de l'information est appelé bit. Un bit ne peut avoir que deux
états distincts: 0 ou 1 (vrai ou faux dans la logique). Dans la mémoire de l'ordinateur, les
données sont manipulées par groupes de 8 bits (octets), ou plus (mots de 16, 32, 64 bits, ...).
Une case mémoire est donc appelée mot et pour que l'unité centrale puisse stocker une
information et la retrouver dans la mémoire, chaque mot est repéré par une adresse.
Dans la programmation, les adresses mémoire sont représentées par des noms. Le
programmeur ne connait pas donc l'adresse d'une case mais plutôt son nom. Il y a donc deux
façons de voir la mémoire centrale de l'ordinateur: côté programmeur et côté ordinateur tel
qu'il est illustré, à titre d'exemple, dans le schéma suivant (figure 3).
Mémoire
Adresses Mots
10000000 6 X
10000001 8 y Variables
10000010 7 moyenne
10000011
...
Syntaxe:
Var nom_variable : type ;
Cons t nom constante = valeur ;
Remarque:
Dans la partie déclarative, les variables et les constantes sont caractérisées essentiellement
par :
Le type d'une variable définit l'ensemble des valeurs que peut prendre la variable, ainsi que
l'ensemble des opérations que l'on peut appliquer sur cette variable. Il existe des types
simples prédéfinis tels que : entier, réel, caractère et booléen.
4.3.1. Type entier
C'est un type numérique représentant l'ensemble des entiers relatifs,tels que: -9, 0,31, ....
Les opérations permises sur ce type sont :+, - , *,div (division entière) et mod (modulo ou
reste de la division entière).
C'est un type numérique aussi représentant l'ensemble des nombres réels,tels que : 0.25,
' 110ns
· .
-1.33, 2 .5 e+ 10,... . Les opera permises sur ce type sont .· +,-, * et /.
Le mot clé est : réel.
Ce type est utilisé dans la logique pour représenter les deux valeurs : vrai et faux.
Les opérations prises en charge sont : NON,ET,OUI.
Le mot clé est : booléen.
Ce type représente les mots et les phrases tels que "Algorithmique","Cours",etc. Le mot
Globalement,la partie déclarative d'un algorithme peut être représentée comme suit.
Exemple:
Var x, y: entier;
z, w: réel;
lettre : caractère ;
nom : chaîne ;
Etat : booléen ;
Const n = 100;
arobase = '@';
mot = "bonjour";
5. Conclusion
Ce chapitre constitue une initiation aux notions basiques de l'écriture des algorithmes. La
syntaxe d'un algorithme, la notion de variable et de constante, ainsi que leurs types sont
définis et expliqués à travers des exemples simples. Ceci constitue pour le lecteur un
prérequis de base qui lui permettra de comprendre la notion d'instructions algorithmiques
dans les prochains chapitres.
Chapitre 2 - Les instructions simples
1. Introduction
Un algorithme, par définition, est un ensemble d'instructions qui peuvent être simples ou
complexes. Dans ce chapitre, on s'intéressera aux instructions simples notamment: les
instructions d'affectation, de lecture et d'écriture.
2. L'instruction d'affectation
Cette instruction est élémentaire en algorithmique, elle permet d'assigner une valeur à une
variable selon la syntaxe suivante
variable -expression ;
Remarque:
X-y; x-z;
y-x; x-a;
z-x; b-y;
a-b; a-z;
b-a;
Les expressions arithmétiques ou logiques sont composées d'au moins deux termes reliés
par un ou plusieurs opérateurs dont on peut distinguer :
Remarque:
Les expressions logiques peuvent être composées des opérateurs logiques et/ou
relationnels. Par exemple, (A<20) ET (B>=l0) est Vrai si A est inférieur à 20 et Best égal
ou supérieur à 10, et faux sinon.
3. L'instruction de lecture
Cette instruction est très primordiale dans un algorithme. Elle permet de lire des valeurs en
entrée (input) et les affecter aux variables stockées dans la mémoire. Les valeurs affectées
sont souvent des données introduites à partir d'un périphérique d'entrée tel que le clavier.
Syntaxe:
Lire (varl, var2, ...);
Exemple:
Lire(x): lit et stocke une valeur donnée dans la case mémoire associée à x.
Lire(x, y): lit et stocke deux valeurs, la première dans x et la deuxième dans y.
Illustration
Mémoire Lire(:1:, y)
<
X 5
y 7 input
Clavier
' ..
4. L'instruction d'écriture
Cette instruction est aussi d'une grande importance dans les algorithmes. Elle permet
d'écrire en sortie (output) les données résultant d'un traitement effectué par l'algorithme
(valeur, texte, ...) en les affichant par exemple sur un périphérique de sortie tel que l'écran.
Syntaxe:
Ecrire (varl, var2, exprl, expr2, ...) ;
Remarque:
Dans le cas d'écriture d'une expression, c'est le résultat d'évaluation de cette expression qui
est affiché et non pas l'expression elle-même.
Par exemple:
Mémoire Ecrire(x., y) ;
>
X 5 5
7
y 7 output
...
Algorithme Moyenne_deux_réels
Var x, y, z: réel;
Début
Ecrire ("Donner la première valeur:");
Lire (x);
Ecrire ("Donner la deuxième valeur:");
Lire (y);
z +- (x + y)/2;
Ecrire ("La moyenne est: ", z);
Il On peut remplacer les deux dernières instructions par une seule:
Ecrire ("La moyenne est: ", (x + y)/2); // dans ce cas on a pas besoin de z
Fin
Dans cet algorithme, si l'utilisateur introduit 10 pour x et 20 pour y alors l'affichage sera:
La moyenne est : 15
5. Conclusion
1. Introduction
Il existe deux formes de test: forme simple (ou réduite) et forme complète.
Dans cette forme, une action qui correspond à une ou plusieurs instructions, est exécuté si
une condition est vérifiée. Sinon l'algorithme passe directement au bloc d'instruction qui
suit immédiatement le bloc conditionnel.
Syntaxe:
Si (condition) Alors
instruction(s); // action Oui
Remarque:
La condition évaluée après l'instruction« Si» est une variable ou une expression booléenne
qui, à un moment donné, est Vraie ou Fausse. par exemple: x=y; x <= y; ...
Exemple:
X- 5 ; y - 9;
Si (x = y) Alors Ecrire ("x est égale à y");
Dans cet exemple, le message« x est égale à y » ne sera pas affiché puisque la condition (x
= y) n'est pas vérifiée.
2.2. Forme complète
Cette forme permet de choisir entre deux actions selon qu'une condition est vérifiée ou non.
Syntaxe:
Si (condition) Alors
on
instruction(s) 1 ;Il action]
Sinon instruction(s) 2;11 action2 Oui
Remarque:
Certains problèmes exigent parfois de formuler des conditions qui ne peuvent pas être
exprimées sous la forme d'une simple comparaison. Par exemple, la condition x E [O, 1
[ s'exprime par la combinaison de deux conditions x >= 0 et x < 1 qui doivent être
vérifiées en même temps.
Pour combiner ces deux conditions, on utilise les opérateurs logiques. Ainsi, la condition x E
[O, 1 [ pourra s'écrire sous la forme : (x >= 0) ET (x < 1 ). Cette dernière est appelée une
condition composée ou complexe.
x+-----5;y+-----9;
Si (x = y) Alors Ecrire ("x est égale à y ") ;
Sinon Ecrire ("x est différente de y ") ;
Avec cette forme, on peut traiter les deux cas possibles. Si la condition (x=y) est vérifiée, le
premier message est affiché, si elle n'est pas vérifiée, le deuxième message est affiché.
3. Tests imbriqués
La forme « Si ... Alors... Sinon » permet deux choix correspondants à deux traitements
différents. Dans d'autres situations, on pourra avoir plus de deux cas ce qui rend cette
alternative insuffisante pour traiter tous les cas possibles (voir exemple ci-dessous).
La forme complète permet de choisir entre plusieurs actions en imbriquant des formes
simples selon la syntaxe ci-dessous.
Syntaxe:
Si (conditionl) Alors instruction(s) 1 ; Sinon
Si (condition2) Alors instruction(s) 2;
Sinon Si (condition3) Alors instruction(s) 3;
Sinon instruction(s) N ;
FinSi
FinSi
FinSi
Exemple: Etat de l'eau
Dans les conditions normales de température et de pression, l'eau est sous forme de glace si
la température est inférieure ou égale à 0° C, sous forme de liquide si la température est
comprise entre 0 ° C et 100 ° C et sous forme de vapeur au-delà de 100 ° C. Ecrivons
l'algorithme qui permet de vérifier l'état de l'eau selon sa température.
La solution pourrait être comme suit :
Algorithme Etat_Eau ;
Var t: réel;
Début
Ecrire ("Donner la température de l'eau:");
Lire (t);
Si (t <= 0) Alors Ecrire ("Etat solide");
FinSi
Si (t > 0 ET t < 100) Alors Ecrire ("Etat liquide");
Finsi
Si (t >= 100) Alors Ecrire ("Etat gazeux");
Finsi
Fin
Cet algorithme est correct mais il évalue les trois conditions qui portent sur la même variable
et qui sont exclusives. En effet, si (t <= 0), alors on ne peut pas avoir (t>= 0 et t < 100) ni (t
> 100). Il est donc inutile d'évaluer les deux dernières conditions si la première est vérifiée,
ou d'évaluer la dernière condition si la deuxième est vérifiée. Pour éviter ce cas de figure, il
sera préférable d'utiliser des tests imbriqués comme suit :
Début
Ecrire ("Donner la température de l'eau:");
Lire (t);
Si (t <= 0) Alors Ecrire ("Etat solide");
Sinon Si (t < 100) Alors Ecrire(" Etat liquide");
Sinon Ecrire ("Etat gazeux");
Finsi
Finsi
Fin
L'organigramme correspondant est illustré
Afficher (Donner fa
œ�e d.é .f'élilu).
Fin
Remarque:
Nous avons les équivalences suivantes:
NON(AETB) �NON AOU NONB
Il existe une autre variante d'instructions conditionnelles qui permet d'effectuer des actions
différentes suivant les différentes valeurs que peut avoir une variable. Cette structure est
décrite comme suit :
Syntaxe:
valeur! : instruction(s) 1 ;
valeur2 : instruction(s) 2;
Non lnstruction{s) 2
valeurN : instruction(s) N;
défaut : instruction(s) par défaut;
FinSelon;
Remarque:
Dans la structure de test à choix multiple s :
L'action peut être une suite d'instructions;
La valeur est une constante de même type que la variable;
La partie « défaut » est exécutée si aucun des autres cas n'est vérifié;
L'exécution des différents cas (y compris le cas par défaut ) est exclusive c'est-à
dire l'exécution d'un seul cas provoque la sortie de cette structure.
Exemple:
Dans ce qui suit, le nom du jour de la semaine correspondant est affiché selon la valeur de
la variable«jour».
jour- 5;
Selon jour
1 : Ecrire ("Dimanche");
2: Ecrire ("Lundi");
3 : Ecrire ("Mardi");
4 : Ecrire ("Mercredi");
5 : Ecrire ("Jeudi");
6: Ecrire ("Vendredi");
7 : Ecrire ("Samedi");
Défaut : Ecrire (''Numéro de jour invalide.") ;
FinSelon
Donc, l'expression« Jeudi» est affichée dans ce cas.
5. Conclusion
1. Introduction
Considérons le même exemple qu'on a vu précédemment concernant le calcul de la moyenne
générale d'un étudiant. Pour se faire, on doit :
• Lire toutes les notes (et leurs coefficients) de l'étudiant,
• Calculer la somme des notes,
• Diviser la somme obtenue sur le nombre (ou sur la somme des coefficients).
Si l'on veut maintenant calculer la moyenne d'un autre étudiant, les mêmes instructions
doivent être répétées.
Pour N d'étudiants, il nous faudra donc répéter N fois la même séquence d'instructions.
Cet exemple soulève deux questions importantes
1- Comment éviter d'écrire plusieurs fois la même séquence d'instructions?
2- Combien de fois doit-on répéter l'exécution de la séquence d'instructions pour
obtenir le résultat attendu?
Pour répondre à ces questions, de nouvelles instructions de contrôle sont introduites. Il s'agit
des instructions itératives (appelées aussi les boucles ou les itérations).
2. Définition
Une boucle (ou itération) est une instruction de contrôle qui permet de répéter plusieurs fois
un ensemble d'instructions. Généralement, deux cas sont distingués :
Le nombre de répétitions est connu.
Le nombre des répétitions est inconnu ou variable.
3. L'instruction« Pour»
ind=vi ind=vi
Oui Oui
Non Non
1 ns truction(s) 1 nstruction(s)
ind=ind+pas ind=ind-pas
Suite de Suite de
l'algorithme l'algorithme
Structure Structure
croissante décroissante
Cette structure est dite«croissante» lorsque la valeur initiale de l'indice est inférieure à sa
valeur finale, le pas de variation est par conséquent positif. Autrem ent, elle est dite
«décroissante».
Résultat d'exécution : 1,2, 3, ... , 99, 100 Résultat d'exécution: 100, 99, 98, ... , 2, 1
Remarque : Si la valeur du«pas» n'est pas précisée dans l'instruction«Pour», elle est
par défaut égale à un (1 ).
4. L'instruction« Tant que... faire »
Cette instruction permet de tester une condition et répéter le traitement associé tant que cette
condition est vérifiée.
Syntaxe:
Non
Tant que condition faire
Oui
instruction(s);
. _____l ______
lnstruction(s)
FinTq
Suite de
l'algorithme
Var i: entier;
Début
i+---1;
Tant que (i<= IOO) faire
Ecrire (i); i +- i+ 1 ;
FinTq
Fin
Dans cet t e inst ruct ion, un t rait ement est exécut é au moins une fois puis sa répét it ion se
poursuit jusqu'à ce que la condition soit vérifiée.
Syntaxe:
Non
lnstruction(s)
Répéter
instruction(s);
Jusqu'à (condition);
Suite de
l'algorithme
Exemple: Soit l'algorithme suivant:
Var n, p: entier;
Début
Répéter
Ecrire ("Donner un nombre:"); Lire (n);
p +- n*n; Ecrire (p);
Jusqu'à (n= O)
Ecrire ("Fin de l'algorithme");
Fin
Les instructions encadrées par les mots répéter et jusqu'à constituent le bloc de la boucle
qu'il faut répéter jusqu'à ce que la condition (n=O) soit vérifiée. Donc le nombre de
répétitions de cette boucle dépend des données fournies par l'utilisateur.
TAF:
Réécrire l'algorithme précédent avec« Tant que... faire» puis avec« Pour».
Remarque:
Dans la boucle «Répéter... jusqu'à», la condition te lle qu'e lle e st e xprimée ci-dessus,
constitue une condition d'arrêt de la boucle; mais réellement, cela diffère selon le langage
de programmation utilisé. Par e xe mple , e n Pascal, la condition de ce tte boucle e st une
condition d'arrêt. Alors qu'e n langage C, ce tte condition e st e xprimée e n tant qu'une
condition de continuation.
7. La notion du compteur
Un compteur est une variable associée à la boucle dont la valeur est incrémentée de un à
chaque itération. Elle sert donc à compter le nombre d'itérations (répétitions) de la boucle.
La notion du compt
e ur e st associé
e particulièr
ee m nt aux deux
boucles : « Répéter...jusqu'à » e t « Tant que...faire ». Par contre , dans la boucle
«Pour», c'est l'indice qui joue le rôle du compteur.
L'utilisation du compteur dans les deux premières boucles est exprimée ainsi :
compt +- 0; compt +- 0;
Répéter Tant que (condition) faire
instruction(s); instruction(s);
Bloc de la boucle
compt +- compt +1 ; compt +- compt +1 ;
Jusqu'à (condition); FinTant que ;
Remarque:
8. La notion d'accumulation
Cette notion est fondamentale en programmation. Elle est utilisée notamment pour calculer
la somme d'un ensemble de valeurs. L'instruction correspondante se présente ainsi:
variable +- variable + valeur ;
Cette i nstructi on consi ste à ajouter une valeur à une vari able numéri que, pui s affecter le
résultat dans la variable elle-même. En d'autres termes, la nouvelle valeur de variable égale
à l'ancienne plus une certaine valeur [4].
Exemple:
Pour ide 1 à 2
Écrire ("i = ", i) ;
Pour j de 1 à 3 boucle 1
Écrire ('J = ", j); ] bouc/e2
Finpour
Finpour
Dans l'exemple ci-dessus, chaque itération de la boucle extérieure (boucle 1) exécute la
boucle intérieure (boucle 2) jusqu'à la fin avant de passer à l'itération suivante, et ainsi de
suite jusqu'à l a fin des deux boucl es. Ainsi, l e résul tat d'exécution peut être représenté
comme suit:
i= 1
j= 1
j=2
j= 3
i=2
j= 1
j=2
j= 3
Remarque:
Des boucles peuvent être imbriquées ou successives. Cependant, elles ne peuvent jamais être
croisées. Par exempl e, l 'al gorithme suivant est faux puisqu'il comporte deux boucles
croisées:
Var i, j : entier;
Début
i+---1 ; j+---1 ;
Répéter
Écrire i;
Répéter
Écrirej;
i+-i+1 ;
Jusqu'à i>2
j+-j+1 ;
Jusqu'àj>3
Fin
1 O. Conclusion
Ce chapitre a été consacré aux structures itératives ou boucles qui permettent de répéter
l'exécution d'une séquence d'instructions plusieurs fois selon un nombre fixe ou certains
critères dont l'utilisation a été explicitée à travers différents exemples. Ainsi, ces instructions
sont d'une grande importance dans la manipulation de certaines structures de données telles
que les tableaux que nous aborderons dans le prochain chapitre.
Chapitre 5 - Les tableaux
1. Introduction
Supposons que l'on a besoin de stocker et de manipuler les notes de 100 étudiants. On doit,
par conséquent, déclarer 100 variables: nl, n2, ..., nl00. Vous pouvez remarquer que c'est
un peu lourd de manipuler une centaine de variables (avec 100 fois de lecture/écriture ...).
Imaginons maintenant le cas pour une promotion de 1000 étudiants, alors là devient notre
cas un vrai problème.
En algorithmique (et en programmation), on peut regrouper toutes ces variables en une seule
structure qui s'appelle tableau.
Un tableau est un ensemble de variables de même type ayant toutes le même nom.
Suite à cette définition, la question suivante se pose:
Comment peut-on différencier entre des variables ayant le même nom?
La réponse est dans la notion du tableau lui-même où chaque élément est repéré par un
indice. Ce dernier est un numéro (généralement un entier) qui permet de différencier chaque
élément du tableau des autres. Ainsi, les éléments du tableau ont tous le même nom, mais
pas le même indice. Pour accéder à un élément d'un tableau, on utilise le nom du tableau
suivi de l'indice de l'élément entre crochets [4].
Exemple
Soit le tableau T contenant les valeurs suivantes: 5, 10, 29, 3, 18 et 14:
L'organisation du tableau T dans la mémoire peut être représentée comme suit:
Remarque:
L'indice d'un élément dans un tableau, peut être exprimé comme un nombre, mais aussi il
peut être exprimé comme une variable ou une expression calculée [10].
La valeur de l'indice doit être toujours:
• Supérieur ou égal à O : dans quelques langages, le premier élément d'un tableau
porte l'indice 1 (comme en Pascal). Mais dans d'autres, comme c'est le cas en
langage C, la numérotation des indices commence à zéro. Par exemple Notes[]} est
le deuxième élément du tableau Notes.
• de type entier: quel que soit le langage, l'élément Notes[], ...] n'existe jamais.
• Inférieur ou égal au nombre des éléments du tableau (moins 1 si l'on commence
à zéro): En langage C, si un tableau T est déclaré comme ayant 10 éléments, la
présence, dans une ligne du corps de l'algorithme, de l'expression T[JOJ déclenchera
automatiquement une erreur.
2.2. Manipulation
Une fois déclaré, un tableau peut être manipulé comme un ensemble de variables
simples. Les trois manipulations de base sont l'affectation, la lecture et l'écriture.
2.2.1. L'affectation
L'affectation d'une valeur v à un élément i d'un tableau T de type numérique, se fait par:
T[i] - V;
Par exemple, l'instruction: T[0] +- 5 ; affecte la valeur 5 au premier élément du tableau T.
Illustration :
indices: i=O i= l i=2 i=3 i=4 i=5
T �
valeurs: 5
Supposons maintenant que l'on veut affecter la même valeur à tous les éléments du tableau
T, on utilisera pour cela une boucle:
Cette boucle permet de parcourir tout le tableau T en affectant à chaque élément la valeur 5.
Illustration :
indices: i= O i= l i=2 i=3 i=4 i= 5
T �
valeurs: 5 5 5 5 5 5
2.2.2. La lecture
Il est possible aussi d'affecter des valeurs aux éléments d'un tableau par une instruction de
lecture.
Exemple:
Ecrire "Entrer une note: " ;
Lire T[O];
Dans cet exemple, la valeur saisie est affectée au premier (1er:) élément du tableau T.
Illustration :
2.2.3. L'écriture
De même que la lecture, l'écriture de la valeur d'un élément du tableau s'écrira comme suit:
Ecrire T[i]; Cette instruction permet d'afficher la valeur de l'élément i du tableau T.
Remarque:
Les éléments d'un tableau sont manipulés de la même façon que les variables simples. S'il
s'agit d'un tableau de type numérique, les éléments peuvent être utilisés dans l'évaluation
des expressions numériques du genre:
x - (Notes [1] + Notes [2]) / 2;
Notes [O] - Notes [O] + 1;
Exemple:
Soit Notes un tableau de valeurs réelles tel qu'il est illustré dans le schéma qui suit.
Illustration :
Après la fin de la 1
ère
boucle (boucle de lecture):
Après la fin de la 2 ème boucle (boucle d'affichage), on aura, sur écran par exemple,
l'affichage suivant:
Valeur O = 5
Valeur 1 = 34
Valeur 18 = 14,5
Valeur 19 = 60
Les tableaux à deux dimensions se présentent généralement sous forme d'un ensemble de
lignes et de colonnes (Matrice). Par conséquent, chaque élément est repéré par deux indices.
Exemple : le tableau T ci-dessous possède 3 lignes et 4 colonnes.
j =O j= l j =2 j =3
i : indice des lignes
i=O j : indice des colonnes
i= l
i=2 X
Donc, T[2][1] (i=2 et j=l) d ésigne l'élément d e la 3 ème ligne et la 2ème colonne (en
commençant de zéro bien sûr).
Syntaxe:
Tableau nom_tableau [taillel][taille2] : type;
Le tableau Notes est composé de 10 lignes et 20 colonnes. Ce tableau pourra contenir donc
10*20 soit 200 valeurs réelles.
Remarque:
L'utilité d'un tableau à deux dimensions réside dans la possibilité de déclarer un seul tableau
au lieu de déclarer plusieurs tableaux identiques. En effet, le tableau de l'exemple précédent
est équivalant à 10 tableaux simples d e 20 éléments chacun. En d 'autres termes, la
déclaration :
Tableau Notes [10][20] : réel;
remplace celle-ci :
Tableau Notesl [20], Notes2 [20], ..., Notesl0 [20] : réel;
Un tableau à deux dimensions est manipulé de la même façon qu'un tableau simple (à une
seule dimension) que ce soit pour l'affectation, la lecture ou l'écriture. Ces trois opérations
sont illustrées dans la sous-section suivante.
3.3. Application 2
Reprenons l'algorithme de la sous-section 2.3 mais cette fois-ci pour un tableau de 5 lignes
et 20 colonnes :
Var i, j : Entier;
Tableau Tab [5][20] : réel;
Début
Pour ide O à 4
Pour j de O à 19
Ecrire ("Donner une valeur : ") ; Lire (Tab [i][i]) ;
Finpour
Finpour
Pour ide O à 4
Pour j de O à 19
Ecrire (Tab [i][i]) ;
Finpour
Finpour
Fin
4. Tableaux à n dimensions
Les tableaux à n dimensions (n>2), peuvent être utilisés pour diverses raisons telles que la
création e t le traite me nt de s obje ts 3D par e xe mple qui néce ssite nt de s table aux de 3
dimensions au minimum. La déclaration de ce type de tableaux est comme suit :
Syntaxe:
Tableau nom_tableau [taillel][taille2] ... [tailleN] : type;
La manipulation d'un tableau à plusieurs dimensions suit le même principe que celle des
tableaux à deux dimensions. Ceci s'appuie sur l'utilisation des boucles imbriquées pour
parcourir le tableau, de sorte qu'il y aura autant de boucles qu'il y a de dimensions.
Finpour
Fin
Illustration
On suppose que N= 6 et les valeurs saisies sont celles figurant dans le schéma suivant :
indices : i=O i= 1 i=2 i=3 i=4 i=5
Tab �
valeurs: �l __1_
0 �__2_2_�__
3_1_�_4_6_�--5-��-7-�
Revenons à l'algorithme, maintenant, il faut combler les points de la boucle (le bloc qui
devra contenir les instructions de la recherche). Évidemment, il va falloir comparer « val »
à chaque élément du tableau, s'il y a une égalité quelque part, alors «val» fait partie du
tableau. Cela va se traduire, bien entendu, par l'instruction conditionnelle «Si ... Alors ...
Sinon».
Début
Ecrire ("Entrez la valeur à rechercher "); Lire (val) ;
Pour ide O à N-1
Si (val = Tab[i]) Alors
Ecrire (val, "figure");
Sinon
Ecrire (val, "ne figure pas");
Finsi
Finpour
Fin
Illustration
On suppose que la valeur à rechercher (val) est égale à 31 :
indices:
•1 l
i=O i=l i=2 i=3 i=4 i=5
Tab �
-vaœtU'S: 10 22 31 46 5 7
Tab[O) =val?
31 ne figure p-as
1 Tab[O] =val?
31 ne figure pas
Tab[Dl =val? Tab[S) =val?
31 figure 31 ne figure pas
Illustration
En utilisant un drapeau (la variable « Existe »)
..1 t
indices: i=O i=l i=2 i=3 i==4 i=5.
Ta.b c::::::::>
-valeurs: 10 22 31 46 5 7
Existe = Faux
Tab[O] =val?
Existe = Faux
Tab(O] =val? Tab[S} =-val?
► TAF
Réécrire le même algorithme mais cette fois-ci, la boucle de recherche doit être arrêtée dès
que la valeur du drapeau change.
Cette technique est parmi les plus simples, elle consiste à sélectionner, pour une place
donnée, l'élément qui doit y être positionné. Par exemple pour trier un tableau en ordre
croissant, on met en première position le plus petit élément du tableau et on passe à la
position suivante pour mettre le plus petit élément parmi les éléments restants et ainsi de
suite jusqu'au dernier.
Exemple:
Soit à trier, en ordre croissant, le tableau suivant :
25 10 13 31 22 4 2 18
Nous commençons par la recherche de la plus petite valeur et sa position. Une fois identifiée
(dans ce cas, c'est le nombre 2 en 7 ème position), nous l'échangeons avec le 1er élément (le
nombre 25). Le tableau devient ainsi:
2 10 13 31 22 4 25 18
Nous recommençons la recherche, mais cette fois, à partir du 2ème élément (puisque le 1er
est à sa position correcte). Le plus petit élément se trouve en 6 ème position (le nombre 4).
Nous échangeons donc le 2ème élément avec le 6ème élément:
2 4 13 31 22 10 25 18
Nous recommençons la recherche à partir du 3ème élément (puisque les deux premiers sont
maintenant bien placés), Le plus petit élément se trouve aussi en 6 ème position (10), en
l'échangeant avec le 3ème, ça donnera:
2 4 10 31 22 13 25 18
2 4 10 13 22 31 25 18
2 4 10 13 18 31 25 22
2 4 10 13 18 22 25 31
2 4 10 13 18 22 25 31
• Boucle principale: prenant comme point de départ le premier élément, puis le second,
etc, jusqu'à l'avant dernier.
Finpour
/* on sait maintenant où est le plus petit élément. Il ne reste plus qu'à effectuer la permutation
*/
temp +-T(posmin);
T(posmin) +-T(i);
T(i) +-temp;
/* On a placé correctement l'élément numéro i, on passe à présent au suivant*/
FinPour
Exemple:
Soit à trier, en ordre croissant, le même tableau précédent en appliquant le tri par insertion :
i=l 25 10 13 31 22 4 2 18
\. t _____________ )
t
On recommence le processus avec une nouvelle clé. Le 1er élément à droite de la partie triée
(25) est décalé vers la droite puisque sa valeur est supérieure à la clé. Le 2 ème élément ne sera
pas décalé puisqu'il est inférieur à la clé. Par conséquent, la clé est insérée dans la 2ème
position du tableau:
i= 3 10 13 25 31 22 4 2 18
t
On ne déplace pas cette clé (31) puisque sa valeur est supérieure à celles des éléments qui la
précèdent.
i= 4 10 13 25 31 22 4 2 18
t
On décale les deux premiers éléments (31 et 25) vers la droite et la clé est insérée à la 3 ème
position:
i= 5 10 13 22 25 31 4 2 18
t
On décale tous les éléments de la partie triée vers la droite puisque leurs valeurs sont
supérieures à celle de la clé. Cette dernière est déplacée à la 1 ère position:
i= 6 4 10 13 22 25 31 2 18
La même opération est répétée pour cette clé (2) :
t
i= 7 2 4 10 13 22 25 31 18
t
Les trois éléments (22,25 et 31) sont décalés vers la droite et la clé est déplacée vers la 5ème
position:
2 4 10 13 18 22 25 31
6.3. Comparaison
Dans l'algorithme de tri par sélection, nous avons dans tous les cas, la boucle interne est
exécuté pour i= l, 2, 3 jusqu'à i= (n-1) par conséquent, nous avons (n-1) + (n-2) + (n-3) + ...
+ 1 étant n (n-1) / 2 exécutions. Par exemple, pour un tableau de 100 éléments, la boucle est
exécutée 4950 fois dans tous les cas.
Dans l'algorithme de tri par insertion, nous avons dans le pire des cas un tableau trié à
l'envers (en ordre décroissant dans ce cas), et la boucle interne est exécuté (n-1) + (n-2) +
(n-3) + ... + 1 fois, étant n (n-1) / 2 exécutions au maximum. Au meilleur des cas, le tableau
est trié en ordre voulu (croissant dans ce cas) et la boucle interne ne s'exécutera jamais. En
moyenne, le nombre d'exécutions est n (n-1) / 4. Par exemple, pour un tableau de 100
éléments, la boucle est exécutée 4950 fois au maximum et 2475 en moyenne.
7. Conclusion
1. Introduction
Nous avons vu dans le chapitre précédent, que les tableaux nous permettent de stocker
plusieurs éléments de même type, tel que stocker les notes des étudiants dans un tableau de
type réel. Supposons maintenant qu'en plus des notes des étudiants, nous voulons stocker
aussi leurs informations (nom, prénom, matricule, ...). Il nous faut dans ce cas de figure, une
autre structure qui permet de stocker des données de différents types. Donc, une nouvelle
structure appelée enregistrement est plus adaptée dans ce cas.
2. Définition
Un enregistrement (ou structure) permet de regrouper un ensemble de données de différents
types sous le même nom (un seul objet). Il est défini par un ensemble d'éléments appelés
champs. Ces derniers sont des données élémentaires ou composées qui peuvent être de types
différents.
3. Déclaration et manipulation
La syntaxe de déclaration d'une structure est la suivante:
Structure nom structure
champl : typel ;
champ2 : type2 ;
champN : typeN ;
FinStructure ;
4. Tableau de structures
Il est possible de déclarer un tableau dont les éléments sont des structures avec la syntaxe
suivante:
Tableau nom_tableau [taille] : Structure nom_structure;
nom_tableau [i].champ
Exemple:
Structure Date
jour, mois, annee : entier;
Finstructure ;
Structure Compte
Ncpt: entier;
nom: chaine;
Dtüuverture : Date;
Finstructure ;
Où « DtOuverture » est une variable structure de type « Date », champ de la structure «
Compte ». Donc, la structure « Date » est déclarée obligatoirement avant la structure «
Compte».
Lorsqu'un champ d'une structure est lui-même une structure, l'accès à ce champ se fait
comme suit:
variable_structure.variable_sous_structure.champ
nom_tableau[indice].variable_sous_structure.champ
6. Conclusion
Nous avons vu dans le cinquième chapitre que les tableaux sont très pratiques, cependant ils
ne permettent pas de répondre à tous les besoins de stockage tels que le regroupement de
plusieurs données de types différents en un seul objet. A cet effet, la notion de structure ( ou
d'enregistrement) abordée dans le présent chapitre permet de pallier ce problème en créant
un nouveau type permettant le stockage des données de types différents ou non. Un
enregistrement qui est composé de plusieurs champs où chaque champ correspond à une
donnée, constitue la brique de base pour les structures de données telles que les listes, les
piles et les files qui ne font pas l'objet d'étude dans ce polycopié.
Chapitre 7 - Les fonctions et les procédures
1. Introduction
Un entier positif en base b est représenté par une suite de chiffres (en Cn- 1 ...c 1 co)b où les Ci
sont des chiffres de la base b (0 :S Ci < b).
On suppose que le nombre x est représenté par un tableau de chiffres (code) en base b ; par
exemple si b = 2 et code = [1,0, 1], alors en base 10 le nombre entier x correspondant vaudra
1x22 + 0x2 1 + 1x2° = 4+0+1 = 5.Etant donné code et b, l'algorithme qui permet de calculer
x en base 10 est le suivant:
x+---0;
Pour ide O à L-1 //Lest la longueur du code
x +- x + code[i]*b/\(L-1-i);
Supposons que l'on veut calculer successivement la valeur décimale x des nombres (123)s
et (123)s, on devra donc recopier deux fois l'algorithme ci-dessus.
b +- 5; b +- 8;
code+- [1,2,3] ; code+- [1,2,3] ;
X+- Ü; X+- Ü;
Pour ide O à L-1 Pour ide O à L-1
x +- x + code[i]*b /\(1-1-i); x +- x + code[i]*b /\(1-1-i);
Dans la pratique, il n'est pas souhaitable d'écrire deux fois le même programme, d'autant
plus, si celui-ci nécessite de très nombreuses lignes de code source. Pour améliorer la
réutilisabilité de l'algorithme la solution est d'encapsuler le code à répéter au sein d'un sous
programme.
2. La notion de sous-programme
Il existe deux types de sous-programmes : les fonctions et les procédures. Cependant, avant
de détailler ces deux concepts, il sera utile de définir quelques notions utiles.
Dans cette sous-section, nous illustrons une notion appelée portée d'une variable. L'idée
principale est qu'il est possible d'avoir deux variables différentes avec le même nom toutefois
qu'elles ont des portées différentes. Le cas le plus connus que l'on peut citer, est qu'une
variable définie au niveau du programme principal (celui qui résout le problème initial) est
appelée variable globale et sa portée est totale, par conséquent, tout sous-programme du
programme principal peut utiliser cette variable. Alors qu'une variable définie au sein d'un
sous-programme est appelée variable locale dont la portée est limitée au sous-programme
dans lequel elle est déclarée.
Remarque:
Si l'identificateur (le nom) d'une variable locale est identique à celui d'une variable globale,
cette dernière est localement masquée. Autrement dit, la variable globale devient
inaccessible dans le sous-programme contenant la variable locale de même nom.
Exemple:
Supposons qu'une partie de notre programme sera le sous-programme suivant:
Algorithme Secondaire;
Var x : entier;//variable locale
Début
x+---3;
Ecrire (x, y) ;
Fin
Supposons maintenant que nous appelons ce sous-programme «Secondaire» depuis une
autre partie du programme « Principal » qui utilise également deux variables globales:
Algorithme Principal;
Var x, y: entier; //variables globales
Début
x+-5;y+-8;
... ; Il Appel au sous-programme Secondaire
Ecrire (x, y);
Fin
L'exécution de ce programme peut être illustrée comme suit:
-Principal :
r---------------------- -�'...
1
�
�,,...
..
x=S
Fin Y=8
' - - - - - - - - - - _ _. , CJ
-Secondaire '---------------- ____ ---, ,,,
1 ..
X-
-3
,,
Début
3,8
Fin
Dans cet exemple, la variable « x », ayant la valeur 5 dans le programme principal, est une
variable globale. Une autre variable qui porte le même nom « x» est utilisée au niveau du
programme secondaire ayant comme valeur 3. Cet variable locale a masqué la variable
globale « x» au niveau du programme secondaire, par conséquent, l'affichage de « x» au
niveau de ce sous-programme correspond à la valeur 3. Par contre, la variable globale y est
quant à elle accessible, ce qui justifie l'affichage de la valeur 8 au niveau du sous
programme.
2.2. Les paramètres
Remarque:
Par exemple, si le sous-programme Racine permet de calculer la racine carrée d'un réel :
Ce sous-programme admet un seul paramètre de type réel positif.
Le programme appelant Racine doit fournir le réel positif dont il veut calculer la
racine carrée, cela peut être une variable (Racine (y)) ou une constante (Racine (9)).
L'association entre les paramètres effectifs et les paramètres formels est appelé passage de
paramètres. Il existe deux types de passage de paramètres :
Le passage par valeur.
Le passage par référence (ou adresse).
Dans le premier type, la valeur du paramètre effectif est affectée (copiée) au paramètre
formel correspondant. Sachant que les paramètres formels ne sont que des variables locales
de la fonction. Ce type de passage sera illustré dans la section qui suit.
Dans le second type, c'est l'adresse du paramètre effectif qui est affectée au paramètre
formel correspondant. Ceci rend possible au sous-programme d'accéder directement à
l'adresse de la variable concernée (le paramètre effectif) et par conséquent la modifier si
nécessaire. Ce type de passage nécessite d'utiliser la notion des pointeurs [5] [9].
Remarque:
Une illustration du passage de paramètre par valeur est donnée dans l'exemple 3 de la section
4. Le passage de paramètre par adresse sera illustré dans le chapitre suivant.
3. Les fonctions
Une fonction est un sous-programme qui admet un nom, un type et des paramètres. Une
fonction admet un type et retourne toujours un résultat.
3.1. Définition d'une fonction
Algorithme A ;
Var a, b: entier;
Fonction Abs �:entier): entier/* Définition de la fonction */
Var valabs: entier
Début :
'
Si (n >=:O) alors valabs +- n ;
Sinon v�labs +- -n ;
FinSi '
Retourner va�abs
•
·
'
---------------------------------------------------------------------------
... ,, '1
Fin :1 ________________ ,,� :i Passage de paramètre par valeur: la valeur de la
..! '.,,., !
l
1----------------1
.� variable a est copiée dans la variable n.
1
;i
Ecrire (" ponner une valeur ");
Lire (a)
b +-Abs(a);
Ecrire (b);
Fin
Lors de l'exécution de la fonction Abs(), il y a une association entre le paramètre effectif a
et le paramètre formel n d'où la valeur de a est copiée dans n. Ce type d'association
s'appelle passage de paramètre par valeur.
4. Les procédures
Une procédure est un sous-programme qui admet également un nom et des paramètres mais
ne retournant aucun résultat.
Exemple 2:
Soit l'algorithme B calculant la valeur absolue d'un entier mais cette fois-ci en utilisant une
procédure:
Algorithme B
Var a: entier;
Procédure Abs (n : entier)/* Définition de la procédure */
Début
Si (n >= 0) alors
Ecrire n;
Sinon
Ecrire -n;
FinSi
Fin
Algorithme C
-�--l ►
1
1
------- ---
Début -- ,.
I
Ecrire(...); --------------
Modif (x); ------
--,
Ecrire(...);--- ____'.>...-,------
► Valeurdexaprès l'appel: 1
'
Fin
(- -.\..... 1
\
1
1
: Appel avec passage de __ :.--
''
\
- -x--w
......... ,,
-
Procédure ModifO
Lorsqu'on passe un paramètre à une fonction (ou à une procédure), cette dernière ne peut
pas modifier la variable. La variable est automatiquement recopiée et la fonction travaille
sur une copie de la variable. La modification de la copie n'entraîne pas une modification de
la variable originale. C'est ce qu'on appelle le passage de paramètre par valeur [3].
5. Fonctions et procédures récursives
La récursivité est une méthode de description d'algorithmes qui permet à une fonction (ou
a) Solution itérative :
b) Solution récursive:
5.2. Interprétation
Une proc édure ou une fonction réc ursive doit c omporter une condition d'arrêt (n=0 dans
l'exemple étudié c i-dessus). Cette c ondition empêc he des appels réc ursifs sans arrêt.
Généralement, la c ondition d'arrêt se présente sous la forme d'une instruc tion « Si ...
Alors ... Sinon» qui permet de stopper la récurrence si la condition d'arrêt est satisfaite. Dans
le cas contraire, la fonction ou la procédure continue à exécuter les appels récursifs.
D'autre part, le paramètre de l'appel récursif doit c onverger toujours vers la condition
d'arrêt. Un processus récursif remplace en quelque sorte une bouc le, ainsi tout processus
récursif peut être également formulé en tant qu'un processus itératif.
FACT(4) = 24 �------------------
--
�
Si {4=0) alors ...
Sinon Retourner 4 * FACT {3);
�
Si {3=0) alors ...
Sinon Retourner 3 * FACT (2);
2
�
Si {2=0) alors ...
Sinon Retourner 2 * FACT {1);
�
Si {1=0) alors ...
Sinon Retourner 1 * FACT (0);
�
Si {0=0) alors Retourner 1 ;
1. Introduction
Lorsqu'une variable est déclarée et ce, quel que soit le langage de programmation, le
compilateur réserve, à une adresse donnée en mémoire, l'espace nécessaire au contenu de
cette variable. Donc, toute variable possède :
Un identificateur (nom),
Une valeur (donnée),
Une adresse en mémoire.
Une donnée p eut s'étaler sur p lusieurs octets, donc occup er une p lage d'adresses (par
exemple 2 octets pour un entier, 4 ou 8 octets pour un réel, plus encore pour une chaîne).
Exemple:
Dans cet exemple, le nom de la variable c'est n, la valeur c'est 5 et l'adresse c'est son emplacement
dans la mémoire.
0xfde23a50
0xfde23a51
0xfde23a52
0xfde23a53
0xfde23a54
0xfde23a55
0xfde23a56
0xfde23a57 Espace réservée à l'entier
n pour stocker sa valeur 5 Variable n
0xfde23a58
0xfde23a59
Figure 8. Représentation d'une variable en mémoire.
On peut donc accéder à une variable de deux façons :
• par son identificateur,
• par l'adresse mémoire à partir de laquelle elle est stockée (pointeur).
2. Notion de pointeur
2.1. Définition
Un pointeur est une variable qui contient l'adresse d'une autre variable.
Le pointeur pointe sur une autre variable dont il contient l'adresse mémoire, cette dernière
étant dite variable pointée. Si l'on affiche le contenu d'un pointeur, on obtient une adresse
qui est celle de la variable pointée, tandis que si l'on affiche le contenu de la variable pointée,
on obtient la valeur associée à cette dernière.
Un pointeur est une variable. De ce f ait, elle doit être déclarée, dispose elle-même de sa
propre adresse en mémoire, et se voit définir un type. Le type d'un pointeur ne décrit pas ce
qu'il contient (c'est une adresse, donc en principe d'une longueur de 32 ou 64 bits selon les
architectures) mais le type de la variable qu'il pointe. Un pointeur sur une variable de type
réel devrait donc être déclaré avec un type réel.
0xfde.23a50
0xfde23a51
0xfde23a52 Oxdfe23a56 Pointeur p
0xfde23a53
0xfde23a54
0xfde:23a55
0xfde23a56·
0xfde23a57 5 Variable n
0xfde23a58
0xfde23a59
Dans ce qui suit, nous décrivons comment déclarer et manipuler un pointeur avec quelques
cas d'applications par la suite.
2.2.2. Initialisation
Début
x-3;
pl - &x; //pl contient l'adresse de x
p2 - NIL ; //p2 ne contient aucune adresse
Ecrire ("Le contenu de la variable pointé par pl est:", *pl);
*pl - 5; // modification de x à travers pl
Ecrire ("x=", x, "*pl=", *pl);
p2 - pl ; // affectation de l'adresse contenue dans pl à p2
Ecrire ("Le contenu de la variable pointé par p2 est:", *p2);
Fin
L'exécution de cet algorithme donne :
Le contenu de la variable pointé par pl est: 3
x= 5, *pl=5
Le contenu de la variable pointé par p2 est: 5
Remarque:
3. Allocation dynamique
Nous avons vu dans la section précédente qu'un pointeur reçoit l'adresse d'une variable qui
existe déjà par affectation. Il est aussi possible de réserver un emplacement mémoire pour
une donnée pointée directement. Dans ce cas, on peut créer un pointeur sur un entier par
exemple, et réserver un espace mémoire (qui contiendra cet entier) sur lequel la variable
pointeur pointera. C'est le principe de l'allocation dynamique de mémoire.
On peut employer la syntaxe suivante :
pointeur +- nouveau type ;
Le type doit bien entendu être celui de la valeur qui sera contenue à l'emplacement mémoire
alloué. Après cette instruction, le pointeur reçoit l'adresse mémoire de la zone réservée. En
cas d'échec (plus de mémoire disponible par exemple) il reçoit la valeur NIL.
Exemple:
Dans l'algorithme qui suit, un pointeur « p » sur un entier est déclaré. Pour placer une valeur
entière dans la zone mémoire pointée, il faut d'abord réserver l'emplacement nécessaire.
Puis on accède à l'élément pointé et on y place un entier.
Algorithme allouer;
Var p: *entier
Début
p +- nouveau Entier; Il allocation d'un espace mémoire dont! 'adresse est affectée à p
*p +- 12345 ; Il affectation d'un entier
Ecrire ("Le contenu de p est:", *p);
Fin
Quand une zone mémoire est allouée dynamiquement, elle reste occupée tout le temps de
l'existence du pointeur. Sans rien d'autre, la mémoire est récupérée uniquement à la sortie
du programme. Il est aussi facile de libérer un espace alloué de la mémoire dès que le ou les
pointeurs ne sont plus utiles. Pour ceci on applique la syntaxe suivante :
Libérer pointeur ;
Exemple:
Dans l'algorithme qui suit, un pointeur « p » sur un entier est déclaré. Pour placer une valeur
entière dans la zone mémoire pointée, il fa ut d'abord réserver l'emplacement nécessaire.
Puis on accède à l'élément pointé et on y place un entier.
Algorithme libérer ;
Var p: *entier
Début
p +- nouveau Entier ;
*p +- 12345;
Ecrire ("Le contenu de p est:", *p);
Libérer p ; // libérer l'espace mémoire pointé par p
p +- NIL ; // réinitialiser p
Fin
Quand on libère un pointeur, on libère la zone mémoire sur laquelle il pointait, cette zone
redevient disponible pour toute autre utilisation. Après chaque libération, il est préférable de
réinitialiser le pointeur par la valeur NIL, et de penser à tester le pointeur avant de l'utiliser.
Dans le cas où l'adresse de la zone mémoire libérée est conservée dans un autre pointeur, il
faut faire attention au fait que ce pointeur pointe sur une zone éventuellement réaffectée à
autre chose. Y accéder risque de fournir une valeur arbitraire, y écrire risque d'occasionner
des problèmes, voire des plantages.
Début :
..
Procédure Modif (px: *entier) Il Procédure utilisant un pointeur comme paramètre local
,,
Fin ,' ________________ ..J.' .......... ,,,
,' •----------------, ,/ ! '
Passage de parametre par adresse: 1 , adresse de i
' ! !
1
..-
.., 1
l
3---t
Algorithme D
Début
x+----1..;----------------_:-_-_-_ -__
-
►\
2
__ 1 I '!\________
1 ► Va1eur dex avant l' appe1: 1
_______
- - - ,
,-
,'
I
Ecrire(... ); ________ ...
__
__
' 1
r
: Appel avec passage de __ :::-
1 \
1 I
1
I
1 /
: paramètre par adresse :
'.... _ ----------------------_ ..,'
1 ,
1 ,
y
; '
Procédure ModifO ;
; ''
,/ \
1 (&x) 1
,,. ,,.
Début " px
'.à. �-�
Fin
Lorsqu'on passe l'adresse d'une variable à une fonction (ou à une procédure), cette dernière
peut modifier directement cette variable à travers le pointeur contenant son adresse. Donc
l'accès au contenu pointé (*px) est équivalent à l'accès à la variable (x) dans ce cas. La
modification se fait directement sur la variable originale. C'est le passage de paramètre par
adresse.
5. Conclusion
Dans ce dernier chapitre de la partie« cours», nous avons présenté la notion des pointeurs
avec des exemples sur leur utilisation. Le lecteur est initié aussi au mécanisme de gestion
dynamique de mémoire à travers les opérations d'allocation et de libération. A la fin de ce
chapitre, un survol sur les principales applications des pointeurs notamment en langage C a
été présenté dans lequel le mode de passage de paramètres par adresse a été pris comme
exemple d'application.