Pointeur (programmation)

Pointeur (programmation)
Page d'aide sur l'homonymie Pour les articles homonymes, voir pointeur.

Un pointeur est en programmation une variable contenant une adresse mémoire.

Sommaire

Utilité

Le pointeur a pointe sur la variable b. On peut noter que b contient un nombre (en hexadécimal 00000011 = en décimal 17), et que a contient l'adresse de b en mémoire (en hexadécimal 1008). Dans ce cas précis, l'adresse et la donnée sont contenues dans 32 bits.

La notion de pointeur reflète l'utilisation différente que l'on peut faire d'un nombre entier, à savoir indiquer une adresse mémoire. Cette utilisation est très différente d'une utilisation arithmétique, d'où la création de registres processeurs spécifiques (les registres d'adresse) et d'un type de donnée spécifique dans les langages de programmations.

Les pointeurs "typés", le type le plus répandu de pointeur actuellement, sont apparus avec le langage C, qui a ajouté un typage sur les données pointées par le pointeur. Quand on incrémente un tel pointeur, il n'est en fait pas forcément incrémenté de un, mais de la taille du type pointé.

L'utilisation des pointeurs permet d'avoir accès à la couche basse de l'ordinateur, un accès direct à la mémoire. On peut littéralement se déplacer de case mémoire en case mémoire. Cette technique permet d'effectuer des optimisations sur l'utilisation de la mémoire ou la performance en termes de vitesse.

Les pointeurs sont entre autres utilisés pour stocker les adresses des zones mémoires allouées dynamiquement par l'application. Si on alloue un bloc de taille T et qu'on reçoit l'adresse A en retour, cela veut dire que le bloc occupe la mémoire à partir de l'adresse A jusqu'à l'adresse A+T-1.

Dans les langages de plus haut niveau, l'utilisation des pointeurs est supprimée, au profit des références et des tableaux dynamiques gérés par le compilateur. Les références remplissent certaines fonctions des pointeurs en supprimant l'accès à la mémoire. Cela évite beaucoup de problèmes, en contrepartie certaines utilisations et optimisations ne sont plus possibles.

Complexification

L'utilisation des pointeurs est très puissante dans certains langages. Cette puissance (et surtout le fait que l'on touche directement à la mémoire sans aucun contrôle) complexifie le développement d'une application.

Si l'on ne fait pas attention et que l'on accède à une zone mémoire qui ne nous est pas allouée, le processeur via le système d'exploitation génèrera une erreur de segmentation qui provoquera une exception voire fera planter l'application. De plus, comme les allocations mémoire sont réalisées en partie par le développeur, il doit également se charger de la libération de la mémoire lorsqu'il n'en a plus besoin, au risque de voir une fuite mémoire apparaître.

Tous ces inconvénients obligent le développeur à prendre en charge des choses supplémentaires, compliquant ainsi l'application et pouvant ajouter des bugs.

Pour toutes ces raisons, les pointeurs sont regardés avec une certaine méfiance. 01 Informatique les a qualifié d'« aussi puissants qu'ils sont dangereux » [1], en expliquant les atouts du langage D. En effet, au vu des avantages et inconvénients des pointeurs, ce langage a été conçu pour en autoriser l'usage aux programmeurs appréciant leur efficacité, tout en fournissant constamment des solutions alternatives à ceux qui s'en méfient.

Langages utilisant les pointeurs

Les pointeurs sont, entre autres, utilisés par le C, le C++, le Pascal, Ada, FreeBASIC, Fortran, C#, D, Modula-2, Oberon et bien sûr l'Assembleur.

Pointeurs en Assembleur

Ce langage ne connait en fait que deux notions pour stocker des données : les registres (assimilables à des variables globales), et les adresses mémoire (qui sont très précisément des pointeurs). Le langage est tellement proche de la machine qu'il est quasiment impossible de se passer de la notion de pointeur.

Pointeurs en C et C++

Les deux principaux langages utilisant énormément les pointeurs sont le C et le C++. Dans ces langages, un pointeur est déclaré avec une étoile '*' postposé au type. On récupère l'adresse d'une variable avec un et commercial '&'.

L'étoile, préposée, sert également à déréférencer l'adresse d'un pointeur, autrement dit à avoir accès au contenu « pointé » par ledit pointeur.

Voici un petit exemple :

int a = 2;       // Déclaration de la variable a de type int (entier) et initialisé avec 2
int * p = NULL;  // Déclaration d'un pointeur sur un int qui vaut NULL
p = &a ;         // L'adresse de a est affectée au pointeur p
//Actuellement a vaut 2
*p = 5;          // Déréférencement de p, pour affecter 5 à la variable a
//Maintenant a vaut 5

Pointeurs en COBOL

Les diverses implémentations du langage comportent la notion de pointeur en COBOL. Bien que rarement employé, il n'en demeure pas moins un outil d'interface avec des programmes écrits en C ou en assembleur.

Un pointeur constitue en COBOL une variable déclarée en DATA DIVISION :

     05  POINTEUR-1       USAGE IS POINTER.
     05  POINTEUR-NUL     USAGE IS POINTER VALUE NULL.

Il est ensuite utilisé en PROCEDURE DIVISION.

Le pointeur stocke l'adresse mémoire d'une donnée ou d'une structure de données. Le mot réservé SET permet de l'initialiser. Il est possible de procéder à des comparaisons.

 DATA DIVISION.
     05  POINTEUR-1            USAGE IS POINTER.
     05  POINTEUR-DEBRANCH1    USAGE IS POINTER.
*
 PROCEDURE DIVISION.
*
     ADD COEFF-1 TO MONTANT GIVING TOTAL.
     SET ADDRESS OF TOTAL  TO POINTEUR-1.
     PERFORM UNTIL POINTEUR-1 = POINTEUR-DEBRANCH1
        ADD 1 TO NBRLUS
     END-PERFORM.
*

Il est également possible de passer en paramètre le pointeur vers un autre programme.

     CALL "CALCUL-TVA" USING POINTEUR-1.

Pointeurs en Pascal

La syntaxe en Pascal est très similaire à celle en C et C++, à l'exception notable que le symbole de déréférencement est inversé par rapport au C et C++. Les pointeurs typés sont déclarés avec un chapeau '^' préposé au type pointé. On récupère l'adresse d'une variable avec une arrobase '@'.

Le chapeau sert également à déréférencer l'adresse d'un pointeur, mais alors il est postposé. L'exemple ci-dessus s'écrit donc en Pascal ainsi :

var a: integer;    { Déclaration de la variable a de type integer (entier) }
    p: ^integer;   { Déclaration de la variable p de type pointeur sur entier }
 
begin
    a := 2;        { Iinitialisation de a à 2 }
    p := @a;       { Adresse de a affectée au pointeur p }
    p^ := 5;       { Déréférencement de p, pour affecter 5 à la variable a }
end;

Certains types de pointeurs peuvent être prédéfinis dans certaines implémentations du Pascal, comme Delphi :

type
    pchar = ^char;
    pinteger = ^integer;

Arithmétique des pointeurs

On appelle arithmétique des pointeurs la possibilité de faire des opérations arithmétiques (incrémentation, décrémentation, addition et soustraction) sur les pointeurs. Cela revient à effectuer un déplacement en mémoire.

La particularité de cette utilisation des pointeurs, est que l'on se déplace par saut de la taille mémoire du type de donnée pointé par le pointeur et non par octet (qui est la plus petit unité accessible).

Exemple en C

char tab[] = {'t', 'a', 'b', '\0'};
char * p1 = &tab[0];

Ici le pointeur p1, contient l'adresse du premier élément du tableau tab (ce qui est équivalent à p1 = tab). Si l'on déréférence p1, nous aurions donc le caractère 't'.

p1 = p1 + 1;

En faisant cela, p1 ne pointe plus sur le caractère 't', mais sur 'a'. Dans cet exemple, le déplacement en mémoire a été de un octet (car le type char vaut toujours un octet). Mais si le tableau avait contenu des données de type long, le déplacement aurait été de quatre octets. Le déplacement se fait donc par saut de la taille mémoire du type de donnée pointé par le pointeur.

Exemple en Pascal

Encore une fois, la syntaxe en Pascal est très proche.

const { les deux définitions sont équivalentes }
    tab: array[0..3] of char = ('T', 'A', 'B', #0);
var
    p1: ^char;
 
begin
    p1 := @tab[0];  { p1 pointe sur le 'T' }
    inc(p1);        { p1 pointe sur le 'A' }
end.

Une différence importante pourtant reste, c'est qu'on ne peut que incrémenter et décrémenter un pointeur typé. Pour faire une addition proprement dite, il faut convertir en entier d'abord :

begin
    p1 := @tab[0];                 { p1 pointe sur le 'T' }
    p1 := ptr( integer(p1) + 2 );  { p1 pointe sur le 'B' }
end.

Dans ce cas-là, il faut prendre soi-même en charge la multiplication éventuelle par la taille du type des données pointées.

Pointeur sur une fonction

Les pointeurs peuvent également contenir l'adresse d'une fonction. Cette dernière peut ainsi être passée en paramètre à une autre fonction et être appelée.

Exemple en C

Voici un exemple en C, de la déclaration d'un pointeur qui pointe successivement vers les fonctions fonction_1() et fonction_2() :

#include<stdio.h>
 
void fonction_1() {
  printf("affiche fonction_1");
}
 
void fonction_2() {
   printf("affiche fonction_2");
}
 
int main() {
   void (*fonction)();
   fonction = fonction_1;
   fonction();
   fonction = fonction_2;
   fonction();
   return 0;
}

Ce code va produire la sortie suivante : affiche fonction_1affiche fonction_2

Même exemple en Pascal

procedure fonction_1;
begin
      writeln('affiche fonction_1');
end;
 
procedure fonction_2;
begin
      writeln('affiche fonction_2');
end;
 
var
    fonc : procedure;
 
begin  { bloc principal }
      @fonc := @fonction_1;
      fonc;
      @fonc := @fonction_2;
      fonc;
end.

Voir aussi

Références

  1. Philippe Davy, « Le langage D rénove la programmation systèmes », 01 Informatique, 19 janvier 2007. Mis en ligne le 19 janvier 2007, consulté le 21 mars 2010



Wikimedia Foundation. 2010.

Contenu soumis à la licence CC-BY-SA. Source : Article Pointeur (programmation) de Wikipédia en français (auteurs)

Игры ⚽ Поможем решить контрольную работу

Regardez d'autres dictionnaires:

  • Programmation générique — Généricité En programmation, la généricité d une fonction repose sur son indépendance vis à vis du type, et éventuellement du nombre, de ses arguments. C est un concept important pour un langage de haut niveau car il permet d augmenter le niveau… …   Wikipédia en Français

  • Pointeur intelligent — En informatique, un pointeur intelligent (en anglais smart pointer) est un type abstrait de données qui simule le comportement d un pointeur en y adjoignant des fonctionnalités telles que la libération automatique de la mémoire allouée ou la… …   Wikipédia en Français

  • pointeur — 3. pointer ou pointeur [ pwɛ̃tɶr ] n. m. • 1834 spanish pointer; pointeur 1878; angl. pointer ♦ Race de chien d arrêt d origine anglaise. ⊗ HOM. Pointeur. pointeur 1. pointeur, euse [ pwɛ̃tɶr, øz ] n. • poincteur 1499; de 1. pointer 1 ♦ Personne… …   Encyclopédie Universelle

  • Pointeur — Cette page d’homonymie répertorie les différents sujets et articles partageant un même nom. Sur les autres projets Wikimedia : « Pointeur », sur le Wiktionnaire (dictionnaire universel) De manière générale, le mot pointeur désigne… …   Wikipédia en Français

  • Pointeur faible — En informatique, un pointeur faible est une référence qui n exclut pas que la valeur référencée soit récupérée par le ramasse miettes. Portail de la programmation informatique Catégorie : Progr …   Wikipédia en Français

  • Pointeur this — Dans beaucoup de langages de programmation orientée objet, this permet d obtenir l adresse de l objet courant. Portail de l’informatique Catégorie : Programmation orientée objet …   Wikipédia en Français

  • Langage de programmation C plus plus — C++ Apparu en 1985 (dernière révision en 2003) Auteur Bjarne Stroustrup …   Wikipédia en Français

  • Langage de programmation C — C (langage) Pour les articles homonymes, voir C. C …   Wikipédia en Français

  • Nombre magique (programmation) — Pour les articles homonymes, voir Nombre magique (homonymie). En programmation informatique, le terme magic number (en français « nombre magique ») peut référer à : une constante numérique ou un ensemble de caractères utilisé pour… …   Wikipédia en Français

  • Interface De Programmation — Pour les articles homonymes, voir API. Une interface de programmation (Application Programming Interface ou API) est un ensemble de fonctions, procédures ou classes mises à disposition des programmes informatiques par une bibliothèque logicielle …   Wikipédia en Français

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”