Pile (informatique)

Un article de Wikipédia, l'encyclopédie libre.
Aller à : navigation, rechercher
Page d'aide sur l'homonymie Pour les articles homonymes, voir pile.
Une pile est gérée en last in, first out.

En informatique, une pile (en anglais stack) est une structure de données fondée sur le principe « dernier arrivé, premier sorti » (ou LIFO pour Last In, First Out), ce qui veut dire que les derniers éléments ajoutés à la pile seront les premiers à être récupérés. Le fonctionnement est celui d'une pile d'assiettes : on ajoute des assiettes sur la pile, et on les récupère dans l'ordre inverse, en commençant par la dernière ajoutée.

Pile système[modifier | modifier le code]

La plupart des microprocesseurs gèrent nativement une pile. Elle correspond alors à une zone de la mémoire, et le processeur retient l'adresse du dernier élément.

Architecture x86[modifier | modifier le code]

Dans l'architecture x86 32bits, le registre ESP sert à indiquer l'adresse du sommet d'une pile dans la RAM. Les opcodes "push" et "pop" permettent respectivement d'empiler et de désempiler des données. Les opcodes "call" et "ret" utilisent la pile pour appeler une fonction et la quitter par la suite en retournant à l'instruction suivant immédiatement l'appel.

En cas d'interruption, les registres EFLAGS, CS et EIP sont automatiquement empilés. Dans le cas d'un changement de niveau de priorité lors de l'interruption, les registres SS et ESP le sont aussi.

Une autre pile existe dans les CPU x86, celle de l'unité de calcul flottant (FPU). Plus précisément, cette unité utilise une pile limitée à 8 éléments, et dont le fonctionnement s’apparente à un barillet. L’élément du barillet courant est nommé st(0), les éléments suivants st(N) avec N compris entre 1 et 7. Cette pile permet d'effectuer des calculs à la manière d'une calculatrice manuelle, en empilant les valeurs, puis en appliquant une opération sur les dernières valeurs empilées par exemple.

Architecture basée sur la pile[modifier | modifier le code]

Certains processeurs n'utilisent pas de registre générique, mais uniquement la pile. Les instructions concernent alors ses premiers éléments. Par exemple, les calculatrices Hewlett-Packard, les processeurs Focus, ou les machines Burroughs de la gamme B 5000. Les instructions sont alors souvent plus courtes, car elles n'ont pas à référencer des registres[1]. Le bytecode du langage Java utilise aussi cette astuce.

Langage de programmation[modifier | modifier le code]

Dans la plupart des langages de programmation compilés, la pile d'exécution est l'endroit où sont poussés tout ou partie des paramètres d'appel des procédures ou fonctions. Par ailleurs, on y crée un espace pour des variables locales. La pile est ainsi formée de cadres de piles (stack frames) comprenant pour chaque procédure en cours d'appel imbriqué ses paramètres, ses variables locales et son point de retour.

Primitives[modifier | modifier le code]

PrimitivesPile.png

Voici les primitives communément utilisées pour manipuler des piles. Il n'existe pas de normalisation pour les primitives de manipulation de pile. Leurs noms sont donc indiqués de manière informelle. Seules les trois premières sont réellement indispensables, les deux autres pouvant s'en déduire.

  • « Empiler » : ajoute un élément sur la pile. Terme anglais correspondant : « Push ».
  • « Désempiler » : enlève un élément de la pile et le renvoie. Terme anglais correspondant : « Pop ».
  • « La pile est-elle vide ? » : renvoie vrai si la pile est vide, faux sinon.
  • « Nombre d'éléments de la pile » : renvoie le nombre d'éléments dans la pile. Selon les implémentations, peut être fait soit en temps constant soit en temps linéaire.
  • « Quel est l'élément de tête ? » : renvoie l'élément de tête sans le désempiler. Terme anglais correspondant : « Peek ».
  • « Vider la liste » : dépiler tous les éléments. Selon l'implémentation, cela peut être fait en temps constant ou linéaire. Terme anglais correspondant : « Clear ».
  • « Dupliquer l'élément de tête » et « Échanger les deux premiers éléments » : existe sur les calculatrices fonctionnant en notation polonaise inverse. Termes anglais correspondants : « Dup » et « Swap » respectivement.

Algorithme[modifier | modifier le code]

 '''Classe Pile'''
 Attributs :
     pile   : tableau[1, MAX] de Objet
     sommet : entier ''{indice du dernier element entre}''
 Methodes
     Mprocédure '''PUSH'''(element)            ''{entre un element (Objet)}''
     Mfonction  '''POP'''() retourne Objet     ''{sort un Objet}'' 
     ''{non données ici}''
     Mfonction  '''FULL'''() retourne booleen  ''{la pile est-elle pleine ? (retourne sommet >= MAX)}''
     Mfonction  '''EMPTY'''() retourne booleen ''{la pile est-elle vide ? (retourne sommet <= 0)}''
     Mfonction  '''SIZE'''() retourne entier   ''{retourne le nombre d'elements (retourne sommet)}
     Mprocedure '''INIT'''()                   ''{constructeur (met sommet à 0)}
 '''Mprocédure''' ''PUSH'' (element)
 ''{ajouter un élément sur la pile}''
 Paramètres :
    (D)   element : Objet
    (D/R) cible   : Pile
 Début
    Si cible.sommet <= MAX
    Alors
       cible.sommet <- cible.sommet + 1
       cible.pile[cible.sommet] <- element
    Sinon
       afficher("Pile pleine")
    Fsi
 Fin
 '''Mfonction''' ''POP'' () retourne objet
 ''{enlever un élément de la pile et le renvoyer}''
 Paramètres :
    (D/R) cible : Pile
 Variables :
    Element : objet
 Début
    Si cible.sommet > 0
    Alors
       Element <- cible.pile[cible.sommet]
       cible.sommet <- cible.sommet - 1
    Sinon
       afficher("Pile vide")
    Fsi
    Retourner Element
 Fin

Cette implémentation est celle utilisée dans les processeurs — elle est simple et la pile occupe peu de place. Une implantation sous forme de liste chaînée est également possible pour des programmes.

Applications[modifier | modifier le code]

  • Dans un navigateur web, une pile sert à mémoriser les pages Web visitées. L'adresse de chaque nouvelle page visitée est empilée et l'utilisateur désempile l'adresse de la page précédente en cliquant le bouton « Afficher la page précédente ».
  • L'évaluation des expressions mathématiques en notation post-fixée (ou polonaise inverse) utilise une pile.
  • La fonction « Annuler la frappe » (en anglais Undo) d'un traitement de texte mémorise les modifications apportées au texte dans une pile.
  • Un algorithme de recherche en profondeur utilise une pile pour mémoriser les nœuds visités.
  • Par exemple, on peut très simplement inverser les éléments contenus dans un tableau ou dans une chaîne de caractères (pour tester un palindrome) en utilisant une pile. Il suffit d'empiler les éléments sur une pile puis de reconstituer le tableau (ou la chaîne) inverse en désempilant les éléments.
  • Les algorithmes récursifs admis par certains langages (LISP, Algol, Pascal, C, etc.) utilisent implicitement une pile d'appel. Dans un langage non récursif (FORTRAN par exemple), on peut donc toujours simuler la récursivité en créant les primitives de gestion d'une pile.

Voir aussi[modifier | modifier le code]

Articles connexes[modifier | modifier le code]

Références[modifier | modifier le code]

  1. (en) Philip Koopman, Stack Computers, 1989.