Stack Implementation
-
#include <iostream> using namespace std; struct Person { int age; }; Person* create_person1(int age); Person* create_person2(int age); Person create_person3(int age); int main() { struct Person *emil = create_person1(15); struct Person *paul = create_person2(16); struct Person lisa = create_person3(17); cout<<"Emils Alter: "; cout<<emil->age<<endl; cout<<"Pauls Alter: "; cout<<(*paul).age<<endl; cout<<"Lisas Alter: "; cout<<lisa.age<<endl; return 0; } struct Person* create_person1(int age) { struct Person *newPerson; newPerson->age = 15; return newPerson; } struct Person* create_person2(int age) { struct Person *newPerson; (*newPerson).age = 15; return newPerson; } struct Person create_person3(int age) { struct Person newPerson; newPerson.age = 15; return newPerson; }5 min gegoogled. 3 Möglichkeiten gefunden ein Element von Struct zu erzeugen.
Der Code ist nicht getestet und da ich selbst grade erst mit C++ anfange wird er vermutlich auch nicht laufen
Aber so in etwa wird es funktionieren.Und lass das alles erstmal in einer Datei. Auslagern kannst du später immer noch.
Scheint auch C mit cout zu sein. Kann ich leider noch nicht so ganz beurteilen

-
Was für ein Scheiß...
-
n3wbie, es ist ja sehr löblich, dass du als Anfänger auch selber über Fragen nachdenkst. Aber wenn du helfen willst, dann sei dir bitte halbwegs sicher, ob deine Antwort auch stimmt. Wenn du selber sagst, dass du dich nicht auskennst und du nicht einmal den Code getestet hast, dann ist deine Antwort sehr wahrscheinlich nicht richtig. In der Tat ist genau das passiert: Alle drei von deinen Versionen gehen entweder voll am Thema vorbei oder sind schlichtweg falsch. Und zwar richtig schlimm falsch, nicht bloß schlecht.
Ich muss leider sagen, dass dies bei vielen deiner Antworten der Fall ist, nicht nur in diesem Thread.
-
Wenn du selber sagst, dass du dich nicht auskennst und du nicht einmal den Code getestet hast, dann ist deine Antwort sehr wahrscheinlich nicht richtig.
WTF. MinGW geladen, compiliert und läuft. Keine Fehler, keine Warnung.
Ja, das macht es nicht unbedingt richtig. Und es ist auch nicht als Lösung gedacht gewesen. Sondern als bsp. dafür wie schnell man zeigen kann, dass man an Eigenleistung interessiert ist. Und ich muss sagen, so beschissen das auch aussehen mag, ich sehe es lieber als: geht alles nicht, macht ihr mal.Und zwar richtig schlimm falsch, nicht bloß schlecht.
Prima, vielleicht schreibst du besser wie es richtig geht. Ich will es ja selbst lernen.
Und ohne dich angreifen zu wollen, in diesem Thema ist absolut gar nichts produktives, was den TO auch nur ein bisschen auf die richtige Spur bringt.Ich muss leider sagen, dass dies bei vielen deiner Antworten der Fall ist, nicht nur in diesem Thread.
Auch das würde ich zu gerne sehen. Bei den 3 Fachbezogenen Antworten die ich gegeben habe.
-
n3wbie schrieb:
....
Das sind halt so etwas von Anfängerfehlern, da lohnt es sich kaum zu antworten. Wenn man jeden Stuss, den jemand schreibt im Details korrigiert, dann kommt man nie zu irgendwas produktivem. Außerdem hast du eigentlich auf jede deiner falschen Antworten schon Kontra bekommen, du hast dich bloß hinterher versucht mit fadenscheinigen Argumenten rauszureden. Darauf hat dann bloß keiner mehr geantwortet, weil es sich nicht lohnt, deine Ausreden auch noch mal zu widerlegen. Aber schön, ausnahmsweise schreib ich mal was zu allen deinen fachlichen Beiträgen. Aber sag hinterher nicht, ich würde dich absichtlich runtermachen. Wenn du um eine Liste deiner Fehler bettelst, dann bekommst du eben auch eine:
WTF. MinGW geladen, compiliert und läuft. Keine Fehler, keine Warnung.
Dann kannst du deinen Compiler nicht benutzen. MinGW basiert auf GCC. GCC gibt folgende Warnungen, wenn man ihn korrekt nutzt:
test.cc:28:16: warning: unused parameter ‘age’ [-Wunused-parameter] struct Person* create_person1(int age) { ^ test.cc:35:16: warning: unused parameter ‘age’ [-Wunused-parameter] struct Person* create_person2(int age) { ^ test.cc:41:15: warning: unused parameter ‘age’ [-Wunused-parameter] struct Person create_person3(int age) { ^ test.cc: In function ‘Person* create_person1(int)’: test.cc:30:24: warning: ‘newPerson’ is used uninitialized in this function [-Wuninitialized] newPerson->age = 15; ^ test.cc: In function ‘Person* create_person2(int)’: test.cc:37:26: warning: ‘newPerson’ is used uninitialized in this function [-Wuninitialized] (*newPerson).age = 15; ^Das Resultat mal mit valgrind ausgeführt:
==13823== Memcheck, a memory error detector ==13823== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==13823== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==13823== Command: ./a.out ==13823== ==13823== Use of uninitialised value of size 8 ==13823== at 0x400967: create_person1(int) (test.cc:30) ==13823== by 0x4008AE: main (test.cc:14) ==13823== ==13823== ==13823== Process terminating with default action of signal 11 (SIGSEGV) ==13823== Bad permissions for mapped region at address 0x400A3D ==13823== at 0x400967: create_person1(int) (test.cc:30) ==13823== by 0x4008AE: main (test.cc:14) ==13823== ==13823== FILE DESCRIPTORS: 3 open at exit. ==13823== Open file descriptor 2: /dev/pts/66 ==13823== <inherited from parent> ==13823== ==13823== Open file descriptor 1: /dev/pts/66 ==13823== <inherited from parent> ==13823== ==13823== Open file descriptor 0: /dev/pts/66 ==13823== <inherited from parent> ==13823== ==13823== ==13823== HEAP SUMMARY: ==13823== in use at exit: 0 bytes in 0 blocks ==13823== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==13823== ==13823== All heap blocks were freed -- no leaks are possible ==13823== ==13823== For counts of detected and suppressed errors, rerun with: -v ==13823== Use --track-origins=yes to see where uninitialised values come from ==13823== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Segmentation fault (core dumped)Ups, Segfault. Tja, war wohl doch nicht richtig.
Die Fehler sind absolute Anfängerfehler:
struct Person *newPerson; newPerson->age = 15;newPerson zeigt auf nix. Zeiger nicht verstanden. C++-Objektmodell nicht verstanden. Wozu überhaupt ein Zeiger? Du hast nicht verstanden, was die Funktion machen soll, noch wie Zeiger und Objekte funktionieren.
create_person2: Gleiche Fehler wie bei Version 1.
struct Person create_person3(int age) { struct Person newPerson; newPerson.age = 15; return newPerson; }Du hast nicht verstanden, wowum es hier überhaupt geht. Die Funktion ist zwar funktional richtig, aber trägt nicht dazu bei, dem Fragesteller beizubringen, wie Objektorientierung in C funktioniert. So wie hier geht das nämlich nicht (ich schreibe jetzt aber keinen Aufsatz, wie es richtig ginge).
Dann noch 3 weitere falsche Antworten von dir:
1. http://www.c-plusplus.net/forum/p2422550#2422550
Thema nicht verstanden. Siehe Bashars darauf folgenden Kommentar.2. http://www.c-plusplus.net/forum/p2422228#2422228
Thema verfehlt oder nicht verstanden. Siehe Bashars darauf folgenden Kommentar.3. http://www.c-plusplus.net/forum/p2422683#2422683
Thema nicht verstanden. Siehe Skym0sh0s darauf folgenden Kommentar. Du willst Speicherverwaltung eines Betriebssystems erklären und kommst mit einer Erklärung zu einem 16-Bit OS, ohne virtuellen Speicher? Dabei ist doch sogar das Hauptproblem des Threaderstellers, dass er virtuellen Speicher nicht verstanden hat.Drei Mal eine total kontraproduktive Hilfe, weil du das Thema selbst nicht verstanden hast, noch begriffen hast was überhaupt das Problem der Threadersteller ist.
Und hier noch deine fadenscheinigen Ausreden zum jeweiligen Thema:
1. http://www.c-plusplus.net/forum/p2422555#2422555
Du hast nicht einmal verstanden, was an der Antwort falsch war. Siehe Bashars darauf folgenden Kommentar. Du hast gar nicht verstanden, worum es in diesem Thread überhaupt geht oder wie die richtige Lösung auch nur im Ansatz aussieht.2. http://www.c-plusplus.net/forum/p2422233#2422233
Noch einmal die gleiche Allgemeinfloskel, in anderen Worten. Immer noch am Thema vorbei. Deine Begründung, warum es nicht am Thema vorbei wäre, ist eine Wiederholung dessen, was du schon geschrieben hast.3. http://www.c-plusplus.net/forum/p2422706#2422706
Wenn du meinst, dass es reicht, virtuellen Speicher zu erwähnen, wieso tust du es dann nicht. Wieso erklärst du stattdessen, wie vor 30 Jahren der Stand der Technik war? Wenn du sagst, dass du Java-Entwickler wärst und eigentlich keine Ahnung vom Thema hast, wieso antwortest du dann?Wie gesagt, mache ich das gerade nur, weil du darum gebettelt hast, sonst würde ich jemandem nicht so detailliert so viele Vorwürfe machen. Wie schon gesagt, ist es sehr löblich, als Anfänger mitzudenken, aber es ist was anderes, eine halbgare Antwort zu geben. Wenn du von Speicherverwaltung in modernen Betriebssystemen, Objektorientierung in C oder von den Feinheiten bei der Wahl einer Programmiersprache keine Ahnung hat, dann fragt man lieber selber was dazu, als dass man vollkommen veraltete Beschreibungen, ungetestete Eigenlösungen oder triviale Allgemeinfloskeln zum besten gibt.
-
Dann kannst du deinen Compiler nicht benutzen. MinGW basiert auf GCC. GCC gibt folgende Warnungen, wenn man ihn korrekt nutzt:
g++.exe main.cpp -o main.exe
Das habe ich gemacht. Kein Error, keine Warnung. Vermutlich ist das falsch, aber ich stehe an der gleichen stelle wie der TO.
Guck dir doch mal die Fragen an:plantplant schrieb:
aber ich kann den Unterbau der Funktionen nicht schreiben.
plantplant schrieb:
Was soll Stack *create_stack(unsigned int); bedeuten?
neues element von stack erzeugen? eine instanz von Stack?
Denkst du, wer solche Fragen stellt kann seinen Compiler richtig bedienen?
Er ist absolut am Anfang.SeppJ schrieb:
Die Funktion ist zwar funktional richtig, aber trägt nicht dazu bei, dem Fragesteller beizubringen, wie Objektorientierung in C funktioniert
DAS ist im Moment auch nicht seine Baustelle. Er kann wie ich keine Zeiger, er kann nicht mal eine Funktion schreiben. Meinst du nicht, vielleicht wäre es erstmal cool, wenn er das könnte?
SeppJ schrieb:
(ich schreibe jetzt aber keinen Aufsatz, wie es richtig ginge).
Prima, das hilft natürlich. Der TO kommt voll nicht klar, dreht sich mit diesem mega kleinen Programm im Kreis, und während ich versuche hinweise zu geben was vielleicht möglicherweise ein Ansatz wäre, jammerst du rum wie schlecht alles ist und verweigerst die Verbesserung.
SeppJ schrieb:
Wenn du sagst, dass du Java-Entwickler wärst und eigentlich keine Ahnung vom Thema hast, wieso antwortest du dann?
Und genau deshalb antworte ich. Weil sonst alle nur laut "Das ist Scheiße" und "Du hast keine Ahnung" schreien und dann ihre Hilfe verweigern.
Drei Mal eine total kontraproduktive Hilfe, weil du das Thema selbst nicht verstanden hast, noch begriffen hast was überhaupt das Problem der Threadersteller ist.
Nein, sehr falsch. DU hast das Problem des TO nicht verstanden.
Das Problem des TO hier ist,dass er absolut gar keinen Ansatz findet.Auch im Speicher-Thema hast DU das Problem des TO nicht verstanden. Denn sein Problem tritt unabhängig von virtuellem Speicher auf. Mal abgesehen davon gab es wieder nur "Ehhhhh, alles kacke" statt Bereicherung (mit einer Tatsächlichen Ausnahme, die für mich sehr interessant ist, dem TO seine Frage aber nicht besser, bzw gar nicht beantwortet).
SeppJ schrieb:
Wie gesagt, mache ich das gerade nur, weil du darum gebettelt hast, sonst würde ich jemandem nicht so detailliert so viele Vorwürfe machen.
Den Rest nehme ich einfach mal als Geschenk hin.
SeppJ schrieb:
Wie schon gesagt, ist es sehr löblich, als Anfänger mitzudenken, aber es ist was anderes, eine halbgare Antwort zu geben.
Das ist deine Meinung. Ein Essen muss erstmal halbgar werden, bevor es gar werden kann.
Denk an deine Anfänge zurück. Womit hast du gekämpft? Worüber hättest du dich gefreut. Die alte Kuh so schnell vergisst, dass sie selbst mal Kalb gewesen ist.Das sind halt so etwas von Anfängerfehlern, da lohnt es sich kaum zu antworten.Und glaubst du, dadurch wird irgend etwas besser? Glaubst du, durch nicht Antworten, macht der TO, oder auch ich, irgend etwas besser?
-
Der Punkt ist: Dadurch, dass du zu helfen versucht, ohne die Antwort zu kennen, machst du alles nur noch schlimmer! Was soll der TE mit deiner Hilfe anfangen? Er und wir müssen sogar noch Zusatzaufwand betreiben, weil wir deine falsche Hilfe als solche kommentieren müssen und er muss diese Kommentare lesen und verstehen. Was meinst du, hätten Bashar, Mechanics, Skym0sh0s und ich in der Zeit tun können? Zum Beispiel dem Threadersteller helfen. Oder dir, wenn du eine Frage gestellt hättest. Stattdessen mussten wir deine falschen Antworten, von denen du anscheinend wusstest, dass sie höchstwahrscheinlich falsch sind, als solche markieren und jetzt auch noch stundenlang mit dir diskutieren, weil du es nicht als selbstverständlich ansiehst, dass man in einem Hilfeforum keine falschen Antworten geben sollte, wenn man von einem Thema nichts versteht.Wenn du bei einem Thema mitreden willst, weil du mehr darüber wissen möchtest, dann stell Fragen, anstatt absichtlich falsche Antworten zu geben!
-
@n3wbie
Wenn du es nicht hinbekommst dir zu ergoogeln wie man in C++ ein Objekt dynamisch erstellt, dann solltest du dir ein anderes Hobby suchen.
Und wenn der OP das nicht hinbekommt, dann gilt für ihn das selbe.
-
Kann mir jemand sagen wir ich die Buchstaben
s->push(s, 'a');
s->push(s, 'b');
s->push(s, 'c');
s->push(s, 'd');durch die Funktion übergeben kann?
void push(Stack *, char);
hab nichts passendes dazu gefunden... top muss ich um 1 erhöhen, das weiß ich.
-
[/code]
#include "stack.h"
#include <iostream>
using namespace std;Stack* Stack::create_stack(unsigned int size)
{
Stack *s = new Stack;
s->depth = size - 1;
s->content = new char[size];
s->top = 0;
return s;
}void Stack::push(Stack *, char)
{
top++;
*content = top;}
char Stack::pop(Stack

{
top--;
*content = top;
return *content;
}int Stack::isEmpty(Stack

{
if (top == 0);return 0;
}
void Stack::destroy_stack(Stack

{
delete content;
content = NULL;
}[/code]Das hab ich soweit zusammengewurschtelt, ich weiß nicht wie ich die isEmpty Methode richtig realisieren soll und auch nicht wie ich depth miteinbeziehen soll. Momentan hab ich eine Endlosschleife.
-
Wieso machst du das jetzt objektorientiert? Hat sich die Aufgabenstellung geändert? Ich dachte die Deklarationen der Struktur und der Funktionen wären vorgegeben.
edit: Die Funktion create_stack sähe ganz gut aus, wenn sie immer noch die alte Signatur hätte. Als Methode ist sie schwachsinnig, ihre Aufgabe würde von einem Konstruktor übernommen werden.
Der Rest ist fast kompletter Unsinn. Ich hoffe stark du bist dir dessen bewusst, ansonsten können wir direkt aufhören und du fängst nochmal ganz von vorne an, C++ zu lernen.
-
plantplant schrieb:
Das hab ich soweit zusammengewurschtelt, ich weiß nicht wie ich die isEmpty Methode richtig realisieren soll und auch nicht wie ich depth miteinbeziehen soll. Momentan hab ich eine Endlosschleife.
Mal langsam. Du scheinst dir gar nicht klar zu sein, was content, top und depth hier für eine Bedeutung haben. Versuch das mal heraus zu finden und uns zu erklären. Gib nicht einfach nur die Aufgabenstellung wieder. Versuch es jemandem zu erklären, der nicht weiß, wie ein Stack funktioniert. Ich finde, diese Methode funktioniert sehr gut, wenn man selber genauer wissen möchte, wie etwas genau funktioniert. Stell dir auch in Gedanken Gegenfragen, die dein Gegenüber haben könnte und komm ihnen zuvor. Mal eventuell ein paar Bildchen.
-
Hi,
ich habe das mal aus neugier umgesetzt, funktioniert auch soweit, aber ich frage mich was depth nun denn genau sein soll? Im moment habe ich depth als maxmiale Größe des Stacks verwendet(also eher sowas wie "size"), die vom Wort her sinnvollere Verwendung wäre aber die aktuelle Größe des Stacks, was wiederum nicht so sinnvoll wäre, weil in top der gleiche Informationsgehalt drinsteckt. Wollte also nur kurz nachfragen wie depth gemeint ist.
-
Seh ich genauso, hab ich genauso interpretiert. Was gemeint ist, weiß aber nur der Aufgabensteller. Und der OP natürlich, der saß ja in der Vorlesung, in der das definiert wurde.
-
Ich denke auch dass
depth == allocateddie einzig sinnvolle Auslegung ist.
-
Würd' mir jemand bitte meine Implementierung um die Ohren haun?
stack.h/* Aufgabe 0.3 (Projekt Stack) (Vorleistung!Abgabe auf Papier und elektronisch) * Implementieren Sie einen Datentyp STACK, der nach dem LIFO - Prinzip arbeitet und einzelne Buchstaben aufnehmen kann. Verwenden Sie dazu folgende Datenstruktur. */ #ifndef STACK_H_INCLUDED #define STACK_H_INCLUDED STACK_H_INCLUDED struct Stack { unsigned int depth; // Tiefe des Stacks char * content; // Inhalt des Stacks unsigned int top; // Index des obersten freien Elements }; /* und implementieren Sie die folgenden Funktionen: */ Stack * create_stack ( unsigned int size ); void push ( Stack * s, char value ); char pop ( Stack * s ); int isEmpty ( Stack * s ); void destroy_stack ( Stack * s ); #endif /* STACK_H_INCLUDED */stack.cpp/* Aufgabe 0.3 (Projekt Stack) (Vorleistung!Abgabe auf Papier und elektronisch) * Implementieren Sie einen Datentyp STACK, der nach dem LIFO - Prinzip arbeitet und einzelne Buchstaben aufnehmen kann. Implementieren Sie die folgenden Funktionen: */ #include "stack.h" #include <cstdlib> Stack * create_stack( unsigned int size ) { if( !size ) size = 0x0f; Stack * s = static_cast< Stack * >( std::malloc( sizeof Stack ) ); if( !s ) return 0; s->content = static_cast< char * >( std::malloc( size ) ); if( !s->content ) { free( s ); return 0; } s->depth = size; s->top = 0; return s; } void push( Stack * s, char value ) { if( s->top == s->depth ) { char * new_content = static_cast< char * >( std::realloc( s->content, s->depth * 2 ) ); if( !new_content ) return; s->content = new_content; s->depth *= 2; } s->content[ s->top++ ] = value; } char pop( Stack * s ) { if( !isEmpty( s ) ) { s->top--; return s->content[ s->top ]; } return 0; } int isEmpty( Stack * s ) { return !s->top ? true : false; } void destroy_stack ( Stack * s ) { free( s->content ); free( s ); }main.cpp/* Aufgabe 0.3 (Projekt Stack) (Vorleistung!Abgabe auf Papier und elektronisch) * Implementieren Sie einen Datentyp STACK, der nach dem LIFO - Prinzip arbeitet und einzelne Buchstaben aufnehmen kann. * Testen Sie Ihre Implementierung mit Hilfe des folgenden Hauptprogramms: */ #include <iostream> using namespace std; #include "stack.h" int main() { // Test der Datenstruktur STACK Stack * s; s = create_stack( 3 ); push( s, 'a' ); push( s, 'b' ); push( s, 'c' ); push( s, 'd' ); while ( !isEmpty( s ) ) cout << pop( s ) << '\n'; /* << endl; wtf? */ pop( s ); destroy_stack( s ); /* cin.ignore(); wtf? */ /* return 0; */ return EXIT_SUCCESS; }
-
Swordfish schrieb:
Würd' mir jemand bitte meine Implementierung um die Ohren haun?
Sehr gerne.
Der Typ von
depthundtopist schon in der Aufgabenstellung falsch, also gehe ich darauf nicht weiter ein.#define STACK_H_INCLUDED STACK_H_INCLUDEDWas soll das bewirken?
Stack * create_stack( unsigned int size ) { if( !size ) size = 0x0f;Warum ist
0hier ein Spezialfall? Woher kommt die 15? Warum hexadezimal?Stack * s = static_cast< Stack * >( std::malloc( sizeof Stack ) );sizeof(*s)ist das Mindeste, das man hier zur Sicherheit tun kann.char * new_content = static_cast< char * >( std::realloc( s->content, s->depth * 2 ) );Die Multiplikation kann überlaufen.
char pop( Stack * s ) { if( !isEmpty( s ) ) { s->top--; return s->content[ s->top ]; } return 0; }Warum kein
assert? Den unsinnigen "Test" in der Aufgabenstellung hätte man doch korrigieren können.return !s->top ? true : false;Really?
-
TyRoXx schrieb:
Swordfish schrieb:
Würd' mir jemand bitte meine Implementierung um die Ohren haun?
Sehr gerne.
Danke!
TyRoXx schrieb:
Der Typ von
depthundtopist schon in der Aufgabenstellung falsch, also gehe ich darauf nicht weiter ein.Jaaa, das ist mir wohl bewusst. Ich hab mich trotzdem an die an mehreren Stellen kaputte Aufgabenstellung gehalten.
TyRoXx schrieb:
#define STACK_H_INCLUDED STACK_H_INCLUDEDWas soll das bewirken?
Sollte ein Holzkopf darauf kommen,
STACK_H_INCLUDEDals Bezeichner zu verwenden, so wird es wenigstens gegen sich selbst ersetzt. Eine Angewohnheit.TyRoXx schrieb:
Stack * create_stack( unsigned int size ) { if( !size ) size = 0x0f;Warum ist
0hier ein Spezialfall? Woher kommt die 15? Warum hexadezimal?Gute Frage. Weil ich nicht mit einem Stack ohne Kapazität starten wollt, falls der Benutzer
0übergibt. Die0x0fkommt daher, daß ich nicht weiß, welcher andere Initialwert effizienter wäre.TyRoXx schrieb:
Stack * s = static_cast< Stack * >( std::malloc( sizeof Stack ) );sizeof(*s)ist das Mindeste, das man hier zur Sicherheit tun kann.Check ich ned.
sizeof( *s )ist doch geradesizeof( Stack )?TyRoXx schrieb:
char * new_content = static_cast< char * >( std::realloc( s->content, s->depth * 2 ) );Die Multiplikation kann überlaufen.
Stimmt. Das sollt man prüfen. Hab' ich ausgelassen, weil ich den Testfall kenne.
TyRoXx schrieb:
char pop( Stack * s ) { if( !isEmpty( s ) ) { s->top--; return s->content[ s->top ]; } return 0; }Warum kein
assert? Den unsinnigen "Test" in der Aufgabenstellung hätte man doch korrigieren können.Wie gesagt, ich habe mich an die verbuggte Aufgabenstellung gehalten.
TyRoXx schrieb:
return !s->top ? true : false;Really?
Why not?
-
TyRoXx schrieb:
return !s->top ? true : false;Really?
... oder meinst man sollt' es umdrehen:
return s->top ? false : true;?
-
return s->top == 0;?