Pointeurs en C PDF
Document Details
Uploaded by Deleted User
Tags
Summary
Ce document présente les pointeurs en langage C. Il explique leur utilisation en détail, notamment leur rôle dans les structures de données dynamiques et comment modifier les valeurs. Différents exemples sont fournis pour en illustrer l'application.
Full Transcript
Les Pointeurs en C ◼ La déclaration de pointeurs ◼ Valeurs pointées et adresses ◼ Passage de paramètres de fonction par référence ◼ Pointeurs et tableaux 1 Les pointeurs, c'est quoi? Un pointeur est une variable partic...
Les Pointeurs en C ◼ La déclaration de pointeurs ◼ Valeurs pointées et adresses ◼ Passage de paramètres de fonction par référence ◼ Pointeurs et tableaux 1 Les pointeurs, c'est quoi? Un pointeur est une variable particulière, dont la valeur est l'adresse d'une autre variable. ◼ Pointeur p: valeur 5A0F3 (adresse hexadécimale) ◼ Adresse 5A0F3: valeur 17 (correspondant à la valeur d'un entier i) En accédant à cette adresse, on peut accéder indirectement à la variable et donc la modifier. i=17 5A0F3 17 p=5A0F3 p i Un pointeur est une adresse mémoire. On dit que le pointeur p pointe vers i, puisque p pointe vers l’emplacement mémoire où est enregistrée i. 2 Les pointeurs: pourquoi ? ◼ Les pointeurs sont nécessaires pour: ◆ effectuer les appels par référence (i.e. écrire des fonctions qui modifient certains de leurs paramètres) ◆ manipuler des structures de données dynamiques (liste, pile, arbre,…) ◆ allouer dynamiquement de la place mémoire 3 Déclaration de Pointeurs Le symbole * est utilisé entre le type et le nom du pointeur ◼ Déclaration d’un entier: int i; ▪ Déclaration d’un pointeur vers un entier: int *p; Exemples de déclarations de pointeurs int *pi; float *pf; char c, d, *pc; double *pd, e, f; double **tab; 4 Opérateurs unaires pour manipuler les pointeurs, & (adresse de) et * (contenu) Exemple: int i = 8; printf("VOICI i: %d\n",i); printf("VOICI SON ADRESSE EN HEXADECIMAL: %p\n",&i); nom_de_Pointeur = &nom_de_variable void main(void) p c { 0x1132 'a' char c = 'a', d = 'z'; 0x1132 char *p; p d 0x91A2 'z' *p = c; 0x91A2 p = &c; printf("%c\n", *p); p = &d; L’opérateur * (“valeur pointée par”) printf("%c\n", *p); } a z 5 #include void main() { int *p, x, y; p = &x; x = 10; y = *p - 1; printf(" y= *p - 1 =? = %d\n" , y); y vaut ? *p += 1; printf(" *p += 1 =? *p = x= ? = %d %d\n" , *p, x); x vaut ? (*p)++; printf(" (*p)++ =? *p = x= ? = %d %d alors y=%d \n" , *p, x, y); incrémente aussi de 1 la variable pointée par p, donc x vaut ??. y vaut 9 *p=0; printf(" *p=0 x=? = %d\n" , x); comme p pointe sur x, maintenant x vaut ? *p++; *p=20; printf(" *p++ x=? = %d\n" , x); } comme p ne pointe plus sur x, x vaut tjr ? 6 Utiliser des pointeurs ◼ On peut donc accéder aux éléments par pointeurs en faisant des calculs d’adresses (addition ou soustraction) long v = { 1,2, 3,4,5,6 }; long *p; p += 4 p++ p = v; printf("%ld\n", *p); 1 p p++; 2 printf("%ld\n", *p); 6 1000 1 2 3 4 5 6 v p += 4; 1000 1008 1016 printf("%ld\n", *p); 1004 1012 1020 7 Passage des paramètres par valeur et par adresse Syntaxe qui conduit à une erreur: Syntaxe correcte: a et b: #include variables #include locales à void ech(int x,int y) void ech(int *x,int *y) { main(). La { int tampon; fonction ech int tampon; tampon = x; ne peut donc tampon = *x; x = y; pas modifier *x = *y; y = tampon; leur valeur. *y = tampon; } On le fait } donc en void main() void main() passant par { { int a = 5 , b = 8; l'adresse de int a = 5 , b = 8 ; ech(a,b); ces variables. ech(&a,&b); printf(“ a=%d\n ”, a) ; a = ? printf(“ a=%d\n ”, a) ; a=? printf(“ b=%d\n ”, b) ; b=? printf(“ b=%d\n ”, b) ; b=? } } PASSAGE DES PARAMETRES PASSAGE DES PARAMETRES PAR VALEUR PAR ADRESSE 8 Passage de paramètres de fonction par référence ou adresse ◼ Quand on veut modifier la valeur d'un paramètre dans une fonction, il faut passer ce paramètre par référence ou adresse ◼ En C, cela se fait par pointeur void change ( int *a, int *b) { int tmp; tmp = *a; *a = *b; *b = tmp; } 9 Appel des fonctions par référence #include void change(int* p); void main(void) { int var = 5; change(&var); printf("main: var = %d\n",var); } ! void change(int* p) { *p *= 100; printf("change: *p = %d\n",*p); } change: *p = 500 main: var = 500 10 #include void somme(int , int , int *); int modif(int , int *, int *); void main(){ int a, b, c; a = 2; b = 8; somme(a, b, &c); Somme de a=? et b=? : ? printf("Somme de a=%d et b=%d : %d\n",a, b, c); a = modif(a, &b, &c); printf(" Modif : a=%d , b=%d et c= %d\n",a, b, c); } Modif : a=?, b=? et c= ? void somme(int x, int y, int *z){ *z = x + y; } int modif(int x, int *y, int *z){ x *= 2; *y= x+ *y; *z= 5; return x; } 11 Identification des tableaux et pointeurs ◼ En C, le nom d’un tableau représente l’adresse de sa composante 0, donc a == &a ◼ C'est pour cela que les tableaux passés comme paramètres dans une fonction sont modifiables Passer des tableaux aux fonctions ◼ Pour le compilateur, un tableau comme argument de fonction, c’est un pointeur vers sa composante 0 (à la réservation mémoire près). ◼ La fonction peut donc modifier n’importe quel élément (passage par référence) ◼ Le paramètre peut soit être déclaré comme tableau, soit comme pointeur int add_elements(int a[], int size) int add_elements(int *p, int size) { { 12 Exemple #include Tab Tab void sum(long [], int); 1 29 int main(void) { 2 2 long Tab = { 1, 2, 3 3 3, 5, 7, 11 }; 5 5 sum(Tab, 6); printf("%ld\n", Tab); 7 7 return 0; 11 11 } a void sum(long a[], int sz) { sz 6 int i; long total = 0; for(i = 0; i < sz; i++) total += a[i]; a = total; } 13 Utiliser des pointeurs - exemple #include long sum(long*, int); Tab Tab int main(void) 1 1000 1 { long Tab = { 1, 2, 2 1004 2 3, 5, 7, 11 }; 3 1008 3 printf("%ld\n", sum(Tab, 6)); 5 1012 5 return 0; } 7 1016 7 long sum(long *p, int sz) 11 1020 11 { long *end = p + sz; 1024 long total = 0; p while(p < end) 1000 total += *p++; end 1024 return total; } 14 Quelle notation? ◼ A est équivalent à *A ◼ A[i] est équivalent à *(A + i) ◼ &A est équivalent à A short a = { 10, 20, 30, 40, 50, 60, 70, 80 }; short *p = a; printf("%d\n", a); 40 printf("%d\n", *(a + 3)); 40 printf("%d\n", *(p + 3)); 40 printf("%d\n", p); 40 p a 1000 10 20 30 40 50 60 70 80 1000 1004 1008 1012 1002 1006 1010 1014 15