Vous êtes sur la page 1sur 29

Chapitre 6

Les pointeurs

1
Introduction
• La mémoire est un tableau de cases (octets)consécutives
numérotées(adressées).

1008 1009 100A 100B 100C 100D 100E

• Lorsqu’on déclare une variable, un nombre bien


déterminée d’octets seront réservées selon le type de la
variable.
▪ Un entier(int):4 octets
▪ Un réel(float):4 octets
▪ Un réel (double):6 octets
▪ Un caractère(char):1 octet

2
Définition d’un pointeur
• Définition :
Un pointeur est une variable spéciale dont la valeur est égale à l’adresse
d’une autre variable.
• Représentation schématique:
p pointe sur a

&a valeur

• Déclaration d’un pointeur


syntaxe:
Type de base * nom_pointeur;
type de base: type de la variable pointée
* :symbole entre le type et le nom de la variable.
nom_pointeur: nom de la variable pointeur.

3
Les opérateurs élémentaires
sur les pointeurs
• Opérateur & (adresse de )pour obtenir
l’adresse d’une variable:
• Exemples:
int v=10,pv=&v;/*le & indique que
l’adresse de la variable v se trouve dans la
variable pointeur pv*/
int x=8,px=&x;
Donc px et pv sont deux pointeurs entiers.
4
Les opérateurs élémentaires sur les
pointeurs
• Opérateur de contenu « * »:
Exemple 1: int w;w=*pv;/*w contient la variable v pointée par v
*/
printf(« %d »,w);/*affiche la valeur 10*/
Exemple 2: int *p,a,b;
NULL 0 0
p 1000 a 1004 b 1008
p=&a;*p=44; 1004 44 0
p 1000 a 1004 b 1008

p=&b;*p=56; 1008 0 56
p 1000 a 1004 b 1008

5
Les opérateurs élémentaires sur les
pointeurs
• Incrémentation et décrémentation:
• L’opérateur ++ permet d’incrémenter l’adresse contenue dans le
pointeur et l’opérateur – permet de décrémenter l’adresse contenue
dans le pointeur.
P a
5C24 10
3F02 3F06 5C20 5C24 5C28 5C2C
• En effet P++,permet à P de pointer sur l’élément qui suit la variable
a d’adresse 5C28 puisque le système avance de 4 octets.
• De meme, l’apérateur – permet décrémenter l’adresse contenue
dans le pointeur.
P--;/*donne 5C20*/

6
Les opérateurs élémentaires
sur les pointeurs
• Exemple:
int a=6,b=8,c=10,*p=&a;
p a b c
1004 6 8 10
1000 1004 1008 100C
*p=12;p++;
p a b c
1008 12 8 10

*p=14;p++; a b c
p
100C 12 14 10

*p=24;p=p-2;
p a b c
1004 12 14 24
7
Les opérateurs élémentaires
sur les pointeurs
Remarques:
*p++ est équivalent à *(p++)
++*p est équivalent à ++*(p)
*++p est équivalent à *(++p)
Affectation:
Soient P1 et P2 deux pointeurs de même type.
P1=P2 permet de copier le contenue de P2 vers P1.
P1 pointe sur la même variable que P2.
Ordre de priorité:
Les opérateurs * et & ont la même priorité que les autres opérateurs
unaires(la négation !,l’incrémentation ++, la décrémentation – et ect).
Dans une meme expression, les opérateurs sont évaluées de droite
à gauche.
Remarque:si un pointeur pointe sur une variable x, alors *p peut etre
utilisée partout ou on peut écrire x.

8
Les opérateurs élémentaires
sur les pointeurs
Exemple 1: Saisie d’un nombre ou d’un caractère
int *p,a;
p= &a;/* p pointe sur a */
printf(’’donner a\n ’’); /*donner a */
scanf(’’%d’’,p) ; ou scanf(’’%d’’,&a) ; /* lire a par le clavier */

Exemple 2:Affichage d’un nombre ou d’un caractére


printf(’’ a=%d\n ’’,*p);ou printf(’’ a=%d\n ’’,a);
Exemple 3: int *p,x,y; p=&x;
y=*p+1;/* y=x+1; */
*p=*p+1;/* x=x+1 */
*p+=2;/* x+=2 */
++*p;/* ++x */
(*p)++;/* x++ */

9
Les opérateurs élémentaires
sur les pointeurs
Remarques:
*p++ est équivalent à *(p++)
++*p est équivalent à ++*(p)
*++p est équivalent à *(++p)
Affectation:
Soient P1 et P2 deux pointeurs de même type.
P1=P2 permet de copier le contenue de P2 vers P1.
P1 pointe sur la même variable que P2.
Ordre de priorité:
Les opérateurs * et & ont la même priorité que les autres opérateurs
unaires(la négation !,l’incrémentation ++, la décrémentation – et ect).
Dans une meme expression, les opérateurs sont évaluées de droite
à gauche.
Remarque:si un pointeur pointe sur une variable x, alors *p peut etre
utilisée partout ou on peut écrire x.

10
Exercice d’application
1. Déterminer les contenus des variables E,F et C après l’exécution
séquentielle des instructions suivantes:
int E,F,C;
int *p,**Q,E=5;
p=&E;
Q=&p;
(*p)++;
F=*p;
++F;
(*(*Q))++;
*Q=&C;
C=*(&F)+2;

11
Exercice d’application
2. Complétez le tableau suivant pour déterminer le résultat du
chaque instruction:
A B C P1 P2
int A=1,B=2,C=3;
int *P1,*P2;
P1=&A;P2=&C;
*P1=(*P2)++;
P1=P2;
P2=&B;
*P1 - =*P2;
++ *P2;
*P1 * = *P2;
A=*P2 * *P1;
P1=&A;
*P2/=*P1;
12
Les pointeurs
avec l’allocation dynamique
• La déclaration d’un tableau définit un tableau
statique (il possède un nombre figé
d’emplacement).il y a donc un gaspillage
d’espace mémoire en réservant toujours l’espace
maximal prévisible.
• Il serait souhaitable que l’allocation de la
mémoire dépend du nombre d’éléments à saisir.
Ce nombre ne sera connu qu’à l’exécution :
c’est l’allocation dynamique.

13
Les pointeurs
avec l’allocation dynamique
• Les fonctions pour l’allocation dynamique:
1. malloc():
– cette fonction est définit dans la bibliothèque stdlib.h.
– Elle permet de réserver un espace mémoire pour un pointeur.
– La fonction malloc retourne l’adresse du premier octet de la zone
mémoire allouée en cas d’échec, elle retourne NULL.
Syntaxe:
objet=(type*)malloc(taille); ou objet=(type*)malloc(sizeof(type));
– L’operateur sizeof(type) retourne la taille en octet selon leur type.
2. free():
- cette fonction est définie dans la bibliothèque stdlib.h.
- si on n’a plus besoin d’un bloc de mémoire réservé dynamiquement
par malloc, alors on peut le libérer à l’aide de la fonction free.

14
Les pointeurs
L’allocation dynamique
Syntaxe:
free(<pointeur>);
- Libère le bloc de mémoire désigné par le pointeur.
Exemple:
main()
{int *p1;
p1=(…….int.*)malloc(…4……);ou p1=(……int..*)malloc(sizeof(…int…));
float *p2;
p2=(……float…*)malloc(…4…..);ou p2=(…float…..*)malloc(sizeof(…float…));
*p1=123;
*p2=12.5;
printf(’’*p1=%d ,*p2=%f \n’’,*p1,*p2);
free(p1);
free(p2);
}

15
Allocation dynamique
Tableau à une dimension
• Déclaration et allocation dynamique:
• Déclaration d’un pointeur l’adresse du 1 er élément du tableau.
• Allocation dynamique de l’ensemble des éléments du tableau.
Exemple:déclaration d’un tableau de 3 éléments.
int * T;
T=(int *)malloc(3*sizeof(int));

1004
1000 T

1004 1008 100C

16
Allocation dynamique
Tableau à une dimension
Exemple 1:(allocation dynamique) Exemple 2:(allocation statique)
#include<stdio.h> #include<stdio.h>
#include<conio.h> #include<conio.h>
main() main()
{int *M; {int T[3];
M=(int*)malloc(3*sizeof(int);
//remplissage de M //remplissage de tableau T
M[0]=19; T[0]=9; ou *T=9
M[1]=20 T[1]=10; ou *(T+1)=10
M[2]=21 T[2]=11; ou *(T+2)=11}
}
Possibilité de combiner les deux méthodes.

17
Allocation dynamique
Les tableaux à deux dimensions

Soit A une matrice de n lignes et m colonnes, on la déclare


dynamiquement comme suit:
int **A;// double étoile pour un tableau à deux dimensions avec A un
pointeur des pointeurs au lieu int A[3][4]
int N=3,M=4;
M colonnes
Exemple:
A[0][0] A[0][1] A[0][2] A[0][3]
A
3000 3004 3008 300C
N lignes

3000
A[1][0] A[1][1] A[1][2] A[1][3]
4000
5000 4000 4004 4008 400C

A[2][0] A[2][1] A[2][2] A[2][3]

5000 5004 5008 500C 18


Allocation dynamique
Les tableaux à deux dimensions

Exemple: lecture et affichage d’une matrice A en utilisant l’allocation dynamique


main()
{ int i,N=2,M=3;
int **A;
A=(int **)malloc(2*sizeof(int *));//on alloue N pointeurs
if(A==NULL){printf(’’ mémoire non disponible’’);}else
{ for(int i=0;i<2;i++)
{
A[i]=(int *)malloc(3*sizeof(int));//on alloue des tableaux de 3 éléments entiers.
if(A[i]==NULL){printf(’’ mémoire non disponible’’);}else
{printf(‘’entrer les éléments de la matrice A\n’’);
for(int i=0;i<2;i++)
{ for(int j=0;i<3;i++)
{printf(‘’entrer la valeur A[%d][%d] ‘’,i,j);
scanf(‘’%d’’, );}
}

19
Allocation dynamique
Les tableaux à deux dimensions

printf(‘’\n======>Matrice A <======\n’’);
for(int i=0;i<2;i++)
{ for(int j=0;i<3;i++)
{printf(‘’ %d \t‘’, );}printf(‘’\n’’);
}
------------------la libération-------------------------
for(int i=0;i<2;i++)
{ free(A[i]); }
free(A);
getch(); return 0;}

20
Les pointeurs et les tableaux
Les tableaux à une dimension
Récupération des adresses des éléments:
• Adresse du premier élément =nom_tableau
• Adresse du deuxième élément=nom_tableau+1
• Adresse du i_ème élément =nom_tableau+i-1
Exemple:
En déclarant un tableau T de 3 éléments et un pointeur P de type int sur des
variables entières:
• L’adresse du premier élément est T qui est égal à 1004.
• L’adresse du 2èmeélément est T+1 qui est égal à 1008(=1004+1).
• L’adresse du 3ème élément est T+2 qui est égale à 100C(=1004+2).

P=T
1004
P 1000 T 1004 1008 100C

21
Les pointeurs et les tableaux
Les tableaux à une dimension
Accès aux éléments:
• Premier élément =*nom_tableau
• Deuxième élément=*(nom_tableau + 1)
• i_ème élément =*(nom_tableau+i-1)
Exemple:
• *T=22;
• *(T+1)=56;
• *(T+2)=49;

P=T
1004 22 56 49
P 1000 T 1004 1008 100C

22
Les pointeurs et les tableaux
Les tableaux à une dimension

En effet:

int T[N],*P;
P=T;//est équivalent de P=&T[0];
•P pointe sur T[0] et *P désigne T[0]
• P+1 pointe sur T[1] et *(P+1) désigne T[1]
•……………………………………………………………….
• P+i pointe sur T[i] et *(P+i) désigne T[i]
i appartient à l’intervalle [0,N-1]

23
Les pointeurs et les tableaux
Les tableaux à une dimension
• Exercice d’application :
Soit P un pointeur qui pointe sur un tableau A:
Int A[]={12,23,34,45,56,67,78,89,90};
Int *P;
P=A;
Quelles valeurs ou adresses fournissent ces expressions:
a) *P+2
b) *(P+2)
c) &P+1
d) &A[4]-3
e) A+3
f) &A[7]-P
g) P+(*P-10)
h) *(P+*(P+8)-A[7])

24
Les pointeurs et les tableaux
Les tableaux à une dimension
Exemple 1(Lecture et affichage d’un tableau matérialisée par un pointeur)
#include<stdio.h>
#include<conio.h>
#define n 10
main()
{float t[n],*pt; int i; pt=t;
printf(« entrer %d entiers\n »,n);
for(i=0;i<n;i++)
{printf(’’donner l’entier n° %d\’’,i+1);
scanf(’’%f’’,pt+i);
}
/*affichage*/
for(i=0;i<n;i++)
{printf(’’ %f\t’’,*(pt+i));
}
getch();
return 0;
}

25
Les pointeurs et les tableaux
Les tableaux à une dimension
Autre solution(Lecture et affichage d’un tableau matérialisée par un pointeur sans
déclarer i)
#include<stdio.h>
#include<conio.h>
#define n 10
main()
{float t[n],*pt;
printf(« entrer %d entiers\n »,n);
for(pt=t;pt<t+n;pti++)
{printf(’’donner l’entier n° %d\’’,(pt-t) +1);
scanf(’’%f’’,pt);
}
/*affichage*/
for(pt=t;pt<t+n;pt++)
{printf(’’ %f\t’’,*pt);
}
getch();
return 0;
}

26
Les pointeurs et les tableaux
Les tableaux à deux dimensions

Soit A un tableau matrice de n lignes et m colonnes et un pointeur P


qui pointe sur ce tableau:
int A[N][M],*P;P=&A[0][0]=A[0];
Le nom de tableau est un pointeur constant sur le premier élément du
tableau.
Exemple: j=0 j=1 j=2 j=3
A A[0][0] A[0][1] A[0][2] A[0][3]
i=0
3000 3004 3008 300C
P
A[1][0] A[1][1] A[1][2] A[1][3]
3000 i=1

4000 4004 4008 400C

A[2][0] A[2][1] A[2][2] A[2][3]


i=2

5000 5004 5008 500C 27


Les pointeurs et les tableaux
Les tableaux à deux dimensions

En effet:
• P pointe sur A[0][0] et *P désigne A[0][0]
• P+1 pointe sur A[0][1] et *(P+1) désigne A[0][1]
• ……………………………………………………………….
• P+M*1+0 pointe sur A[1][0] et *(p+M) désigne A[1][0]
• P+M*1+1 pointe sur A[1][1] et *(p+M+1) désigne A[1][1]
• ………………………………………………………………………………..
• P+M*i+j pointe sur A[i][j] et *(p+M*i+j) désigne A[i][j]
• Ou’ i appartient à l’intervalle[0,N-1] et j appartient à l’intervalle [0,M-1]

28
Les pointeurs et les tableaux
Les tableaux à deux dimensions
Exemple 2(Lecture et affichage d’une matrice matérialisée par un pointeur)
#include<stdio.h>
#include<conio.h>
#define n 4
#define m 10
main()
{int t[n][m],*pi; int i; pi=t[0];
for(i=0;i<n;i++)
{
printf(’’ ligne n° %d \n ’’,i+1);
for(j=0;j<m;j++)
{printf(’’donner l’entier n° %d\’’,j+1);
scanf(’’%i’’,pt+m*i+j);
}
/*affichage*/
for(i=0;i<n;i++)
{for(j=0;j<m;j++)
{
printf(’’ %d\t’’,*(pt+m*i+j));
}
pritnf(’’\n’’);
}
getch();
return 0;
}

29

Vous aimerez peut-être aussi