Sunteți pe pagina 1din 10

K.

Zabo Pointeurs et rfrences Centre Universitaire professionnalis

Notions de Pointeurs

I. Introduction: notion d'adresse


La mmoire centrale utilise par les programmes, est dcoupe en octets.
Chacun de ces octets est identifi par un numro squentiel appel adresse. Par
convention, une adresse est note en hexadcimal et prcde par 0x.

0x3fffd10
0x3fffd11
0x3fffd12
0x3fffd13
0x3fffd14
0x3fffd15
0x3fffd16
0x3fffd17

Dclarer une variable, c'est attribuer un nom (l'identificateur) une zone de la


mmoire centrale. Cette zone est dfinie par :
- sa position c'est--dire ladresse de son premier octet
- sa taille c'est--dire le nombre doctets

short int toto = 18;


0x3fffd10
0x3fffd11
0x3fffd12
0x3fffd13
0x3fffd14 toto
18
0x3fffd15
0x3fffd16
0x3fffd17

Pour accder la valeur contenue dans une variable, on utilise tout simplement
son nom.
Mais il peut arriver qu'on veuille accder l'adresse d'une variable. Dans ce cas,
on utilise l'oprateur d'adresse & (notation C++) suivi du nom de la variable.

&toto vaut 0x3fffd14 (adresse du premier octet de toto)

L3-M1-M2-INFORMATIQUE-TELECOMS 1
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

II. Notion de pointeur


Un pointeur est une variable qui contient l'adresse d'une autre variable.

L'adresse contenue dans un pointeur est celle d'une variable qu'on appelle
variable pointe. On dit que le pointeur pointe sur la variable dont il contient
l'adresse.

variable pointe

pointeur

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 entires.

Un pointeur est lui-mme une variable et ce titre il possde une adresse.


Il convient de ne pas confondre l'adresse de la variable pointeur et l'adresse
contenue dans le pointeur (adresse de la variable pointe)

0x3fffd10
0x3fffd11 toto est plac l'adresse
0x3fffd14
0x3fffd12 ptoto 0x3fffd14
0x3fffd13
18
0x3fffd14 toto ptoto contient l'adresse de la variable toto

0x3fffd15
0x3fffd16 ptoto pointe sur toto

0x3fffd17 ptoto est contenu


l'adresse 0x3fffd14.
Reprsentation

ptoto toto
18

Petites rvisions dAMSI...


Pourquoi le pointeur ptoto est-il reprsent sur 4 octets??
Pour pouvoir coder un hexa il faut octet donc pour en coder 7 il faut 4 octets 7
valeurs hexadcimales ont une puissance lexicographique de 167 soit 256Mga.
Cela veut dire que la mmoire possdent 256Mo.
L3-M1-M2-INFORMATIQUE-TELECOMS 2
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

A. Dclaration d'un pointeur


Par convention, les pointeurs commencent par la lettre p.
Il faut dclarer le type de la variable pointe.

en algorithmique en C++
nom : pointeur sur type type * nom;
point
exemple :
exemple : int * ptoto;
ptoto: pointeur sur entier
* est appel oprateur de
drfrencement
B. Utilisation d'un pointeur
On utilise un pointeur pour mmoriser l'emplacement d'une autre variable.
Il est trs rare d'affecter directement une adresse un pointeur. On affecte en
gnral l'adresse d'une variable existante.
Pour cela, en algorithmique, on utilise l'expression "adresse de" alors qu'en C, on
utilise l'oprateur d'adresse &

Exemple:
Algorithmique C/C++
Var
va : entier int va; int
pent: pointeur sur entier * pent;
pcar: pointeur sur caractre char * pcar;

Dbut
pcar 0x3fffd14 //affectation directe pcar = 0x3fffd14; //affectation directe
pent adresse de va pent = &va;

Soit v une variable de type rel et p un pointeur sur rel. Quelle instruction
crire pour que p pointe sur v? (en algorithmique et en C/C++)

Il est possible d'extraire la valeur d'une variable pointe.

Drfrencer un pointeur consiste extraire la valeur de la variable sur laquelle il


pointe.

L3-M1-M2-INFORMATIQUE-TELECOMS 3
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

On peut aussi modifier la valeur d'une variable pointe travers un pointeur


drfrenc (accs en criture)
Algorithmique C/C++

Var n: int n = 33;


entier int *p; //dclaration du pointeur p
p: pointeur sur entier
Dbut p = &n; // p pointe sur n
p adresse de n // p pointe sur n cout << *p //affiche 33 l'cran, la valeur
afficher *p //la valeur 33 est affiche de n
*p 34 // n vaut maintenant 34 *p = 34 // n vaut maintenant 34

Attention toujours initialiser un pointeur. Un pointeur qui n'est pas initialis


s'appelle un pointeur pendant. Un pointeur pendant ne pointe pas nul part mais
n'importe o. Si l'on drfrence ce pointeur et qu'on affecte une nouvelle valeur,
on va craser un emplacement mmoire 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)
ou NULL en C/C++. C'est l'quivalent de 0 pour les pointeurs. Mais attention, il ne
faut jamais drfrencer un pointeur nul. Avant de drfrencer un pointeur, il faut
toujours s'assurer qu'il n'est pas nul.

p: pointeur sur entier int *p = NULL;


p NIL //p pointe nul part

C. Exemple rcapitulatif
Var
n, x: entiers p:
pointeur sur entier

Dbut Etat des variables aprs excution

Double indirection

Le fait qu'un pointeur pointe sur une variable s'appelle indirection (comme accs
indirect). Quand un pointeur pointe sur un autre pointeur, il y a double indirection.

L3-M1-M2-INFORMATIQUE-TELECOMS 4
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

0x3fffd0e
0x3fffd10
0x3fffd0e pptoto
0x3fffd0e pptoto pointe sur ptoto qui pointe sur toto
0x3fffd0f
0x3fffd10 0x3fffd14 ptoto
0x3fffd11 ptot
o
0x3fffd12
0x3fffd13 toto
0x3fffd14 18
0x3fffd15 toto 18

On peut accder toto par pptoto en utilisant deux fois l'oprateur de


drfrencement *

* *pptoto est quivalent toto et *ptoto

On pourrait imaginer de la mme faon des indirections triples voire quadruples.

D. Transmission de paramtres par adresse

Nous avons vu l'anne dernire que pour pouvoir modifier la valeur d'un paramtre
dans un sous-programme, il fallait passer ce paramtre non pas "par valeur" mais
"par variable" (ou par rfrence en C++). Il existe une autre manire de passer un
paramtre permettant de modifier sa valeur dans un sous-programme: il s'agit du
passage par adresse. Nous n'tudierons celui-ci qu'en langage C++.
Le passage par adresse consiste passer, non pas la valeur ni une rfrence de la
variable paramtre, mais de passer l'adresse de cette variable. Pour cela, lors de
l'appel, l'adresse du paramtre effectif est passe grce l'oprateur &. Dans
l'entte de la fonction, le paramtre formel est donc un pointeur, dclar grce
l'oprateur *. Et dans le corps de la fonction, lorsqu'on veut manipuler la valeur de
la variable pointe (le paramtre effectif), on drfrence le paramtre formel
grce l'oprateur *;

Exemple:
Utilisation d'une fonction void qui permet d'changer les valeurs de deux
paramtres entiers.

L3-M1-M2-INFORMATIQUE-TELECOMS 5
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

//prototype de la fonction. Les paramtres formels sont des pointeurs sur


entiers void echange (int *a, int *b); // a et b sont des pointeurs

main( )
{ int x,
y; x =
10; y =
20;
cout << "avant appel" << x << y
echange(&x, &y) // on passe l'adresse des variables changer cout
<< "aprs appel" << x << y
}

void echange (int *a, int *b)


{
int temp; // variable temporaire pour l'change
temp = *a; // temp prend la valeur pointe par a
*a = *b; // la variable pointe par a prend pour valeur celle pointe par b
*b = temp; // la variable pointe par b prend pour valeur temp
}

Lors de l'appel, la valeur pointe par a est x et la valeur pointe par b est y.

Remarque: La transmission des paramtres se fait toujours par valeur! (la


valeur des adresses !) On passe la valeur des expressions &x et &y. Les
paramtres effectifs sont ici des adresses, qui sont passes par valeur.
E. Pointeur vers un enregistrement
Il est trs courant d'utiliser un pointeur pour mmoriser l'adresse d'un
enregistrement. Avec un pointeur sur un enregistrement, on peut accder aux
champs de
l'enregistrement point en utilisant l'oprateur "->" (moins et suprieur)

Exemple

L3-M1-M2-INFORMATIQUE-TELECOMS 6
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

Type
tpersonne = enregistrement
nom : chaine tel : chaine
finenreg

Var
pers: tpersonne
pointpers : pointeur sur
tpersonne
Dbut

pers.nom "Mohamed"
pers.tel "0145698521"
pointpers &pers

Afficher pointpers -> nom donne l'cran


Afficher pointpers -> tel Mohamed 0145698521

Fin

pointpers->nom est quivalent momo.nom

pointeur sur l'enregistrement -> champ est quivalent enregistrement . champ

F. Lien entre enregistrements grce un pointeur


Dans un enregistrement, un des champs peut trs bien tre un pointeur, par
exemple sur un autre enregistrement

Exemple

Type
tpersonne = enregistrement
nom_ins : chaine
tel : chaine
finenreg

tlve = enregistrement
nom_el: chaine
pinstit : pointeur sur tpersonne
finenreg

L3-M1-M2-INFORMATIQUE-TELECOMS 7
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

Var
instituteur : tinstit
lve1, lve2: tlve

Dbut
instituteur.nom_ins "Dupond"
instituteur.tel "0123654896"
lve1.nom_el "Pierre"
lve1.pinstit &insituteur
lve2.nom_el "Hakim"
lve2.pinstit &insituteur
Afficher lve1.pinstit->nom // affiche Dupond l'cran
Afficher lve2.pinstit->nom // idem

lve1 nom Dupond


nom
Pierre
tel 0123654896
pinsit

lve2
nom Hakim

pinsit

A partir d'un lve, on peut connatre les caractristiques de son instituteur grce
au pointeur contenu dans l'enregistrement de l'lve. Le pointeur ralise un lien
entre un lve et son instituteur.
Mais l'enregistrement instituteur ne possde pas de pointeur vers la liste de ses
lves. A partir de l'instituteur, on ne peut pas accder aux champs des lves.
Un pointeur est donc un lien univoque (dans un seul sens)
Plusieurs pointeurs peuvent pointer sur un mme enregistrement (ici, deux lves
ont le mme instituteur), mais un pointeur ne peut pointer que sur une seule
variable (enregistrement) la fois.

Comment reprsenteriez-vous le lien ralis par le pointeur grce au


modle entit-association?

ELEVE INSTITUTEUR

nom_el nom_ins
1,1 avoir pour 0, n
tel

L3-M1-M2-INFORMATIQUE-TELECOMS 8
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

Un pointeur ralise une association (1,n) mais dans un seul sens. On peut naviguer
du 1 vers le n mais pas dans le sens inverse.

III. Allocation dynamique de la mmoire


Il y a deux faons dallouer un emplacement mmoire pour une variable :
Soit par une dclaration, telle quon la vu jusqu prsent
Soit par une allocation dynamique explicite, ce que nous allons voir maintenant

La dclaration permet dallouer un emplacement dans une partie de la mmoire appele pile. Les
variables dclares dans la pile possdent un nom. Leur porte (cest--dire l o elles peuvent tre
utilises) est dtermine par lendroit o elles sont dclares. Elles sont cres ds lentre dans la
porte et dtruites ds la sortie de leur porte.

Lallocation dynamique permet dallouer un emplacement dans une autre partie de la mmoire
appel tas. Les variables du tas ne sont pas dclares, elles sont cres par une instruction
spcifique. Elles ne portent pas de nom mais on peut y accder par leur adresse. Elles peuvent tre
utilises partout et jusqu leur destruction (il ny a pas de porte pour les variables du tas).

En algorithmique En C++

Pour crer une variable dans le tas, on utiliser Pour crer une variable dans le tas, on utiliser
loprateur nouveau, suivi du type de la loprateur new, suivi du type de la variable
variable quon veut crer. Cet oprateur quon veut crer. Cet oprateur retourne
renvoie ladresse de la variable quon affecte ladresse dun emplacement mmoire libre,
un pointeur du mme type. que lon affecte un pointeur du mme type.
Var
p : pointeur sur rel float* p ;
Dbut p = new float; p= nouveau rel
p contient ladresse dun emplacement
Ensuite on peut accder la variable cre enmmoire dans le tas. Pour accder cet
drfrenant le pointeur emplacement, on drfrence le pointeur p.

*p = 12.5 *p = 12.5 ;

Par cette instruction, on affecte 12.5 la On peut dclarer le pointeur et lui affecter
variable du tas. ladresse dun emplacement du tas en une seule instruction :
float* p = new float ;

Dsallouer la mmoire

En C++, il est ncessaire de dsallouer explicitement la mmoire alloue dans le tas. Si la mmoire nest pas
dsalloue, il peut arriver quelle sature et fasse planter le programme et mme lordinateur tout entier. En effet,
quand plus aucun pointeur ne pointe sur un emplacement allou du tas, cet emplacement nest plus accessible pour
le systme. (En algorithmique, nous supposons quil existe un mcanisme permettant de dsallouer
automatiquement les emplacements qui ne sont plus points, comme en Java)
Pour viter la saturation de la mmoire, il est donc ncessaire de dsallouer les emplacements allous dans le tas.
Pour cela, on utilise loprateur delete en C++ ou dsallouer en algo, suivi du pointeur qui pointe sur
lemplacement dsallouer.

L3-M1-M2-INFORMATIQUE-TELECOMS 9
K.Zabo Pointeurs et rfrences Centre Universitaire professionnalis

Algorithmique C++
dsallouer p delete p ;

Cette instruction nefface pas le pointeur mais la variable pointe.


Ne jamais utiliser cette instruction sur un pointeur qui pointe sur une variable de la pile
(un variable nomme)

L3-M1-M2-INFORMATIQUE-TELECOMS 10

S-ar putea să vă placă și