0% ont trouvé ce document utile (0 vote)
45 vues21 pages

Introduction aux Pointeurs en C

Transféré par

mouadfushigurochico
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
45 vues21 pages

Introduction aux Pointeurs en C

Transféré par

mouadfushigurochico
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

2/22

Chapitre I

Les Pointeurs

espace
Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée
4/22

1. Introduction : Définitions de base

Variable

Dans beaucoup de langages, les informations sont manipuler par le biais de


variables.
Une variable est un emplacement ou zone de l’espace mémoire portant un nom
et dont le contenu peut évoluer.
Elle peut être composée d’une ou plusieurs cases mémoire.
Une variable a une adresse qui correspond à l’adresse de la première case. On
l’obtient avec l’opérateur &.
&a = adresse de a
Une variable a un type.
Le type d’une variable indique le nombre de cases qu’elle occupe.
Une variable de type tableau est constituée d’un ensemble de variables de même
type.

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


5/22

2. Les Pointeurs

Présentation générale
Le langage C est un langage de programmation qui offre la possibilité d’accéder
aux données dans la mémoire de l’ordinateur à l’aide de pointeurs,
et permet de manipuler des adresses d’objets informatiques (valeurs, variables,
fonctions,...) par le biais des pointeurs.
Autrement, l’utilisation des pointeurs en langage C permet d’avoir un accès à la
mémoire par les adresses sans passer par les identifcateurs.
Ceci permet de se déplacer dans la mémoire et par suite l’optimisation de son
utilisation.
Un pointeur peut être défini comme étant un emplacement en mémoire
destinées à contenir les adresses d’autres objets informatique.
En langage C, les pointeurs jouent un rôle essentiel
pour échanger avec une fonction un gros volume de données. En effet, le
passage des paramètres en C se fait toujours par la valeur, les pointeurs
sont le seul moyen de changer le contenu de variables déclarées dans
d’autres fonctions.
Pour traiter des tableaux dynamiques et de chaı̂nes de caractères.
La manipulation des structures de données avancées (listes, piles, files,
arbres, graphes).
Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée
6/22

2. Les Pointeurs

Présentation générale (suite)

Syntaxe : L’utilisation d’un pointeur se fait selon la syntaxe suivante :

type * identificateur ;

L’accès à une variable se fait par l’application de l’opérateur * (dit opérateur de


déréférenciation) à un pointeur.
Pour obtenir l’adresse d’une variable on utilise l’opérateur &. Exemple :

int *p,x=2; //p variable destinée à recevoir une adresse d’entier, x recoit 2
p=&x; //p recoit l’adresse de la variable x
printf("%X ",p); //affiche, en hexadecimal l’adresse de x stockée dans p
printf("%d ",*p); //affiche 2, l’entier pointé par p
printf("%d ",x); //affiche 2, la valeur stockée dans la variable x
*p=13; //place la valeur 13 dans l’objet (varaible x) pointé par p
printf("%X ",p); //affiche, en hexadecimal l’adresse de x stockée dans p
printf("%d ",*p); //affiche 13, l’entier pointé par p
printf("%d ",x); //affiche 13, la valeur stockée dans la variable x

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


7/22

2. Les Pointeurs

Remarque

Rappelons qu’en langage C, nous utilisons des variables pour stocker et


manipuler des informations.
La valeur d’une variable se trouve à un emplacement spécifique dans la mémoire.
Pour accéder à cette valeur, on utilise 2 techniques :
Adressage direct : Accès au contenu d’une variable par le nom de la
variable. Exemple :

int x;
x=5; cases mémoires 5
adresses 1E04 1E06 1E08 1E0A

Adressage indirect: Accès au contenu d’une variable, en passant par un


pointeur qui contient l’adresse de la variable. Exemple :

x p

int x=5, *p;


p=&x;
5 1E06
1E04 1E06 1E08 3F06 3F08 3F0A

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


8/22

2. Les Pointeurs

Exemple et exercice
Commenter et exécuter les lignes du programme suivant :
#include<stdio.h>
main()
{ int *p,*q,x=7;
p=&x;
printf("%X \n",p);
printf("%X \n",q);
printf("%d \n",*p);
printf("%d
("%d \n",*q);
\n",x);
printf("%d \n",x);
*p=11;
q=&x;
printf("%X \n",p);
printf("%X \n",q);
printf("%d \n",*p);
printf("%d \n",*q);
printf("%d \n",x);
q=&p;
printf("%X \n",p);
printf("%X \n",q);
printf("%d \n",*p);
printf("%X \n",*q);
printf("%d \n",x);
}

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


9/22

2. Les Pointeurs

Les opérations élémentaires sur pointeurs (1)

Les adresses sont des nombres sur lesquels on peut réaliser des calculs.
C-à-d, on peut ajouter une valeur numérique à une adresse pour accéder à une
autre case mémoire.
En C, il y a des règles particulières pour les opérations de calcul des adresses.
C’est ce qu’on appelle l’arithmétique des pointeurs.
En effet, on peut effectuer des calculs basées sur des pointeurs. Autrement, on
peut ajouter ou soustraire un entier à un pointeur ou faire la différence de deux
pointeurs.
Les seules opérations valides sont les opérations externes :
addition et soustraction des entiers,
la soustraction de pointeurs.
Elles sont définies comme suit (la soustraction d’un entier est considérée comme
l’addition d’un entier négatif) :
p + i = adresse contenue dans p + iútaille(élément pointé par p)
p1 ≠ p2 = adresse contenue dans p1 - adresse contenue dans p2
Si p est un pointeur de type entier, p+1 est donc le pointeur sur l’entier qui suit
immédiatement celui pointé par p.
C-à-d que l’entier qu’on additionne au pointeur est multiplié par la taille de
l’élément pointé pour obtenir la nouvelle adresse.
Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée
10/22

2. Les Pointeurs

Exemple 1

Soit le programme C suivant :


#include <stdio.h>
main()
{ int x=7;
int *p;
p=&x;
printf("Adresse de p est %X \n",p);
printf("Adresse de p+1 est %X \n",p+1);
printf("Adresse de p+2 est %X \n",p+2);
}

Ce programme affiche
Adresse de p est 12FF7C
Adresse de p+1 est 12FF80
Adresse de p+2 est 12FF84

Commentaire

Les résultats sont affichés en hexadécimal (le code des adresses mémoire).
On remarque que dans la ligne 8, le compilateur a ajouté 4 octets à l’adresse
contenue dans p.
La ligne 9 affiche 12FF84, 4 octets de plus par rapport à 12FF80. Il y a donc
une nouvelle fois un décalage de 4 octets.
Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée
11/22

2. Les Pointeurs

Exemple 2

Soit le programme C suivant :


#include <stdio.h>
main()
{ int x=3, y=5,z=7;
int *p, *q, *u;
p=&x; q=&y; u=&z;
printf("Adresse de p-q est %d
%X \n",p-q);
printf("Adresse de p-u est %d
%X \n",p-u);
printf("Adresse de u-q est %d
%X \n",u-q);
}

Ce programme affiche
Adresse de p-q est 1
Adresse de p-u est 2
Adresse de u-q est -1
FFFFFFFF

Commentaire
Remarque

En
Le fait, on peut
résultat de ladire que la soustraction
soustraction de deux P1
de deux pointeurs pointeurs n’est que l’opération
et P2 est:
inverse de l’incrémentation : si p1 et p2 sont des pointeurs de même type tels que l’on
- Négatif, si P1 précède P2
- Zéro, si P1 = P2
ait p2 = p1 si
- Positif, + i,
P2alors p2 ≠
précède P1p1 = i ou p1 ≠ p2 = ≠i.

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


12/22

2. Les Pointeurs

Les opérations élémentaires sur pointeurs (2)

Rappelons qu’en C, les pointeurs servent à manipuler des adresses.


Mais leur intérêt principal est de permettre d’appliquer aux objets pointés des
opérations comparables à celles qu’on applique à une variable ”ordinaire”.
Incrémenration :
– *p+=2 équivalent à *p=*p+2 (augmenter de 2 la valeur de l’objet pointé par p).
– (*p)++ équivalent à *p=*p+1 (augmenter de 1 la valeur de l’objet pointé par
p).
Attention ! aux parenthèses, *p++ serait équivalent à *(p++)
– On trouve la même chose si on utilise l’opérateur --.
Affectation :
– Si p et q sont deux pointeurs alors l’instruction p=q signifie que p et q
pointent sur le même objet.
– L’affectation p=q n’est correcte que si p et q sont de même type.
Le pointeur NULL :
– Le pointeur NULL est une adresse fictive ne correspondant à aucune zone de
mémoire accessible.
– Dans la plupart des systèmes, il vaut 0. C’est une constante définie
notamment dans le fichier stdio.h.
– La constante NULL sert à la fois pour initialiser un pointeur et pour vérifier
qu’un pointeur est initialisé.
Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée
13/22

2. Les Pointeurs

Exemple et exercice

Soit le programme C suivant :

#include <stdio.h>
main()
{ int x=1, y=2,z=3;
int *p, *q;
p=&x; q=&z;
*p=(*q)++;
p=q;
q=&y;
*p-=*q;
++*q;
*p*=*q;
x=++*q**p;
p=&x;
*q=*p/=*q;
}

1 Commenter ligne par ligne de ce programme.


2 A chaque ligne du programme, donner les valeurs stocker dans les variables x, y,
z et les valeurs des variables pointées par les pointeurs p et q.

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


14/22

3. Pointeurs et tableaux

Il existe une relation très étroite entre les pointeurs et les tableaux. Rappelons que :

Un tableau est un ensemble de variables de même type qui sont stockés les unes à la suite des

autres en mémoire.
Un pointeur contient une adresse qui lui permet d’accéder à une variable en mémoire.
Il est possible, grâce à l’arithmétique des pointeurs, de modifier le contenu du pointeur afin
d’accéder à une autre variable.
Définir des pointeurs vers les tableaux est l’unique solution pour passer un tableau à une fonction.
En C, le nom d’un tableau correspond à l’adresse du premier élément du tableau. En d’autre terme, si
int tab[20]; est une déclaration d’un tableau de 20 entiers portant le nom tab alors
&tab[0] et tab sont une seule et même adresse. C-à-d, le nom d’un tableau est un pointeur (constant qui
ne peut pas être modifié) sur le premier élément du tableau.
Exemple :
1.#include<stdio.h>
2. main()
3. {
4. int tab[5]={1,2,3,4,5};
5. int *pTab;
6. pTab=tab;
7. printf(" %d \n",*tab); // Affiche : 1
8. printf("%d \n",pTab[0]); // Affiche : 1
9. }
Commentaire : Les lignes 7 et 8 montrent que le nom d’un tableau peut être utilisé comme un pointeur sur
son premier élément.

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


15/22

3. Pointeurs et tableaux

Ainsi,

nous pouvons employer la notation pointeur pour désigner les éléments du tableau.

Inversement, nous pouvons utiliser la notation tableau avec un pointeur.


Exemple :
1.#include<stdio.h>
2. main()
3. {
4. int tab[10];
5. int *pTab;
6. pTab=tab;
7. *tab=1;
8. pTab[0]=1;
9. *(tab+1)=2;
10. pTab[1]=2;
11. }
Commentaire :
– A la ligne 6, le pointeur pTab est initialisé avec l’adresse de tab.
– Les lignes 7 et 8 initialisent le premier élément du tableau tab avec 1. A la ligne 7, le tableau est
manipulé avec la notation pointeur *, alors qu’à la ligne 8, c’est le pointeur qui est utilisé avec la
notation tableau [].
– Même chose, pour les lignes 9 et 10.
D’une façon générale, on peut toujours utiliser la notation tableau avec un pointeur ou la notation pointeur
avec tableau. En C, on utilise souvent la notation tableau dans tous les cas.

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


16/22

3. Pointeurs et tableaux

Remarque :

Si pTab pointe sur un élément quelconque d’un tableau, alors pTab+1 pointe sur
l’élément suivant. Plus généralement,
– pTab+i pointe sur le i-ième élément devant pTab.
Ainsi, si pTab pointe sur tab[0] alors
– *(pTab+1) désigne le contenu de tab[1].
– *(pTab+i) désigne le contenu de tab[i].
Notons que, le compilateur se charge d’effectuer les calculs lorsqu’on incrémente
et décrémente des pointeurs. En effet,
– Pour l’instruction tab+3 (ou *(pTab+3) le pointeur ne se déplace pas de 3
octets à droite mais de 3 objets après l’adresse de tab.

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


17/22

3. Pointeurs et tableaux

Exemple et exercice :

Commenter et donner le résultat du programme C suivant :


1.#include<stdio.h>
2. main()
3. {
4. int tab1[20], tab2[10];
5. int i,j;
6. for(j=0,i=0;i<20;i++)
7. {
8. *(tab1+i)=i+1;
9. if(*(tab1+i)%2==0)
10. {
11. *(tab2+j)=*(tab1+i);
12. j++;
13. }
14. }
15. for(i=0;i<20;i++)
16. printf("%d ",tab1[i]);
17. printf("\n");
18. for(i=0;i<10;i++)
19. printf("%d ",tab2[i]);
20. printf("\n");
21. }

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


18/22

4. Pointeurs et fonction

Pointeur en paramètre de fonction

L’une des utilités des pointeurs est de permettre à des fonctions d’accéder aux
données elles même et non à des copies.
En effet, la fonction recoit l’adresse de l’argument formel, ensuite elle travaille
directement sur cette adresse. En conséquence, elle peut modifier la valeur de
l’argument formel.

Exemple 1 :

calcul de min de deux entiers calcul de puissance d’un entier


Définition de la fonction : Définition de la fonction :
void min(int a, int b, int *m) void puissance(int x, int n, int *res)
{ {
if(a<b) int i;
*m=a; *res=a;
else for(i=1;i<n;i++)
*m=b; *res=(*res)*a;
} }
Appel de la fonction : Appel de la fonction :
min(12,19,&m); puissance(3, 4, &res);
Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée
19/22

4. Pointeur et fonction

Pointeur en paramètre de fonction (suite)

Exemple 2 : Passer un tableau à une fonction

En fait, pour passer un tableau à une fonction, on doit toujours envoyer


l’adresse de ce tableau.
Toute fonction qui récupère un tableau doit définir un argument de type
pointeur pour stocker l’adresse du tableau.
L’exemple suivant montre la définition et l’utilisation d’une fonction qui permet
la saisie, au clavier, des élément d’un tableau :

Définition de la fonction :
void saisieTableau(int *tab, int taille)
{ int i;
for(i=0;i<taille;i++)
{
printf("tab[%d]= ",i+1);
scanf("%d",&tab[i]);
}
}
Appel de la fonction :
saisieTableau(tab, 20);

Exercice : Écrire un programme en C, en utilisant des fonctions, permettant


la saisie, l’affichage et l’échange des valeurs d’un tableau.
Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée
20/22

4. Allocation dynamique de mémoire

L’allocation de mémoire est nécessaire pour les raisons suivantes :


lorsque la taille mémoire nécessaire au stockage des données n’est pas
connue à l’écriture du programme, le programmeur doit demander au
système d’exploitation de lui allouer de la mémoire durant l’exécution.
Cette mémoire est allouée dynamiquement dans une zone dédiée appelée
tas (heap).
L’accès à la mémoire doit être réglementé pour qu’il n’y ait pas de conflits
tels que des zones utilisées deux fois.
La fonction malloc() de la bibliothèque <stdlib> permet d’allouer un bloc de
mémoire (un ensemble de cases contigues).
Elle prend en paramètre le nombre de cases à allouer et elle retourne un
pointeur vers la première case de la zone allouée. En effet :
malloc(n)≠æ retourne l’adresse d’un bloc en mémoire de n octets libres ou la
valeur zéro s’il n’y a pas assez de mémoire.
La réservation de la mémoire pour des données d’un type dont la grandeur varie
d’une machine à l’autre exige la grandeur effective d’une donnée de ce type.

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée


21/22

4. Allocation dynamique de mémoire

L’opérateur unaire sizeof() aide à préserver la portabilité du programme. En


fait,
L’opérateur sizeof() prend un type en paramètre et retourne sa taille en
nombre de cases (i-e. en nombre d’octets).
L’opérateur sizeof() n’est pas une fonction.
– sizeof(variable) ≠æ retourne la grandeur de la variable variable.
– sizeof(const) ≠æ retourne la grandeur de la constante const.
– sizeof(type) ≠æ retourne la grandeur pour un objet du type type.
La fonction free() complète malloc().
Elle permet de libérer un bloc de mémoire.
Elle prend en paramètre l’adresse de la zone de mémoire à libérer. Cette adresse
doit avoir été retournée par malloc() et elle ne doit pas avoir déjà été libérée.
Une zone de mémoire libérée ne doit plus être utilisée.

Filière SMIA Parcours SMI & SMA Semestre3 Programmation C avancée

Vous aimerez peut-être aussi