Cours de Programmation Impérative: Zones de mémoires et pointeurs Julien David A101 - david@lipn.univ-paris13.fr Julien David (A101 - david@lipn.univ-paris13.fr) 1 / 1
Z`o n`e s `d`e m`é m`o i r`e Julien David (A101 - david@lipn.univ-paris13.fr) 2 / 1
Zones de mémoire Pile d appel Variables locales, information sur les fonctions Tas Allocation dynamique Zone de données Variables Globales et statiques Zone texte Contenu des fonctions Julien David (A101 - david@lipn.univ-paris13.fr) 3 / 1
Zone texte Rappel Un fichier exécutable contient déjà : Une zone correspondant aux variables globales et statiques. Une zone correspondant à l ensemble des fonctions décrit dans le programme. À l exécution du programme L ensemble des fonctions est chargée en mémoire dans la zone texte. Chaque instruction de chaque fonction possède une adresse propre en mémoire. Zone texte Cette zone est en lecture seule. Sa taille est donc déterminée avant l exécution. Julien David (A101 - david@lipn.univ-paris13.fr) 4 / 1
Zone texte Rappel Un fichier exécutable contient déjà : Une zone correspondant aux variables globales et statiques. Une zone correspondant à l ensemble des fonctions décrit dans le programme. À l exécution du programme L ensemble des fonctions est chargée en mémoire dans la zone texte. Chaque instruction de chaque fonction possède une adresse propre en mémoire. Zone texte Cette zone est en lecture seule. Sa taille est donc déterminée avant l exécution. Julien David (A101 - david@lipn.univ-paris13.fr) 4 / 1
Zone texte Rappel Un fichier exécutable contient déjà : Une zone correspondant aux variables globales et statiques. Une zone correspondant à l ensemble des fonctions décrit dans le programme. À l exécution du programme L ensemble des fonctions est chargée en mémoire dans la zone texte. Chaque instruction de chaque fonction possède une adresse propre en mémoire. Zone texte Cette zone est en lecture seule. Sa taille est donc déterminée avant l exécution. Julien David (A101 - david@lipn.univ-paris13.fr) 4 / 1
Zone de données À l exécution du programme La zone de données de l exécutable est recopié dans la mémoire. La taille de cette zone est déterminée avant l exécution. Accès permanent Les variables dans la zone de donnée sont accessibles durant toute la durée du programme. L utilisation de la mémoire n est donc pas optimisée. Julien David (A101 - david@lipn.univ-paris13.fr) 5 / 1
Pile d appel Caractérisation La pile d appel permet de : stocker les variables locales, stocker les paramètres des fonctions, sauver des informations sur les appels de fonctions. Précision Dans ce cours on représente les appels de fonctions avec une zone grisée dans la pile. Cette zone contient des informations permettant, à la fin d une fonction, de dépiler la pile, de revenir à la ligne de l instruction qui a provoqué l appel de fonction. Julien David (A101 - david@lipn.univ-paris13.fr) 6 / 1
Les limites de la pile d appel Limites La taille de la pile Les limites d accès des variables locales Julien David (A101 - david@lipn.univ-paris13.fr) 7 / 1
Les limites de la pile d appel La taille de la pile La pile a une taille limitée. À chaque appel de fonction, on ajoute des informations dans la pile. Si un programme effectue trop d appels imbriqués, la pile déborde. Julien David (A101 - david@lipn.univ-paris13.fr) 8 / 1
Les limites de la pile d appel Les limites d accès des variables locales Avec nos connaissances actuelles : Il n est pas possible de modifier une variable locale d une fonction A avec une fonction B. Exception faite du résultat de la fonction B. Exemple Essayons d écrire une fonction qui échange la valeur de deux variables. Julien David (A101 - david@lipn.univ-paris13.fr) 9 / 1
1 void swap ( i n t x, i n t y ){ 2 i n t tmp=x ; 3 x=y ; 4 y=tmp ; 5 } 6 i n t ( ) { 7 i n t x =5; 8 i n t y =7; 9 swap ( x, y ) ; 0 return EXIT SUCCESS ; 1 } y 7 84 x 5 80 tmp 5 94 tmp 5 94 y 7 94 y 5 94 x 5 90 x 7 90 y 7 84 swap(7,5) swap(7,5) x 5 80 y 7 84 y 7 84 x 5 80 x 5 80 Julien David (A101 - david@lipn.univ-paris13.fr) 10 / 1
1 void swap ( i n t x, i n t y ){ 2 i n t tmp=x ; 3 x=y ; 4 y=tmp ; 5 } 6 i n t ( ) { 7 i n t x =5; 8 i n t y =7; 9 swap ( x, y ) ; 0 return EXIT SUCCESS ; 1 } y 7 84 x 5 80 tmp 5 94 tmp 5 94 y 7 94 y 5 94 x 5 90 x 7 90 y 7 84 swap(7,5) swap(7,5) x 5 80 y 7 84 y 7 84 x 5 80 x 5 80 Julien David (A101 - david@lipn.univ-paris13.fr) 10 / 1
Constat Notre accès à la mémoire est pour l instant très limité. Une fonction ne peut accéder qu à ses propres variables locales ou à des variables de la zone de données. Julien David (A101 - david@lipn.univ-paris13.fr) 11 / 1
L`e s p`o i n t eˇu r s Julien David (A101 - david@lipn.univ-paris13.fr) 12 / 1
Pointeurs Rappel Une variable est caractérisé par : son nom son type sa valeur son adresse Adresse d une variable Soit une variable int x; Pour accéder à l adresse de x, on écrit : &x Julien David (A101 - david@lipn.univ-paris13.fr) 13 / 1
Pointeurs Les pointeurs Un pointeur est une variable dont la valeur est une adresse. Si un pointeur contient l adresse d une variable, on dit qu il pointe sur elle. Le type d un pointeur est le type des variables sur lesquelles il peut pointer. Pour faire quoi? En stockant l adresse d autres variables, on va pouvoir accéder n importe qu elle zone de la mémoire. Julien David (A101 - david@lipn.univ-paris13.fr) 14 / 1
Pointeurs Les pointeurs Un pointeur est une variable dont la valeur est une adresse. Si un pointeur contient l adresse d une variable, on dit qu il pointe sur elle. Le type d un pointeur est le type des variables sur lesquelles il peut pointer. Pour faire quoi? En stockant l adresse d autres variables, on va pouvoir accéder n importe qu elle zone de la mémoire. Julien David (A101 - david@lipn.univ-paris13.fr) 14 / 1
Pointeurs Les pointeurs Un pointeur est une variable dont la valeur est une adresse. Si un pointeur contient l adresse d une variable, on dit qu il pointe sur elle. Le type d un pointeur est le type des variables sur lesquelles il peut pointer. Pour faire quoi? En stockant l adresse d autres variables, on va pouvoir accéder n importe qu elle zone de la mémoire. Julien David (A101 - david@lipn.univ-paris13.fr) 14 / 1
Pointeurs Déclaration int * p; Nom : p Type : pointeur sur un entier (int *) char * c; Nom : c Type : pointeur sur un caractère (char c) Utilisation Soit un pointeur int * z Pour accéder à la case pointée par z, on écrit *z Julien David (A101 - david@lipn.univ-paris13.fr) 15 / 1
Pointeurs 1 i n t ( ) { 2 i n t z =6; 3 i n t p=&z ; 4 p r i n t f ( %d\n, p ) ; 5 return EXIT SUCCESS ; 6 } p 80 84 z 6 80 Le programme affiche 6 Julien David (A101 - david@lipn.univ-paris13.fr) 16 / 1
Initialisation d un pointeur Initialisation Comme toute variable, un pointeur doit être initialisé. Si un pointeur n est pas initialisé, il peut contenir une adresse quelconque et tenter d accéder à la variable correspondante peut avoir de grave conséquence. Ne pointer vers rien Soit un pointeur p. Pour exprimer qu un pointeur ne pointe vers aucune variable, on écrit : p=null; Cette instruction est valable, quelque soit le type du pointeur. Julien David (A101 - david@lipn.univ-paris13.fr) 17 / 1
Incrémenter un pointeur Incrémenter un pointeur Soit un pointeur p. Lorsque l on écrit p+1, cela signifie l adresse contenu dans p + la taille d une case du type de p Exemple Supposons que p contient l adresse 80 Si p pointe vers un type int, alors p+1=84 Si p pointe vers un char, alors p+1=81 Si p pointe vers un double, alors p+1=88 Julien David (A101 - david@lipn.univ-paris13.fr) 18 / 1
Incrémenter un pointeur 1 i n t ( ) { 2 i n t x =17; 3 i n t y =23; 4 i n t p=&x ; 5 p r i n t f ( %d\n, p ) ; 6 p=p+1; 7 p r i n t f ( %d\n, p ) ; 8 return EXIT SUCCESS ; 9 } p 80 88 y 23 84 x 17 80 Ligne 5 : Affiche 17 p 84 88 y 23 84 x 17 80 Ligne 7 : Affiche 23 Julien David (A101 - david@lipn.univ-paris13.fr) 19 / 1
Pointeurs Échange On peut à présent réécrire la fonction swap Julien David (A101 - david@lipn.univ-paris13.fr) 20 / 1
1 void swap ( i n t x, i n t y ){ 2 i n t tmp= x ; 3 x= y ; 4 y=tmp ; 5 } 6 i n t ( ) { 7 i n t x =5; 8 i n t y =7; 9 swap(&x,& y ) ; 0 return EXIT SUCCESS ; 1 } y 7 84 x 5 80 tmp 5 94 tmp 5 94 y 84 94 x 80 90 swap(80,84) y 7 84 y 84 94 x 80 90 swap(80,84) y 5 84 y 5 84 x 7 80 x 5 80 x 7 80 Julien David (A101 - david@lipn.univ-paris13.fr) 21 / 1
1 void swap ( i n t x, i n t y ){ 2 i n t tmp= x ; 3 x= y ; 4 y=tmp ; 5 } 6 i n t ( ) { 7 i n t x =5; 8 i n t y =7; 9 swap(&x,& y ) ; 0 return EXIT SUCCESS ; 1 } y 7 84 x 5 80 tmp 5 94 tmp 5 94 y 84 94 x 80 90 swap(80,84) y 7 84 y 84 94 x 80 90 swap(80,84) y 5 84 y 5 84 x 7 80 x 5 80 x 7 80 Julien David (A101 - david@lipn.univ-paris13.fr) 21 / 1
Question Question Ecrire la fonction void ajouter(int * p,int val) qui ajoute la valeur de val à la variable pointée par p. Julien David (A101 - david@lipn.univ-paris13.fr) 22 / 1
P`o i n t eˇu r s `eˇt sfi tˇr u`cˇtˇu r`e s Julien David (A101 - david@lipn.univ-paris13.fr) 23 / 1
Pointeurs et structures Pointeurs et structures Un pointeur peut contenir l adresse d un type scalaire comme d un type structuré. Pointeurs sur point t Déclaration du pointeur : point t * p; Julien David (A101 - david@lipn.univ-paris13.fr) 24 / 1
Pointeurs et structures 1 / point. h / 2 s t r u c t p o i n t s { 3 i n t x ; 4 i n t y ; 5 }; 6 typedef s t r u c t p o i n t s p o i n t t ; Accès aux champs de la strucure Soit le pointeur : point t * p; Accès au champ x. soit (*p).x soit p->x Julien David (A101 - david@lipn.univ-paris13.fr) 25 / 1
Pointeurs et structures 1 void copie ( p o i n t t src, p o i n t t dest ){ 2 dest >x=src. x ; 3 dest >y=src. y ; 4 } 5 6 i n t ( ) { 7 p o i n t t p1={1,2}; 8 p o i n t t p2 ; 9 copie ( p1,&p2 ) ; 0 return EXIT SUCCESS ; 1 } p2.y? 88 p2.x? 88 p1.y 2 84 p1.x 1 80 Initialisation Julien David (A101 - david@lipn.univ-paris13.fr) 26 / 1
Pointeurs et structures dest 88 108 src.y 2 104 1 void copie ( p o i n t t src, p o i n t t dest ){ 2 dest >x=src. x ; 3 dest >y=src. y ; 4 } 5 6 i n t ( ) { 7 p o i n t t p1={1,2}; 8 p o i n t t p2 ; 9 copie ( p1,&p2 ) ; 0 return EXIT SUCCESS ; 1 } src.x 1 100 copie({1,2},88) p2.y? 92 p2.x? 88 p1.y 2 84 p1.x 1 80 Appel à copie Julien David (A101 - david@lipn.univ-paris13.fr) 27 / 1
Pointeurs et structures dest 88 108 1 void copie ( p o i n t t src, p o i n t t dest ){ 2 dest >x=src. x ; 3 dest >y=src. y ; 4 } 5 6 i n t ( ) { 7 p o i n t t p1={1,2}; 8 p o i n t t p2 ; 9 copie ( p1,&p2 ) ; 0 return EXIT SUCCESS ; 1 } src.y 2 104 src.x 1 100 copie({1,2},88) p2.y 2 92 p2.x 1 88 p1.y 2 84 p1.x 1 80 Julien David (A101 - david@lipn.univ-paris13.fr) 28 / 1
Pointeurs et structures 1 void copie ( p o i n t t src, p o i n t t dest ){ 2 dest >x=src. x ; 3 dest >y=src. y ; 4 } 5 6 i n t ( ) { 7 p o i n t t p1={1,2}; 8 p o i n t t p2 ; 9 copie ( p1,&p2 ) ; 0 return EXIT SUCCESS ; 1 } p2.y 2 92 p2.x 1 88 p1.y 2 84 p1.x 1 80 On dépile Julien David (A101 - david@lipn.univ-paris13.fr) 29 / 1
P`o i n t eˇu r s, t ãb l e åu x `eˇt f o n`cˇtˇi`o n s Julien David (A101 - david@lipn.univ-paris13.fr) 30 / 1
Fonctions avec tableaux en arguments 1 i n t i n i t t a b ( i n t tab [ ], i n t n){ i n t ( ) { 2 i n t i ; i n t tab [ 3 ] ; 3 f o r ( i =0; i<n ; i ++) i n i t t a b ( tab, 3 ) ; 4 tab [ i ] = 0 ; r e t u r n EXIT SUCCESS ; 5 } } i? 108 i 0,1,2,3 108 n 3 104 tab 80 100 init tab(80,3) tab[2]? 88 tab[1]? 84 tab[0]? 80 n 3 104 tab 80 100 init tab(80,3) tab[2] 0 88 tab[1] 0 84 tab[0] 0 80 tab[2] 0 88 tab[1] 0 84 tab[0] 0 80 On dépile Julien David (A101 - david@lipn.univ-paris13.fr) 31 / 1
Fonctions avec tableaux en arguments 1 i n t i n i t t a b ( i n t tab [ ], i n t n){ i n t ( ) { 2 i n t i ; i n t tab [ 3 ] ; 3 f o r ( i =0; i<n ; i ++) i n i t t a b ( tab, 3 ) ; 4 tab [ i ] = 0 ; r e t u r n EXIT SUCCESS ; 5 } } i? 108 i 0,1,2,3 108 n 3 104 tab 80 100 init tab(80,3) tab[2]? 88 tab[1]? 84 tab[0]? 80 n 3 104 tab 80 100 init tab(80,3) tab[2] 0 88 tab[1] 0 84 tab[0] 0 80 tab[2] 0 88 tab[1] 0 84 tab[0] 0 80 On dépile Julien David (A101 - david@lipn.univ-paris13.fr) 31 / 1
Tableaux et pointeurs Twist hollywoodien Un tableau de type est en réalité un pointeur vers type. Déclaration de fonctions Il est identique d écrire : void init tab(int tab[],int n) et void init tab(int * tab,int n) Les petites différences Déclaration d un tableaux. La fonction sizeof L opérateur & Julien David (A101 - david@lipn.univ-paris13.fr) 32 / 1
Question Qu affiche ce programme? 1 i n t ( ) { 2 i n t t a b l e [3]={4,2,3}; 3 i n t p= t a b l e ; 4 i n t i ; 5 f o r ( i =0; i <3; i ++){ 6 p r i n t f ( %d\n, (p+ i ) ) ; 7 } 8 return EXIT SUCCESS ; 9 } Julien David (A101 - david@lipn.univ-paris13.fr) 33 / 1
Opérations sur la tableaux Opération Lorsque l on accède à la case i d un tableau tab tab[i] On effectue en réalité la commande suivante : *(tab+i) Julien David (A101 - david@lipn.univ-paris13.fr) 34 / 1
Au prochain TD On s entrainera à Écrire des fonctions qui manipulent : des structures, des pointeurs sur des structures, des tableaux. Le tout avec une petite couche de pile d appel. Julien David (A101 - david@lipn.univ-paris13.fr) 35 / 1
Zones de mémoire Pile d appel Tas À quoi sert cette zone? Zone de données Zone texte Julien David (A101 - david@lipn.univ-paris13.fr) 36 / 1