https://de.wikipedia.org/w/api.php?action=feedcontributions&feedformat=atom&user=PrototypePHXWikipedia - Benutzerbeiträge [de]2025-05-29T22:29:32ZBenutzerbeiträgeMediaWiki 1.45.0-wmf.3https://de.wikipedia.org/w/index.php?title=Benutzer:PrototypePHX&diff=105080182Benutzer:PrototypePHX2012-07-02T00:07:21Z<p>PrototypePHX: </p>
<hr />
<div>http://en.wikipedia.org/w/index.php?title=User:PrototypePHX</div>PrototypePHXhttps://de.wikipedia.org/w/index.php?title=Diskussion:Stapelspeicher&diff=105034855Diskussion:Stapelspeicher2012-06-30T18:39:33Z<p>PrototypePHX: /* Implementierung */</p>
<hr />
<div>{{Autoarchiv<br />
|Alter =90<br />
|Ziel ='((Lemma))/Archiv/((Jahr))'<br />
|Übersicht =[[Spezial:Präfixindex/Diskussion:Stapelspeicher/Archiv|Archiv]]<br />
|Klein =Nein<br />
|Mindestbeiträge =2<br />
|Zeigen =Ja<br />
|Mindestabschnitte =2<br />
|Frequenz =monatlich<br />
}}<br />
<br />
== Richtung ==<br />
<br />
Im Text steht: "Der Stapel wächst also nach unten." heißt das, Richtung kleinere Speicheradressen? - "Der Stapel wächst also nach unten, in Richtung der kleineren Speicheradressen." könnte man doch dann schreiben. --[[Benutzer:Ost38|Ost38]] 11:31, 23. Feb. 2008 (CET)<br />
<br />
== Aufrufstapel (Call Stack) ==<br />
<br />
Ich denke, dass wir unbedingt eine deutsche Entsprechung zu [[en:Call stack]] brauchen, da dieser ein sehr wichtiges Werkzeug beim Abhandeln von Unterprogrammen ist. Viele Artikel, wie z. Bsp. [[Dynamischer Speicher]] verweisen auf diesen Artikel, obwohl dort nicht die Datenstruktur, sondern der Aufrufstapel im Hauptspeicher gemeint ist. --[[Benutzer:Kockster|Kockster]] 15:35, 9. Jul. 2008 (CEST)<br />
<br />
== Abschnitt "Compiler" ==<br />
<br />
So, wie der Abschnitt vorher war, hat er Compile-Zeit und Laufzeit vermischt. Ich habe den Laufzeit-Teil nach oben verschoben. Außerdem war die Darstellung des Parsing-Prozesses falsch. Ich habe sie darum entsorgt und statt dessen auf [[Kellerautomat]] verlinkt. Wäre es evtl. besser, auf entsprechende Parsing-Algorithmen zu verlinken? -- [[Benutzer:UKoch|UKoch]] 18:55, 21. Nov. 2011 (CET)<br />
<br />
== Implementierung ==<br />
<br />
Die angegebene Implementierung ist sinnlos. Ein Stack, der durch ein Array implementiert ist, könnte direkt durch ein Array ersetzt werden. Man sollte ein Beispiel eines richtigen Stacks mit Zeigern einbauen. -- [[Benutzer:Mfnalex|Mfnalex]] 19:29, 10. Jan. 2012 (CET)<br />
:Ich habe die Implementierung durch einen Stack der mit Zeigern arbeitet ersetzt. --[[Benutzer:PrototypePHX|PrototypePHX]] ([[Benutzer Diskussion:PrototypePHX|Diskussion]]) 17:37, 30. Jun. 2012 (CEST)<br />
::ja, aber das ist hier trotzdem kontraproduktiv. Der Witz beim Stack ist ja gerade der, dass er sich extrem leicht verwalten lässt, man braucht im Prinzip nur einen Index in einem Array zu verwalten. Alle eingebauten Hardware-Stacks (z.B. beim Intel) arbeiten genau so. Die Version mit den verzeigerten Listen ist größenordnungsmäßig komplizierter. Was [[Benutzer:Mfnalex|Mfnalex]] hier als „richtigen Stack mit Zeigern“ bezeichnet, ist gar kein Stack, sondern - spätestens in deiner Implementierung - eine verzeigerte Liste. --[[Benutzer:Klaeren|Herbert Klaeren]] ([[Benutzer Diskussion:Klaeren|Diskussion]]) 19:16, 30. Jun. 2012 (CEST)<br />
:::Stimmt, ist mir beim Programmieren dann auch aufgefallen, habe mir aber nichts weiter dabei gedacht. Kopierkonstruktor und Zuweisungsoperator sind deswegen ja auch nicht besonders hübsch ... --[[Benutzer:PrototypePHX|PrototypePHX]] ([[Benutzer Diskussion:PrototypePHX|Diskussion]]) 20:39, 30. Jun. 2012 (CEST)</div>PrototypePHXhttps://de.wikipedia.org/w/index.php?title=Benutzer:PrototypePHX&diff=105030354Benutzer:PrototypePHX2012-06-30T15:38:24Z<p>PrototypePHX: AZ: Die Seite wurde geleert.</p>
<hr />
<div></div>PrototypePHXhttps://de.wikipedia.org/w/index.php?title=Benutzer:PrototypePHX&diff=105030352Benutzer:PrototypePHX2012-06-30T15:38:17Z<p>PrototypePHX: AZ: Die Seite wurde neu angelegt: Test</p>
<hr />
<div>Test</div>PrototypePHXhttps://de.wikipedia.org/w/index.php?title=Diskussion:Stapelspeicher&diff=105030328Diskussion:Stapelspeicher2012-06-30T15:37:26Z<p>PrototypePHX: /* Implementierung */</p>
<hr />
<div>{{Autoarchiv<br />
|Alter =90<br />
|Ziel ='((Lemma))/Archiv/((Jahr))'<br />
|Übersicht =[[Spezial:Präfixindex/Diskussion:Stapelspeicher/Archiv|Archiv]]<br />
|Klein =Nein<br />
|Mindestbeiträge =2<br />
|Zeigen =Ja<br />
|Mindestabschnitte =2<br />
|Frequenz =monatlich<br />
}}<br />
<br />
== Richtung ==<br />
<br />
Im Text steht: "Der Stapel wächst also nach unten." heißt das, Richtung kleinere Speicheradressen? - "Der Stapel wächst also nach unten, in Richtung der kleineren Speicheradressen." könnte man doch dann schreiben. --[[Benutzer:Ost38|Ost38]] 11:31, 23. Feb. 2008 (CET)<br />
<br />
== Aufrufstapel (Call Stack) ==<br />
<br />
Ich denke, dass wir unbedingt eine deutsche Entsprechung zu [[en:Call stack]] brauchen, da dieser ein sehr wichtiges Werkzeug beim Abhandeln von Unterprogrammen ist. Viele Artikel, wie z. Bsp. [[Dynamischer Speicher]] verweisen auf diesen Artikel, obwohl dort nicht die Datenstruktur, sondern der Aufrufstapel im Hauptspeicher gemeint ist. --[[Benutzer:Kockster|Kockster]] 15:35, 9. Jul. 2008 (CEST)<br />
<br />
== Abschnitt "Compiler" ==<br />
<br />
So, wie der Abschnitt vorher war, hat er Compile-Zeit und Laufzeit vermischt. Ich habe den Laufzeit-Teil nach oben verschoben. Außerdem war die Darstellung des Parsing-Prozesses falsch. Ich habe sie darum entsorgt und statt dessen auf [[Kellerautomat]] verlinkt. Wäre es evtl. besser, auf entsprechende Parsing-Algorithmen zu verlinken? -- [[Benutzer:UKoch|UKoch]] 18:55, 21. Nov. 2011 (CET)<br />
<br />
== Implementierung ==<br />
<br />
Die angegebene Implementierung ist sinnlos. Ein Stack, der durch ein Array implementiert ist, könnte direkt durch ein Array ersetzt werden. Man sollte ein Beispiel eines richtigen Stacks mit Zeigern einbauen. -- [[Benutzer:Mfnalex|Mfnalex]] 19:29, 10. Jan. 2012 (CET)<br />
: Ich habe die Implementierung durch einen Stack der mit Zeigern arbeitet ersetzt. --[[Benutzer:PrototypePHX|PrototypePHX]] ([[Benutzer Diskussion:PrototypePHX|Diskussion]]) 17:37, 30. Jun. 2012 (CEST)</div>PrototypePHXhttps://de.wikipedia.org/w/index.php?title=Stapelspeicher&diff=105030250Stapelspeicher2012-06-30T15:34:51Z<p>PrototypePHX: Implementierung eines Stacks in C++ ohne die Verwendung von Arrays</p>
<hr />
<div>[[Datei:Data stack.svg|miniatur|Vereinfachte Darstellung eines Stacks mit den Funktionen Push (drauflegen) und Pop (runternehmen)]]<br />
<br />
In der [[Informatik]] bezeichnet ein '''Stapelspeicher''' oder '''Kellerspeicher''' (kurz '''Stapel''' oder '''Keller''', häufig auch mit dem englischen Wort '''Stack''' bezeichnet) eine häufig eingesetzte [[Datenstruktur]]. Sie wird von den meisten [[Mikroprozessor]]en in der [[Hardware]] direkt unterstützt.<br />
<br />
== Funktionsprinzip ==<br />
Ein Stapel kann eine theoretisch beliebige, in der Praxis jedoch begrenzte Menge von Objekten aufnehmen. Elemente können nur oben auf den Stapel gelegt und auch nur von dort wieder gelesen werden. Elemente werden übereinander gestapelt und in umgekehrter Reihenfolge vom Stapel genommen. Dies wird auch [[Last In – First Out|Last-In-First-Out]]-Prinzip (LIFO) genannt.<br />
<br />
Dazu werden folgende Operationen zur Verfügung gestellt:<br />
* {{lang|en|''push''}} (auch ''einkellern'') legt das Objekt oben auf den Stapel.<br />
* {{lang|en|''pop''}} (''auskellern'') liefert und entfernt das oberste Objekt vom Stapel. Bei manchen Prozessoren wie dem [[MOS Technology 6502]] wird diese Aktion dagegen {{lang|en|''pull''}} (herunterziehen) genannt.<br />
* {{lang|en|''peek''}} (''nachsehen'') liefert das oberste Objekt, ohne es zu entfernen.<br />
<br />
In der [[Automatentheorie]] werden Stapel benutzt, um bestimmte Problemklassen theoretisch betrachten zu können (vgl. [[Kellerautomat]]). Sie unterscheidet deshalb genauer zwischen einem echten Kellerspeicher (kurz ''Keller''), bei dem kein Element außer dem obersten gelesen werden kann, und einem ''Stapelspeicher'', bei dem jedes Element betrachtet, aber nicht verändert werden kann. In der Praxis spielt diese Unterscheidung jedoch kaum eine Rolle; beinahe jede [[Implementierung#Softwaretechnik|Implementierung]] ist ein Stapel. Daher werden die Begriffe im Allgemeinen synonym verwendet.<br />
<br />
== Illustration ==<br />
[[Datei:Kellerspeicher.svg|miniatur|hochkant=1.5|Skizze eines Stapels]]<br />
<br />
Ein 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 möglich. Ein Hinzufügen oder Entfernen einer Kiste weiter unten im Stapel ist nicht möglich. Es gibt aber in manchen Implementierungen Befehle, um die obersten Elemente zu vertauschen (SWAP, ROT).<br />
<br />
== Geschichte ==<br />
Die Verwendung eines Stapelspeichers zur Übersetzung von Programmiersprachen wurde 1957 von [[Friedrich Ludwig Bauer]] und [[Klaus Samelson]] unter dem Namen „Kellerprinzip“ patentiert<ref>Bauer, Goos: ''Informatik, Eine einführende Übersicht, Erster Teil''. Springer-Verlag, Berlin 1982, S. 222. „Die Bezeichnung ‚Keller‘ hierfür wurde von Bauer und Samuelson in einer deutschen Patentanmeldung vom 30. März 1957 eingeführt.“</ref><ref name="patent">{{Patent|Land=DE|V-Nr=1094019|Titel=Verfahren zur automatischen Verarbeitung von kodierten Daten und Rechenmaschine zur Ausübung des Verfahrens|Erfinder=Friedrich Ludwig Bauer, Klaus Samelson|V-Datum=1960-12-01|A-Datum=1957-03-30}}</ref> und etwa zur selben Zeit unabhängig vom australischen Philosophen [[Charles Leonard Hamblin|Charles Hamblin]] entdeckt. Die lange ausgebliebene internationale Anerkennung und Ehrung ihrer Leistung erfolgte erst im Jahre 1988. Bauer erhielt den renommierten [[Computer Pioneer Award]] ([[IEEE]]) für ''Computer Stacks''. Samelson war bereits 1980 verstorben.<br />
<br />
== Anwendungen ==<br />
Mithilfe des Stapelspeichers lassen sich einfach Terme oder Syntaxen auf richtige Verschachtelung prüfen, so wie es oft im Internet bei [[BBCode|BB-Codes]] oder [[Extensible Markup Language|XML]]-Dokumenten der Fall ist.<br />
<br />
=== Mikroprozessoren ===<br />
In Mikroprozessoren gibt es oft ein spezielles [[Register (Computer)|Register]], den Stackpointer (Stapelzeiger). Dieses Register enthält eine Speicheradresse, die auf den aktuellen Stapeleintrag (des aktuellen [[Prozess (Informatik)|Prozesses]]) zeigt. Viele Befehle/Operationen des Mikroprozessors nutzen diesen Stapeleintrag. Unter anderem gibt es Befehle, mit denen man in den Stack schreiben (z.&nbsp;B. ''push'' beim [[x86-Prozessor]]) oder von ihm lesen kann (z.&nbsp;B. ''pop''). Dabei wird automatisch der Stapelzeiger verringert oder erhöht.<br />
<br />
Die Operation ''Jump To Subroutine'' (Sprung in ein [[Unterprogramm]]) legt auf dem Stack die Rücksprungadresse ab, die später von der Operation ''Return From Subroutine'' verwendet wird. Unterprogrammen bzw. Funktionen, wie man sie aus Programmiersprachen wie C kennt, werden die Parameter über den Stack übergeben, der auch die Rückgabewerte aufnimmt. Außerdem werden lokale Variablen auf dem Stack gespeichert. Dies erlaubt unter anderem [[Rekursion]], das Aufrufen einer Funktion aus eben dieser Funktion heraus. – Wird bei der Rückkehr aus einer Funktion nur ein Eintrag zu viel oder zu wenig ausgelesen, führt dies zu besonders gravierenden Programmfehlern, da der Prozessor dann versuchen wird, Code an völlig zufälliger Speicherposition auszuführen. Durch das Ausnützen einer nicht korrekt behandelten Größenangabe der Daten können Angreifer versuchen, einen [[Pufferüberlauf]] zu produzieren, der den Stack so verändert, dass durch Umleiten des Rücksprungs bösartiger Code ausgeführt wird.<br />
<br />
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 erhöht wird. Der Stapel wächst „nach unten“, in Richtung niedrigerer Speicheradressen. Dies ist historisch begründet: Legt man bei begrenztem Speicher den Stack unterhalb des Speicherplatzes, der von den Programmen benutzt wird, können so andere Programmdaten (die normal hinter dem Programm abgelegt werden) den Stapel nicht so leicht überschreiben und der Stapel nicht das Maschinenprogramm.<br />
<br />
In [[Multitasking]]-Systemen gibt es für jeden Prozess und innerhalb der Prozesse für jeden [[Thread (Informatik)|Thread]] einen eigenen Stapelspeicher. Beim Umschalten zwischen Prozessen bzw. Threads wird neben anderen Registern auch der jeweilige Stapelzeiger gespeichert und geladen.<br />
<br />
Um Fehler in der Benutzung des Stacks durch einen „Unterlauf“ des Stapelzeigers aufzudecken, legen manche [[Betriebssystem]]e wie beispielsweise [[Disk Operating System|DOS]] oder [[CP/M]] (Bei [[Component Object Model|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 ggf. noch auf den Ablauffehler reagiert werden. Manche Betriebssysteme können auch den Stapelspeicher während der Laufzeit vergrößern, was bei einem bereits sehr großen Stapel relativ viel Zeit in Anspruch nehmen kann. Bei anderen Betriebssystemen hat der Programmierer selbst anzugeben, wie groß der Stack sein soll.<br />
<br />
Um den Nutzungsgrad des meist begrenzten Stapelspeichers zu ermitteln, bedient man sich der sogenannten Wasserstands-Methode: Der gesamte für 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.<br />
<br />
=== Moderne Programmiersprachen ===<br />
[[Compiler]] für moderne [[Programmiersprache]]n nutzen gewöhnlich ''push''- und ''pop''-Operationen vor dem Aufruf eines Unterprogramms, um an dieses Parameter zu übergeben. Ähnlich können so auch Ergebnisse des Unterprogramms zurückgegeben werden. Für [[rekursive Programmierung]] wird dieser Mechanismus nochmal erweitert, indem auch für die lokalen Variablen des Unterprogramms auf dem Stapelspeicher Platz reserviert wird. Bei der Umwandlung einer rekursiven Funktion in eine [[Iterative Programmierung|iterative Funktion]] muss dieser Mechanismus häufig explizit implementiert werden.<br />
<br />
Programmiersprachen, die auf eine [[virtuelle Maschine]] aufsetzen (zum Beispiel [[Java (Programmiersprache)|Java]], [[P-Code]]-[[Pascal (Programmiersprache)|Pascal]]), optimieren den kompilierten Zwischencode für die Verwendung eines Stapels, um zur [[Laufzeit (Informatik)|Laufzeit]] die Interpretation dieses Zwischencodes zu beschleunigen.<br />
<br />
=== Stack-Implementierung ===<br />
In C++:<br />
<source lang="cpp"><br />
#include <stdexcept><br />
<br />
<br />
template <typename T><br />
class stack<br />
{<br />
public:<br />
// erzeugt einen leeren Stack<br />
stack(): size_(0) {}<br />
<br />
// erzeugt einen Stack mit n Elementen von T<br />
stack(size_t n, T value_): size_(0)<br />
{<br />
for (int i = 0; i < n; ++i)<br />
push(value_);<br />
}<br />
<br />
// Kopierkonstruktor<br />
stack(const stack &rhs): size_(0)<br />
{<br />
// Wenn der "rechte" Stack keine Elemente aufweist, muss nichts weiter getan werden.<br />
if (rhs.size_ != 0) {<br />
node *traverser = rhs.top;<br />
size_t size_ = rhs.size();<br />
//Absteigen zum ersten Element, dann zum zweiten Element, usw.<br />
for (; size_ > 0; --size_ ) {<br />
for (unsigned i=1; i < size_; ++i)<br />
traverser = traverser->previous;<br />
push(traverser->value);<br />
traverser = rhs.top;<br />
}<br />
}<br />
}<br />
<br />
~stack()<br />
{<br />
for (; size_ != 0; pop());<br />
}<br />
<br />
<br />
// Zuweisungsoperator<br />
stack& operator=(const stack &rhs)<br />
{<br />
// überprüfe ob ein Stack sich selbst zugewiesen wird.<br />
if (&rhs != &*this)<br />
{<br />
for (; size_ != 0; pop());<br />
<br />
// vgl. Kopierkonstruktor<br />
if (rhs.size_ != 0) {<br />
node *traverser = rhs.top;<br />
size_t size_ = rhs.size();<br />
for (; size_ > 0; --size_ ) {<br />
for (unsigned i=1; i < size_; ++i)<br />
traverser = traverser->previous;<br />
push(traverser->value);<br />
traverser = rhs.top;<br />
}<br />
}<br />
<br />
}<br />
return *this;<br />
}<br />
<br />
<br />
void push(T value_)<br />
{<br />
node *newNode;<br />
// .previous des untersten Stackelementes muss 0 sein, damit das Ende des Stacks<br />
// ermittelt werden kann.<br />
if (size_ == 0)<br />
newNode = new node(value_, 0);<br />
else<br />
newNode = new node(value_, top);<br />
top = newNode;<br />
++size_;<br />
}<br />
<br />
T pop()<br />
{<br />
if (size_ == 0)<br />
throw std::underflow_error("Nothing to pop.");<br />
// Rückgabewert sichern<br />
T returnValue = top->value;<br />
node *newTop = top->previous;<br />
delete top;<br />
top = newTop;<br />
--size_;<br />
return returnValue;<br />
}<br />
<br />
T peek() const { return top->value; }<br />
size_t size() const { return size_; }<br />
<br />
<br />
private:<br />
struct node<br />
{<br />
T value;<br />
node *previous;<br />
<br />
node(T value_, node *previous_): value(value_), previous(previous_) {}<br />
};<br />
node *top;<br />
<br />
std::size_t size_; //ab C++11 nicht mehr im std-Namensraum<br />
};<br />
</source><br />
In Java:<br />
<source lang="java"><br />
// Ein Stapel dynamischer Größe, der alle<br />
// Elemente der Klasse Object sowie deren<br />
// Unterklassen verwalten kann.<br />
public class Stack {<br />
private Item start = null;<br />
public void push(Object object) { // Speichert ein neues Objekt<br />
start = new Item(object,start);<br />
}<br />
public Object top() { // Gibt das oberste Objekt wieder<br />
return !(empty()) ? start.getObject() : null;<br />
}<br />
public boolean empty() { // Prüft, ob der Stapel leer ist<br />
return start == null;<br />
}<br />
public void pop() { // Entfernt das oberste Objekt aus dem Stapel<br />
if(!empty()) start = start.getNext();<br />
}<br />
}<br />
<br />
public class Item {<br />
private Object object; // Das zu verwaltende Objekt<br />
private Item next; // Referenz auf den nächsten Knoten<br />
public Item(Object object, Item next) {<br />
this.object = object;<br />
this.next = next;<br />
}<br />
public Object getObject() { // Gibt das gespeicherte Objekt aus<br />
return object;<br />
}<br />
public Item getNext() { // Gibt den nächsten Knoten aus<br />
return next;<br />
}<br />
}<br />
</source><br />
<br />
In den meisten Programmbibliotheken werden Stacks als [[verkettete Listen]] implementiert, da diese bessere Speicherausnutzung bieten. So bietet etwa die [[C++]] [[Standard Template Library]] das Template <code>deque&lt;T&gt;</code> mit den Methoden <code>push_back()</code> und <code>pop_back()</code> an. [[Java (Programmiersprache)|Java]] stellt diese Funktionalität in der Klasse <code>java.util.LinkedList</code> zur Verfügung.<br />
<br />
=== Compiler ===<br />
Zur Übersetzung des Quellcodes einer [[Formale Sprache|formalen Sprache]] nutzen Compiler und [[Interpreter]] einen [[Parser]], der einen Stapel verwendet. Der Parser kann z.&nbsp;B. wie ein [[Kellerautomat]] arbeiten.<br />
<br />
=== Verarbeitung von Klammerstrukturen ===<br />
Stapelspeicher eignen sich auch zur Auswertung von Klammerausdrücken, wie sie etwa in der Mathematik geläufig sind. Dabei wird zunächst für Operatoren und Operanden je ein Stapelspeicher initialisiert. Der zu verarbeitende Klammerausdruck wird nun symbolweise eingelesen. Wird eine öffnende Klammer eingelesen, so ist diese zu ignorieren. Wird ein Operand oder Operator eingelesen, so ist dieser auf den jeweiligen Stapelspeicher zu legen.<br />
Wird eine schließende Klammer eingelesen, so wird der oberste Operator vom Stapelspeicher für die Operatoren genommen und entsprechend diesem Operator eine geeignete Anzahl von Operanden, die zur Durchführung der Operation benötigt werden. Das Ergebnis wird dann wieder auf dem Stapelspeicher für Operanden abgelegt. Sobald der Stapelspeicher für die Operatoren leer ist, befindet sich im Stapelspeicher für die Operanden das Ergebnis.<br />
<br />
=== Postfixnotation ===<br />
Zur Berechnung von [[Term]]en wird gelegentlich die [[Postfixnotation]] verwendet, die mit Hilfe der Operationen eine Klammersetzung und [[Prioritätsregel (Mathematik)|Prioritätsregeln]] für die Operationen überflüssig macht. Zahlwerte werden automatisch auf dem Stapel abgelegt. Binäre Operatoren (zum Beispiel +, −, *, /) holen die oberen beiden Werte, unäre Operatoren (zum Beispiel Vorzeichenwechsel) einen Wert vom Stapel und legen anschließend das (Zwischen-)Ergebnis dort wieder ab.<br />
<br />
=== Infixnotation ===<br />
Bei der maschinengestützten Auflösung von arithmetischen Ausdrücken in der so genannten [[Infixnotation]] (der Operator steht ''zwischen'' den beteiligten Zahlwerten) werden zunächst 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.<br />
<br />
=== Stapelorientierte Sprachen ===<br />
Stapelorientierte Sprachen (z.&nbsp;B. [[Forth (Programmiersprache)|Forth]] oder [[Postscript]]) wickeln fast alle [[Variable (Programmierung)|Variablen]]-Operationen über einen Stapel ab und stellen neben den oben genannten Operatoren noch weitere zur Verfügung. 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.<br />
<br />
Forth benutzt einen zweiten Stapel (Return-Stapel) zur Zwischenspeicherung der Rücksprungadressen von Unterprogrammen während der Ausführungsphase. Dieser Stapel wird auch während der Übersetzungsphase für die Adressen der Sprungziele für die Kontrollstrukturen verwendet. Die Übergabe und Rückgabe von Werten an Unterprogrammen geschieht über den ersten Stapel, der zweite nimmt die Rücksprungadresse auf.<br />
<br />
== Verwandte Themen ==<br />
Eine [[First In – First Out|First-In-First-Out]]-Datenstruktur nennt sich [[Warteschlange (Datenstruktur)|Warteschlange]] (engl. ''Queue''). Beide Strukturen haben dieselbe Signatur (d.&nbsp;h. Methoden-Struktur), aber unterschiedliches Verhalten, weswegen sie oft zusammen unterrichtet werden.<br />
<br />
Eine andere Art Speicher zu verwalten ist die [[Dynamischer Speicher|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 eingeschränkten Prinzip des Stapelspeichers oder der Warteschlange entspricht.<br />
<br />
== Siehe auch ==<br />
* [[Floodfill]]<br />
* [[Deque]]<br />
* [[Stacktrace]]<br />
<br />
== Literatur ==<br />
* {{Patent|Land=DE|V-Nr=1094019|Titel=Verfahren zur automatischen Verarbeitung von kodierten Daten und Rechenmaschine zur Ausübung des Verfahrens|Erfinder=Friedrich Ludwig Bauer, Klaus Samelson|V-Datum=1960-12-01|A-Datum=1957-03-30|Kommentar=Erteilt 12. August 1971}}<br />
<br />
== Einzelnachweise ==<br />
<references /><br />
<br />
== Weblinks ==<br />
{{Commonscat|Stack data structure|Stack-Datenstruktur}}<br />
<br />
[[Kategorie:Datenstruktur]]<br />
[[Kategorie:Rekursion]]<br />
[[Kategorie:Programmierung]]<br />
<br />
[[ar:مكدس]]<br />
[[be-x-old:Стэк]]<br />
[[bg:Стек (структура от данни)]]<br />
[[ca:Memòria en pila (estructura de dades)]]<br />
[[cs:Zásobník (datová struktura)]]<br />
[[da:Stak (datastruktur)]]<br />
[[el:Στοίβα (δομή δεδομένων)]]<br />
[[en:Stack (abstract data type)]]<br />
[[es:Pila (informática)]]<br />
[[et:Pinumälu]]<br />
[[eu:Pila (informatika)]]<br />
[[fa:پشته]]<br />
[[fi:Pino]]<br />
[[fr:Pile (informatique)]]<br />
[[he:מחסנית (מבנה נתונים)]]<br />
[[hr:Stog]]<br />
[[hu:Verem (számítástechnika)]]<br />
[[id:Stack (struktur data)]]<br />
[[is:Stafli (tölvunarfræði)]]<br />
[[it:Stack]]<br />
[[ja:スタック]]<br />
[[kk:Стек]]<br />
[[ko:스택]]<br />
[[lb:Stack (Informatik)]]<br />
[[lt:Rietuvė]]<br />
[[lv:Steks (datu struktūra)]]<br />
[[ml:സ്റ്റാക്ക് (ഡാറ്റാ സ്ട്രക്ച്ചർ)]]<br />
[[mn:Stack]]<br />
[[nl:Stack (informatica)]]<br />
[[no:Stakk (datastruktur)]]<br />
[[pl:Stos (informatyka)]]<br />
[[pt:Pilha (informática)]]<br />
[[ro:Stivă (structură de date)]]<br />
[[ru:Стек]]<br />
[[simple:Stack (data structure)]]<br />
[[sl:Sklad (računalništvo)]]<br />
[[sq:Stack (struktura e të dhënave)]]<br />
[[sr:Стек (апстрактни тип података)]]<br />
[[sv:Stack (datastruktur)]]<br />
[[th:กองซ้อน]]<br />
[[tr:Yığın (soyut veri türü)]]<br />
[[uk:Стек]]<br />
[[vi:Ngăn xếp]]<br />
[[zh:堆栈]]</div>PrototypePHX