Leçons de niveau 14

Introduction au langage C/Pointeurs

Une page de Wikiversité.
Sauter à la navigation Sauter à la recherche
Début de la boite de navigation du chapitre
Pointeurs
Icône de la faculté
Chapitre no 9
Leçon : Introduction au langage C
Chap. préc. :Structures répétitives
Chap. suiv. :Pointeurs de fichiers
fin de la boite de navigation du chapitre
Icon falscher Titel.svg
En raison de limitations techniques, la typographie souhaitable du titre, « Introduction au langage C : Pointeurs
Introduction au langage C/Pointeurs
 », n'a pu être restituée correctement ci-dessus.

Présentation[modifier | modifier le wikicode]

Un pointeur est une variable qui contient l'adresse d'une autre variable.

La mémoire vive est découpée en un ensemble de cases, le plus souvent d’un octet (8 bits). Chaque case est identifiée par une adresse. Quand on déclare une variable, une ou plusieurs cases, en fonction du type de variable, sont alors réservées (allouées).

Quand on veut récupérer l'information contenue dans la mémoire, on utilise soit l'identifiant de la variable, soit son adresse qui correspond à la première case mémoire de l'allocation.

Chaque pointeur est « typé », c'est-à-dire qu’il pointe vers un type précis de variable.

Déclaration
type * identificateur;
La variable identificateur est un pointeur vers une variable de type type.
L'opérateur &
Il permet d'obtenir un pointeur vers une variable.
&identificateur permet d'obtenir un pointeur vers la variable identificateur. Il renvoie en réalité une adresse mémoire, l'adresse où est stockée physiquement la variable identificateur. C’est donc une variable pointeur.
L'opérateur *
* variable
C'est l'opérateur de déréférencement. Il permet d'obtenir et donc de manipuler les données pointées par la variable : variable
*pointeur permet d'obtenir la valeur de la variable pointée par pointeur.

Conseil de codage à respecter : c_rec_13.

Searchtool.svg Voir aussi les pointeurs dans le WikiLivre Programmation C, chapitre Pointeurs.

Déclaration de pointeur[modifier | modifier le wikicode]

int * entier; //Pointeur d'entier
char * caractere; //Pointeur de caractère
struct ELEM * e; //Pointeur e sur une structure de type ELEM

Affectation de l'adresse d'une variable[modifier | modifier le wikicode]

int entier; //Variable entière
int * ptINT; //Pointeur d'entier

entier = 15; //Affectation de valeur
ptINT = &entier; //Affectation d'adresse
(*ptINT)++; //Déréférencement et incrémentation de la valeur pointée.
(void)printf("%d\r\n",entier); // affiche 16
(void)printf("%d\r\n", *ptINT); // affiche 16

Le symbole '&' (et commercial) renvoie l'adresse d'une variable. Lorsqu'on met un '*' devant un pointeur on accède a la valeur pointée par ce pointeur.

Dangers liés aux pointeurs[modifier | modifier le wikicode]

Le problème[modifier | modifier le wikicode]

Les pointeurs ont énormément d’applications et permettent notamment l'accès à la totalité des zones de la mémoire, ce qui peut être dangereux car le programme pourrait lire ou écrire une zone qui ne correspond pas à la donnée souhaitée.

Les pointeurs sont aussi utilisés pour l'allocation mémoire qui est aussi un des points dangereux du langage.

L'utilisation de pointeurs peut conduire à des programmes incompréhensibles pour des programmeurs habitués à d'autres langages.

Quelques causes possibles[modifier | modifier le wikicode]

  • Utiliser un pointeur non initialisé ou ayant valeur nulle.
  • Passer une valeur au lieu d’un pointeur à un fonction comme scanf.

Les conséquences[modifier | modifier le wikicode]

Les systèmes d'exploitations modernes limitent les dégâts dus à ces erreurs : dès qu'un programme écrit dans un emplacement en mémoire qui ne lui est pas alloué, le sytème d'exploitation l'arrête.

Par contre, rien n'empêche un processus d'effectuer ces opérations dans son espace d'adressage, ce qui aura souvent des effets désastreux ou imprévus : écrasement de zones de données et erreur d'exécution, ayant des répercutions dans du code parfois très distant de l'erreur initiale.

Les solutions[modifier | modifier le wikicode]

  • Ne pas abuser de l'usage des pointeurs. Dans le cas des tableaux et des chaines de caractères, préférer leur parcours en utilisant des indices entre crochets.
  • Utiliser une notation aidant à distinguer une variable pointeur des autres variables. Par exemple, en préfixant par "p_" toutes les variables pointeurs.

Par exemple, écrire

int * p_entier; //Pointeur d'entier
char * p_caractere; //Pointeur de caractère
struct ELEM * p_e; //Pointeur e sur une structure de type ELEM

plutôt que:

int * entier; //Pointeur d'entier
char * caractere; //Pointeur de caractère
struct ELEM * e; //Pointeur e sur une structure de type ELEM
  • Une solution radicale contestable : utiliser un autre langage. Les langage modernes comme Java ont abandonné le concept de pointeur et utilisent celui des références pour une question de sécurité.

TP[modifier | modifier le wikicode]

Searchtool.svg Faîtes les exercices du WikiLivre Exercices en langage C sur les pointeurs.