Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 10

Les pointeurs

Programmation C
Les pointeurs
Fabien Calcado – Notions de pointeurs
– Manipulation de pointeurs
fabien.calcado@isty.uvsq.fr
• Indirections simples et multiples
– Fonction et pointeur
• Effet de bord à l’aide de passage par copie « de pointeurs »
Mise à disposition de mon cours de 1ère année
– Tableau statique et pointeur :
dans le cadre des rappels / compléments de C • Ecriture équivalente des [ ]

ISTY– IATIC3 - 2020/2021 1


Fabien Calcado ISTY– IATIC3 - 2020/2021 2

Les pointeurs Les pointeurs

Rappels sur les variables Rappels sur les variables


– Une variable est une case m émoire – Une variable est une case m émoire
• Stocke une valeur • Stocke une valeur
» Valeur aléatoire si non initialisée » Valeur aléatoire si non initialisée
» Accessible / modif iable par son nom : adressage direct » Accessible / modif iable par son nom : adressage direct
• Possède un type • Possède un type
» Représentation utilisée : entier signé / non signé, réel, caractère, … » Représentation utilisée : entier signé / non signé, réel, caractère, …
» Taille de la zone mémoire : interv alle des v aleurs possibles » Taille de la zone mémoire : interv alle des v aleurs possibles
• Localisée en mémoire • Localisée en mémoire
» adresse mémoire ou référence » adresse mémoire ou référence
int a ; int a ; a
Adresse de « a » &a a a = 100 ; // @ direct &a @direct

valeur de « a » ? 100

Fabien Calcado ISTY– IATIC3 - 2020/2021 3 Fabien Calcado ISTY– IATIC3 - 2020/2021 4

1
Les pointeurs Les pointeurs
Variable de type « pointeur de » Opérateur spécifique pour les pointeurs
– Un pointeur est une variable – Opérateur « * » : indirection ou déréférencement
• Stocke une valeur adresse (d’une variable du programme)
• Accéder à la valeur située à l’adresse stockée dans le pointeur
» Valeur aléatoire si non initialisée : adresse aléatoire
» Uniquement possible sur les pointeurs
» Accessible / modif iable par son nom : adressage direct
– Pointeur non valide : valeur « NULL »
• Possède un type : « type pointeur de … »
• Le déréférencement conduira à une erreur de segmentation
» Le ty pe de la case mémoire réf érencée doit être précisé
» Taille de la zone mémoire : même taille qu’un ty pe « int » – Exem ple de code et point de vue m émoire
• Localisée en mémoire • Précisez si l’adressage est direct ou indirect
» A sa propre adresse mémoire ou référence ( pointeur multiple) ptr a
int a ; &ptr &a
@direct
Adressage direct int * ptr = NULL ; // @ direct
int * Adre sseMaVariable = & MaVariable ; NULL ?

Type adresse d’ entier Nom du pointeur Adresse d’ une variable int « pointeur non valide »

Fabien Calcado ISTY– IATIC3 - 2020/2021 5 Fabien Calcado ISTY– IATIC3 - 2020/2021 6

Les pointeurs Les pointeurs

Opérateur spécifique pour les pointeurs Opérateur spécifique pour les pointeurs
– Opérateur « * » : indirection ou déréférencement – Opérateur « * » : indirection ou déréférencement
• Accéder à la valeur située à l’adresse stockée dans le pointeur • Accéder à la valeur située à l’adresse stockée dans le pointeur
» Uniquement possible sur les pointeurs » Uniquement possible sur les pointeurs
– Pointeur non valide : valeur « NULL » – Pointeur non valide : valeur « NULL »
• Le déréférencement conduira à une erreur de segmentation • Le déréférencement conduira à une erreur de segmentation
– Exem ple de code et point de vue m émoire – Exem ple de code et point de vue m émoire
• Précisez si l’adressage est direct ou indirect • Précisez si l’adressage est direct ou indirect
ptr a ptr a
int a ; int a ; &ptr ptr (@direct) &a
&ptr &a @direct
int * ptr = NULL ; // @ direct int * ptr = NULL ; // @ direct
NULL &a 100
100 a = 100 ; // @ direct
a = 100 ; // @ direct
ptr = &a ; // @ direct !!
« ptr pointe sur a »
Fabien Calcado ISTY– IATIC3 - 2020/2021 7 Fabien Calcado ISTY– IATIC3 - 2020/2021 8

2
Les pointeurs Les pointeurs

Opérateur spécifique pour les pointeurs


Manipulation de pointeurs
– Opérateur « * » : indirection ou déréférencement
• Accéder à la valeur située à l’adresse stockée dans le pointeur int * pa ; //pointeur non initialisé… En mémoire
» Uniquement possible sur les pointeurs
– Pointeur non valide : valeur « NULL » pa
&pa
• Le déréférencement conduira à une erreur de segmentation
?
– Exem ple de code et point de vue m émoire ?
• Précisez si l’adressage est direct ou indirect
ptr a
int a ; &ptr &a
int * ptr = NULL ; // @ direct A ne pas faire : Pointeur pointe n’importe où en mémoire : valeur aléatoire
&a 42 (Peut pointer sur une variable du programme non voulue)
*ptr
a = 100 ; // @ direct (@indirect) Le programme ne plante pas obligatoirement et peut avoir un comportement indéfinie
ptr = &a ; // @ direct !!
*ptr = 42 ; // @ indirect Initialisation d’un pointeur : adresse valide ou NULL (adresse non valide)

Fabien Calcado ISTY– IATIC3 - 2020/2021 9 Fabien Calcado ISTY– IATIC3 - 2020/2021 10

Les pointeurs Les pointeurs

Manipulation de pointeurs Manipulation de pointeurs


int * pa = NULL ; //@direct En mémoire int * pa = NULL ; //@direct En mémoire

int a ;
pa int b = 5 ; //@direct pb pa a b
&pa &pb &pa &a &b
int * pb = &b; //@direct
NULL &b NULL ? 5

Erreur classique : croire que la déclaration


d’un pointeur créé la variable sur laquelle
il pointe…

Fabien Calcado ISTY– IATIC3 - 2020/2021 11 Fabien Calcado ISTY– IATIC3 - 2020/2021 12

3
Les pointeurs Les pointeurs

Manipulation de pointeurs Manipulation de pointeurs


int * pa = NULL ; //@direct En mémoire int * pa = NULL ; //@direct En mémoire

int a ; int a ;
int b = 5 ; //@direct pb pa a b int b = 5 ; //@direct pb pa a b
&pb &pa &a &b &pb &pa &a &b
int * pb = &b; //@direct int * pb = &b; //@direct
&b NULL
&a ?2 5 &b NULL
&a ?2 5
a = 2 ; //@direct a = 2 ; //@direct
pa = &a ; //@direct pa = &a ; //@direct

*pb = *pa + b ; //@indirect + @direct

2 5

*pb = *pa + b;
Fabien Calcado ISTY– IATIC3 - 2020/2021 13 Fabien Calcado ISTY– IATIC3 - 2020/2021 14

Les pointeurs Les pointeurs

Manipulation de pointeurs Manipulation de pointeurs


int * pa = NULL ; //@direct En mémoire int * pa = NULL ; //@direct En mémoire

int a ; int a ;
int b = 5 ; //@direct pb pa a b int b = 5 ; //@direct pb pa a b
&pb &pa &a &b &pb &pa &a &b
int * pb = &b; //@direct int * pb = &b; //@direct
&b NULL
&a ?2 57 &b NULL
&a 14
?2 7
a = 1 ; //@direct a = 1 ; //@direct
pa = &a ; //@direct pa = &a ; //@direct

*pb = *pa + b ; //@indirect + @direct *pb = *pa + b ; //@indirect + @direct


7 *pa = *pa * *pb ; //@indirect 14
2 + 5 2 * 7

*pb = *pa + b; *pa = *pa * *pb ;


Fabien Calcado ISTY– IATIC3 - 2020/2021 15 Fabien Calcado ISTY– IATIC3 - 2020/2021 16

4
Les pointeurs Les pointeurs

Manipulation de pointeurs Manipulation de pointeurs


int * pa = NULL ; //@direct En mémoire int * pa = NULL ; //@direct En mémoire

int a ; int a ;
int b = 5 ; //@direct pb pa a b int b = 5 ; //@direct pb pa a b
&pb &pa &a &b &pb &pa &a &b
int * pb = &b; //@direct int * pb = &b; //@direct
&b &a
&b 14
? 7 &b &b 14 -7
7
a = 1 ; //@direct a = 1 ; //@direct
pa = &a ; //@direct pa = &a ; //@direct

*pb = *pa + b ; //@indirect + @direct *pb = *pa + b ; //@indirect + @direct


*pa = *pa * *pb ; //@indirect *pa = *pa * *pb ; //@indirect -7
Les deux pointeurs pointent
7 - 14
pa = pb ; //@direct sur la même case mémoire pa = pb ; //@direct
*pb = *pa - a ; //@indirect + @direct
*pb = *pa - a ;
Fabien Calcado ISTY– IATIC3 - 2020/2021 17 Fabien Calcado ISTY– IATIC3 - 2020/2021 18

Les pointeurs Les pointeurs


Les indirections multiples Les indirections multiples
– Un pointeur peut stocker l’adresse d’un autre pointeur – Un pointeur peut stocker l’adresse d’un autre pointeur
• Un déréférencement « * » annule une référence « & » • Un déréférencement « * » annule une référence « & »
int a = 2 ; int a = 2 ; a
int * pa = &a ; int * pa = &a ;
int ** ppa = &pa ; int ** ppa = &pa ;
*(pa)
int *** pppa = &ppa ; int *** pppa = &ppa ;

***ppa = **pa + *pa + a ; a ***ppa = **pa + *pa + a ; *(*(&pa)) a

pppa ppa pa *(&a) 2 pppa ppa pa *(*(ppa)) *(&a) 2


a a
&pppa &ppa &pa &a &pppa &ppa &pa &a

&pa ***pppa = **ppa + *pa + a ; &pa ***pppa = **ppa + *pa + a ;


&ppa &a 2 &ppa &a 2

Fabien Calcado ISTY– IATIC3 - 2020/2021 19 Fabien Calcado ISTY– IATIC3 - 2020/2021 20

5
Les pointeurs Les pointeurs
Les indirections multiples Les indirections multiples
– Un pointeur peut stocker l’adresse d’un autre pointeur – Un pointeur peut stocker l’adresse d’un autre pointeur
• Un déréférencement « * » annule une référence « & » • Un déréférencement « * » annule une référence « & »
int a = 2 ; a a int a = 2 ; a a
int * pa = &a ; int * pa = &a ;
int ** ppa = &pa ; int ** ppa = &pa ;
*(*(ppa))) *(pa) *(*(ppa))) *(pa)
int *** pppa = &ppa ; int *** pppa = &ppa ;

***ppa = **pa + *pa + a ; *(*(*(&ppa))) *(*(&pa)) a ***ppa = **pa + *pa + a ; *(*(*(&ppa))) *(*(&pa)) a

pppa ppa pa *(*(*(pppa))) *(*(ppa)) *(&a) 2 pppa ppa pa *(*(*(pppa))) *(*(ppa)) *(&a) 2
a a
&pppa &ppa &pa &a &pppa &ppa &pa &a

&pa ***pppa = **ppa + *pa + a ; &pa ***pppa = **ppa + *pa + a ;


&ppa &a 2 &ppa &a 2
6
a = a + a + a
2 + 2 + 2

Fabien Calcado ISTY– IATIC3 - 2020/2021 21 Fabien Calcado ISTY– IATIC3 - 2020/2021 22

Les pointeurs Les pointeurs


Passage par copie de référence Passage par copie de référence
– Perm et à une fonction d’avoir un effet de bord – Perm et à une fonction d’avoir un effet de bord
• Modification d’une variable en dehors de son environnement local • Modification d’une variable en dehors de son environnement local
v oid f ct( int a , int* p) ; Env. du main Env. de fct v oid f ct( int a , int* p) ; Env. du main Env. de fct

int main(v oid) { a b int main(v oid) { a b a p


int a=1, b=2; &a &b int a=1, b=2; &a &b &a &p
f ct( a , &b) ; f ct( a , &b) ;
printf (" a=%d, b=%d \n", a, b); 1 2 printf (" a=%d, b=%d \n", a, b); 1 2
return 0; return 0;
} }

v oid f ct( int a , int* p) { v oid f ct( int a , int* p) {


a = 3; a = 3;
*p = a + 1; Création des variables locales du main *p = a + 1; 1) Création des paramètres de la fonction
return; return; variables locales à l’environnement fct
} }
Fabien Calcado ISTY– IATIC3 - 2020/2021 23 Fabien Calcado ISTY– IATIC3 - 2020/2021 24

6
Les pointeurs Les pointeurs
Passage par copie de référence Passage par copie de référence
– Perm et à une fonction d’avoir un effet de bord – Perm et à une fonction d’avoir un effet de bord
• Modification d’une variable en dehors de son environnement local • Modification d’une variable en dehors de son environnement local
v oid f ct( int a , int* p) ; Env. du main Env. de fct v oid f ct( int a , int* p) ; Env. du main Env. de fct
int main(v oid) { a b a p int main(v oid) { a b a p
&a &b &a &p &a &b &a &p
int a=1, b=2; int a=1, b=2;
f ct( a , &b) ; f ct( a , &b) ;
printf (" a=%d, b=%d \n", a, b); 1 2 1 &b printf (" a=%d, b=%d \n", a, b); 1 2 1 &b
return 0; return 0;
} Copie de argument 2 dans paramètre 2
}

v oid f ct( int a , int* p) { Copie de argument 1 dans paramètre 1 v oid f ct( int a , int* p) {
a = 3; a = 3; 3) Exécution du corps de la fonction :
*p = a + 1; 2) Passage par copie : *p = a + 1; - 2 variables dans des environnements différents portant
return; Valeur de « a » (main) copiée dans « a » (fct) return; le même identificateur « a » Adresses différentes
} Valeur « adresse de b » (main) copiée dans « p » (fct) } - « p » pointe sur une variable d’un autre environnement

Fabien Calcado ISTY– IATIC3 - 2020/2021 25 Fabien Calcado ISTY– IATIC3 - 2020/2021 26

Les pointeurs Les pointeurs


Passage par copie de référence Passage par copie de référence
– Perm et à une fonction d’avoir un effet de bord – Perm et à une fonction d’avoir un effet de bord
• Modification d’une variable en dehors de son environnement local • Modification d’une variable en dehors de son environnement local
v oid f ct( int a , int* p) ; Env. du main Env. de fct v oid f ct( int a , int* p) ; Env. du main Env. de fct

int main(v oid) { a b a p int main(v oid) { a b a p


&a &b &a &p &a &b &a &p
int a=1, b=2; int a=1, b=2;
f ct( a , &b) ; f ct( a , &b) ;
printf (" a=%d, b=%d \n", a, b); 1 2 3 &b printf (" a=%d, b=%d \n", a, b); 1 2 3 &b
return 0; return 0;
} }

v oid f ct( int a , int* p) { v oid f ct( int a , int* p) {


a = 3; 3) Exécution du corps de la fonction : a = 3; 3) Exécution du corps de la fonction :
*p = a + 1; Modif. de « a » par adressage direct (environnement fct) *p = a + 1;
Accès à « a » par adressage direct (environnement fct)
return; return;
Pas d’effet de bord sur le main expression « a + 1 » vaut 4
} }
Fabien Calcado ISTY– IATIC3 - 2020/2021 27 Fabien Calcado ISTY– IATIC3 - 2020/2021 28

7
Les pointeurs Les pointeurs
Passage par copie de référence Passage par copie de référence
– Perm et à une fonction d’avoir un effet de bord – Perm et à une fonction d’avoir un effet de bord
• Modification d’une variable en dehors de son environnement local • Modification d’une variable en dehors de son environnement local
v oid f ct( int a , int* p) ; Env. du main Env. de fct v oid f ct( int a , int* p) ; Env. du main Env. de fct
int main(v oid) { a b a p int main(v oid) { a b a p
&a &b &a &p int a=1, b=2; &a &b &a &p
int a=1, b=2;
f ct( a , &b) ; f ct( a , &b) ;
printf (" a=%d, b=%d \n", a, b); 1 4 3 &b printf (" a=%d, b=%d \n", a, b); 1 4 3 &b
return 0; return 0;
} }

v oid f ct( int a , int* p) { v oid f ct( int a , int* p) {


a = 3; 3) Exécution du corps de la fonction : a = 3; 4) Destruction des variables locales de la fonction
*p = a + 1; Accès à la case pointée par « p » (adressage indirect) *p = a + 1;
return; Modification de « b » du main return;
} Effet de bord de la fonction sur « b » (main) }

Fabien Calcado ISTY– IATIC3 - 2020/2021 29 Fabien Calcado ISTY– IATIC3 - 2020/2021 30

Les pointeurs Les pointeurs


Passage par copie de référence
Erreur fréquente
– Perm et à une fonction d’avoir un effet de bord
• Modification d’une variable en dehors de son environnement local – Renvoyer l’adresse d’une variable locale à la fonction
int * fct( int a , int b) ;
v oid f ct( int a , int* p) ; Env. du main Env. de fct Env. du main Env. de fct
int main(void) {
int main(v oid) { a b int a=1, b=2; a b res
int a=1, b=2; &a &b &a &b &res
int * res = NULL;
f ct( a , &b) ; res = fct( a , b) ;
printf (" a=%d, b=%d \n", a, b); 1 4 printf(" res = %p \n", res); 1 2 NULL
return 0; printf(" *res = %d \n", *res);
} return 0;
}
v oid f ct( int a , int* p) {
int fct( int a , int b) {
a = 3;
int res;
*p = a + 1; a=1, b=4 res = a + b; Création des variables locales du main
return; return &res;
Effet de bord de la fonction sur « b » uniquement
} }

Fabien Calcado ISTY– IATIC3 - 2020/2021 31 Fabien Calcado ISTY– IATIC3 - 2020/2021 32

8
Les pointeurs Les pointeurs

Erreur fréquente Erreur fréquente


– Renvoyer l’adresse d’une variable locale à la fonction – Renvoyer l’adresse d’une variable locale à la fonction
int * fct( int a , int* p) ; int * fct( int a , int* p) ;
Env. du main Env. de fct Env. du main Env. de fct
int main(void) { int main(void) {
int a=1, b=2; a b res a b int a=1, b=2; a b res a b res
&a &b &res &a &b &a &b &res &a &b &res
int * res = NULL; int * res = NULL;
res = fct( a , b) ; res = fct( a , b) ;
printf(" res = %p \n", res); 1 2 NULL 1 2 printf(" res = %p \n", res); 1 2 NULL 1 2 ?
printf(" *res = %d \n", *res); printf(" *res = %d \n", *res);
return 0; return 0;
} }

int fct( int a , int b) { int fct( int a , int b) {


int res; int res;
res = a + b; Appel à « fct » : res = a + b; Création des variables locales (hors paramètres)
return &res; Création des paramètres passage par copie return &res;
} }

Fabien Calcado ISTY– IATIC3 - 2020/2021 33 Fabien Calcado ISTY– IATIC3 - 2020/2021 34

Les pointeurs Les pointeurs

Erreur fréquente Erreur fréquente


– Renvoyer l’adresse d’une variable locale à la fonction – Renvoyer l’adresse d’une variable locale à la fonction
int * fct( int a , int* p) ; int * fct( int a , int* p) ;
Env. du main Env. de fct Env. du main Env. de fct
int main(void) { int main(void) {
int a=1, b=2; a b res a b res int a=1, b=2; a b res a b res
&a &b &res &a &b &res &a &b &res &a &b &res
int * res = NULL; int * res = NULL;
res = fct( a , b) ; res = fct( a , b) ;
printf(" res = %p \n", res); 1 2 NULL 1 2 3 printf(" res = %p \n", res); 1 2 &res 1 2 3
printf(" *res = %d \n", *res); printf(" *res = %d \n", *res);
return 0; return 0;
} }

int fct( int a , int b) { int fct( int a , int b) {


Fin d’appel à « fct » :
int res; int res;
1) Retourne l’adresse de « res » de la fonction fct
res = a + b; res = a + b;
return &res; return &res; Le pointeur « res » du main pointe sur
} } la variable « res » de fct

Fabien Calcado ISTY– IATIC3 - 2020/2021 35 Fabien Calcado ISTY– IATIC3 - 2020/2021 36

9
Les pointeurs Les pointeurs

Erreur fréquente Erreur fréquente


– Renvoyer l’adresse d’une variable locale à la fonction – Renvoyer l’adresse d’une variable locale à la fonction
int * fct( int a , int* p) ; int * fct( int a , int* p) ;
Env. du main Env. de fct Env. du main Env. de fct
int main(void) { int main(void) {
int a=1, b=2; a b res a b res int a=1, b=2; a b res
&a &b &res &a &b &res &a &b &res 0xF4A1
int * res = NULL; int * res = NULL;
res = fct( a , b) ; res = fct( a , b) ;
printf(" res = %p \n", res); 1 2 &res 1 2 3 printf(" res = %p \n", res); 1 2 0xF4A1
printf(" *res = %d \n", *res); printf(" *res = %d \n", *res);
return 0; return 0;
} }

int fct( int a , int b) { Fin d’appel à « fct » : int fct( int a , int b) {
int res; int res; On suppose que la valeur de « res » vaut 0xF4A1
2) Destruction des variables locales
res = a + b; res = a + b; Adressage direct sur « res » ok
return &res; Le pointeur « res » du main pointe sur une return &res;
Adressage indirect sur « res » erreur de segmentation
} variable qui n’est plus accessible… }

Fabien Calcado ISTY– IATIC3 - 2020/2021 37 Fabien Calcado ISTY– IATIC3 - 2020/2021 38

Les pointeurs Les pointeurs


En résumé
Tableau statique et pointeur – Un pointeur est une variable
– Tableau statique est un pointeur constant • Valeur : adresse d’une (autre) variable du programme
• Qualificatif « const » : lecture seule (pas de modification autorisée) » La variable pointée doit exister et n’est pas « créée » à la déclaration
» int tab[4] « tab » est de ty pe « const int * » » Valeur d’un pointeur non valide : « NULL » (dans stdlib.h)
» Affichage : format « % p »
• Ecriture équivalente de l’opérateur « [ ] »
– Opérateurs liés aux pointeurs
» Cf . cours sur les tableaux : décalage par rapport à l’adresse de début
» Ecriture équiv alente : tab[3] *(tab + 3) • « & » : opérateur « adresse de » ou « référence à » une variable
• « * » : opérateur « indirection » ou « déréférencement »
* (tab + 3) » Annule un opérateur de référencement
» Indirection d’pointeur non valide erreur de segmentation
&tab[ 0 ] Contenu de « &tab[ 0 ] + 3 »
» Indirections multiples : pointeur de pointeur
tab – Fonction et pointeur
• Une adresse passée en argument peut permettre à une fonction
&tab[0] 1 3 5 0
d’avoir un effet de bord
• Ne jamais renvoyer l’adresse d’une variable locale
Fabien Calcado ISTY– IATIC3 - 2020/2021 39 Fabien Calcado ISTY– IATIC3 - 2020/2021 40

10

Vous aimerez peut-être aussi