Cours programmation en langage C : Chapitre 6 - Les pointeurs
Ce cours porte sur les pointeurs en langage C, destiné aux étudiants de première année en informatique appliquée. Il explique les notions fondamentales d'adressage direct et indirect, la déclaration et l'utilisation des pointeurs, leur relation avec les tableaux, ainsi que l'arithmétique des pointeurs.
D'après le document Cours programmation en langage C : Chapitre 6 - Les pointeurs
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.
Document source
Computer Science · PDF · 9 pages · 2011
Afficher l'aperçu du document
Ce cours porte sur les pointeurs en langage C, destiné aux étudiants de première année en informatique appliquée. Il explique les notions fondamentales d'adressage direct et indirect, la déclaration et l'utilisation des pointeurs, leur relation avec les tableaux, ainsi que l'arithmétique des pointeurs. Ce matériel est conçu pour faciliter la compréhension et la manipulation des pointeurs dans la programmation C.
Adressage direct
En programmation, une variable stocke une information à un emplacement précis en mémoire. Le nom de la variable permet d'accéder directement à cette valeur. Cet accès s'appelle adressage direct.
Exemple :
int a = 10;
printf("%d", a); // affiche : 10
printf("%p", &a); // affiche l'adresse mémoire de a, par exemple : F800
Adressage indirect
Si l'on ne veut pas ou ne peut pas utiliser le nom d'une variable, on peut utiliser un pointeur, c'est-à-dire une variable spéciale qui contient l'adresse d'une autre variable. L'accès à la valeur se fait alors via ce pointeur. C'est l'adressage indirect.
Exemple :
int a = 10;
int *q;
q = &a;
printf("%d", a); // 10
printf("%p", &a); // adresse de a, par exemple F802H
printf("%p", q); // même adresse que &a : F802H
printf("%p", &q); // adresse de q, différente : F400H
printf("%d", *q); // 10, contenu pointé par q
On dit que q pointe sur a.
Définition : Pointeur
Un pointeur est une variable spéciale qui contient l'adresse d'une autre variable. En C, chaque pointeur est lié à un type de données précis. Un pointeur sur int ne peut contenir que l'adresse d'une variable de type int ou d'un élément d'un tableau d'int.
Remarque : Le nom d'une variable est lié à une adresse fixe, tandis qu'un pointeur peut changer d'adresse pointée.
Les opérateurs de base
- Opérateur adresse de : & — permet d'obtenir l'adresse d'une variable.
- Opérateur contenu de : * — permet d'accéder au contenu de l'adresse pointée par un pointeur.
- Déclaration d'un pointeur :
<Type> *<NomPointeur>;
Exemple d'utilisation de & avec scanf :
int n;
printf("donner un nombre entier : ");
scanf("%d", &n);
Attention : L'opérateur & ne peut s'appliquer qu'à des variables ou tableaux, pas à des constantes ou expressions.
Opérations élémentaires sur pointeurs
Les opérateurs unaires * et & ont la même priorité que les autres opérateurs unaires et sont évalués de droite à gauche.
Si P pointe sur une variable X, alors *P peut être utilisé partout où X est utilisé.
Exemples d'équivalences après P = &X; :
Y = *P + 1;équivaut àY = X + 1;*P = *P + 10;équivaut àX = X + 10;*P += 2;équivaut àX += 2;++*P;équivaut à++X;(*P)++;équivaut àX++;(parenthèses nécessaires)
On ne peut affecter qu'une adresse à un pointeur. Les pointeurs peuvent être affectés entre eux :
int *P1, *P2;
P1 = P2; // P1 pointe sur le même objet que P2
Pointeurs et tableaux
En C, le nom d'un tableau représente l'adresse de son premier élément. Ainsi :
tabest équivalent à&tab[0]tab[i]est équivalent à*(tab + i)&tab[i]est équivalent àtab + i
Exemple :
int tab[5] = {11, 12, 13, 14, 15};
| Indice | Valeur | Adresse (exemple) |
|---|---|---|
| 0 | 11 | F800 |
| 1 | 12 | F810 |
| 2 | 13 | F820 |
| 3 | 14 | F830 |
| 4 | 15 | F840 |
On peut accéder aux éléments ainsi :
tab[0]ou*tabou*(tab+0)donne 11tab[1]ou*(tab+1)donne 12- etc.
Exemple d'utilisation d'un tableau et d'un pointeur
int tab[5] = {11, 12, 13, 14, 15};
int *q;
q = tab; // q pointe sur tab[0]
printf("%d\n", *q); // 11
printf("%d\n", *(q+1)); // 12
printf("%d\n", *(q+4)); // 15
Exemple avec déplacement du pointeur
q = tab + 2; // q pointe sur tab[2]
printf("%d\n", *q); // 13
printf("%d\n", *(q+1)); // 14
printf("%d\n", *(q-2)); // 11
Incrémentation du pointeur
q = tab;
q++;
printf("%d\n", *q); // 12, q pointe sur tab[1]
Résumé sur pointeurs et tableaux
Pour un tableau tab de type int et un pointeur q sur int :
int tab[10];
int *q;
q = tab; // équivalent à q = &tab[0];
Les opérations suivantes sont valides :
q + ipointe sur la i-ème composante aprèsqq - ipointe sur la i-ème composante avantq*(q + i)donne le contenu de la i-ème composante aprèsq
Remarque : q + i n'adresse pas le i-ième octet après q, mais la i-ème composante, en tenant compte de la taille du type pointé.
Exemple :
float tab[20], X;
float *q;
q = tab;
X = *(q + 9); // X reçoit la valeur de tab[9]
Le compilateur calcule l'adresse en ajoutant 9 fois la taille d'un float (4 octets) à l'adresse dans q.
Attention : Le nom d'un tableau est une constante, on ne peut pas faire tab++, alors que q++ est permis.
Formalisation tableau et pointeur
Il est possible de traduire un programme utilisant la notation tableau en un programme utilisant la notation pointeur.
Exemple :
#include <stdio.h>
void main() {
int tab[50];
int i, n;
printf("saisir la taille du tableau ");
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &tab[i]);
for (i = 0; i < n; i++)
printf("l'element d'indice %d est %d \n", i, tab[i]);
}
Version équivalente en formalisme pointeur :
#include <stdio.h>
void main() {
int tab[50];
int i, n;
printf("saisir la taille du tableau ");
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", tab + i);
for (i = 0; i < n; i++)
printf("l'element d'indice %d est %d \n", i, *(tab + i));
}
Arithmétique des pointeurs
Le langage C permet d'effectuer des opérations arithmétiques sur les pointeurs, en tenant compte du type pointé :
- Affectation : Si
P1etP2sont pointeurs du même type,P1 = P2;fait pointerP1sur le même objet queP2. - Addition et soustraction : Si
Ppointe surA[i], alorsP + npointe surA[i + n]etP - nsurA[i - n]. - Incrémentation et décrémentation :
P++pointe surA[i + 1]P += npointe surA[i + n]P--pointe surA[i - 1]P -= npointe surA[i - n]
Domaine des opérations : Ces opérations sont définies uniquement à l'intérieur d'un tableau. Sortir du domaine du tableau produit un comportement indéfini.
Exemples
int A[10];
int *P;
P = A + 9; // légal : dernier élément
P = A + 11; // illégal : dépasse la taille
P = A - 1; // illégal : avant le début
Soustraction de deux pointeurs
Si P1 et P2 pointent dans le même tableau :
P1 - P2donne le nombre d'éléments entre eux.- Le résultat est négatif si
P1précèdeP2, zéro s'ils sont égaux, positif siP2précèdeP1. - Indéfini si les pointeurs ne pointent pas dans le même tableau.
Comparaison de pointeurs
On peut comparer deux pointeurs avec <, >, <=, >=, ==, !=. Si les pointeurs pointent dans le même tableau, la comparaison correspond à celle des indices.
Exemple de programme avec pointeur pour remplir et afficher un tableau
#include <stdio.h>
void main() {
int tab[50];
int i, n, *q;
printf("saisir la taille du tableau ");
scanf("%d", &n);
for (q = tab; q < tab + n; q++)
scanf("%d", q);
for (q = tab; q < tab + n; q++)
printf("l'element d'indice %d est %d \n", (int)(q - tab), *q);
}
Glossaire des termes clés
- Adressage direct : Accès à la valeur d'une variable via son nom.
- Adressage indirect : Accès à la valeur d'une variable via un pointeur contenant son adresse.
- Pointeur : Variable spéciale contenant l'adresse d'une autre variable.
- Opérateur & : Opérateur "adresse de" qui donne l'adresse d'une variable.
- Opérateur * : Opérateur "contenu de" qui donne la valeur pointée par un pointeur.
- Tableau : Ensemble contigu d'éléments de même type, dont le nom représente l'adresse du premier élément.
- Arithmétique des pointeurs : Opérations d'addition, soustraction, incrémentation et décrémentation sur des pointeurs, tenant compte de la taille des éléments pointés.
- Déclaration d'un pointeur : Syntaxe
<Type> *<NomPointeur>;pour déclarer un pointeur sur un type donné.
Points clés à retenir
- Un pointeur contient l'adresse d'une variable et permet un accès indirect à sa valeur.
- Les opérateurs
&et*sont essentiels pour manipuler les pointeurs. - Le nom d'un tableau est un pointeur constant vers son premier élément.
- Les expressions
tab[i]et*(tab + i)sont équivalentes. - L'arithmétique des pointeurs permet de naviguer dans un tableau en décalant le pointeur.
- Les opérations sur pointeurs doivent rester dans les limites du tableau pour éviter un comportement indéfini.
- On peut comparer et soustraire des pointeurs qui pointent dans le même tableau.
- La manipulation des pointeurs est plus flexible que celle des noms de tableaux, qui sont des constantes.
Commentaires
Aucun commentaire pour le moment. Posez la première question.