En langage C, il est possible de définir une variable destinée à contenir une adresse. On pourrait dire qu'une telle variable est de type pointeur. En fait, ceci n'est pas assez précis, car le langage C distingue plusieurs types de pointeurs en se basant sur le type des informations qu'on trouvera à l'adresse indiquée : caractères, entiers, décimaux ...
Syntaxe :
type * nom_du_pointeur;
C'est ainsi qu'on déclare une variable de type pointeur, il s'agit en fait de la déclaration d'une variable nommée nom_du_pointeur, destinée à contenir l'adresse d'un élément de type type.
Exemples :
int * point_ent; /* point_ent est un pointeur
sur un entier */
char * ad_c; /* ad_c est un pointeur sur
un caractère */
float * ptr_x; /* ptr_x est un pointeur
sur un décimal */
Le symbole & placé devant le nom d'une variable permet d'utiliser l'adresse de cette variable, plutôt que son contenu.
Exemple :
#include<stdio.h>
main()
{
int * adr_i;
int n=20;
adr_i=&n;
}
L'exécution de la dernière instruction, va affecter à adr_i l'adresse de notre variable n. On dit alors que adr_i pointe sur n.
Le symbole * permet lorsqu'il est placé devant un nom de pointeur, d'utiliser la variable pointée. Cette opérateur peut donc permettre soit de récupérer la valeur contenue dans la variable pointée, soit de modifier le contenu de cette variable pointée.
Exemple :
#include<stdio.h>
main()
{
int *
adr_i;
int n=20;
int p;
adr_i=&n; /* affecte
à adr_i l'adresse de la variable n */
p=*adr_i;
/* affecte à p la valeur de la variable pointée par
adr_i (équivaut à p=n) */
*adr_i=30;
/* affecte à la variable pointée par adr_i la valeur
30 (équivaut à n=30) */
adr_i=&p; /*
affecte à adr_i l'adresse de la variable p */
*adr_i=30;
/* affecte à la variable pointée par adr_i la valeur
30 (équivaut à p=30) */
}
Si adr_i=&n, alors *adr_i peut être considérée comme étant la variable n. Toutes les opérations sur n peuvent être faites en utilisant *adr_i.
a) Lorsqu'on souhaite déclarer, dans une même instruction, plusieurs pointeurs de même type, il ne faut pas écrire :
Exemple mauvais :
char * adc1, adc2;
En effet, dans ce cas adc1 serait certes un pointeur sur des caractères, mais en revanche, adc2 serait tout simplement de type char. Si l'on souhaite que adc2 soit également de type pointeur sur des caractères, il faudra écrire :
Exemple correct :
char * adc1, * adc2;
b) Lorsqu'on réserve l'emplacement pour une variable pointeur, on ne réserve pas pour autant un emplacement pour un entier. L'adresse contenue initialement dans la variable pointeur, est imprévisible.
Exemple mauvais :
#include<stdio.h>
main()
{
int * adi;
*adi=12;
}
On introduit ici une affectation sur la variable qui serait pointée par adi, alors que nous n'avons fait pointer aucune variable par adi. Nous avons en fait demandé de placer la valeur 12 à un emplacement inconnu.
c) Lorsqu'on manipule les pointeurs, il faut faire attention au moment des affectations.
Exemple :
#include<stdio.h>
main()
{
int * ad1, * ad2;
int n=1, p=2;
ad1= &n; /* ad1 pointe
sur l'entier n */
ad2= &p; /*
ad2 pointe sur l'entier p */
*ad1 = *ad2 + 3;
/* même rôle que n=p+3, n contient 5 après cette instruction */
ad1=ad2; /* ad1
pointe sur la même variable que ad2, donc ad1 pointe sur p */
}
d) Il n'est pas permis d'affecter la valeur d'un pointeur d'un certain type à une variable pointeur d'un type différent.
Exemple mauvais :
#include<stdio.h>
main()
{
int * adi; /* adi
est du type pointeur sur des entiers */
char * adc; /*
adc est du type pointeur sur des caractères */
adi = adc; /*
incorrect */
adc = adi; /*
incorrect */
}