Outils pour utilisateurs

Outils du site


nsi:langages:c:pointeurs

Pointeurs

Variable ordinaire

Supposons que je définisse un entier :

int x = 12;

La déclaration int x réserve en mémoire un espace de deux octets destinés à contenir un entier. On écrit aussitôt 12 en codage CA2, donc 0000 0000 0000 1100 dans ces deux octets.

Dans la suite du programme, on pourra rencontrer des lignes comme

y = x + 3;
x = 5;
x = x + 1;
  • ligne 1 : c'est la valeur contenue dans la case mémoire étiquetée x qui intervient dans le calcule. Donc ici ce serait 12.
  • ligne 2 : on écrit la valeur 5 dans la case mémoire étiquetée par x
  • linge 3 : les deux cas précédents l'un après l'autre. On commence par lire le contenu de la mémoire étiquetée par x, on trouve 5, on fait le calcul qui donne 6 et on écrit le résultat dans la mémoire étiquetée par x.

À chaque fois, x désigne le contenu d'une certaine mémoire contenant un entier.

Adresse

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

int main() {
    int x = 12;
    printf("%u\n", &x);
    return 0;
}

ligne 6, on affiche &x c'est à dire l'adresse de la mémoire x.

Le formatage demandé est "%u\n", c'est l'affichage d'un entier non signé (binaire naturel, pas de CA2, ce qui est logique étant donné que l'adresse ne devrait pas être négative !)

Donc le caractère & sert à obtenir l'adresse d'une variable (déjà été signalé dans l'appel de fonction scanf lors de l'exemple de l'imc.)

Pointeur

Un pointeur est une variable dont le contenu est une adresse vers un contenu en mémoire.

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

int main() {
    int x = 13;
    int *p;
    p = &x;
    printf("%u\n", p);
    printf("%d\n", *p);
    return 0;
}
  • Ligne 5 on définit la variable x contenant 13.
  • Ligne 6 on définit un pointeur p qui devra pointer une case mémoire contenant un entier.

Comprendre que p contiendra l'adresse mémoire d'une mémoire contenant un int.

  • Ligne 7, on affecte à p l'adresse de x si bien que le pointeur p pointe maintenant sur la case mémoire x.
  • Ligne 8, le contenu de p est donc l'adresse.
  • Ligne 9, en écrivant *p on désigne le contenu de la case mémoire pointée, donc ici le contenu de x. En quelque sorte, * fait le contraire de &.

Remarque : On peut écrire int* p qui est équivalent à int *p.

Ce qu'on ne pourrait pas faire...

int *p = 17;

Ne fonctionnera pas. En effet, en définissant int *p on définit la variable p pointant sur un entier, mais on n'a pas définit sur quel entier p doit pointer. Pour l'instant p ne pointe nulle part et on n'a donc aucun endroit où écrire 17.

int x = 17;
int *p;
*p = 17;

Ne fonctionnera pas non plus, pour la même raison.

Mais ceci fonctionne...

int x = 17;
int *p = &x;
*p = 25;

Cette fois on initialise p en lui donnant une adresse &x ce qui revient à dire que p pointera sur x. Prenons l'exemple plus complet :

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

int main() {
    int x = 17;
    int *p = &x;
    *p = 25;
    printf("%d\n", x);
    return 0;
}

En ligne 7, on modifie le contenu de la case pointée par p, c'est à dire que l'on modifie x ce que l'on voit ligne 8 lors de l'affichage de x.

Autrement dit, dès lors que p = &x, *p devient équivalent à x.

nsi/langages/c/pointeurs.txt · Dernière modification : de goupillwiki