Chapitre III
Chapitre III
Chapitre III
94
1 Introduction
Les variables utilisées dans un programme sont stockée
quelque part en mémoire centrale constituée d'octets
adjacents identifiés par un numéro unique : adresse.
95
1 Introduction
Quand on écrit :
int x = 3;
printf("x = %d et se trouve dans l’adresse : %d\n", x, &x);
97
2 Adresse et valeur d’un objet
Exemple :
int i, j;
i = 3;
j = i;
98
3 Notion de pointeur
Pointeur : objet (Lvalue) dont la valeur = une adresse.
Déclaration:
Type * nomPointeur;
99
3 Notion de pointeur
Exemples :
int *p1; /* pointeur sur une variable de type entier */
float *p2; /* pointeur sur une variable de type float */
Eleve *p3; /* pointeur sur une variable de type Eleve */
double **p5; /* pointeur sur un pointeur sur un double! */
100
3 Notion de pointeur
L'exemple suivant, définit un pointeur p sur un entier i :
int i = 3;
int *p;
p = &i;
101
3 Notion de pointeur
L'opérateur * permet d'accéder à la valeur de l'objet pointé.
Si p est un pointeur vers un entier i, *p désigne la valeur de i.
Exemple:
main(){
int i = 3;
int *p;
*p = 3
p = &i;
printf("*p = %d \n", *p);
}
Avant : i = 3 et *p = 3
Apres : i = 7 et *p = 7
103
3 Notion de pointeur
On peut donc dans un programme manipuler à la fois les
objets p et *p.
è Ces deux manipulations sont très différentes.
Comparons les deux programmes suivants :
(Programme 1) (Programme 2)
main(){ main(){
int i = 3, j = 6; int i = 3, j = 6;
int *p1, *p2; int *p1, *p2;
p1 = &i; p1 = &i;
p2 = &j; p2 = &j;
*p1 = *p2; p1 = p2;
} }
104
3 Notion de pointeur
Configuration des deux programmes avant la dernière affectation :
107
4 Arithmétiques des pointeurs
Exemple :
main(){
int i = 3;
int *p1, *p2;
p1 = 2293572 p2 = 2293576
p1 = &i;
p2 = p1 + 1;
printf("p1 = %ld \t p2 = %ld\n", p1, p2);
}
main(){
double i = 3; p1 = 2293568 p2 = 2293576
double *p1, *p2;
p1 = &i;
p2 = p1 + 1;
printf("p1 = %ld \t p2 = %ld\n", p1, p2);
}
p = &a;
110
5 Allocation dynamique
Il est également possible d'affecter directement une valeur à
*p, mais pour cela, il faut d'abord réserver à *p un espace-
mémoire de taille adéquate.
L’allocation de la mémoire en C se fait par la fonction malloc
de la librairie standard stdlib.h. dont le prototype est :
void *malloc(size_t size);
112
5 Allocation dynamique
Le programme suivant définit un pointeur p sur un objet *p
de type int, et affecte à *p la valeur de la variable i :
#include <stdio.h>
#include <stdlib.h>
main(){
int i = 3;
int *p;
printf("valeur de p avant initialisation = %d\n", p);
p = (int*)malloc(sizeof(int));
printf("valeur de p apres initialisation = %d\n", p);
*p = i;
printf("valeur de *p = %d\n",*p);
}
114
6 Pointeurs et tableaux
L'usage des pointeurs en C est, en grande partie, orienté vers
la manipulation des tableaux.
Tout tableau en C est en fait un pointeur constant.
Dans la déclaration :
int tab[10];
115
6 Pointeurs et tableaux
On peut donc utiliser un pointeur initialisé à tab pour
parcourir les éléments du tableau.
#define N 5
int tab[5] = {1, 2, 6, 0, 7};
main(){
int i;
int *p;
p = tab;
for (i = 0; i < N; i++){
printf("%d\t",p[i]);
}
}
1 2 6 0 7
116
6 Pointeurs et tableaux
On accède à l'élément d'indice i du tableau tab grâce à
l'opérateur d'indexation [], par l'expression tab[i].
Cet opérateur d'indexation peut en fait s'appliquer à tout
objet p de type pointeur.
Il est lié à l'opérateur d'indirection * par la formule :
p[i] == *(p + i)
117
6 Pointeurs et tableaux
Exemple:
#define N 5
int tab[5] = {1, 2, 6, 0, 7};
main(){
int i;
int *p;
p = tab;
for (i = 0; i < N; i++)
printf("%d\t", *(p+i));
}
1 2 6 0 7
118
6 Pointeurs et tableaux
Un tableau à 2D est, par définition, un tableau de tableaux.
èIl s'agit donc en fait d'un pointeur vers un pointeur.
Considérons le tableau à deux dimensions défini par :
int tab[M][N];
119
6 Pointeurs et tableaux
120
6 Pointeurs et tableaux
On déclare un pointeur qui pointe sur un objet de type Type *
(deux dimensions) de la même manière qu'un pointeur:
Type ** nomPointeur;
121
6 Pointeurs et tableaux
Exemple:
main(){
int k, n;
int **tab;
tab = (int**)malloc(k * sizeof(int*));
122
7 Pointeurs et structures
Contrairement aux tableaux, les objets de type structure
en C sont des Lvalues.
Ils possèdent une adresse, correspondant à l'adresse du
premier élément du premier membre de la structure.
On peut donc manipuler des pointeurs sur des structures.
123
7 Pointeurs et structures
Exemple:
struct Eleve {
char nom[20];
float note;
};
typedef struct Eleve Eleve;
typedef Eleve * Classe;
main(){
int n, i;
Classe TE;
printf("Nombre d'eleves de la classe : "); scanf("%d",&n);
TE = (Classe)malloc(n * sizeof(Eleve));
for (i =0 ; i < n; i++){
printf("\nSaisie de l'eleve numero : %d\n",i);
printf("\tNom : "); scanf("%s", TE[i].nom);
printf("\tNote : "); scanf("%f",&TE[i].note);
}
printf("\nEntrez un numero : "); scanf("%d",&i);
printf("\nEleve numero %d est : ", i);
printf("\nNom ===> %s",TE[i].nom);
printf("\nNote ===> %.2f\n",TE[i].note);
free(TE);
124
}
7 Pointeurs et structures
Si p est un pointeur sur une structure, on peut accéder à un
membre de la structure pointé par l'expression :
p-‐>membre
Ou
(*p).membre
125
7 Pointeurs et structures
Exemple:
struct Eleve {
char nom[20];
float note;
};
typedef struct Eleve Eleve;
main(){
Eleve * pE;
pE = (Eleve*)malloc(sizeof(Eleve));
strcpy(pE-‐>nom, "Alami");
pE-‐>note = 13;
printf("L'eleve %s a %.2f/20\n", (*pE).nom, (*pE).note);
free(pE);
}
126