Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Les pointeurs en C

Après cette leçon: Je peux lire et écrire du code C qui utilise des pointeurs.

Leçon de 60 min5 commandesLab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Un pointeur contient une adresse

Un pointeur, en langage C, est une variable qui contient l’adresse d’une autre variable. Lire du code C sans comprendre les pointeurs est impossible, car presque toutes les fonctions de la bibliothèque en reçoivent.

Une bibliothèque municipale note, pour chaque livre, le numéro de son étagère plutôt que le livre lui-même. Le pointeur joue ce rôle : on le suit pour trouver la valeur.

À la fin de cette leçon

Remarque

Je peux lire et écrire du code C qui utilise des pointeurs.

Mots-clés

MotCe que ça veut direExemple
Pointeurune variable qui contient une adresseint *p
Adresse del’opérateur & donne l’adresse d’une variable&x
Déréférencementl’opérateur * va lire ou écrire à l’adresse*p
Arithmétique de pointeursp + 1 avance d’un élément entier
NULLl’adresse spéciale qui ne désigne aucune variable

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Le signe & donne l’adresse, le signe * la suit

Écrire &x donne l’adresse de la variable x. Écrire int *p déclare un pointeur p vers un int. Le signe * devant un pointeur, comme dans *p, va à l’adresse et lit ou écrit la valeur qui s’y trouve.

Après p = &x, écrire *p = 9 change x lui-même. Il n’y a qu’une seule valeur, avec deux façons de l’atteindre.

Pointeurs vers un entier et un tableau

Code: c
int x = 7;
int *p = &x;
*p = 9;
int t[4] = {10, 20, 30, 40};
int *q = t;

Aller dans le dossier de travail

Commande
mkdir -p ~/c && cd ~/c

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le programme dans un fichier

Commande
printf '#include <stdio.h>\nint main(void) {\n    int x = 7;\n    int *p = &x;\n    *p = 9;\n    printf("%%d\\n", x);\n    int t[4] = {10, 20, 30, 40};\n    int *q = t;\n    printf("%%d %%d\\n", *(q + 1), q[2]);\n    printf("%%ld\\n", (long)((q + 3) - q));\n    printf("%%ld\\n", (long)((char *)(q + 3) - (char *)q));\n    return 0;\n}\n' > pointeurs.c

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Compiler et lancer le programme

Commande
gcc -Wall -o pointeurs pointeurs.c && ./pointeurs

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

p + 1 saute un élément, pas un octet

Un pointeur vers un int avance par pas de quatre octets, la taille d’un int. Le compilateur multiplie pour vous : q + 3 est l’adresse de départ plus 3 fois 4. Et q[2] s’écrit aussi *(q + 2).

Le programme a affiché 3 pour (q + 3) - q, une distance en éléments, puis 12 une fois les deux pointeurs convertis en pointeurs d’octets.

Exemple travaillé : un tableau de quatre entiers

ExpressionDécalage en octetsValeur lue
*q ou q[0]010
*(q + 1)420
q[2]830
*(q + 3)1240

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une fonction modifie une variable par adresse

En C, une fonction reçoit une copie de chaque argument. Pour qu’elle change la variable de l’appelant, on lui passe l’adresse de cette variable.

La fonction echanger reçoit deux pointeurs et échange les deux valeurs. L’appel echanger(&a, &b) change vraiment a et b, sans rien retourner.

Échanger deux entiers par leurs adresses

Code: c
void echanger(int *a, int *b) {
    int reserve = *a;
    *a = *b;
    *b = reserve;
}

Écrire le programme d’échange

Commande
printf '#include <stdio.h>\nvoid echanger(int *a, int *b) {\n    int reserve = *a;\n    *a = *b;\n    *b = reserve;\n}\nint main(void) {\n    int x = 1;\n    int y = 2;\n    echanger(&x, &y);\n    printf("%%d %%d\\n", x, y);\n    return 0;\n}\n' > echange.c

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Compiler et lancer l’échange

Commande
gcc -Wall -o echange echange.c && ./echange

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Erreur fréquente

Attention

Beaucoup de gens pensent qu’un pointeur déclaré contient déjà une adresse utilisable. Un pointeur sans valeur désigne n’importe quoi, et NULL ne désigne rien. Suivre l’un ou l’autre fait planter le programme. Donnez toujours une adresse valide à un pointeur avant d’écrire *p.

À propos de ce labo et de sa source: Lab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.