Vous êtes ici :
Accueil Cours Programmations Débuter en programmation avec le langage C Les pointeurs

Débuter en programmation avec le langage C : Les pointeurs

Introduction

 

Avant de parler de pointeurs, nous allons brièvement passer en revue les deux modes d'adressage principaux :
 
Adressage direct : Dans la programmation, nous utilisons des variables pour stocker des informations. La valeur d'une variable se trouve à un endroit spécifique dans la mémoire interne de l'ordinateur. Le nom de la variable nous permet alors d'accéder directement à cette valeur.  
 
Adressage direct = Accès au contenu d'une variable par le nom de la variable.
 
Exemple :
 
short X ;
X = 20 ;


Adressage indirect : Si nous ne voulons pas ou  encore nous ne pouvons pas utiliser le nom d'une variable X, nous pouvons copier l'adresse de cette variable dans une variable spéciale P, appelée pointeur. Ensuite, nous pouvons retrouver l'information de la variable X en passant par le pointeur P.
 
Adressage indirect = Accès au contenu d'une variable, en passant par un pointeur  qui contient l'adresse de la variable.
 
Exemple :
 
Soit X une variable contenant la valeur 20 et P un pointeur qui contient l'adresse de X.
 
La plupart des langages de programmation offrent la possibilité d'accéder aux données dans la mémoire de l'ordinateur à l'aide de pointeurs, c'est-à-dire à l'aide de variables auxquelles on peut attribuer les adresses d'autres variables.  
On peut donc définir un pointeur comme une variable spéciale qui peut contenir l'adresse d'une autre variable. En C, chaque pointeur est limité à un type de données.
 
 Si un pointeur P contient l'adresse d'une variable X, on dit que " P pointe sur X "

 

Attention : Les pointeurs et les noms de variables ont le même rôle : Ils donnent accès à un emplacement dans la mémoire interne de l'ordinateur. Il faut quand même bien faire la différence :

  •  Un pointeur est une variable qui peut 'pointer' sur différentes adresses.
  •   Le nom d'une variable reste toujours lié à la même adresse.

 .

Les opérateurs de base


 Lors du travail avec des pointeurs, nous avons besoin
 
-  d'un opérateur adresse de: &   pour obtenir l'adresse d'une variable.
-  d'un opérateur contenu de: *  pour accéder au contenu d'une adresse.
-  d'une syntaxe de déclaration pour pouvoir déclarer un pointeur.
 

L'opérateur adresse de : &

 

&<NomVariable>   fournit l'adresse de la variable <NomVariable>
 
L'opérateur & nous est déjà familier par la fonction scanf, qui a besoin de l'adresse de ses arguments pour pouvoir leur attribuer de nouvelles valeurs.
 
Exemple  
 
int X;
printf("Entrez un nombre entier : ");
scanf("%d", &X);

 
Soit P un pointeur non initialisé et X une variable (du même type) contenant la valeur 20 : Alors l'instruction  
 
   P = &X;  affecte l'adresse de la variable X à la variable P.
 

L'opérateur contenu de : *

 


*<NomPointeur> désigne le contenu de l'adresse référencée par le pointeur <NomPointeur>
 
Exemple
 
int X , Y;
int *P ;

Soit X une variable contenant la valeur 20, Y une variable contenant la valeur 40 et P un pointeur non initialisé:
Après les instructions,  
 
   P = &X;
   Y = *P;
   *P = 100;
 

- P pointe sur X,
- le contenu de X (référencé par *P) est affecté à Y, et
- le contenu de X (référencé par *P) est mis à 100.
 
 
La déclaration d'un pointeur  est comme suit :
 
<Type> *<NomPointeur>  
déclare un pointeur <NomPointeur> qui peut recevoir des adresses de variables du type <Type>
 
Une déclaration comme  
 
   int *P_num;  
 
peut être interprétée comme suit:
 
    "*P-num est du type int"   ou   "P_num est un pointeur sur int"  ou  
    "P_num peut contenir l'adresse d'une variable du type int"
 

 

Les opérations élémentaires sur pointeurs

En travaillant avec des pointeurs, nous devons observer les règles suivantes:
 
Priorité de  * et &
 

  •   Les opérateurs * et & ont la même priorité que les autres opérateurs unaires (la négation !, l'incrémentation ++, la décrémentation --). Dans une même expression, les opérateurs unaires *, &, !, ++, -- sont évalués de droite à gauche.
  •   Si un pointeur P pointe sur une variable X, alors *P peut être utilisé partout où on peut écrire X.  

 
Exemple
 
Après l'instruction     P = &X;
 
les expressions suivantes, sont équivalentes:
 
  Y = *P+1   ou Y = X+1  
  *P = *P+10  ou X = X+10  
  *P += 2   ou X += 2  
  ++*P    ou ++X  
  (*P)++   ou X++

 

Adressage des composantes d'un tableau

 
 Comme nous l'avons déjà constaté, le nom d'un tableau représente l'adresse de son premier élément. En d'autre termes:
 
                                         &tableau[0] et tableau  sont une seule et même adresse.  
 
En simplifiant, nous pouvons retenir que le nom d'un tableau est un pointeur constant sur le premier élément du tableau, par exemple :
 
En déclarant un tableau T de type int et un pointeur P sur int,  
 
   int T[20];

   int *P;

 

 
l'instruction:
P = T; est équivalente à P = &T[0];
 
Si P pointe sur une composante quelconque d'un tableau, alors P+1 pointe sur la composante suivante. Plus généralement,
 
P+i   pointe sur la i-ième composante derrière P et P-i      pointe sur la i-ième composante devant P. Ainsi, après l'instruction,
 
   P = T;  le pointeur P pointe sur T[0], et


 *(P+1)   désigne le contenu de T[1]  
 *(P+2)   désigne le contenu de T[2]  
 ...  
 *(P+i)   désigne le contenu de T[i]
 

 
 Pointeurs et chaînes de caractères
 
De la même façon qu'un pointeur sur int peut contenir l'adresse d'un nombre isolé ou d'une composante d'un tableau, un pointeur sur char peut pointer sur un caractère isolé ou sur les éléments d'un tableau de caractères. Un pointeur sur char peut en plus contenir l'adresse d'une chaîne de caractères constante et il peut même être
initialisé avec une telle adresse.  
 
 
Affectation
 
 On peut attribuer l'adresse d'une chaîne de caractères constante à un pointeur sur char :
 
Exemple  
 
  char *c;
  c = "Salut !";

 

Nous pouvons lire cette chaîne constante (par exemple : pour l'afficher), mais il n'est pas recommandé de la modifier, parce que le résultat d'un programme qui essaie de modifier une chaîne de caractères constante n'est pas prévisible en ANSI-C.

 

Initialisation
 

Un pointeur sur char peut être initialisé lors de la déclaration si on lui affecte l'adresse d'une chaîne de caractères constante:  
 
      char *C = "Salut !";
 
Attention ! :  Il existe une différence importante entre les deux déclarations:  
      char T[] = "Salut !";   /* un tableau  */
      char *C  = "Salut !";   /* un pointeur */
 

T est un tableau qui a exactement la grandeur pour contenir la chaîne de caractères et la terminaison '\0'. Les caractères de la chaîne peuvent être changés, mais le nom T va toujours pointer sur la même adresse en mémoire. C est un pointeur qui est initialisé de façon à ce qu'il pointe sur une chaîne de caractères constante stockée quelque part en mémoire. Le pointeur peut être modifié et pointer sur autre chose. La chaîne constante peut être lue, copiée ou affichée, mais pas modifiée.

 

 




Vous êtes ici :
Accueil Cours Programmations Débuter en programmation avec le langage C Les pointeurs