Sunteți pe pagina 1din 19

Algorithmiqueetprogrammation

(3)

STIC1/EEA1
UniversitdeSousse
ESSTHS
20142015
WajdiElhamzi
elhamziwajdi@yahoo.fr

L
Lespointeurs
i t

Gnralit

Manipulationdesobjets
les variables possdent les 4 caractristiques suivantes:

un type

un nom

une valeur

une adresse

les 3 premires dj bien exploites. Mais la 4me ?

Adresses/Contenus
Schmatisation par une bote ou cellule :
l'ordinateur doit stocker cette variable quelque part : dans la
RAM
les octets (ou cellules) de la RAM sont numrots pour que la
machine s'y retrouve : chaque cellule une adresse, et peut
contenir une valeur (son contenu)
Attention la distinction adresse/contenu

EspacesMmoires
Structure physique de la mmoire :
contenus
adresse

n
n+1
n+2

Cellules
conscutives

n+3
n+4
n+5
n+6

Lesadresses
Illustration par un petit programme
void main()
{
int val1,val2;

Le compilateur utilise des


cellules en mmoire pour stocker
ces valeurs. Il les 'alloue'.

val1 = 3;
val2 = -2*val1+4;
if (val2 < val1)
{
printf("%d < %d\n",val2,val1);
}
}
Exemple : val1 l'adresse 1000, val2 l'adresse 1001 (arbitraire)
6

Lesadresses
Lorsque l'on utilise val1, la machine va consulter
l'adresse 1000

Lorsque l'on utilise val2, la


machine va consulter l'adresse
1001

1000
1001
1002
1003
1004
1005
1006

Valeur stocke dans val1


Valeur stocke dans val2

Ladresse est invisible pour le programmeur ou l'utilisateur


7

Lesadresses
void main()
{
int val1
val1,val2;
val2;

Le compilateur utilise sa table de


correspondance : val1 adresse
1000

val1 = 3;
val2 = -2*val1+4;
if (val2 < val1)
{
printf("%d < %d\n",val2,val1);
}
}

Le nom de la variable "masque" son adresse


8

Lesadresses
Effet de l'instruction val1 = 3; en mmoire

1000
1001
1002
1003
1004
1005
1006

3
Valeur stocke dans val2

Lesadresses
void main()
{
int val1
val1,val2;
val2;
val1 = 3;
val2 = -2*val1+4;

Le compilateur utilise sa table de


correspondance pour val1 et val2

if (val2 < val1)


{
printf("%d < %d\n",val2,val1);
}
}

10

Lesadresses
Effet de l'instruction val2 = -2*val1+4;
en mmoire
1000
1001
1002
1003
1004
1005
1006

3
-2

11

Adresseetvaleurd'unobjet(1)
Adresse (@)

Exemple:

Inti;
Int j;
Intj;
i=5;
i=j;

Int i;

Int j;

Deux variables diffrentes ont des


adresses diffrentes.

Contenu (valeur)

4831836000

00

4831836001

00

4831836002

00

4831836003

05

4831836004

00

4831836005

00

4831836006

00

4831836007

05

..

L'affectation i = j; n'opre que sur les


valeurs des variables.
Les variables i et j tant de type int, elles
sont stockes sur 4 octets.
12

Adresseetvaleurd'unobjet(2)
Adresse (@)

Exemple:

Inti;
Int j;
Intj;
i=5;
J=3;

Int i;

Int j;

Contenu (valeur)

4831836000

00

4831836001

00

4831836002

00

4831836003

05

4831836004

00

4831836005

00

4831836006

00

4831836007

03

..

Chaque variable a sa propre @, mais la


valeur de j qui change

13

Introductionauxpointeurs
Un pointeur est un objet (variable) dont sa valeur est

gale ladresse dun autre objet.


On dclare un pointeur par linstruction :
type *nom-du-pointeur;

o type est le type de lobjet point.


Cette dc
dclaration
a at o dc
dclare
aeu
un identificateur,
de t cateu , nom-du
o du

pointeur, associ un objet dont la valeur est ladresse dun


autre objet de type type.

14

Dclarationdunpointeur
Unevariabledetypepointeursedclarel'aidedel'objetpoint
prcddusymbole*(oprateurd'indirection).
type *nom-du-pointeur;
Exemple:
char*pc;//pcestunpointeurpointantsurunobjetdetypechar
int *pi;//piestunpointeurpointantsurunobjetdetypeint
float *pr;//pr estunpointeurpointantsurunobjetdetypefloat
L'oprateur* dsigneenfaitlecontenudel'adresse.
Exemple:

char*pc;
*pc=34 ;
printf("CONTENUDELACASEMEMOIRE:%c\n",*pc);
printf("VALEURDEL'ADRESSEENHEXADECIMAL:%p\n",pc);
15

tatdupointeuraprsdclaration
Programme exemple suivant : version 1
illustration avec botes et flches
#include <stdio.h>
var1
void main()
{
short int var1;
short int *ptr;

ptr

var1 = 43; /* correct */


*ptr = 5; /* provoquera une erreur */
}

16

tatdupointeuraprsdclaration
Programme exemple suivant : version 1
effet des instructions
#include <stdio.h>
var1

void main()
{
short int var1;
short int *ptr;

43
ptr

var1 = 43; /* correct */


* t = 5
*ptr
5; /* provoquera une erreur */
}

17

tatdupointeuraprsdclaration
ptr est juste le panneau (flche), il ne pointe pas un endroit prcis dans la mmoire

ptr
18

tatdupointeuraprsdclaration
*ptr n'est pas dfini : si l'on suit le panneau, on va n'importe o : erreur lors de
l'excution du programme.
Aj t
Ajoutons
l ligne
la
li
suivante,
i
t entre
t var1=43;
1 43 ett *ptr=5;
* t 5
ptr = &var1;
dtail de cette ligne avec botes et flches :

ptr
&var1

var1

43

galit entres les flches

19

tatdupointeuraprsdclaration
ptr
var1

43

Ou encore :
Var1: qqpart

ptr
20

10

Lespointeurs:illustration
contenus
adresse
1000

ptr

3
15
0
-845
6311

1001
1002

1002
1003
1004

Si ptr vaut 1002 :

1005

*ptr est ce qui est contenu


l'adresse 1002 : 0

1006

21

ValeuretAdresse:exemple(1)
#include <stdio.h>
main()
{
int i = 3;
int *p;
p = &i;
printf("*p = %d \n",*p);
}

imprime *p = 3
objet

adresse

valeur

4831836000

4831836004 4831836000

*p

4831836000

22

11

ValeuretAdresse:exemple(2)
main()
{
int i = 3, j = 6;
int *p1, *p2;
p1 = &i;
p2 = &j;
*p1 = *p2;
}
objet

adresse

main()
{
i ti=3
int
3, j = 6
6;
int *p1, *p2;
p1 = &i;
p2 = &j;
p1 = p2;
}
valeur

objet

adresse

valeur

4831836000

4831836000

4831836004

4831836004

p1

4831835984

4831836000

p1

4831835984

4831836004

p2

4831835992

4831836004

p2

4831835992

4831836004
23

Arithmtiquedespointeurs
La valeur dun pointeur tant un entier, on peut lui
appliquer un certain nombre doprateurs arithmtiques
classiques.
Les seules oprations arithmtiques valides sur les
pointeurs sont :
laddition dun entier un pointeur. Le rsultat est un pointeur
de mme type que le pointeur de dpart ;
la soustraction dun entier un pointeur. Le rsultat est un
pointeur de mme type que le pointeur de dpart ;
la diffrence de deux pointeurs pointant tous deux vers des
objets de mme type. Le rsultat est un entier.
24

12

Arithmtiquedespointeurs:
exemples
Si i est un entier et p est un pointeur sur un objet de type type,
lexpression p + i dsigne un pointeur sur un objet de type type
dont la valeur est gale
g
la valeur de p incrmente de i *
sizeof(type).
main()
{
int i = 3;
int *p1, *p2;
p1 = &i;
p2 = p1 + 1;
printf("p1 = %ld \t\n
p2 = %ld\n",p1,p2);
}

main()
{
double i = 3;
double *p1, *p2;
p1 = &i;
p2 = p1 + 1;
printf("p1 = %ld \t\n
p2 = %ld\n",p1,p2);
}

affiche
p1 = 4831835984
p2 = 4831835988

affiche
p1 = 4831835984
p2 = 4831835992

25

Initialisationdupointeur
Un pointeur doit toujours tre initialis avant utilisation.
Po rq oi?
Pourquoi?
A la dclaration d'une variable quelconque, sa valeur ne
peut pas tre dtermine. Elle peut valoir "n'importe
quoi".
Les pointeurs tant des variables aussi
aussi, alors la
dclaration ils valent n'importe quoi!!!!

26

13

Initialisationdupointeur
L'initialisation peut avoir trois formes :
Avec
A ec la valeur
ale r NULL : int * ptr = NULL;
NULL
Avec l'adresse d'une variable:
int val;
int * ptr;
ptr = &variable;
Avec allocation dynamique:
int * ptr = malloc(10);
27

Allocationdynamique
Le fait de rserver un espace-mmoire pour stocker
lobjet point par p sappelle allocation dynamique.
Elle se fait en C par la fonction malloc de la librairie
standard stdlib.h :
malloc(nombre-octets)
Cette fonction retourne un pointeur de type char *
pointant
i t t vers un objet
bj t d
de ttaille
ill nombre-octets
b
t t octets.
t t

28

14

Allocationdynamique
Pour initialiser des pointeurs vers des objets qui ne sont
pas de type char, il faut convertir le type de la sortie de la
fonction malloc.
Largument nombre-octets est souvent donn laide de la
fonction sizeof() qui renvoie le nombre doctets utiliss pour
stocker un objet.
pour initialiser un pointeur vers un entier, on crit :
#include <stdlib
<stdlib.h>
h>
int *p;
p = (int*)malloc(sizeof(int));
On aurait pu crire galement p = (int*)malloc(4);
29

Allocationdynamique:exemple
#include <stdio.h>
#include <stdlib.h>
main()
{ int i = 3;
int *p;
p;
printf("valeur de p avant initialisation = %ld\n",p);
p = (int*)malloc(sizeof(int));
printf("valeur de p aprs initialisation = %ld\n",p);
*p = i;
printf("valeur de *p = %d\n",*p); }
Le p
programme
g
suivant dfinit un p
pointeur p sur un objet
j *p
p de type
yp int,, et
affecte *p la valeur de la variable i.
Il imprime l'cran :
valeur de p avant initialisation = 0
valeur de p aprs initialisation = 5368711424 valeur de *p = 3

30

15

Allocationdynamique:exemple
Avant l'allocation dynamique, on se trouve dans la configuration
objet

adresse

valeur

4831836000

4831836004

A ce stade, *p n'a aucun sens. En particulier, toute manipulation de la


variable *p gnrerait une violation mmoire
L'allocation dynamique a pour rsultat d'attribuer une valeur p et de
rserver cette adresse un espace-mmoire compos de 4 octets pour
stocker la valeur de*p. On a alors
objet

adresse

valeur

4831836000

4831836004

5368711424

*p

5368711424

?(int)
31

L
Lespointeurs
i t

Pointeurs et
tableaux

32

16

Pointeursettableaux
Relation entre tableaux et pointeurs
Tout tableau en C est un pointeur !
Donne accs au premier lment du tableau
tableau pointe sur le premier
lment du tableau !
char tab[4]; se reprsente ainsi :

tab
Stockage d'un char

tab[0]

Stockage d'un char

tab[1]

Stockage d'un char

tab[2]

Stockage d'un char

tab[3]

Pointeursettableaux

EndclarantuntableauAdetype int etunpointeurPsur int,


int A[10];
int *P;
l'instruction:P=A; estquivalente P=&A[0];

SiPpointesurunecomposantequelconqued'untableau,alorsP+1pointe
surlacomposantesuivante.
Plusgnralement:
P+i pointesurlaiime composantederrire P
Pi pointesurlaiime composantedevant P.

17

Pointeursettableaux
Ainsi, aprs l'instruction,
P = A;
le pointeur P pointe sur A[0], et
*(P+1)
(P+1) dsigne le contenu de A[1]
*(P+2) dsigne le contenu de A[2]
...
...
*(P+i) dsigne le contenu de A[i]

Pointeursettableaux
Enfaittab=&tab[0]
parcontretabestconstant:nonmodifiable

tab

On a :

&tab[0]
Stockage d'un char

tab[0]

Stockage d'un char

tab[1]

Stockage
g d'un char

tab[2]

Stockage d'un char

tab[3]

&tab[1]
&tab[2]
&tab[3]

tab+i = &tab[i]

18

L
Lespointeurs
i t

Pointeurs et
fonctions

37

Pointeurscommeparamtresdefonctions
Une autre utilit des pointeurs est de permettre des fonctions d'accder
aux donnes elles mme et non des copies. Prenons pour exemple une
fonction qui change la valeur de deux entiers :
void exchange (int *x, int *y)
{ int tmp;
tmp = *x;
*x = *y;
*y = tmp;}

19

S-ar putea să vă placă și