Generischer Stack
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 60 von 61.
Aufgabe
EinfachEin Stack (Stapel) ist eine grundlegende Datenstruktur, die dem Last-In-First-Out (LIFO)-Prinzip folgt — das letzte hinzugefügte Element wird als erstes wieder entfernt. Denken Sie an einen Stapel Teller: Sie legen oben einen Teller auf und nehmen ihn auch von oben wieder weg.
Lassen Sie uns einen Generic Stack bauen — eine vielseitige Datenstruktur, die mithilfe von void*-Pointern jeden Datentyp speichern kann. Ihr Stack wird dem Last-In-First-Out-Prinzip folgen und alle wesentlichen Operationen enthalten.
Sie werden Ihren Code auf drei Dateien verteilen:
stack.h: Definieren Sie dasStack-Struct mit drei Membern: einvoid**-Array für die Elemente, einintfür den Top-Index (nächster freier Platz) und einintfür die Kapazität. Deklarieren Sie Funktionsprototypen zum Erstellen eines Stacks (nimmt eine Kapazität entgegen), zum Hinzufügen eines Elements (push), zum Entfernen eines Elements (pop), zum Ansehen des obersten Elements (peek), zum Überprüfen, ob der Stack leer ist, und zum Freigeben des Stacks.stack.c: Implementieren Sie Ihren generischen Stack:create_stack— alloziert einen Stack auf dem Heap, alloziert das items-Array mit der angegebenen Kapazität, initialisiert top auf 0 und gibt den Pointer zurückpush— fügt ein Element oben hinzu, wenn noch Platz ist (wenn top kleiner als capacity ist)pop— entfernt das oberste Element und gibt es zurück, oder gibtNULLzurück, wenn der Stack leer istpeek— gibt das oberste Element zurück, ohne es zu entfernen, oderNULL, wenn der Stack leer istis_empty— gibt 1 zurück, wenn der Stack keine Elemente enthält, andernfalls 0free_stack— gibt zuerst das items-Array frei und dann das Stack-Struct selbst
main.c: Lesen Sie die Anzahl der auszuführenden Operationen ein. Lesen Sie dann für jede Operation einen Befehl ein:pushgefolgt von einem ganzzahligen Wert,popoderpeek. Erstellen Sie einen Stack mit der Kapazität 10. Fürpushallozieren Sie einen Integer auf dem Heap und pushen dessen Pointer. Fürpoprufen Sie das Element ab, geben seinen Wert aus und geben den Integer frei. Fürpeekgeben Sie den Wert aus, ohne ihn zu entfernen. Wennpopoderpeekauf einem leeren Stack aufgerufen werden, geben Sieemptyaus. Geben Sie nach allen Operationen alle verbleibenden Elemente und den Stack frei.
Ihr Programm erhält:
- Die Anzahl der Operationen
- Jede Operation in einer separaten Zeile (
push X,popoderpeek)
Beispielhafte Ausgabe, wenn die Eingaben 5, dann push 10, push 20, peek, pop, pop sind:
20
20
10Beispielhafte Ausgabe, wenn die Eingaben 3, dann pop, push 42, peek sind:
empty
42Beispielhafte Ausgabe, wenn die Eingaben 4, dann push 5, push 15, pop, pop sind:
15
5Denken Sie daran, dass Ihr Stack void*-Pointer speichert — der Aufrufer ist für das Allozieren und Freigeben der eigentlichen Daten verantwortlich. Casten Sie beim Poppen den zurückgegebenen void* zurück in einen int*, um auf den Wert zuzugreifen. Verwenden Sie strcmp aus <string.h>, um Befehls-Strings zu vergleichen.
Probier es selbst
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
int main() {
int n;
scanf("%d", &n);
// TODO: Erstelle einen Stack mit einer Kapazität von 10
// TODO: Verarbeite jede Operation
for (int i = 0; i < n; i++) {
char command[10];
scanf("%s", command);
if (strcmp(command, "push") == 0) {
int value;
scanf("%d", &value);
// TODO: Reserviere einen Integer auf dem Heap und pushe seinen Pointer
}
else if (strcmp(command, "pop") == 0) {
// TODO: Entferne das Element (pop)
// - Wenn nicht NULL, gib den Wert aus und gib den Integer frei
// - Wenn NULL (leerer Stack), gib "empty" aus
}
else if (strcmp(command, "peek") == 0) {
// TODO: Sieh dir das oberste Element an (peek)
// - Wenn nicht NULL, gib den Wert aus (nicht entfernen oder freigeben)
// - Wenn NULL (leerer Stack), gib "empty" aus
}
}
// TODO: Gib alle verbleibenden Elemente im Stack frei
// TODO: Gib den Stack selbst frei
return 0;
}
Alle Lektionen in Object Oriented Programming
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-Implementierung