Movatterモバイル変換


[0]ホーム

URL:


Aller au contenu
Wikipédial'encyclopédie libre
Rechercher

Pointeur (programmation)

Un article de Wikipédia, l'encyclopédie libre.
Page d’aide sur l’homonymie

Pour les articles homonymes, voirpointeur.

Si ce bandeau n'est plus pertinent, retirez-le. Cliquez ici pour en savoir plus.
Si ce bandeau n'est plus pertinent, retirez-le. Cliquez ici pour en savoir plus.

Cet articlene cite pas suffisamment ses sources().

Si vous disposez d'ouvrages ou d'articles de référence ou si vous connaissez des sites web de qualité traitant du thème abordé ici, merci de compléter l'article en donnant lesréférences utiles à savérifiabilité et en les liant à la section « Notes et références ».

En pratique :Quelles sources sont attendues ?Comment ajouter mes sources ?

Enprogrammation informatique, unpointeur est un objet qui contient l'adresse mémoire d'unedonnée ou d'unefonction. C'est l'outil fondamental de l'adressage dit « indirect ».

Utilité

[modifier |modifier le code]
Le pointeura pointe sur la variableb. On peut noter queb contient un nombre (en hexadécimal 00000011 = en décimal 17), et quea contient l'adresse deb 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'unentier naturel, à savoir indiquer uneadresse mémoire. Cette utilisation est très différente d'une utilisationarithmétique, d'où la création deregistres de processeurs spécifiques (les registres d'adresse) et d'un type de donnée spécifique dans leslangages de programmations.

Les pointeurs « typés », le type le plus répandu de pointeur actuellement, sont apparus avec le langageAlgol 68, sous le vocable de "référence". Le langageC y a ajouté l'arithmétique des pointeurs : 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, à savoir la mémoire. On peut se déplacer de case mémoire en case mémoire. Cette technique permet au programmeur d'effectuer des optimisations sur l'utilisation de la mémoire ou la performance.

Les pointeurs sont entre autres utilisés pour stocker les adresses des zones mémoiresalloué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 desréférences et des tableaux dynamiques gérés par lecompilateur. 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, tandis que d'autres le deviennent.

Complexification

[modifier |modifier le code]

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 le programme accède à une zone mémoire qui ne lui est pas allouée, leprocesseur via lesystème d'exploitation engendrera uneerreur de segmentation qui provoquera uneexception voire plantera 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 unefuite de mémoire apparaître.

Tous ces inconvénients obligent le développeur à prendre en charge des tâches 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és d'« aussi puissants qu'ils sont dangereux »[1], en expliquant les atouts du langageD. 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.

Arithmétique des pointeurs

[modifier |modifier le code]

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 parbyte (la plus petite unité de mémoire adressable).

Langages sans pointeurs

[modifier |modifier le code]

Certains langages ne permettent pas l'utilisation explicite de pointeurs. La majorité des langages de programmation utilisent (ou au moins permettent) le passage de paramètres par valeur. Typiquement, sin est un entier, alors l'appel de fonctionf(n) ne pourra pas modifiern même si dans le code de la fonction, l'argument est incrémenté ; la raison est que la valeur de la variablen est d'abord copiée, si bien que la fonctionf peut lire et écrire cette copie de la variablen, mais ne peut pas modifier la variablen originale.

Avec les pointeurs, il devient possible de passer en argument d'une fonction l'adresse d'une variable, et ainsi d'accéder en lecture et en écriture à la variable originale, et ce dans le code de la fonction.

Dans la plupart des langages de programmation sans pointeurs, par exemplePython,Java ouJavaScript/ActionScript, les variables ou objets sont toujours passés par valeur, mais l'accès aux champs de ces objets se fait par référence ou par adresse. Typiquement, sio est un objet, alorsf(o) ne pourra modifiero, mais pourra modifier (s'ils existent) les champs deo, par exemple s'il existe le champo.taille de l'objeto original pourra être incrémenté dans le code de la fonction. Ainsi, en passant par référence / adresse les champs des objets, c'est-à-dire en modélisant un objet comme étant une liste de références / pointeurs sur ses champs, il devient possible d'implémenter toutes les structures de données qui nécessitent des pointeurs tels que les arbres, les listes chaînées, etc. Pour ce qui est des tableaux, tout fonctionne comme si les tableaux étaient des objets possédant un opérateur[], l'écrituretab[i] donnant accès au champi de l'objettab. Dans une fonction prenant en argument un tableau, il est donc (uniquement) possible de modifier les éléments du tableau.

Mais certains langages fonctionnent différemment. EnPHP, les variables ou objets peuvent être au choix passés par valeur/copie ou par référence/adresse, en utilisant au choix la syntaxef(&$n) au lieu def($n).

Langages utilisant les pointeurs

[modifier |modifier le code]

Les pointeurs sont, entre autres, utilisés par les langages suivants (liste non exhaustive) :C,C++,Pascal,Ada,FreeBasic,Fortran,C#,D,Modula-2,Oberon,Go et, bien sûr, tous lesassembleurs.

Assembleur

[modifier |modifier le code]
Exemple : le pointeur p à l'adresse C10A pointe vers l'adresse a qui contient la valeur 55.

Unassembleur (langage d'assemblage) ne connaît en fait que deux notions pour stocker des données : les registres, et les adresses mémoire. Un pointeur est une adresse mémoire qui contient une autre adresse mémoire. Ce qui fait que pour accéder à une donnée pointée par un pointeur (en lecture ou écriture), il faut deux accès mémoire : le premier pour lire l'adresse elle-même, le second pour l'accès à la donnée qui y est stockée.

Un assembleur dispose presque toujours d'une instruction permettant d'indiquer l'accès à une donnéevia un pointeur : en général, le pointeur est entre parenthèses, ce qui indique de traiter la donnée à l'adresse indiquée par le pointeur, au lieu de l'adresse elle-même. Le double accès-mémoire est alors implicite. Un tel langage est tellement proche de la machine qu'il est quasiment impossible de se passer de la notion de pointeur, en particulier pour stocker des données de taille variable.

C et C++

[modifier |modifier le code]

Les deux principaux langages utilisant énormément les pointeurs sont leC et leC++ (même si, dans ce dernier, ils tendent à être remplacés par des alternatives plus « sécuritaires »).

Dans ces langages, l'étoile « * » est un opérateur préfixe qui dénote ledéréférencement d'un pointeur, c'est-à-dire l'accès à la donnée dont l'adresse est dans le pointeur.Suivant la logique des déclarations en C, la déclaration d'une variablese conforme à son usage. Exemple en C :

structPoint{floatx,y;};structPoint*p;//  lire :  *p   est un "struct Point"

Ce pointeur peut ensuite être affecté, à partir de l'adresse d'une donnée existante en utilisant l'opérateuresperluette "&" (address-of), ou l'allocation dynamique, ou encore l' "arithmétique des pointeurs"

structPointunPoint,autrePoint,*q;...p=&unPoint;// adresse d'une donnée existanteq=malloc(sizeof(structPoint));// allocation dynamique

Il peut ếtre déréférencé

*q=unPoint;// copieautrePoint=*p;

et l'opérateur-> est une abréviation commode (sucre syntaxique) pour accéder à ses membres

q->x=12.3;// équivaut à   (*q).x = 12.3;q->y=-5.6;

COBOL

[modifier |modifier le code]

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

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

     05POINTEUR-1USAGEISPOINTER.     05POINTEUR-NULUSAGEISPOINTERVALUENULL.

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.

 DATADIVISION.     05POINTEUR-1USAGEISPOINTER.     05POINTEUR-DEBRANCH1USAGEISPOINTER.* PROCEDUREDIVISION.*     ADDCOEFF-1TOMONTANTGIVINGTOTAL.     SETADDRESSOFTOTALTOPOINTEUR-1.     PERFORMUNTILPOINTEUR-1=POINTEUR-DEBRANCH1ADD1TONBRLUS     END-PERFORM.*

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

     CALL"CALCUL-TVA"USINGPOINTEUR-1.

Pascal

[modifier |modifier le code]

La syntaxe enPascal est très similaire à celle en C et C++, à l'exception notable que les symboles diffèrent et leur position sont inversées par rapport au C et C++. Les pointeurs typés sont déclarés avec un chapeau « ^ » préfixé au type pointé. L'adresse d'une variable est récupérée avec unearobase « @ » préfixée à la variable. Le chapeau sert également à déréférencer un pointeur, mais alors il est postfixé à la variable.

varn:integer;{ Déclaration de la variable n de type entier. }p:^integer;{ Déclaration de la variable p de type pointeur d'entier. }beginn:=2;{ Initialisation de la variable n à la valeur 2. }p:=@n;{ Initialisation de la variable p à la valeur « adresse de la variable n ». }p^:=5;{ Déréférencement de la variable p pour affecter la valeur 5 à la variable n. }end;

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

typepchar=^char;pinteger=^integer;

C

[modifier |modifier le code]
chart[]={'t','a','b','\0'};char*p=&t[0];

Ici le pointeur p, contient l'adresse du premier élément du tableau de caractères t (ce qui est équivalent àchar* p = t;). Si l'on déréférence p, nous aurions donc le caractère « t ».

p=p+1;

En faisant cela, p ne pointe plus sur le caractère « t », mais sur « a ». Dans cet exemple, le déplacement en mémoire est d'un byte (car le typechar vaut toujours un byte). Mais si le tableau avait contenu des données de typelong, le déplacement aurait été de plusieurs bytes. Le déplacement se fait ainsi par saut de la taille mémoire du type de donnée pointé par le pointeur.

Pascal

[modifier |modifier le code]

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

constt:array[0..3]ofchar=('T','A','B',#0);varp:^char;beginp:=@t[0];{ La variable p pointe sur le caractère 'T' de la variable t. }inc(p);{ La variable p pointe sur le caractère 'A' de la variable t. }end.

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

beginp:=@t[0];{ La variable p pointe sur le caractère 'T' de la variable t. }p:=ptr(integer(p)+2);{ La variable p pointe sur le caractère 'B' de la variable t. }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

[modifier |modifier le code]

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.

C

[modifier |modifier le code]

Voici un exemple en C de la déclaration d'un pointeur de fonction f qui pointe successivement vers les fonctions f1() et f2() :

#include<stdio.h>voidf1(){printf("Affichage de f1.\n");}voidf2(){printf("Affichage de f2.\n");}intmain(){void(*f)();f=f1;f();f=f2;f();return0;}

Ce code va produire la sortie suivante :

Affichage de f1.

Affichage de f2.

Pascal

[modifier |modifier le code]
proceduref1;beginwriteln('Affichage de f1.\n');end;proceduref2;beginwriteln('Affichage de f2.\n');end;varf:procedure;begin@f:=@f1;f;@f:=@f2;f;end.

Voir aussi

[modifier |modifier le code]

Articles connexes

[modifier |modifier le code]

Liens externes

[modifier |modifier le code]

Références

[modifier |modifier le code]
  1. Philippe Davy, « Le langage D rénove la programmation systèmes »,01 Informatique,(consulté le).
v ·m
Bibliothèque logicielle
Vocabulaire
Fonctions
Objet
ÉvénementielInversion de contrôle
Code source
Structures de données
Déclarations
Structures de contrôle
Fonctions usuelles
Outil de développement
Folklore
Ce document provient de « https://fr.wikipedia.org/w/index.php?title=Pointeur_(programmation)&oldid=209935276 ».
Catégorie :
Catégories cachées :

[8]ページ先頭

©2009-2025 Movatter.jp