Vous l'ignorez sans-doute, mais vous avez très certainement déjà utilisé des pointeurs :
scanf("%d", &n);
Le &
(et commercial ou esperluette) placé devant une variable signifie que
l'on utilise son adresse. La fonction scanf()
reçoit l'adresse
de la variable, ce qui permet de modifier son contenu pour y écrire la
saisie de l'utilisateur.
Lorsque l'on oublie le &
dans un scanf()
, la fonction
prend pour adresse la valeur de la variable. Si la variable contient 0, la fonction
va tenter d'écrire dans le premier octet de la mémoire ce qui engendre généralement
une erreur de segmentation.
L'exemple ci-dessous affiche l'adresse de la variable x
:
var x;
printf ("%p", &x);
Il est possible de déclarer un pointeur, c'est-à-dire une variable destinée à contenir l'adresse d'une autre variable. Il suffit d'ajouter un astérisque devant le nom du pointeur :
int *adresse1;
char *adresse2;
Un pointeur est toujours associé à un type. Comme le pointeur ne contient que l'adresse
du premier octet, la désignation du type permet au compilateur de connaître la taille
de la variable pointée. Dans l'exemple suivant, le pointeur adresse
contient l'adresse
de la variable var
. On dit que var
est pointée par le pointeur adresse
ou que
adresse
pointe vers var
:
float var;
float *adresse = &var;
L'intérêt des pointeurs est de pouvoir accéder à une variable en lecture et/ou en écriture par son adresse. L'accès au contenu pointé se fait en ajoutant un astérisque devant le pointeur :
float var;
float *adresse = &var;
*adresse = 5.2; // Equivalent à var=5.2;
Voici un exemple des différentes syntaxes pour les pointeurs :
// Déclare une variable
short var=0xABCD;
// Déclare un pointeur vers var
short* adresse = &var;
// Affiche la variable var
printf ("var : %hX\n", var);
// Affiche le contenu pointé (= var)
printf ("*adresse : %hX\n", *adresse);
// Affiche l'adresse de var
printf ("&var : %p\n", &var);
// Affiche le contenu du pointeur (adresse de var)
printf ("adresse : %p\n", adresse);
// Affiche l'adresse du pointeur
printf ("&adresse : %p\n", &adresse);
Voici un affichage possible pour ce programme :
var : ABCD *adresse : ABCD &var : 0x7ffcda51423a adresse : 0x7ffcda51423a &adresse : 0x7ffcda514230
L'image suivante illustre la représentation de la mémoire pour cette exécution du programme. On retrouve bien les deux entités principales :
var
adresse
On constate que le contenu du pointeur est bien l'adresse de var
. Le pointeur adresse
pointe
sur la variable var
:
Écrire une programme qui
var
et l'initialise à 18 ;adresse
;var
au pointeur ;var
adresse
(*adresse
).var = 18 *adresse = 18
Écrire une programme qui
var
et l'initialise à 27 ;adresse
;var
au pointeur ;On constate que le pointeur n'a pas été augmenté d'un octet, mais de 4 octets, ce qui correspond à la taille d'un entier :
Avant : 0x7ffe4b0a7e88 Après : 0x7ffe4b0a7e8c
Comment obtenir l'adresse d'une variable ?
Quelles syntaxes permettent de déclarer un pointeur ?
int*
ou int *
déclarent un pointeur destiné à contenir l'adresse d'un entier
Essaie encore ...
Comment afficher le contenu de la variable pointée par le pointeur ad
?
*ad
est la valeur pointée par ad
Essaie encore ...
Comment afficher l'adresse contenue dans le pointeur ad
?
ad
une adresse que l'on affiche avec le code format %p
.
Essaie encore ...
Comment afficher l'adresse du pointeur ad
?
&ad
est l'adresse du pointeur.
Essaie encore ...
Qu'affiche le programme suivant ?
int var = 128, *adresse;
adresse = &var;
printf ("%d %d", var, *adresse);
Qu'affiche le programme suivant ?
int var = 128, *adresse;
adresse = &var;
printf ("%p", adresse);
Un pointeur est associés à un type ...