Les pointeurs Suite
Pointeurs Un pointeur, c’est une variable dont la valeur est l'adresse d'une cellule de la mémoire Traduction : Imaginons que la mémoire de l’ordinateur, c’est un grand tableau. Un pointeur, c’est alors une variable de type int (un nombre) qui permet de se souvenir d’une case particulière. On comprend bien que le pointeur ne se soucis pas de savoir ce qu’il y a dans la case, mais bien de l’adresse de la case.
Qu’est ce que ça change? Un pointeur est une adresse On sépare le contenu (une valeur) du contenant (une adresse) On a l’adresse de quelque chose, et on peut le partager : Imaginons deux pointeurs a et b pointant sur la 10ème case Imaginons que l’utilisateur modifie (avec un cin par exemple) la 10ème case. a et b peuvent détecter cette modification en allant voir à la 10ème case !
Syntaxe Déclaration : * type *idPtr; Nom de la variable Ce petit signe indique que l’on ne travaille plus sur une variable normale, mais sur un pointeur Le type peut être un type simple (int, float…) ou un objet (n’importe quelle classe).
Syntaxe Opérateur d’adresse : & cout<<&idVar; Nom d’une variable de n’importe quel type Ce petit signe indique que l’on veux récupérer l’adresse d’une variable Plutôt que d’afficher la valeur de la variable, on affiche l’adresse de la case mémoire
Syntaxe Opérateur de déréférencement : * cout<<*ptr; Nom d’un pointeur Ce petit signe indique que l’on veux récupérer la valeur située à une adresse précise Plutôt que d’afficher l’adresse du pointeur, on affiche la valeur qui est dans la case mémoire
Syntaxe Exemple : char c = ‘a’; char *p; p=&c; cout << *p; On déclare une variable normale de type caractère Exemple : char c = ‘a’; char *p; p=&c; cout << *p; On déclare un pointeur sur une case de type caractère On donne l’adresse de la variable c au pointeur p On affiche la valeur de la case pointée par p (‘a’)
Exemple… int i; int *p; i=23; //diff entre i et &i ? p=&i; 4AC0 4ABF 4ABE Finalement : Tas int i; int *p; i=23; //diff entre i et &i ? p=&i; //diff entre p et *p ? i=58; //valeur de p et *p ? 23AA 23A9 23A8 p 23A7 23A6 BSS 23A6 23 58 i 23A5 F3DE Prog 23A4 0F4D
Mais ce n’est pas tout ! Half life 2 : 4Go de texture, de sons… Windows Vista : 4Go de programmes… Question : Comment faire pour jouer à Half Life 2 quand on exécute Windows Vista sur une machine ne disposant que de 1Go de mémoire vive?
Réponse Vista et Half Life2 ne doivent pas charger tout en mémoire… Uniquement ce qu’il faut Il faut donc prévoir un mécanisme pour charger et décharger des zones en mémoire : new pour réserver une case delete pour supprimer le contenu d’une case
Rappels… Finalement : int i; int *p; i=23; //diff entre i et &i ? 4AC0 4ABF 4ABE Finalement : Tas int i; int *p; i=23; //diff entre i et &i ? p=&i; //diff entre p et *p ? i=58; //valeur de *p ? p=new int; *p=6; 23AA 23A9 23A8 6 23A7 23A8 23A6 p BSS 23A6 58 23 i 23A5 F3DE 23A4 0F4D Prog
Rappels… int *p; p=new int; *p=6; Exemples de bugs : Tas 6 p 23A8 23A9 4AC0 4ABF 4ABE Exemples de bugs : Tas 23AA 23A9 23A9 6 int *p; p=new int; *p=6; 23A8 23A8 23A7 23A8 23A9 p BSS 23A6 F3DE 23A5 0F4D Prog 23A4
Segmentation Fault !!! Rappels… int *p; int *q; p=new int; q=p; *p=6; 4AC0 4ABF 4ABE Exemples de bugs : Tas Segmentation Fault !!! int *p; int *q; p=new int; q=p; *p=6; delete p; cout<<*q; 23AA 23A9 23A8 6 23A7 23A8 p BSS 23A6 q 23A8 23A5 F3DE Prog 23A4 0F4D
Mémoire dynamique Allocation de mémoire dynamique int *tab; tab = new int [10]; Destruction de la mémoire delete [] tab; Avantage : Créer des tableaux de taille défini par l’utilisateur
Il est possible d’utiliser les crochets, comme pour un tableau normal… void afficheToutTableau (int *tab, int taille) { for (int i=0; i<taille; i++) cout<<tab[i]<<endl; } void saisieToutTableau (int *tab, int taille) cin>>tab[i]; int main(void) int *tab; int taille; cin >> taille; tab = new int [taille]; saisieToutTableau(tab, taille); afficheToutTableau(tab, taille); delete []tab; return 0; Il est possible d’utiliser les crochets, comme pour un tableau normal… On ne connait plus par contre le nombre de case !