La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

8PRO107 Éléments de programmation Les adresses et les pointeurs.

Présentations similaires


Présentation au sujet: "8PRO107 Éléments de programmation Les adresses et les pointeurs."— Transcription de la présentation:

1 8PRO107 Éléments de programmation Les adresses et les pointeurs

2 Les adresses Les cases mémoire ont toutes un numéro qui les distingue les une des autres. Ce numéro est appelé adresse. C’est par cette adresse que le processeur peut communiquer avec la mémoire. 1 2 3 4 . . max

3 Les adresses et les variables
Le nom que l’on donne aux cases mémoire est traduit en une adresse juste avant l’exécution d’un programme. Cela est nécessaire afin que le processeur sache à quelle case mémoire est associée chaque variable. En général, il est impossible de prévoir à quelle adresse sera placée une variable. Le nom des variables est donc nécessaire. c1: 1 char c1 = c2 ; Lire le contenu de la case 3. Mettre ce qui a été lu dans la case 1. 2 c2: 3 1324 char 4 . . max

4 Les adresses et les variables
Le nom que l’on donne aux cases mémoire est traduit en une adresse juste avant l’exécution d’un programme. Cela est nécessaire afin que le processeur sache à quelle case mémoire est associée chaque variable. En général, il est impossible de prévoir à quelle adresse sera placée une variable. Le nom des variables est donc nécessaire. c1: 1 1324 char c1 = c2 ; Lire le contenu de la case 3. Mettre ce qui a été lu dans la case 1. 2 c2: 3 1324 char 4 . . max

5 Le partage de la mémoire
Sur les systèmes modernes il peut y avoir plusieurs usagers se partageant la mémoire et chaque usager peut exécuter plusieurs programmes simultanément. Cela signifie que l’on n’est pas libre d’utiliser toutes les cases mémoire comme on le veut. Une case peut être occupée par un programme à un certain moment et libre à un autre. Cette situation est aléatoire. Pour cette raison, on ne mentionne jamais explicitement une adresse dans un programme même si cela est théoriquement possible.

6 Adresses valides et non valides
Exemple. Dans le pseudo-code suivant: Lire le contenu de la case 3. Mettre ce qui a été lu dans la case 1. Que se passe-t-il si, au moment de l’exécution, la case mémoire 1 est déjà utilisée par un autre programme? La case est alors non valide et il y aura erreur à l’exécution. C’est pour cette raison que l’on utilise des variables. Avant l’exécution, une adresse valide est associée à chaque variable. Seul notre programme pourra utiliser ces cases mémoire.

7 Position des variables dans la mémoire
c int . . Sauf pour les tableaux, il n’y a aucune garantie que les variables occupent des cases adjacentes en mémoire. Exemple: int a, b[4], c, d[3] ; b[0] int b[1] int b[2] int b[3] int int a . . d[0] int d[1] int d[2] int . .

8 Les adresses et les types
Une des principales fonctions des types est d’indiquer le nombre d’octets utilisés par une variable. Par exemple nous avons vu que: un caractère prend 1 octet (8 bits) un entier prend 4 octets (32 bits). Cela signifie que si on divise la mémoire en case d’un octet alors: un char utilise 1 case un int utilise 4 cases adjacentes n: 0 int 1 2 3 c1: 4 char c2: 5 . char . . max

9 Remarque On peut aussi voir la mémoire comme une suite de cases de taille variable. n: 0 int int c1: 4 char c2: 5 . char . . max

10 Les adresses et les tableaux
Le nom d’un tableau correspond à l’adresse du début du tableau. Exemple: char tab[5]; printf("%p\n", tab); printf("%p\n", tab+1); printf("%p\n", tab+2); Note: "%p" sert à afficher les pointeurs.

11 Les tableaux d’entiers
Exemple: int tab[5] ; cout << tab ; cout << tab+1 ; cout << tab+2 ; Question: Pourquoi? +4 +4

12 L’incrémentation d’une adresse
L’adresse a+1 n’est pas valide a: int . . b[0]: b=24600 int b[1]: b+1=24604 int Incrémenter une adresse ne veux pas dire ajouter 1, cela veut dire aller à l’adresse suivant la variable courante. En général cela n’a du sens que si on est dans un tableau. b[2]: b+2=24608 int b[3]: b+3=24612 int . . d[0]: d=54316 char d[1]: d+1=54317 char d[2]: d+2=54318 char . .

13 Remarque Si tab est un tableau alors L’adresse de tab[0] est tab,
etc. Cela est vrai quel que soit le type des éléments de tab.

14 L’opérateur & Il est possible de connaître, pendant l’exécution d’un programme, l’adresse associée à une variable. En C++, cela se fait à l’aide de l’opérateur unaire & Exemple: char c; int n, tab[1000]; L’adresse de c est &c L’adresse de n est &n L’adresse de tab[3] est &tab[3]

15 Détail important Exemple: tab[1000]; L'adresse de tab[0] est
&tab[0] ou encore tab ou encore &tab Il n'y a aucune différence entre &tab[0] et tab puisque tab est (par définition) l'adresse de la première case du tableau. Mais il y a une différence subtile entre tab et &tab car &tab est l'adresse de tout le tableau.

16 Détail important (suite)
Le code suivant: int tab[10]; cout << tab << " " << tab << endl; cout << &tab[0] << " " << &tab[0]+1 << endl; cout << &tab << " " << &tab+1 << endl; affichera ce qui suit: Note: Les adresses seront écrites en hexadécimal plutôt qu'en décimal comme dans cet exemple.

17 L’opérateur * Il est aussi possible de connaître, pendant l’exécution d’un programme, le contenu de la case mémoire située à une adresse donnée. En C++, cela est possible à l’aide de l’opérateur unaire * Exemple: char c ; int tab[1000] ; Le contenu de l’adresse tab + 25 est *(tab + 25) *(tab + 25) est donc identique à tab[25] *(&c) est identique à c *c n’a aucun sens

18 Exemple Les expressions logiques suivantes sont vraies: &n == 12556
*(12560) == 60 *(12560) < c2 *(&r) == . . n: int c1: 60 char c2: 61 char r: 12.345 double . .

19 Opérations permises sur les adresses
On peut: Additionner une adresse et un entier Déterminer l’adresse d’une variable Déterminer le contenu d’une adresse Soustraire deux adresses d'un même tableau On ne peut pas Additionner deux adresses

20 Les pointeurs Un pointeur est une variable pouvant contenir une adresse. Exemple: int *pn; pointeur sur une valeur entière char *pc; pointeur sur un caractère double *pr; pointeur sur un réel

21 Les pointeurs: exemple
pn: int* Exemple: int *pn, m ; . . m: int . .

22 Les pointeurs: exemple
pn: 65710 int* Exemple: int *pn, m ; pn = &m ; . . m: int . .

23 Les pointeurs: exemple
pn: 65710 int* Exemple: int *pn, m ; pn = &m ; m = 6 ; . . m: 6 int . .

24 Les pointeurs: exemple
pn: 65710 int* Exemple: int *pn, m ; pn = &m ; m = 6 ; *pn = 38 ; . . m: 38 int . .

25 Les pointeurs et les tableaux
En C++ les pointeurs sont intimement liés aux tableaux. Exemple: int tab[11], *p ; p = tab ; tab[3] = 70 ; *(tab + 3) = 70 ; p[3] = 70 ; *(p + 3) = 70 ; tous équivalent: tab: 1 2 3 4 5 6 7 8 9 10 p: 70

26 Remarque Le nom d’un tableau est une adresse constante et non pas un pointeur qui est une variable. Exemple: int tab[11], *p ; p = tab ; /* Valide */ tab = p ; /* Non valide */ tab: 1 2 3 4 5 6 7 8 9 10 p:

27 Quelques utilités des pointeurs
Pour implanter le passage de paramètres par référence Pour implanter le passage de tableaux en paramètre Pour utiliser des indices négatifs avec les tableaux Fondamental en structure de données

28 Les pointeurs comme paramètres
b En C++: echanger(a, b) void echanger ( int &x, int &y ) { int tmp ; tmp = x ; x = y ; y = tmp ; } x y tmp

29 Les pointeurs comme paramètres
b En C: echanger(&a, &b) void echanger ( int *x, int *y ) { int tmp ; tmp = *x ; *x = *y ; *y = tmp ; } x y tmp &a &b

30 Les tableaux passés en paramètre
Une des plus importantes utilisations des pointeurs réside dans le passage des tableaux en paramètre. Lorsque l’on passe le nom d’un tableau en paramètre, on passe une adresse. La fonction appelée reçoit donc une adresse qu’elle met dans une variable: cette variable doit donc être un pointeur.

31 Les tableaux passés en paramètre
void liretab ( int tab[], int max ) { int c ; int i = 0 ; while ( (c = getchar() ) != EOF ) tab[i] = c ; i = i + 1 ; }

32 Les tableaux passés en paramètre
void liretab ( int *tab, int max ) { int c ; int i = 0 ; while ( (c = getchar() ) != EOF ) *(tab+i) = c ; i = i + 1 ; }

33 Pour tester #include <iostream> using std::cout ;
using std::endl ; void liretab ( int tab[] , int max ) { int c ; int i = 0 ; while ( (c = getchar() ) != EOF && i < max ) tab[i] = c ; i = i + 1 ; } void ecriretab ( int tab[] , int max ) while ( tab[i] != 0 && i < max ) cout << char(tab[i]) << " " ; cout << endl ; void liretab2 ( int * tab , int max ) *(tab+i) = c ; void ecriretab2 ( int *tab , int max ) { int i = 0 ; while ( *(tab+i) != 0 && i < max ) cout << char(*(tab+i)) << " " ; i = i + 1 ; } cout << endl ; int main () const int MAX = 100 ; int vec [MAX] = { 0 } ; liretab(vec, MAX) ; ecriretab(vec, MAX) ; liretab2(vec, MAX) ; ecriretab2(vec, MAX) ; return 0 ;

34 Les indices de tableaux
Exemple 1 Tableau d’entiers dont les indices vont de -5 à 5: int tab[11] ; int *ptab ; ptab = tab + 5; ptab[0] est identique à tab[5] ptab[-5] est identique à tab[0] ptab[5] est identique à tab[10] 1 2 3 4 5 6 7 8 9 10 tab: ptab:

35 Les indices de tableaux
Exemple 2 Tableau d’entiers dont les indices vont de ‘A’ à ‘Z’: int tab[26] ; int *ptab ; ptab = tab – 'A' ; /* A vaut 65 en ASCII */ ptab['A'] est identique à tab[0] ptab['Z'] est identique à tab[25] -65 1 2 3 4 21 22 23 24 25 tab: ptab:

36 Les pointeurs et les tableaux à plusieurs dimensions
int mat[N][M] ; mat[i][j] = 0 ; *(mat + M*i + j) = 0 ; C'est pourquoi, lors d'un appel de fonction: void f ( int mat[][M] ) {...} il est nécessaire d'indiquer le nombre de colonnes. { identique:

37 Les structures et les pointeurs
L’opérateur de prise d’adresse & fonctionne avec les structures. On peut définir des pointeurs sur des types composés. complexe *pc, x ; pc = &x ; (*pc).reel = 3 ; (*pc).imag = 5 ; Remarque: Les parenthèses sont nécessaires puisque l’opérateur . a une priorité supérieure à l’opérateur *.

38 Les structures et les pointeurs
Les pointeurs de structures sont si fréquemment utilisés qu’il existe une notation abrégée. Exemple: complexe *p, x ; pc = &x ; pc->reel = 3 ; /* identique à (*pc).reel=3 */ pc->imag = 5 ; /* identique à (*pc).imag=5 */


Télécharger ppt "8PRO107 Éléments de programmation Les adresses et les pointeurs."

Présentations similaires


Annonces Google