Vous êtes sur la page 1sur 13

Université de Manouba

Ecole supérieure d’économie numérique ESEN

Algorithmique et structures de
données II
(Cours 3)

Le Pointeur

Réalisé par: Dhouha Maatar 1

1. Introduction: notion d’adresse

La mémoire centrale utilisée par les programmes est découpée


en octets, dont chacun est identifié par un numéro séquentiel
appelé adresse.
Par convention, une adresse est notée en hexadécimal et
précédée par 0x.

0x3fffd10
0x3fffd11
0x3fffd12
0x3fffd13
0x3fffd14
2
....

1
1. Introduction: notion d’adresse

Déclarer une variable c’est attribuer un nom (identificateur) à


une zone de la mémoire centrale. Cette zone est définie par:
- sa position: l’adresse de de son premier octet
- sa taille: le nombre d’octets

0x3fffd10
Exemple
0x3fffd11
toto: entier
0x3fffd12 toto
toto ← 18 18
0x3fffd13
0x3fffd14
...
3

2. Définition
Pour accéder à une valeur d’une variable, il suffit d’utiliser
son nom.
Pour accéder à l’adresse d’une variable, on utilise un pointeur

« Un pointeur est une variable qui contient l’adresse d’une autre


variable».

Un pointeur permet d’accéder directement à la mémoire, de


faire référence à toute entité, sans la nommer.

4 4

2
3. Les variables pointeurs:

3.1 Déclaration
En algorithmique:
nom: ^ type pointé // pointeur sur type pointé

Exemple:
Variables p: ^ entier //pointeur sur entier
toto: entier

3. Les variables pointeurs:


3.2 Initialisation
Il existe 3 manières d’initialiser une variable de type pointeur

- initialisation avec la constante NIL (le pointeur ne pointe sur


rien)

- initialiser avec l’adresse d’une donnée existante (adresse


d’une variable ou valeur d’un autre pointeur)

- initialiser par allocation dynamique de mémoire (allouer)


Pour une variable donnée, seule une des trois manières doit
être utilisée 6

3
3. Les variables pointeurs:
3.2.1 Initialisation par NIL
Attention à toujours initialiser un pointeur. Un pointeur qui n’est pas
initialisé s’appelle pointeur pendant. C’est un pointeur qui pointe
n’importe où. Si on déréférence ce pointeur et on lui affecte une
nouvelle valeur, on va écraser un emplacement mémoire quelconque
et on risque de faire planter le programme.

Si on veut que le pointeur pointe nul part, il faut l’initialiser à NIL


(not identified link, NULL en C) c’est l ’équivalent de 0 pour les
entiers.

p: ^ entier
p← NIL //p pointe nul part
7 7

3. Les variables pointeurs:


3.2.2 Initialisation par des données
On affecte l’adresse d’une variable en utilisant l’opérateur
d’adresse &.
A. EXEMPLE 0x3fffd10 0x3fffd12 ptoto
variable 0x3fffd11
ptoto: ^ entier 0x3fffd12 18 toto
0x3fffd13
toto: entier
0x3fffd14
Début ...
toto←18 (toto est placé à l’adresse 0x3fffd12)
ptoto ←& toto (ptoto contient l’adresse de toto)
ptoto pointe alors sur toto
8

4
3. Les variables pointeurs:

B.REMARQUE
Le pointeur pointe sur la variable dont il contient l’adresse

Un pointeur est associé à un type de variable sur lequel il


peut pointer. Par exemple, un pointeur sur entier ne peut
pointer que sur des variables entières.

3. Les variables pointeurs:


Il est possible d’extraire la valeur de la variable pointée.
Déréférencer un pointeur consiste à extraire la valeur sur
laquelle il pointe
Variable
x : entier
p : ^ entier
Début
x ← 33
p← &x //p pointe sur x
écrire (p^) // écrire (*p) // la valeur 33 est affichée
p^ ← 34 //*p ← 34 // x vaut maintenant 34 10

5
3. Les variables pointeurs:
Avant de déréférencer un pointeur (extraire sa valeur), il faut
s’assurer qu’il n’est pas nul.

C. EXEMPLE RÉCAPITULATIF
Variable
x, n: entier
p: ^ entier
Début
n ← 20 n 20 x ? p ?
p←&n n 20 x ? p
x ← p^ n 20 x 20 p
P^ ← 30 n 30 x 20 p
p ← &x n 30 x 20 p 11

4. Allocation dynamique
4.1 Mémoire dynamique

Code Code du programme


Variables globales et
Mémoire statique
constantes
Pile
mémoire automatique
Piles d’appels de fonctions

Tas Allocation dynamique de


Mémoire dynamique mémoire
12

6
4. Allocation dynamique
Mémoire statique: zone de la mémoire où sont stockés les données
qui ont la même durée de vie que le programme (variables globales)

Mémoire automatique: zone de la mémoire appelée Pile


d’exécution où sont stockés les paramètres, les adresses et valeurs du
retour et variables locales des fonctions empilées. Cette mémoire est
gérée automatiquement par le compilateur (réservation et libération).

Mémoire dynamique: zone de la mémoire appelée tas dans laquelle


le programmeur peut réserver explicitement de la place. Il devra la
libérer explicitement.

13

4. Allocation dynamique
La déclaration permet d’allouer un emplacement dans une partie
de la mémoire appelée PILE. Les variables déclarées dans la
PILE possèdent un nom. Leur portée (càd là où elles peuvent
être utilisées) est déterminée par l’endroit où elles sont
déclarées. Elles sont crées dès l’entrée dans la portée et
détruites dès la sortie de leur portée.

L’allocation dynamique permet d’allouer un emplacement dans


une autre partie de la mémoire appelée TAS. Les variables du
TAS ne sont pas déclarées. Elles sont créées par une
instruction spécifiques. Elles ne portent pas de nom, mais on
peut y accéder par leur adresse. Elles peuvent être utilisées
partout jusqu’à leur destruction. 14

7
4. Allocation dynamique
4.2 Accès à la mémoire dynamique
Pour créer une variable dans le tas, on utilise l’opérateur
ALLOUER suivi du type de la variable qu’on veut créer.
En algorithmique:
variables • px est une variable de type pointeur
• allouer réserve de la mémoire dans
px: ^ entier le tas
Début • px contient alors l’adresse de la
allouer px mémoire allouée (NIL si plus de
… mémoire disponible)

15

4. Allocation dynamique
Attention:
Allouer réserve de la mémoire mais ne l’initialise pas!

Début
px^ ← 123 //On affecte alors 123 à la variable du TAS.
4.3 Libération de la mémoire dynamique
Si on ne libère pas la mémoire, elle peut être saturée et le
programme peut se planter.

Pour éviter la saturation de la mémoire, il est donc nécessaire de


désallouer les emplacements alloués dans le TAS.
16

8
4. Allocation dynamique
On utilise donc, l’opérateur libérer.
libérer px

Attention: il est interdit de


 libérer un pointeur de valeur NIL

 libérer une zone déjà libérée

 accéder à une zone mémoire libérée

 Libérer de la mémoire allouée automatiquement par le


compilateur (variable nommée))

17

4. Allocation dynamique
4.5 Arithmétique de pointeurs
Les seules opérations arithmétiques valides sur les pointeurs (de type
entier par exemple) sont :
• l’addition d’un entier à un pointeur. Le résultat est un pointeur de
même type que le pointeur de départ.
• la soustraction d’un entier à un pointeur. Le résultat est un pointeur
de même type que le pointeur de départ.
• la différence de deux pointeurs pointant sur des objets de même
type. Le résultat est entier.

Si i est un entier et p un pointeur sur un objet de type X, l’expression


p+i désigne un pointeur sur un objet de type X dont la valeur de
l’adresse = l’adresse de p incrémentée de i * taille du type X 18

9
4. Allocation dynamique
 EXEMPLE:

Variable x,y: entier


p: ^entier p
x
Début Entier quelconque
124
x ← 124 (x vaut 124)
125
allouer p (p pointe sur un emplacement entier libre)
p←&x (p vaut l’adresse de x)
P^ ← p^ +1 (ce qui est pointé par p, qui est x, est incrémenté de 1)
écrire(x)
libérer p
fin
19

5. Pointeur vers un enregistrement


On peut considérer l’enregistrement suivant:
type
Personne = enregistrement
nom: chaine
num: entier Début
fin Personne Pers.nom ← "ali"
Pers.num ← 12345
variable Écrire(Pers.nom)
Pers: personne Ecrire(Pers.num)
fin
20

10
5. Pointeur vers un enregistrement
Nous pouvons utiliser un pointeur pour mémoriser l’adresse
d’un enregistrement.
variable
pointpers: ^ personne

On peut accéder aux champs de l’enregistrement pers en


utilisant l’opérateur ^. //ou ->
Début
Pers.nom ← "ali"
Pointpers ← & pers
Écrire(pointpers^. nom) // Écrire(pointpers -> nom)
21
fin

8. Pointeur vers un enregistrement


Pointeur sur l’enregistrement-> champs est équivalent à
Pointeur sur l’enregistrement^. champs
Début
pointpers ^. nom ← "ali" //pointpers ->nom ← "ali"
pointpers ^. num ← 12345 //pointpers -> num ← 12345
Écrire(pointpers^. nom) //Écrire(pointpers -> nom)
Ecrire(pointpers^. num) //Ecrire(pointpers -> num)
Fin

22

11
6. Pointeurs et tableaux
6.1 Tableaux numériques
Tout tableau, en algorithmique (et en C), est en fait un pointeur
constant. Exemple: T: tableau [0..9] d’entier
T est un pointeur constant dont la valeur est l’adresse du
premier élément du tableau

Allouer N case pour T


T contient l’adresse de T[0]
T^ // ou *T// contient la valeur de T[0]
(T+1)^ //ou *(T+1) // contient la valeur de T[1]
T[i] correspond à (T+i)^ //ou *(T+i) //
23

6. Pointeurs et tableaux

6.2 Chaînes de caractères


Une chaine de caractères est un tableau à une dimension
d’objets de type caractère se terminant par le caractère nul
‘\0’
On peut manipuler toute chaîne de caractères à l’aide des
pointeurs sur un objet de type caractère

Cela est souvent utilisé car on connaît rarement à la


compilation les tailles de chaînes dont on aura besoin.

24

12
6. Pointeurs et tableaux
Exemple: calculer la taille d une chaine de caractère
Algorithme taille_chaine
Var
ch : ^ caractère
i: entier
Début
ch^ ← ‘’ chaîne de caractères’’
i←1
tant que (ch^ <> ‘\0’) faire
ch ← ch+1
i ← i+1
FinTQ
Écrire (‘’ taille de la chaine est’’, i) 25
fin

13

Vous aimerez peut-être aussi