« Programmation C++/Les pointeurs » : différence entre les versions

Un livre de Wikilivres.
Contenu supprimé Contenu ajouté
Ligne 88 : Ligne 88 :
Dans l'exemple 2, la différence d'adresse est de 20 octets (<code>5 * sizeof(int)</code>).
Dans l'exemple 2, la différence d'adresse est de 20 octets (<code>5 * sizeof(int)</code>).
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 (<code>sizeof *ptr</code>).
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 (<code>sizeof *ptr</code>).

====Opération utilisant deux pointeurs====
La seule opération valable (ayant un sens) utilisant deux pointeurs de même type est la soustraction ( <code>-</code> ) 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 :
char str[]="Message ou rechercher des caractères.";
char *p1 = strchr(str,'a'); // recherche le caractère 'a' dans str
char *p2 = strchr(str,'è'); // recherche le caractère 'è' dans str
cout << "Nombre de caractères de 'a' à 'è' = " << (p2-p1) << endl;
// affiche : Nombre de caractères de 'a' à 'è' = 28


===Pointeur constant et pointeur vers valeur constante===
===Pointeur constant et pointeur vers valeur constante===

Version du 22 juillet 2006 à 17:52

Les pointeurs

Un pointeur désigne une variable contenant une adresse mémoire. 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 très souvent complexes.

Déclaration

type * identificateur;
La variable identificateur est un pointeur vers une variable de type type.

L'opérateur &

Il permet d'obtenir un pointeur vers une variable.
&identificateur permet d'obtenir un pointeur vers la variable identificateur. Il renvoit en réalité une adresse mémoire, l'adresse où est stocké physiquement la variable identificateur. C'est donc une variable pointeur.

L'opérateur *

* variable<br\> 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 *pointeur permet d'obtenir la valeur de la variable pointée par pointeur.

Exemple de programme

 #include <iostream>
 using namespace std;
 
 int main()
 {
     int a, b, c;
     int *x, *y;
 
     a = 98;
     b = 108;
 
     x = &a;
     c = *x + 5;
 
     y = &b;
     *y = a + 10;
 
     cout << "La variable b vaut : " << b << endl;
     cout << "La variable c vaut : " << c << endl;
 
     return 0;
 }

Exécution :
La variable b vaut 108
La variable c vaut 103

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 et b à 78.
  • x=&a; permet de mettre dans x l'adresse de a. x est désormais un pointeur vers a.
  • *x est la valeur de la variable pointée par x, c'est-à-dire la valeur de a, et vaut donc 98.
c=*x+5; permet donc de tranférer 98+5 donc 103 dans la variable c.
  • y=&b permet de mettre dans y l'adressee la variable b. y est désormais un pointeur vers b.
a+10 vaut 98+10 donc 108.
  • *y=a+10; permet de tranférer dans la variable pointée par y la valeur de a+10, c'est-à-dire 108. On transfère donc 108 dans b.
  • 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

 char* ptr="Pointeur";  // ptr pointe le premier caractère de la chaîne de caractères
 
 cout << ptr << endl;   // affiche "Pointeur"
 
 ptr = ptr+3;
 cout << ptr << endl;   // affiche "nteur"
 
 cout << ++ptr << endl;   // affiche "teur"
 cout << --ptr << endl;   // affiche "nteur"

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

 int premiers[] = { 2, 3, 5, 7, 11, 13, 17 };
 int* ptr = premiers; // pointe le premier élément du tableau
 
 cout << hex << ptr << endl;  // affiche l'adresse pointée (par exemple 01C23004)  
 cout << *ptr << endl;     // affiche "2"
 cout << *(ptr+5) << endl; // affiche "13"
 
 ptr=&premiers[3]; // pointe le 4ème élément (index 3)
 cout << hex << ptr << endl;  // affiche l'adresse pointée (par exemple 01C23018)
 cout << *ptr << endl;     // affiche "7"
 cout << *(ptr-1) << endl; // affiche "5"

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 :

 char str[]="Message ou rechercher des caractères.";
 char *p1 = strchr(str,'a'); // recherche le caractère 'a' dans str
 char *p2 = strchr(str,'è'); // recherche le caractère 'è' dans str
 
 cout << "Nombre de caractères de 'a' à 'è' = " << (p2-p1) << endl;
 // affiche :   Nombre de caractères de 'a' à 'è' = 28

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 constant

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

Exemple:

const char* msg="essai constant";

*msg = 'E'; // <- Interdit, la valeur pointée ne peut être modifiée

msg="Test"; // OK -> "Test"

Pointeur vers une valeur constante

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

Exemple:

char* const msg="essai constant";

msg="Test"; // <- Interdit (erreur de compilation),
            //    ne peut pointer la chaîne "Test"

*msg = 'E'; // OK -> "Essai constant"

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 est celle de la valeur pointée.

Exemple:

const char* const msg="essai constant";

msg="Test"; // <- Interdit (erreur de compilation),
            //    ne peut pointer la chaîne "Test"

*msg = 'E'; // <- Interdit, la valeur pointée ne peut être modifiée