# Programmation C++/Les pointeurs

* Avant-propos
* Introduction
* Compilation
* Un premier programme
* Les commentaires
* Le préprocesseur
* Les types de base et les déclarations
** Exercices
* Les opérations de base
* Les entrées-sorties
* Les pointeurs
** Exercices
* Les références
* Les tableaux
** Exercices
** Exercices sur les tableaux statiques
** Exercice : Tris des tableaux à une dimension
** Solution : Tris des tableaux à une dimension
* Les structures de contrôle
** Exercices
** Exercices if...else et switch
* Les fonctions
** Exercices
* Les structures
** Exercices
* Les classes
** Exercices
** Exercices de développement
* Les espaces de noms
* Les exceptions
* Les templates
** Exercices
* Conventions d'appel
* Les fichiers
* La librairie standard
* Expressions rationnelles
* Interfaces graphiques
* Bibliographie et liens

## Anciennes pages

* Opérateurs
* Héritage
* Polymorphisme
* Avant-propos
* Introduction
* Compilation
* Un premier programme
* Les commentaires
* Le préprocesseur
* Les types de base et les déclarations
** Exercices
* Les opérations de base
* Les entrées-sorties
* Les pointeurs
** Exercices
* Les références
* Les tableaux
** Exercices
** Exercices sur les tableaux statiques
** Exercice : Tris des tableaux à une dimension
** Solution : Tris des tableaux à une dimension
* Les structures de contrôle
** Exercices
** Exercices if...else et switch
* Les fonctions
** Exercices
* Les structures
** Exercices
* Les classes
** Exercices
** Exercices de développement
* Les espaces de noms
* Les exceptions
* Les templates
** Exercices
* Conventions d'appel
* Les fichiers
* La librairie standard
* Expressions rationnelles
* Interfaces graphiques
* Bibliographie et liens

## Anciennes pages

* Opérateurs
* Héritage
* Polymorphisme
[ Modifier le sommaire ]

## Introduction

Une variable correspond à un emplacement en mémoire (adresse) où se trouve une valeur. Toute variable a permet d'accéder :
* à sa valeur en lecture et en écriture :
* à son adresse en lecture seulement car l'adresse (l'emplacement mémoire) est choisie par le système :
Un pointeur désigne un type particulier de variable dont la valeur est une adresse. Un pointeur permet donc de contourner la restriction sur le choix de l'adresse d'une variable, et permet essentiellement d'utiliser la mémoire allouée dynamiquement.
Il est utilisé lorsque l'on veut manipuler les données stockées à cette adresse. C'est donc un moyen indirect de construire et de manipuler des données souvent très complexes.

## Déclaration

La variable identificateur est un pointeur vers une valeur de type type.

## L'opérateur &

C'est l'opérateur d'indirection. Il permet d'obtenir l'adresse d'une variable, c'est-à-dire un pointeur vers cette variable.
Il renvoie en réalité une adresse mémoire, l'adresse où est stockée physiquement la variable identificateur.

## L'opérateur *

C'est l'opérateur de déréférencement. Il permet d'obtenir et donc de manipuler les données pointées par la variable variable. Ainsi *pointeur permet d'accéder à la valeur pointée par pointeur en lecture et en écriture.

## Comparaison avec une variable classique

| écriture de la valeur de a | a = 10; | *pA = 10; |
| lecture de la valeur de a | cout << "A vaut " << a ; | cout << "A vaut " << *pA ; |
| lecture de l'adresse de a | cout << "L'adresse de A est " << &a ; | cout << "L'adresse de A est " << pA ; |
Le pointeur pA peut par la suite pointer l'adresse d'une autre variable, où bien pointer l'adresse d'un bloc de mémoire alloué dynamiquement.

## Exemple de programme
### Explications

* Dans ce programme, on déclare 3 variables a, b et c. On déclare ensuite 2 pointeurs vers des entiers x et y.
* a est initialisé à 98.
* x=&a; permet de mettre dans x l'adresse de a. x est désormais un pointeur vers a.
* *x est la variable pointée par x, c'est-à-dire a, qui vaut donc 98 après évaluation.
    c=*x+5; permet donc de transférer 98+5 donc 103 dans la variable c.
* y=&b; permet de mettre dans la variable y l'adresse de la variable b. y est désormais un pointeur vers b.
    a+10 vaut 98+10 donc 108.
* *y=a+10; permet de transférer dans la variable pointée par y la valeur de a+10, c'est-à-dire 108. On stocke donc 108 dans b, de manière indirecte via le pointeur y.
* on affiche ensuite les valeurs de b et c c'est-à-dire respectivement 108 et 103.

## Opérations arithmétiques sur les pointeurs

Hormis l'opérateur de déréférencement, les pointeurs peuvent être utilisés avec l'opérateur d'addition ( + ). L'addition d'un pointeur avec une valeur entière permet d'avancer ou reculer le pointeur du nombre d'éléments indiqué.

### Exemple 1

Comme l'exemple précédent le montre, il est également possible d'utiliser les opérateurs d'incrémentation et de décrémentation.

### Exemple 2

Dans l'exemple 2, la différence d'adresse est de 20 octets (5 * sizeof(int)). Cela montre que l'adresse contenue dans le pointeur est toujours incrémentée ou décrémentée d'un multiple de la taille d'un élément (sizeof *ptr).

## Opération utilisant deux pointeurs

La seule opération valable (ayant un sens) utilisant deux pointeurs de même type est la soustraction ( - ) donnant le nombre d'éléments entre les deux adresses. Elle n'a de sens que si les deux pointeurs pointent dans le même tableau d'éléments.
Exemple :

## Pointeur constant et pointeur vers valeur constante

Il ne faut pas confondre un pointeur constant (qui ne peut pointer ailleurs) avec un pointeur vers une valeur constante (l'adresse contenue dans le pointeur peut être modifiée mais pas la valeur pointée).
Dans les 2 cas le mot clé const est utilisé, mais à 2 endroits différents dans le type de la variable.

### Pointeur vers une valeur constante

Le mot-clé const placé avant le type du pointeur permet d'empêcher la modification de la valeur pointée.
Exemple:

### Pointeur constant

Le mot-clé const placé entre le type du pointeur et le nom de la variable permet d'empêcher la modification du pointeur lui-même (l'adresse).
Exemple:

### Pointeur constant vers une valeur constante

Le mot-clé const apparaissant aux 2 endroits empêche à la fois la modification du pointeur lui-même et celle de la valeur pointée.
Exemple:

### Position du mot clé const

Une méthode simple a été proposée par Dan Sacks pour déterminer si c'est la valeur pointée ou le pointeur lui-même qui est constant. Elle se résume en une seule phrase mais n'a jamais été intégrée dans les compilateurs :
Par conséquent, une déclaration ne commencera jamais par const qui ne serait précédé de rien et qui ne pourrait donc s'appliquer à rien. En effet, les deux déclarations suivantes sont strictement équivalentes en C++ :
Cette méthode peut s'avérer précieuse dans le cas de déclarations plus complexes :

## Voir aussi

* Exercices