Pointeurs

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 35

Ecole Nationale Supérieure d’El Harrach

Chapitre 4: Les pointeurs et


l’allocation dynamique de la mémoire

325 P: pointeur
Partie1: Les
pointeurs
12.5 x: variable

Cours élaboré par: Fenineche Khadidja

Année universitaire 2015-2016


1
Plan du chapitre (partie 1)

1- Représentation des données en mémoire.


2- Un pointeur en langage C (définition,
déclaration, affectation et communication
avec les variables).
3- Utilisation des pointeurs en langage C.
- Passage des paramètres par adresse.
- Pointeurs et structures (enregistrements).
- Pointeurs et tableaux.

Fenineche Khadidja 2
Objectifs du chapitre

A l’issue de ce chapitre, vous serez capables de:


• Déclarer et utiliser correctement un pointeur.
• Utiliser les pointeurs avec les enregistrements
• Utiliser les pointeurs dans les appels de
fonctions par adresse.
• Utiliser les pointeurs avec les tableaux à une
et deux dimensions.

Fenineche Khadidja 3
1- Représentation des données en mémoire

• Pour s’exécuter un programme a besoin de


données et a besoin de cases mémoires pour
stocker les résultats après traitement.
• Chaque type de donnée nécessite un certain
nombre d’octets pour qu’il soit totalement
stocké en mémoire (int 4 octets, char 1
octet,..).
• Les cases contiennent parfois les valeurs des
variables en cours de traitement ou à la fin de
ce dernier.
Fenineche Khadidja 4
1- Représentation des données en mémoire

• L’adresse d’une variable est celle du premier octet


qui la compose.
• Exemple: Un float tient sur 4 octets, l’adresse de ce
float est l’adresse du premier octet, les autres octets
se suivent en mémoire.
• Le symbole utilisé pour spécifier l’adresse d’une
variable est: & (symbole de référencement)
Exemple:
printf("l’adresse de a en mémoire est %p\n",&a);
• Ces adresses peuvent être stockées dans ce qu’on
appelle: pointeurs afin d’accéder autrement aux
variables. Fenineche Khadidja 5
1- Représentation des données en mémoire

300 325 P: pointeur de type float


Adressage …….
indirect ……..
………

325 12.5 x: variable


P: possède une adresse (300) et
une valeur (325 qui est elle-même
une adresse du premier octet du
float). &x est 325

X: possède une adresse (325) et


une valeur (12.5 de type float)
x a comme valeur 12.5
Fenineche Khadidja 6
2- Un pointeur en langage C

• Un pointeur en C est une variable un peu


spéciale qui ne contient pas une valeur à
traiter mais une adresse d’une autre variable.
Exemple: Si a est une variable et p un pointeur
qui contient l’adresse de a alors on peut écrire
(dans un certain sens):
p est équivalent à &a

• Le type du pointeur est le type de la variable


qu’il pointe.
Fenineche Khadidja 7
2- Un pointeur en langage C

• Un pointeur permet de résoudre divers


problèmes liés au:
– passage d’arguments de fonction par adresse,
– parcours de tableaux sans utiliser les indices.
– Allocation de la mémoire,
– Utiliser des structures complexes (liste linéaire
chainée, pile, file, …)

Fenineche Khadidja 8
2- Un pointeur en langage C

A/ Déclaration d’un pointeur


• Un pointeur est déclaré comme suit:
type *nom_pointeur;
• Il peut être initialisé avec la valeur NULL (pas
d’adresse):
Type * nom_pointeur=NULL;
• Il peut être initialisé avec l’adresse de la
variable qu’il pointe (la variable doit être
déclaré avant le pointeur dans ce cas):
Type * nom_pointeur=&nom_variable;
Fenineche Khadidja 9
2- Un pointeur en langage C

Exemples de déclaration de pointeurs


int *p;
int a;
p=&a;
• On déclare ici un pointeur et une variable de type
entier.
• On affecte l’adresse de a à p. Donc p va pointer a.
• Tout changement dans a est accessible via p par
*p (* symbole d’indirection ou
déréférencement).
Fenineche Khadidja 10
2- Un pointeur en langage C
B/ Affectation de valeurs à un pointeur et accès à
la valeur de la variable pointée par ce dernier
#include <stdio.h>
int main()
{ La même valeur est
int *p; /*déclaration d’un pointeur de type entier*/ dans *p et a (Toute
int a=1; modification de a
est une modification
p=&a; /*Affectation de l’adresse de a au pointeur*/ de *p et vice-versa
*p=5;
printf("la valeur de a est maintenant égale à %d\n",a);
printf("la valeur de a est maintenant égale à %d\n",*p);
a+=10;
printf("la valeur de a est maintenant égale à %d\n",*p);
return 0;
} Fenineche Khadidja 11
2- Un pointeur en langage C
C/ Affichage du contenu d’un pointeur, incrémentation,
opération sur la valeur référencée par le pointeur
On utilise %p pour afficher l’adresse que contient un pointeur
#include <stdio.h>
int main()
{
int a=1;
int *p=&a; /*déclaration d’un pointeur de type entier*/
printf("L'adresse de a est à %p\n",&a); /* affiche l'adresse de a*/
printf("L'adresse de a est à %p\n",p);/* affiche le contenu de p: adresse de a*/
(*p)++; /* incrémentation de la valeur de a */
printf("La valeur de a est à %d\n",a); /* affiche 2 */
*p++;
printf("La valeur de a est à %d\n",a); /* affiche 2, c'est l'adresse du pointeur qui
s'incrémente */
printf("L'adresse de a est à %p\n",p); /* affiche une nouvelle adresse dans p qui n’est
pas celle de a */
return 0;
}
Fenineche Khadidja 12
2- Un pointeur en langage C
D/ Remarques à retenir
• *p  a (sauf au niveau de la déclaration. Ex: int *p=&a)
• p  &a (sauf que p++ est correct, &a++ est fausse)
• int *p;  int* p;  int*p; int * p;
• On affiche la valeur d’un pointeur avec %p dans un
printf.
Exemple1:
Si p pointe x alors
*p=2; est équivalent à x=2;
Exemple2:
Affiche la valeur de p  afficher la valeur de &x.
Exemple 3 (lecture avec le pointeur):
int a = 0; int *p = &a; scanf("%d",
Fenineche Khadidja
p); /* non pas &p */ 13
2- Un pointeur en langage C

Exemples illustrés de
Kernighan et Ritchie
• int x = 1, y = 2, z[10];
• int *pi;
• pi = &x;
• y = *pi;
• *pi = 0;
• pi = &z[0];

Source: Internet
Fenineche Khadidja 14
2- Un pointeur en langage C
E/ opérations sur un pointeur
Un pointeur contient l’adresse du premier octet
d’une variable de type donné.
Si p pointe sur une variable de type int (4 octets)
alors p+1 est l’adresse +4.
Si p pointe un double (8octets) alors p+1 est
l’adresse +8.
4 octets (int)
Cette …….
Valeur entière 1 Valeur entière 2
représentation
est à retenir
pour les
tableaux P P+1 P+2

Fenineche Khadidja 15
3- Utilisation des pointeurs en langage C

A- Pointeur vers une structure


• On utilise les pointeurs avec les structures de
la façon suivante:
– On définit la structure,
– On déclare le pointeur vers cette structure.
– On accède aux champs avec le pointeur.

P->champ1  (*p).champ1
accède au contenu du champ de la variable pointée
par p de type structure.

Fenineche Khadidja 16
3- Utilisation des pointeurs en langage C
A- Pointeur vers une structure (Exemple)
#include <stdio.h>
struct article
{int code;
float prix;};
int main()
{
struct article art, *p=&art;
p->code=1452; /* accès à la valeur du champ de la variable pointée
par p */
p->prix=1000.00;
printf("Le code de l'article saisi est %d\n",art.code); /* (*p).code*/
printf("Le prix de l'article saisi est %f\n",art.prix); /* p->prix */
return 0;
}
Fenineche Khadidja 17
3- Utilisation des pointeurs en langage C
B- Pointeurs et passage de paramètres par adresse.
• Si on veut modifier le contenu d’une variable passée
comme paramètre à une fonction, on doit faire un
passage par adresse. Le passage par valeur laisse la
variable inchangée.
• Le passage par valeur ne peut retourner plus d’une
valeur à une fonction (return valeur).
• Le passage par adresse nécessite l’utilisation des
pointeurs.
• Les pointeurs permettent de rendre plus d’un
résultat au programme appelant.
• L’appel d’une fonction dans ce cas se fait avec
l’opérateur & avant la Fenineche
variable Khadidja
ou avec un pointeur. 18
B- Pointeurs et passage de paramètres par adresse (exemple1).
#include <stdio.h> #include <stdio.h>
int main() int main()
{void changer(int* x); {void changer(int* x);
int a=3; int a=3;
changer(&a);/* va multiplier a par int *p=&a;
5 */ changer(p);/* va multiplier a par 5
printf("La valeur de a est à */
%d\n",a); printf("La valeur de a est à
return 0; %d\n",*p);
} return 0;
void changer(int* x) }
{ void changer(int* x)
(*x)*=5; { (*x)*=5; }
}

Fenineche Khadidja 19
B- Pointeurs et passage de paramètres par adresse (exemple2).
#include <stdio.h>
int main()
{
void permuter(int* x, int*y); /* permute deux variables */
int a=3,b=5;
permuter(&a,&b);
printf("La valeur de a= %d et b= %d\n",a,b); /* a=5 et b=3*/
return 0;
}
void permuter(int*x,int*y)
{
int tmp;
tmp=*x;
*x=*y;
*y=tmp;
}
Fenineche Khadidja 20
3- Utilisation des pointeurs en langage C
C- Pointeurs et tableaux
• Le nom d’un tableau est considéré comme une
adresse (adresse du premier élément).
• Si on utilise un pointeur vers un tableau, ce dernier
sera égal au nom du tableau:
Exemple:
int M[5];
int *p;
p=M; /* ou p=&M[0]; */
• L’adresse d’un tableau est constante, on ne peut lui
affecter l’adresse stockée dans un pointeur.
• p=M; est vrai mais M=p; estKhadidja
Fenineche fausse 21
3- Utilisation des pointeurs en langage C
C- Pointeurs et tableaux
• On peut manipuler un tableau avec ses indices
comme d’habitude ou à l’aide de pointeurs avec
différentes façons.
• Il est à noter que:
Si p est &M[0] alors p+1 est &M[1], p+2 est &M[2],…
donc *p est M[0], *(p+1) est M[1], …
Ainsi, si on a: p=M
On peut afficher le tableau M de cette façon:
For(i=0;i<n;i++) printf("%d",*(p+i));)

Fenineche Khadidja 22
3- Utilisation des pointeurs en langage C
C- Pointeurs et tableaux
M

M[0] M[1] M[2]

*P *(P+1) *(P+2)

Remarque: A un moment
P P+1 P+2 donné P peut recevoir une
autre adresse mais ce n’est
&M[0] &M[1] &M[2]
pas le cas de M qui est une
valeur constante (adresse
constante).

Fenineche Khadidja 23
3- Utilisation des pointeurs en langage C
C- Pointeurs et tableaux (exemple avec les fonctions)
#include <stdio.h> 1- Initialise un tableau avec une
void init(int *x,int taille,int val) valeur val
2- On peut soit utiliser la
{int i;
méthode habituelle ou
for(i=0;i<taille;i++) x[i]=val; } *(x+i)=val;

void affiche(int *x,int taille)


{int i; Permet d’afficher le tableau
for(i=0;i<taille;i++) printf("%d\t",*(x+1)); avant et après affectation.
On peut utiliser aussi x[i]
printf("\n"); }

int main()
{ int T[5]={1,2,3,7,8};
affiche(T,5); 1- On initialise le tableau
avec la valeur 12.
init(T,5,12); /* initialise tout le tableau
2- on ne met pas &T car T est
avec 12 */ une adresse
affiche(T,5);
return 0; }
Fenineche Khadidja 24
3- Utilisation des pointeurs en langage C
C- Pointeurs et tableaux (opérations entre pointeurs et tableaux)
Soient les déclarations suivantes: int M[10], *P;
Les écritures suivantes peuvent être correctes ou fausses
• P= M; /* correct : P reçoit l’adresse du premier élément du
tableau M*/
• M = P; /* Erreur, on ne peut affecter à un tableau de cette
façon*/
• M++; /* Erreur, on ne peut passer à la case suivante de cette
manière.
• P = &M[1]; /* correct : P reçoit l’adresse du deuxième élément
du tableau*/
• *P += 1; /* correcte: incrémente M[1] de 1*/
• P += 1; /* correct: passe à l’élément M[2]*/
• *(M+1); /* équivalent à M[1] */
Fenineche Khadidja 25
3- Utilisation des pointeurs en langage C
Exemple d’affichage d’un tableau en utilisant les pointeurs

#include <stdio.h> #include <stdio.h>


int M[9]={20,4,30,3,7,6,9,2,0}; int M[9]={20,4,30,3,7,6,9,2,0};
int main() int main()
{ {
int i, *p; int i,*p;
p=M; p=M;
for(i=0;i<9;i++) for(i=0;i<9;i++)
{ printf("%d\t",*p); printf("%d\t",p[i]);
p++; } return 0;
return 0; }
}

Fenineche Khadidja 26
3- Utilisation des pointeurs en langage C
Exemple: Calcul de la longueur d’une chaine

#include <stdio.h>
int main()
{
int taille_chaine(char* chaine);
char ch[20];
printf("Introduisez votre chaine: ");
scanf("%19s",ch);
printf("La taille de la chaine %s est: %d",ch,taillechaine(ch));
}
int taillechaine(char* chaine)
{ int i = 0;
while(*(chaine+i)!='\0') i++;
return i;} Fenineche Khadidja 27
3- Utilisation des pointeurs en langage C
C- Pointeurs et tableaux à deux dimensions
• Un tableau a deux dimensions peut être considéré comme un
tableau simple et chaque case est elle-même un tableau
(tableau de tableaux).
• Soit un tableau M de 3X10 (mXn), alors M pointe sur la
première ligne.
• Si p pointe ce tableau alors les éléments sont accessibles via les
adresses suivantes:
• Pour un élément M[i][j], on y accède avec p par: p+j+i*n
P P+1 P+9
M 12 0 4 1 -2 2 3 45 4 5
P+0+10 P+1+10 P+9+10
M+1 7 8 -12 -3 1 0 2 9 42 12
P+0+2*10 P+1+2*10 P+9+2*10
M+2 -3 -5 5 1 4 5 7 1 0 2
Fenineche Khadidja 28
3- Utilisation des pointeurs en langage C
C- Exemple saisie des éléments d’un tableau à deux dimensions
avec les pointeurs)
#include <stdio.h>
#define m 2
#define n 3
int main()
{int X[2][3]={{1,3,6},{0,4,8}};
int *p; int i,j;
p=(int *)X;; \* p=X peut générer des erreurs de compilation donc il est préférable de forcer le type à
pointeurs de int vu que M pointe sur une ligne complète. On peut écrire p=&M[0][0] */
for (i=0;i<m;i++)
{ printf("Donnez les elements de la ligne %d:\n",i);
for (j=0;j<n;j++)
scanf("%d",p+n*i+j);
printf("\n");}
for (i=0;i<m;i++)
{ printf("les elements de la ligne %d: sont ",i);
for (j=0;j<n;j++)
{ printf("%d ",*(p+n*i+j)); }
printf("\n"); }
} Fenineche Khadidja 29
3- Utilisation des pointeurs en langage C
C- Pointeurs et tableaux à deux dimensions
Remarque: Un tableau à deux dimensions est représenté de façon
continue en mémoire.
Si M est un tableau d’entiers de m ligne et n colonne, on peut
afficher par exemple ses éléments par:
For(i=0;i<m*n;i++) printf("%d ",*(p+i));
int X[m][n];
int *p; int i,j;
p=(int*)X;
for (i=0;i<m;i++)
{printf("Donnez les elements de la ligne %d:\n",i+1);
for (j=0;j<n;j++)
scanf("%d",p+n*i+j);
printf("\n");}
/* Affichage avec une seule boucle */
printf("les elements du tableau sont:\n ");
for (i=0;i<m*n;i++)
printf("%d \n ",*(p+i));
Fenineche Khadidja 30
3- Utilisation des pointeurs en langage C
C- Pointeurs et tableaux à deux dimensions
Utilisation d’une seule boucle pour la saisie et l’affichage des
éléments d’un tableau à deux dimensions en utilisant (/ et %):
#include <stdio.h>
#define m 2
#define n 3
int main()
{int X[m][n];
int *p; int i,j;
p=(int*)X;
printf("Donnez les elements du tableau\n",i+1);
for (i=0;i<m*n;i++)
{
printf("X[%d][%d]=",i/n,i%n);
scanf("%d",p+i);
printf("\n");}
for (i=0;i<m*n;i++)
printf("X[%d][%d]=%d\n",i/n,i%n,*(p+i));
}
Fenineche Khadidja 31
3- Utilisation des pointeurs en langage C
D- Tableaux de pointeurs
• Exemple:
char *M[3]={“admis", “redouble", “exclu”}; déclare et initialise un
tableau de 3 pointeurs sur des chaines constantes.
• On affiche le contenu comme suit:
int i; for (i=0; i<3; I++) printf("%s\n", M[i]);
• On accède à un élément j d’une chaine pointée par le ieme
pointeur par: M[i]+j et à son contenu par : *(M[i]+j)
M
‘a’ ‘d’ ‘m’ ‘i’ ‘s’ ‘\0’

‘r’ ‘e’ ‘d’ ‘o’ ‘u’ ‘b’ ‘l’ ‘e’ ‘\0’

‘e’ ‘x’ ‘c’ ‘l’ ‘u’ ‘\0’


Fenineche Khadidja 32
3- Utilisation des pointeurs en langage C
D- Tableaux de pointeurs
• Exercice: Exploiter l’exemple précédent pour trier les chaines
par ordre alphabétique de telle façon d’obtenir le schéma
suivant (utiliser la fonction strcmp de la bibliothèque string.h):

M
‘a’ ‘d’ ‘m’ ‘i’ ‘s’ ‘\0’

‘e’ ‘x’ ‘c’ ‘l’ ‘u’ ‘\0’

‘r’ ‘e’ ‘d’ ‘o’ ‘u’ ‘b’ ‘l’ ‘e’ ‘\0’

Fenineche Khadidja 33
3- Utilisation des pointeurs en langage C
D- Tableaux de pointeurs #include <stdio.h>
#include <string.h>
• Solution de l’exercice: #define n 3
int main()
{int i,j;
char *M[]={"admis","redouble","exclu"};
/* Tri */
for (i=0;i<n-1;i++)
for (j=i+1;j<n;j++)
{char *c;
if (strcmp(M[i],M[j])>0)
{c=M[i];
M[i]=M[j];
M[j]=c;}
}
/* Affichage des chaines triées */
printf("\n");
for (i=0;i<n;i++) printf("%s \n",M[i]);
return 0;}

Fenineche Khadidja 34
Ressources bibliographiques

• Rémy Malgouyres, Rita Zrour, Fabien Feschet,


« Initiation à l’algorithmique et à la
programmation en C », Edition Dunod, 2014
• El Sakaan Nadim, « Programmation en langage
C », éditions pages bleues.
• http://monge.univ-
mlv.fr/~pivoteau/STRUCT/index.html

Vous aimerez peut-être aussi