Initiation à la programmation : Langage C++
Chapitre 5 : Pointeurs
Pr. Driss ABADA
Filière SMP - S4
Faculté des Sciences El Jadida
Année Universitaire : 2019/2020
Plan
1 Adressage d’une variable
2 Pointeurs
3 Pointeurs et tableaux
4 Allocation dynamique
5 Tableaux dynamiques
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 2 / 25
Adressage d’une variable
1 Adressage d’une variable
La mémoire d’un ordinateur est divisée en emplacements numérotés
séquentiellement et pourrait être représentée comme un très long tableau
constitué d’octets.
L’adresse mémoire d’une variable est l’adresse du premier octet du bloc de
mémoire réservé pour cette variable.
I L’adresse de n est 0x000CF F 00.
I En C++, pour accéder à l’adresse mémoire d’une variable on utilise &.
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 3 / 25
Adressage d’une variable
On distingue deux modes d’adressage principaux :
I Adressage direct : accéder au contenu d’une variable par son nom.
I Adressage indirect : accéder au contenu d’une variable, en passant par un
pointeur qui contient l’adresse de la variable.
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 4 / 25
Pointeurs
2 Pointeurs
Définition
I Un pointeur est une variable spéciale qui peut contenir l’adresse d’une autre
variable.
Déclaration
I Un pointeur ou une variable pointeur se déclare comme suit :
Syntaxe de déclaration :
type *nom_pointeur;
I Le symbole * est dit l’opérateur d’indirection.
I Exemples :
float *ptrx = 0 ; //ptrx variable qui va pointer vers un float.
int *ptrn ; //ptrn variable qui va pointer vers un int.
char *ptrc = NULL ; //ptrc variable qui va pointer vers un char.
I Il est conseillé toujours d’initialiser un pointeur à 0 ou NULL si l’on n’affecte
pas l’adresse d’une variable.
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 5 / 25
Pointeurs
Variable pointeur et variable pointée
I Lors du travail avec des pointeurs, on a besoin de deux opérateurs :
L’opérateur & : pour obtenir l’adresse d’une variable.
[type] nom_pointeur=&nom_variable
L’opérateur * : pour manipuler le contenu d’une variable par un pointeur.
*nom_pointeur
Exemple :
int * ptrn ; int n = 1;
ptrn = & n ; // ptrn contient maintenant l ’ adresse de la variable n .
int valn = * ptrn ; // valn contient la valeur de n qui est 1.
cin > >* ptrn ; // saisir n en passant par ptrn .
(* ptrn )++; // incr é menter n de 1 en passant par ptrn .
cout < < " La valeur finale de " < <* ptrn ;
I Toute opération que l’on peut effectuer directement sur n, on peut la faire
indirectement avec *ptrn.
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 6 / 25
Pointeurs
Arithmétique des pointeurs
I Les seules opérations admises sur les pointeurs eux-mêmes sont :
L’affectation : on peut affecter à un pointeur l’adresse d’une variable ou la
valeur d’un autre pointeur.
La comparaison : on peut comparer les adresse mémoire.
L’addition ou la soustraction : on peut ajouter (soustraire) une valeur entière à
une adresse mémoire pour atteindre une autre.
Exemple d’opérations possibles sur les pointeurs :
int *x , y =1 , *z , t ;
x =& y ;
z = x ; // z re ç oit l ’ adresse stock é e dans x .
z = x +2; // z re ç oit l ’ adresse de y + 2 x4 =8( int =4 octets ).
z ++; // l ’ adresse de z est incr é ment é e de 4 ( int =4 octet ).
x =&* z ; // x re ç oit l ’ adresse de la case point é e par z .
t =*& y ; // t re ç oit le contenu de la variable y .
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 7 / 25
Pointeurs et tableaux
3 Pointeurs et tableaux
Soit la déclaration suivante :
int tab [5] ;
I tab est un tableau de 5 éléments.
I tab est aussi un pointeur sur le premier élément du tableau tab.
C’est-à-dire :
tab stocke l’adresse du premier élément du tableau.
tab est équivalent à &tab[0] et tab+1 est équivalent à &tab[1], etc.
*tab est équivalent à tab[0] et *(tab+1) est équivalent à tab[1], etc.
I On accède à la ième valeur du tableau tab par tab[i-1].
I On peut aussi accéder à la ième valeur du tableau tab par *(tab+(i-1)).
tab est le nom du tableau, mais aussi est un pointeur qui peut servir à
manipuler ses éléments.
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 8 / 25
Pointeurs et tableaux
Exemple :
int tab [5] ;
// Saisie des é l é ments du tableau tab
for ( int i =0 ; i < 5 ; i ++)
cin > >*( tab + i );
// affichage des é l é mnets du tableau tab
for ( int i =0 ; i < 5 ; i ++)
cout < <*( tab + i );
Remarque :
I Le pointeur tab est dit pointeur constant, ça veut dire qu’on ne peut pas
modifier sa valeur qu’est l’adresse du premier élément.
I On ne peut pas faire ce genre d’instructions : tab++ ou tab=...
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 9 / 25
Pointeurs et tableaux
Parcourir un tableau à l’aide d’un pointeur
# include < iostream >
using namspace std ;
int main ()
{
double A [10]; // tableau statique
double * P = NULL ; // pointeur
// Saisie des donn é es du tableau
for ( P = A ; P < A +10 ; P ++)
cin > >* P ;
// Affichage des donn é es
for ( P = A ; P < A +10; P ++)
cout < <* P ;
}
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 10 / 25
Allocation dynamique
Structure de la mémoire
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 11 / 25
Allocation dynamique
4 Allocation dynamique
Définition
I Une allocation dynamique est une opération qui consiste à réserver un espace
mémoire dans un endroit particulier de la mémoire appelé le tas (heap).
I Cet espace est géré par le programmeur, grâce à deux opérateurs : new et
delete.
L’opérateur new
I L’opérateur new permet d’allouer de l’espace mémoire dynamiquement.
I L’opérateur new renvoie une adresse q’elle faudra conserver dans un pointeur.
Syntaxe de l’allocation dynamique de la mémoire :
type *nom_pointeur ;
nom_pointeur = new type;
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 12 / 25
Allocation dynamique
L’opérateur delete
I L’opérateur delete permet de libérer l’espace mémoire alloué par new.
Libération de l’espace mémoire alloué :
delete nom_pointeur ;
Exemple :
float * p ; // p : pointeur sur float
p = new float ; // new : op é rateur d ’ allocation m é moire
cin > >* p ;
* p =3** p +1;
cout < <* p ;
delete p ; // delete : op é rateur de d é sallocation m é moire
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 13 / 25
Tableaux dynamiques
5 Tableaux dynamiques
Définition
I Il s’agit d’allouer des espaces mémoire contiguës pendant l’exécution en
fonction des besoins.
Tableaux dynamiques unidimensionnel
I Pour allouer dynamiquement un espace mémoire pour un tableau à une
dimension, on utilise la syntaxe suivante :
Syntaxe de l’allocation dynamique pour un tableau unidimensionnel :
type *nom_tableau ;
nom_tableau = new type[ N ];
I où N est la taille du tableau qui peut être une constante, une variable ou une
expression entière.
Libération de l’espace mémoire alloué pour un tableau à une dimension :
delete [] nom_tableau ;
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 14 / 25
Tableaux dynamiques
Illustration
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 15 / 25
Tableaux dynamiques
Exemple :
int n ;
double * T ; // pointeur
/* Saisir le nombre d ’é l é ments du tableau */
cin >> n ;
// alouer l ’ espace n é cessaire pour recevoir n r é els
T = new double [ n ];
/* T est maintenant un tableau de n é l é ments */
for ( int i =0; i < n ; i ++)
cin >> T [ i ];
/* Lib é rer l ’ espace allou é pour le tableau */
delete [] T ;
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 16 / 25
Tableaux dynamiques
Tableaux dynamiques bidimensionnel
I Tableaux des pointeurs
Syntaxe de déclaration d’un tableau de pointeurs :
type *nom_tableau [ taille ] ;
I où taille est une constante entière qui représente le nombre d’éléments
pointeurs.
Initialisation d’un tableau de pointeurs :
for ( int i =0 ; i < taille ; i ++)
{
nom_tableau [ i ]= new type [ m ] ;
}
I nom_tableau est un tableau à 2 dimensions dont la première est taille et la
deuxième est m. m est un entier qui peut être fixe ou varie.
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 17 / 25
Tableaux dynamiques
Exemple :
int * M [3]; // tableau de 3 pointeurs vers int
int n =4;
// allouer l ’ espace n é cessaire pour chaque é l é ment
for ( int i =0; i <3; i ++)
M [ i ]= new int [ n ];
// M est maintenant une matrice de 3 lignes et n cols
for ( int i =0; i <3; i ++)
{
for ( int j =0; j < n ; j ++)
M [ i ][ j ] = i + j ;
}
// lib é rer l ’ espace m é moire allou é pour chaque é l é ment .
for ( int i =0; i <3; i ++)
delete [] M [ i ] ;
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 18 / 25
Tableaux dynamiques
Pointeurs des pointeurs
I Déclaration
Syntaxe de déclaration d’un pointeur de pointeurs :
type **nom_tableau ;
I Allocation de la mémoire : l’allocation dynamique pour un tableau
bidimensionnel se fait comme suit :
Initialisation d’un pointeur de pointeurs :
nom_tableau = new type * [ n ];
for ( int i =0 ; i < n ; i ++)
{
nom_tableau [ i ]= new type [ m ] ;
}
I nom_tableau est un tableau à 2 dimensions n × m. n et m peuvent être des
constantes, des variables ou des expressions entières.
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 19 / 25
Tableaux dynamiques
Libération de la mémoire
I La libération de la mémoire allouée pour un tableau à deux dimension se fait
suivant l’ordre inverse à l’allocation :
Désallocation d’un tableau dynamique bidimensionnel:
for ( int i =0 ; i < n ; i ++)
{
delete [] nom_tableau [ i ] ;
}
delete [] nom_tableau ;
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 20 / 25
Tableaux dynamiques
Exemple :
double ** mat ; // pointeur de pointeurs
int nlignes , ncols ;
cin > > nlignes >> ncols ;
// allouer l ’ espace n é cessaire
mat = new double * [ nlignes ];
for ( int i =0; i < nlignes ; i ++)
mat [ i ]= new double [ ncols ];
// mat est maintenant une matrice nlignes * ncols
for ( int i =0; i < nlignes ; i ++)
{
for ( int j =0; j < ncols ; j ++)
cin > > mat [ i ][ j ];
}
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 21 / 25
Tableaux dynamiques
// affichage de la matrice
for ( int i =0; i < nlignes ; i ++)
{
for ( int j =0; j < ncols ; j ++)
cout < < mat [ i ][ j ];
}
// lib é rer l ’ espace m é moire allou é
for ( int i =0; i < nlignes ; i ++)
delete [] mat [ i ] ;
delete [] mat ;
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 22 / 25
Tableaux dynamiques
Exercice :
En utilisant le formalisme de pointeur et d’allocation dynamique:
1 Écrire une fonction qui retourne la moyenne des valeur d’un
tableau.
2 Écrire un programme qui permet de demander à l’utilisateur de
saisir les éléments d’ un tableau puis calcule la moyenne.
Solution :
# include < iostream >
using namespace std ;
double moyenne ( double *T , int taille );
int main ()
{
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 23 / 25
Tableaux dynamiques
double * T = NULL ; // pointeur nul
int n ;
cout < < " Combien d elements ? " << endl ;
cin > > n ;
T = new double [ n ] ; // allocation
cout < < " Saisir le tableau " << endl ;
for ( int i =0; i < n ; i ++)
{
cin > > T [ i ]; // ou cin > >*( T + i );
}
cout < < " La moyenne est " << moyenne (T , n ) < < endl ;
delete [] T ; // lib é rer l ’ espace allou é pour T ;
}
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 24 / 25
Tableaux dynamiques
// d é finition de la fonction
double moyenne ( double * tab , int taille )
double Somme =0.0;
for ( double * P = tab ; P < tab + taille ; P ++)
Somme +=* P ;
return Somme / taille ;
Driss ABADA Initiation à la programmation : Langage C++ Année Universitaire : 2019/2020 25 / 25