www.wikidata.de-de.nina.az
In der Informatik bezeichnet ein Stapelspeicher oder Kellerspeicher kurz Stapel oder Keller haufig auch mit dem englischen Wort Stack bezeichnet eine haufig eingesetzte dynamische Datenstruktur Sie wird von den meisten Mikroprozessoren direkt mithilfe von Maschinenbefehlen unterstutzt Vereinfachte Darstellung eines Stacks mit den Funktionen Push drauflegen und Pop herunternehmen Inhaltsverzeichnis 1 Funktionsprinzip 2 Illustration 3 Geschichte 4 Anwendungen 4 1 Mikroprozessoren 5 Abstrakter Datentyp 6 Programmierung 6 1 Stack Implementierung 6 1 1 C 6 1 2 C 6 1 3 Java 6 1 4 Python 6 1 5 Beispiel mit Spielkarten 6 2 Compiler 6 3 Verarbeitung von Klammerstrukturen 6 4 Postfixnotation 6 5 Infixnotation 6 6 Stapelorientierte Sprachen 6 7 Stack Architektur 7 Verwandte Themen 8 Siehe auch 9 Literatur 10 Weblinks 11 EinzelnachweiseFunktionsprinzip Bearbeiten nbsp Dieser Stapel wachst von seinem Ursprung nach unten Der Stapelzeiger zeigt auf das aktuell oberste Datenelement auf dem Stapel Eine Push Operation dekrementiert den Zeiger und kopiert die Daten auf den Stapel Eine Pop Operation kopiert Daten vom Stapel und inkrementiert dann den Stapelzeiger Jede im Programm aufgerufene Prozedur speichert Ruckgabeinformationen in Gelb und lokale Daten in anderen Farben indem sie auf den Stapel geschoben werden Ein Stapel kann eine theoretisch beliebige in der Praxis jedoch begrenzte Menge von Objekten aufnehmen Elemente konnen nur oben auf den Stapel gelegt und auch nur von dort wieder gelesen werden Elemente werden ubereinander gestapelt und in umgekehrter Reihenfolge vom Stapel genommen Dies wird auch Last In First Out Prinzip LIFO genannt Dazu werden folgende Operationen zur Verfugung gestellt push auch einkellern legt das Objekt oben auf den Stapel pop auskellern liefert das oberste Objekt und entfernt es vom Stapel Bei manchen Prozessoren wie dem MOS Technology 6502 wird diese Aktion dagegen pull herunterziehen genannt peek nachsehen liefert das oberste Objekt ohne es zu entfernen zuweilen auch top genannt also oben In der Automatentheorie werden Stapel benutzt um bestimmte Problemklassen theoretisch betrachten zu konnen siehe Kellerautomat Sie unterscheidet deshalb genauer zwischen einem echten Kellerspeicher bei dem kein Element ausser dem obersten gelesen werden kann und einem Stapelspeicher bei dem jedes Element betrachtet aber nicht verandert werden kann In der Praxis spielt diese Unterscheidung jedoch kaum eine Rolle beinahe jede Implementierung ist ein Stapel Daher werden die Begriffe im Allgemeinen synonym verwendet Es gibt viele Variationen des Grundprinzips von Stapeloperationen Jeder Stapel hat einen festen Speicherort im Speicher an dem er beginnt Wenn Datenelemente zum Stapel hinzugefugt werden wird der Stapelzeiger verschoben um die aktuelle Ausdehnung des Stapels anzuzeigen die sich vom Ursprung weg ausdehnt Stapelzeiger konnen auf den Ursprung eines Stapels oder auf einen begrenzten Adressbereich entweder uber oder unter dem Ursprung zeigen abhangig von der Richtung in die der Stapel wachst Der Stapelzeiger kann jedoch den Ursprung des Stapels nicht uberschreiten Mit anderen Worten wenn der Ursprung des Stapels bei der Speicheradresse 1000 liegt und der Stapel nach unten in Richtung der Speicheradressen 999 998 usw wachst darf der Stapelzeiger niemals uber 1000 auf 1001 1002 usw hinaus erhoht werden Wenn eine Pop Operation auf dem Stapel bewirkt dass sich der Stapelzeiger uber den Ursprung des Stapels hinaus bewegt tritt ein Stapelunterlauf auf Wenn eine Push Operation bewirkt dass der Stapelzeiger uber die maximale Ausdehnung des Stapels hinaus erhoht oder verringert wird tritt ein Stapeluberlauf auf Einige Laufzeitumgebungen die stark von Stapeln abhangig sind bieten moglicherweise zusatzliche Vorgange zum Beispielduplicate duplizieren Das oberste Element wird eingeblendet und dann erneut gedruckt zweimal sodass jetzt eine zusatzliche Kopie des vorherigen obersten Elements mit dem Original darunter oben liegt swap oder exchange tauschen Die beiden obersten Gegenstande auf dem Stapel tauschen Platze aus rotate oder roll rotieren Die n obersten Elemente werden rotierend auf dem Stapel verschoben Wenn beispielsweise n 3 ist werden die Elemente 1 2 und 3 auf dem Stapel an die Positionen 2 3 bzw 1 auf dem Stapel verschoben Viele Varianten dieser Operation sind moglich wobei die haufigste als Linksdrehung und Rechtsdrehung bezeichnet wird Stapel werden oft so dargestellt dass sie von unten nach oben wachsen Sie konnen auch visualisiert werden wie sie von links nach rechts wachsen so dass ganz oben zu ganz rechts wird oder sogar von oben nach unten wachsen Das wichtige Merkmal ist dass sich der Boden des Stapels in einer festen Position befindet Die Abbildung in diesem Abschnitt ist ein Beispiel fur eine Wachstumsvisualisierung von oben nach unten Die Oberseite 28 ist der Stapel unten da der Stapel oben 9 der Ort ist an dem Elemente geschoben oder herausgeschoben werden Ein Stapel wird in Computern normalerweise durch einen Block von Speicherzellen dargestellt wobei sich der untere an einer festen Stelle befindet und der Stapelzeiger die Speicheradresse der aktuellen oberen Zelle im Stapel enthalt Die obere und untere Terminologie werden verwendet unabhangig davon ob der Stapel tatsachlich in Richtung niedrigerer Speicheradressen oder in Richtung hoherer Speicheradressen wachst Wenn Sie ein Element auf den Stapel schieben wird der Stapelzeiger um die Grosse des Elements angepasst also entweder dekrementiert oder inkrementiert abhangig von der Richtung in der der Stapel im Speicher wachst indem er auf die nachste Speicherzelle zeigt und das neue oberste Element in den Stapelbereich kopiert Abhangig von der genauen Implementierung kann der Stapelzeiger am Ende einer Push Operation auf die nachste nicht verwendete Position im Stapel oder auf das oberste Element im Stapel zeigen Wenn der Stapel auf das aktuell oberste Element zeigt wird der Stapelzeiger aktualisiert bevor ein neues Element auf den Stapel verschoben wird Wenn es auf die nachste verfugbare Position im Stapel zeigt wird es aktualisiert nachdem das neue Element auf den Stapel verschoben wurde Illustration Bearbeiten nbsp Skizze eines StapelsEin Stapelspeicher ist mit einem Stapel von Umzugskisten vergleichbar Es kann immer eine neue Kiste oben auf den Stapel gepackt werden entspricht push oder eine Kiste von oben heruntergenommen werden entspricht pop Der Zugriff ist im Regelfall nur auf das oberste Element des Stapels moglich Ein Hinzufugen oder Entfernen einer Kiste weiter unten im Stapel ist nicht moglich Es gibt aber in manchen Implementierungen Befehle um die obersten Elemente zu vertauschen SWAP ROT Geschichte BearbeitenDie Verwendung eines Stapelspeichers zur Ubersetzung von Programmiersprachen wurde 1957 von Friedrich L Bauer und Klaus Samelson unter dem Namen Kellerprinzip patentiert 1 2 und etwa zur selben Zeit unabhangig vom australischen Philosophen Charles Hamblin entwickelt Die lange ausgebliebene internationale Anerkennung und Ehrung ihrer Leistung erfolgte erst im Jahr 1988 Bauer erhielt den renommierten Computer Pioneer Award IEEE fur Computer Stacks Samelson war bereits 1980 verstorben Anwendungen BearbeitenMit Stapelspeichern kann man Terme und Syntaxen einfach auf richtige Verschachtelung prufen Dies wird oft z B bei der Verarbeitung von BB Codes und XML Dokumenten benotigt Mikroprozessoren Bearbeiten In Mikroprozessoren gibt es oft ein spezielles Register den Stackpointer Stapelzeiger Dieses Register enthalt eine Speicheradresse die auf den aktuellen Stapeleintrag des aktuellen Prozesses zeigt Viele Befehle Operationen des Mikroprozessors nutzen diesen Stapeleintrag Unter anderem gibt es Befehle mit denen man in den Stack schreiben z B push beim x86 Prozessor oder von ihm lesen kann z B pop Dabei wird automatisch der Stapelzeiger verringert oder erhoht Die Operation Jump To Subroutine Sprung in ein Unterprogramm legt auf dem Stack die Rucksprungadresse ab die spater von der Operation Return From Subroutine verwendet wird Unterprogrammen bzw Funktionen wie man sie aus Programmiersprachen wie C kennt werden die Parameter uber den Stack ubergeben der auch die Ruckgabewerte aufnimmt Ausserdem werden lokale Variablen auf dem Stack gespeichert Dies erlaubt unter anderem Rekursion das Aufrufen einer Funktion aus ebendieser Funktion heraus Wird bei der Ruckkehr aus einer Funktion nur ein Eintrag zu viel oder zu wenig ausgelesen fuhrt dies zu besonders gravierenden Programmfehlern da der Prozessor dann versuchen wird Code an vollig zufalliger Speicherposition auszufuhren Durch das Ausnutzen einer nicht korrekt behandelten Grossenangabe der Daten konnen Angreifer versuchen einen Pufferuberlauf zu produzieren der den Stack so verandert dass durch Umleiten des Rucksprungs bosartiger Code ausgefuhrt wird Bei den meisten Prozessoren beginnt der Stapel bei einer hohen Adresse und wird in Richtung der Adresse 0 gestapelt Das bedeutet dass bei push der Stapelzeiger vermindert und etwas in den Stack geschrieben wird und bei pop vom Stack gelesen und der Stapelzeiger erhoht wird Der Stapel wachst nach unten in Richtung niedrigerer Speicheradressen Dies ist historisch begrundet Legt man bei begrenztem Speicher den Stack unterhalb des Speicherplatzes der von den Programmen benutzt wird konnen so andere Programmdaten die normal hinter dem Programm abgelegt werden den Stapel nicht so leicht uberschreiben und der Stapel nicht das Maschinenprogramm Des Weiteren kann so das oberste Element auf dem Stapel immer mit dem Offset Null relativ zum Stapelzeiger adressiert werden und das Hinzufugen eines Elements auf dem Stack ist moglich ohne die Grosse des bisher obersten Elements zu kennen In Multitasking Systemen gibt es fur jeden Prozess und innerhalb der Prozesse fur jeden Thread einen eigenen Stapelspeicher Beim Umschalten zwischen Prozessen bzw Threads wird neben anderen Registern auch der jeweilige Stapelzeiger gespeichert und geladen Um Fehler in der Benutzung des Stacks durch einen Unterlauf des Stapelzeigers aufzudecken legen manche Betriebssysteme wie beispielsweise DOS oder CP M bei COM Programmen oder OSEK OS als untersten Wert im Stapel die Sprungadresse einer Abbruch oder Fehlerbehandlungsroutine ab Holt der Prozessor durch einen Fehler in der Aufrufverschachtelung diese Adresse vom Stapel kann gegebenenfalls noch auf den Ablauffehler reagiert werden Manche Betriebssysteme konnen auch den Stapelspeicher wahrend der Laufzeit vergrossern was bei einem bereits sehr grossen Stapel relativ viel Zeit in Anspruch nehmen kann Bei anderen Betriebssystemen hat der Programmierer selbst anzugeben wie gross der Stack sein soll Um den Nutzungsgrad des meist begrenzten Stapelspeichers zu ermitteln bedient man sich der sogenannten Wasserstands Methode Der gesamte fur den Stapelspeicher reservierte Speicher wird mit einem fixen Datenmuster initialisiert und dann das Programm gestartet Anhand der Bereiche die nach einer gewissen Laufzeit noch das Initialisierungsmuster enthalten kann festgestellt werden wie viel Platz auf dem Stapel wirklich genutzt wurde Abstrakter Datentyp BearbeitenBei der Implementierung eines Stapelspeichers als abstrakter Datentyp in einer einfach verketteten Liste wird der Zeiger auf Daten gespeichert anstelle die Daten in jedem Knoten zu speichern Das Programm weist den Speicher fur die Daten zu und die Speicheradresse wird an den Stapelspeicher ubergeben Der Kopfknoten und die Datenknoten sind im abstrakten Datentyp gekapselt Eine aufgerufene Funktion kann nur den Zeiger auf den Stapelspeicher sehen Der Datentyp enthalt auch einen Zeiger auf die Oberseite und den Zahler fur die Anzahl der Elemente im Stapel 3 struct StackNode void dataPointer StackNode link struct Stack int count StackNode top Programmierung BearbeitenCompiler bzw Interpreter fur Programmiersprachen nutzen gewohnlich push Operationen vor dem Aufruf eines Unterprogramms um an dieses Parameter zu ubergeben Weil der Compiler die Typen der Parameter kennt konnen sie unterschiedliche Grossen haben Ahnlich konnen so auch Ergebnisse des Unterprogramms zuruckgegeben werden Fur lokale Variablen des Unterprogramms wird dieser Mechanismus nochmal erweitert indem auch fur sie auf dem Stapelspeicher Platz reserviert wird Dadurch wird das Unterprogramm dann rekursiv aufrufbar Bei der Umwandlung eines rekursiven Unterprogramms in ein iteratives Unterprogramm muss dieser Mechanismus haufig explizit implementiert werden Programmiersprachen die auf eine prozessbasierte virtuelle Maschine aufsetzen zum Beispiel Java P Code Pascal optimieren den kompilierten Zwischencode fur die Verwendung eines Stapels um zur Laufzeit die Interpretation dieses Zwischencodes zu beschleunigen Stack Implementierung Bearbeiten C Bearbeiten Implementierung eines Stacks in der Programmiersprache C mit einer einfach verketteten Liste 4 5 include lt memory gt include lt stdexcept gt include lt utility gt using namespace std template lt typename T gt class stack struct item T value unique ptr lt item gt next nullptr item T amp value value value unique ptr lt item gt peek nullptr size t size 0 public erzeugt einen leeren Stack stack erzeugt einen Stack mit n Elementen von T stack size t n T value for size t i 0 i lt n i push value Kopierkonstruktor stack stack lt T gt amp rhs this rhs Zuweisungsoperator stack amp operator stack lt T gt amp rhs Uberprufe ob ein Stack sich selbst zugewiesen wird if this amp rhs return this item traverse rhs peek get Absteigen zum ersten Element dann zum zweiten etc while traverse nullptr push traverse gt value traverse traverse gt next get return this void push T amp value unique ptr lt item gt temp make unique lt item gt value temp swap peek next des letzten Stackelements ist ein nullptr peek gt next move temp size T pop if peek nullptr throw underflow error Nothing to pop T value peek gt value peek move peek gt next size return value T amp peek if peek nullptr throw underflow error Nothing to peek return peek gt value size t size return size C BearbeitenImplementierung eines Stacks in der Programmiersprache C mit einem Array include lt stdbool h gt include lt stddef h gt define LEN 100 int data LEN size t count 0 bool is empty return count 0 bool is full return count LEN void push int value if is full return data count value count int pop if is empty return 0 count return data count int peek if is empty return 0 return data count 1 size t size return count Java Bearbeiten Implementierung eines Stacks in der Programmiersprache Java mit einer einfach verketteten Liste 6 class Stack lt T gt private class Item T value Das zu verwaltende Objekt Item next Referenz auf den nachsten Knoten Item T value Item next this value value this next next private Item peek Pruft ob der Stapel leer ist public boolean empty return this peek null Speichert ein neues Objekt public void push T value this peek new Item value this peek Gibt das oberste Objekt wieder und entfernt es aus dem Stapel public T pop T temp this peek value if empty this peek this peek next return temp Gibt das oberste Objekt wieder public T peek return empty this peek value null Python Bearbeiten Implementierung eines Stacks in der Programmiersprache Python mit einer dynamisch erweiterbaren Liste class Stack def init self self data def is empty self return len self data 0 def push self element self data append element def pop self if self is empty return None return self data pop def peek self if self is empty return None return self data 1 def str self return self data str def main my stack Stack print my stack is empty my stack push 5 my stack push 3 print my stack is empty print my stack print my stack peek my stack pop print my stack peek if name main main In vielen Programmiersprachen sind Stacks bereits in der Standardbibliothek implementiert So stellt Java diese Funktionalitat in der Klasse java util LinkedList zur Verfugung In der C Standard Template Library bietet das Template stack lt T gt entsprechende Funktionalitat welche normalerweise jedoch anders als hier nicht mit einer verketteten Liste implementiert ist Beispiel mit Spielkarten Bearbeiten Das folgende Beispiel in der Programmiersprache C zeigt die Implementierung von einem Stapel aus Spielkarten mit einem Stack in der Methode main Dabei wird die Klasse stack der Programmbibliothek von C verwendet 7 Kartenspiele und Gesellschaftsspiele bei denen wahrend des Spiels Karten auf einen Stapel gelegt oder von einem Stapel gezogen wird zum Beispiel Texas Hold em Omaha Hold em Canasta und Die Siedler von Catan konnen sinnvoll mithilfe von Stacks programmiert werden Bindet den Datentyp stack in das Programm ein include lt stack gt include lt iostream gt using namespace std int main Initialisiert einen Stapel mit dem Elementtyp string auto myStack stack lt string gt Legt nacheinander 3 Elemente auf den Stapel myStack push Kreuz Bube myStack push Herz Dame myStack push Karo Konig Ausgabe auf der Konsole Karo Konig cout lt lt Die Hohe des Stapels ist lt lt myStack size lt lt und die oberste Karte des Stapels ist lt lt myStack top lt lt endl Entfernt das oberste Element Karo Konig myStack pop Ausgabe auf der Konsole Herz Dame cout lt lt Die Hohe des Stapels ist lt lt myStack size lt lt und die oberste Karte des Stapels ist lt lt myStack top lt lt endl Legt ein Element oben auf den Stapel myStack push Karo Ass Ausgabe auf der Konsole Karo Ass cout lt lt Die Hohe des Stapels ist lt lt myStack size lt lt und die oberste Karte des Stapels ist lt lt myStack top lt lt endl Compiler Bearbeiten Zur Ubersetzung des Quellcodes einer formalen Sprache nutzen Compiler und Interpreter einen Parser der einen Stapel verwendet Der Parser kann z B wie ein Kellerautomat arbeiten Verarbeitung von Klammerstrukturen Bearbeiten Stapelspeicher eignen sich auch zur Auswertung von Klammerausdrucken wie sie etwa in der Mathematik gelaufig sind Dabei wird zunachst fur Operatoren und Operanden je ein Stapelspeicher initialisiert Der zu verarbeitende Klammerausdruck wird nun symbolweise eingelesen Wird eine offnende Klammer eingelesen so ist diese zu ignorieren Wird ein Operand oder Operator eingelesen so ist dieser auf den jeweiligen Stapelspeicher zu legen Wird eine schliessende Klammer eingelesen so wird der oberste Operator vom Stapelspeicher fur die Operatoren genommen und entsprechend diesem Operator eine geeignete Anzahl von Operanden die zur Durchfuhrung der Operation benotigt werden Das Ergebnis wird dann wieder auf dem Stapelspeicher fur Operanden abgelegt Sobald der Stapelspeicher fur die Operatoren leer ist befindet sich im Stapelspeicher fur die Operanden das Ergebnis Postfixnotation Bearbeiten Zur Berechnung von Termen wird gelegentlich die Postfixnotation verwendet die mit Hilfe der Operationen eine Klammersetzung und Prioritatsregeln fur die Operationen uberflussig macht Zahlwerte werden automatisch auf dem Stapel abgelegt Binare Operatoren zum Beispiel holen die oberen beiden Werte unare Operatoren zum Beispiel Vorzeichenwechsel einen Wert vom Stapel und legen anschliessend das Zwischenergebnis dort wieder ab Infixnotation Bearbeiten Bei der maschinengestutzten Auflosung von arithmetischen Ausdrucken in der sogenannten Infixnotation der Operator steht zwischen den beteiligten Zahlwerten werden zunachst vorrangige Teilterme in einem Stapel zwischengelagert und so faktisch der Infix Term schrittweise in einen Postfix Term umgewandelt bevor das Ergebnis durch Abarbeiten des Stapels errechnet wird Stapelorientierte Sprachen Bearbeiten Stapelorientierte Sprachen z B Forth oder PostScript wickeln fast alle Variablen Operationen uber einen oder mehrere Stapel ab und stellen neben den oben genannten Operatoren noch weitere zur Verfugung Beispielsweise tauscht der Forth Operator swap die obersten beiden Elemente des Stapels Arithmetische Operationen werden in der Postfix Notation aufgeschrieben und beeinflussen damit ebenfalls den Stapel Forth benutzt einen zweiten Stapel Return Stapel zur Zwischenspeicherung der Rucksprungadressen von Unterprogrammen wahrend der Ausfuhrungsphase Dieser Stapel wird auch wahrend der Ubersetzungsphase fur die Adressen der Sprungziele fur die Kontrollstrukturen verwendet Die Ubergabe und Ruckgabe von Werten an Unterprogrammen geschieht uber den ersten Stapel der zweite nimmt die Rucksprungadresse auf In den meisten Implementierungen ist zudem ein weiterer Stapel fur Gleitkommaoperationen vorgesehen Stack Architektur Bearbeiten Eine Stack Architektur bezieht sich bei Datenoperationen implizit also ohne separate Push und Pop Befehle auf einen Stack Beispiele sind die Intel FPU Gleitkommaprozessor und die Hewlett Packard Taschenrechner Verwandte Themen BearbeitenEine First In First Out Datenstruktur nennt sich Warteschlange englisch Queue Beide Strukturen zeigen ein unterschiedliches Verhalten haben aber dieselbe Signatur d h Methoden Struktur weswegen sie oft zusammen unterrichtet werden Eine andere Art Speicher zu verwalten ist die dynamische Speicherverwaltung die zur Laufzeit entstehende Speicheranforderungen bedienen kann Dieser Speicher wird oft als Heap bezeichnet und wird eingesetzt wenn die Lebensdauer der zu speichernden Objekte unterschiedlich ist und nicht dem eingeschrankten Prinzip des Stapelspeichers oder der Warteschlange entspricht Siehe auch BearbeitenFeld Datentyp Liste Datenstruktur Floodfill Deque StacktraceLiteratur BearbeitenPatent DE1094019 Verfahren zur automatischen Verarbeitung von kodierten Daten und Rechenmaschine zur Ausubung des Verfahrens Angemeldet am 30 Marz 1957 veroffentlicht am 1 Dezember 1960 Erfinder Friedrich Ludwig Bauer Klaus Samelson Erteilt 12 August 1971 Weblinks Bearbeiten nbsp Commons Stack Datenstruktur Sammlung von Bildern Videos und AudiodateienEinzelnachweise Bearbeiten Friedrich L Bauer Gerhard Goos Informatik Eine einfuhrende Ubersicht Erster Teil 3 Auflage Springer Berlin 1982 ISBN 3 540 11722 9 S 222 Die Bezeichnung Keller hierfur wurde von Bauer und Samelson in einer deutschen Patentanmeldung vom 30 Marz 1957 eingefuhrt Patent DE1094019 Verfahren zur automatischen Verarbeitung von kodierten Daten und Rechenmaschine zur Ausubung des Verfahrens Angemeldet am 30 Marz 1957 veroffentlicht am 1 Dezember 1960 Erfinder Friedrich Ludwig Bauer Klaus Samelson GeeksforGeeks Abstract Data Types www geeksforgeeks org Stack Data Structure Introduction and Program Universitat Ulm Einfacher Stack in C und im C Stil www geeksforgeeks org Stack Class in Java Microsoft Docs stack ClassNormdaten Sachbegriff GND 4808341 0 lobid OGND AKS Abgerufen von https de wikipedia org w index php title Stapelspeicher amp oldid 237706757