Hallo, ich brauche bitte dringend Hilfe bei dem Thema Stapelspeicher in C, um die anstehende Klausur zu schaffen (bin leider im letzten Versuch und nein ich studiere kein Info). Ich hoffe jemand ist so nett und hilft mir Schritt für Schritt? 1.) Geben Sie die Strukturen für den gegeben Stapel mit den Datentypen stack_t und frame_t an [c] typedef struct stack{ frame_t *top; int size; }stack_t; typedef struct frame{ frame_t *previous; double value; }frame_t; 2.) Implementieren Sie eine Funktion push, die ein Nutzdatenobjekt oben auf den Stapel "auflegt". Nutzdaten werden als Zeiger an die Funktion ¨ubergeben und m¨ussen nicht erst allokiert werden. Ist das Argument ein Nullzeiger, so nimmt die Funktion keine Ver¨anderungen am. Hier ist eigentlich mein größtes Problem, ich weiß nicht wie der Prototyp der Funktion auszusehen hat. Ich denke mal ich muss hier was mit der Nutzdatenstruktur anfangen(void(frame_t *frame)?) 3.)Implementieren Sie eine Funktion double top(void), die den obersten Wert des Stapels liefert, ohne ihn zu entfernen. Ist der Stapel leer so wird 0 zurückgeliefert.
Oh je... Sowas wie void(frame_t *frame) als Antwort auf die Frage lässt befürchten, daß das tatsächlich deine letzte Klausur wird.
1 | void push(double* Nutzdaten); |
2 | double Top(void); |
Und bei allem nötigem Respekt, ich wette, daß die Lösungen dazu A) in der Schulstunde B) in den Hausaufgaben C) im Netz vorkommen. Viel Glück. Oliver
Ich wollte die Aufgabe nur verstehen, bis zur Klausur habe ich ja noch reichlich zeit (einen Monat). Und ich dachte jetzt schon anfangen kann gar nicht verkehrt sein. Okey danke, dass heißt wohl Nachhilfe suchen.
Und das sollte nicht die ganze Antwort sein bei 2., ich wollte nur wissen wie die Funktion als Prototyp aussieht.
Dann schau dir die Aufgabenstellung nochmal genau an. push soll auf einen bestehenen Stack (1. Parameter) ein neues Element (2. Parameter) legen. Kein Rückgabgewert erwähnt. Ich würde den Stack wieder zurückgebgen, ist aber egal, "void" tuts auch. also:
1 | void push(stack_t * wohin, frame_t * was) { |
2 | if (!was) return; |
3 | if (!wohin) return; |
4 | was.previous=wohin.top; |
5 | wohin.top=was; |
6 | wohin.size++; |
7 | }
|
Wichtig zum Verständnis: Selber nachvollziehen, ganz altmodisch mit Bleistift und Papier, was jede dieser Anweisungen macht. Dann findest du auch den Fehler. :)
Linksammler schrieb: > void push(stack_t * wohin, frame_t * was) Ähem... Besser nicht... frame und frame_t sind die internen Datemstrukturen des Stacks, die haben draußen keinen zu interessieren. Die Daten sind vom Typ double. Gepusht werden Daten, sonst nix. Die Funktion Push muß die dann in die internen Strukturen verpacken und einhängen. Oliver
Vielen Dank.Muss ich davor nicht etwas allokiert haben, die Aufgabenstellung verwirrt mich. Jetzt wüsste ich nicht was ich mit "was, wohin"ersetzen soll. Soll ich dann einfach etwas annehmen?
Kimi schrieb: > Ich wollte die Aufgabe nur verstehen, bis zur Klausur habe ich ja noch > reichlich zeit (einen Monat). Das reicht nicht. Was du da implementieren sollst, ist Stoff im 4. Semester Informatik-Studium (Vorlesung Datenstrukturen). Dir fehlen aber die Kentnisse, die du dir in den Semestern 1, 2, und 3 hättest aneignen sollen.
Oliver S. schrieb: > Linksammler schrieb: >> void push(stack_t * wohin, frame_t * was) > > Ähem... > > Besser nicht... Hans Ulli Kroll schrieb: > Und ja allozieren musst du. Aufgabenstellung lesen! Kimi schrieb: > Nutzdaten werden als Zeiger an die Funktion ¨ubergeben und m¨ussen nicht > erst allokiert werden.
Rolf Magnus schrieb: > Oliver S. schrieb: >> Linksammler schrieb: >>> void push(stack_t * wohin, frame_t * was) >> >> Ähem... >> >> Besser nicht... > > Hans Ulli Kroll schrieb: >> Und ja allozieren musst du. > > Aufgabenstellung lesen! > Ich habe nicht geschrieben was. Das jetzt die Nutzdaten schon alloziert sind sagt nicht aus das noch was anderes alloziert werden muss. Oder denkst du der Stack liegt einfach so rum ??
Hans Ulli Kroll schrieb: > Das jetzt die Nutzdaten schon alloziert sind sagt nicht aus das noch was > anderes alloziert werden muss. Du meinst, es wurde explizit darauf hingewiesen, daß man den einen double nicht dynamisch allokieren, aber trotzdem per Zeiger an die Funktion übergeben soll? Was sollte das denn bringen? > Oder denkst du der Stack liegt einfach so rum ?? Ich vermute, daß das dynamische Speicherhandling hier ganz bewußt weggelassen werden soll. In einem real-world-Programm wäre das natürlich unsinnig, aber hier handelt es sich um eine Übungsaufgabe.
:
Bearbeitet durch User
Den double brauch ich ja nicht zu allozieren. Ich muss aber meine Listobject, also frame_t allozieren, oder meinen die mit Nutzdatenobject das Listobjekt ??. In real world würde das denn so aussehen struct object { struct object *prev; void *item; }; struct stack { struct object *top; int size; }; void *push(struct stack *st, void *data); void *top(struct stack *st); void *pop(struct stack *st); int stack_size(struct stack *st); Beachte auch das hier Kimi schrieb: > 2.) > Implementieren Sie eine Funktion push, die ein Nutzdatenobjekt oben auf > den Stapel "auflegt". > Nutzdaten werden als Zeiger an die Funktion ¨ubergeben und m¨ussen nicht > erst allokiert > werden. Ist das Argument ein Nullzeiger, so nimmt die Funktion keine > Ver¨anderungen am. Die Nutzdaten werden als Zeiger übergeben !
Hans Ulli Kroll schrieb: > Den double brauch ich ja nicht zu allozieren. Ja, eben. Warum sollte man das aber explizit erwähnen? Und warum sollte der double per Zeiger übergeben werden? Gibt keinen so richtigen Sinn, deshalb gehe ich davon aus, daß sich die Aussage > Nutzdaten werden als Zeiger an die Funktion ¨ubergeben und m¨ussen nicht > erst allokiert werden. nicht darauf bezieht. > Ich muss aber meine Listobject, also frame_t allozieren, oder meinen die > mit Nutzdatenobject das Listobjekt ??. Das dachte ich zumindest.
Hans Ulli Kroll schrieb: > Die Nutzdaten werden als Zeiger übergeben ! Das ergibt im Zusammenhang mit dem vorgegebenen Datentyp 'double' keinen wirklichen Sinn. Ich denke hier ist 'Nutzdaten' synonym zu 'Nutzdatenobjekt' zu sehen.
So nochmal gelesen, die NUtzdaten der "double" wird per Zeiger übergeben. Sample mit obigen Prototypen
1 | int main (int argc, char **argv) |
2 | {
|
3 | double *nutzdaten; |
4 | struct stack st; |
5 | |
6 | nutzdaten = malloc(sizeof(*nutzdaten)); |
7 | |
8 | if (push(&st, nutzdaten) == NULL) |
9 | pintf("stack push failed\n"); |
10 | |
11 | /* Jetzt übergabe von NULL Pointer, der Stack soll sich nicht ändern */
|
12 | /* Ist das Argument ein Nullzeiger, so nimmt die Funktion keine */
|
13 | /* Veräanderungen am.*/
|
14 | |
15 | if (push(&st, NULL) == NULL) |
16 | printf("stack push failed\n"); |
17 | |
18 | |
19 | return 0; |
20 | }
|
Karl Heinz schrieb: > Hans Ulli Kroll schrieb: > >> Die Nutzdaten werden als Zeiger übergeben ! > > Das ergibt im Zusammenhang mit dem vorgegebenen Datentyp 'double' keinen > wirklichen Sinn. Ich denke hier ist 'Nutzdaten' synonym zu > 'Nutzdatenobjekt' zu sehen. Obwohl auch das nicht wirklich Sinn ergibt. Auf den einen malloc() im push() und den free() im pop() wärs auch nicht angekommen. Ganz im Gegenteil: das hätte es sogar vereinfacht ein vernünftiges Testprogramm zu schreiben. Mit der Vorgabe des 'Ausserhalb-Allokierens' verkompliziert sich beim Aufrufer wieder alles.
:
Bearbeitet durch User
Weiter im Text ... push und pop lasse ich mal aus, ds soll der Schüler machen.
1 | void *top(struct stack *st) |
2 | {
|
3 | return st->top->item; |
4 | }
|
5 | |
6 | int stack_size(struct stack *st) |
7 | {
|
8 | return st->size; |
9 | }
|
Das einzige, was ich gerade vergessen habe: Den Stack muss ich ausserhalb von main deklarieren !
1 | struct stack st; |
2 | |
3 | int main(int argc, char **argv) |
4 | {
|
5 | /* Der ganze Rest */
|
6 | }
|
Hans Ulli Kroll schrieb: > Den Stack muss ich ausserhalb von main deklarieren ! Darf man fragen wieso?
Wenn eine Variable in einer Funktion deklariert wird, dann wird diese auf dem Stack (CPU) abgelegt. Der Wert, der Variablen ist nicht definiert. Ausserhalb von main() sind diese NULL bzw. 0 Ich könnte es auch so machen
1 | int main(int argc, char **) |
2 | {
|
3 | struct stack st; |
4 | |
5 | st.size = 0; |
6 | }
|
Hans Ulli Kroll schrieb: > Wenn eine Variable in einer Funktion deklariert wird, dann wird diese > auf dem Stack (CPU) abgelegt. und dort bleiben sie auch bis die Funktion beendet wird und wenn man einen Pointer darauf an eine Funktion übergibt kann man auch darauf zugreifen. > Der Wert, der Variablen ist nicht definiert. bis man etwas zuweist und wieso sollte man eine Variable verwenden wenn man nichts hineinspeichern will? > Ausserhalb von main() sind diese NULL bzw. 0 Außerhalb der main ist das Programm zu ende, da interessiert es mich nicht mehr was in den Variablen stand und wenn doch würde ich sie irgendwie ausgeben.
:
Bearbeitet durch User
Das ist doch so einfach:
1 | #include <stdio.h> |
2 | #include <unistd.h> |
3 | #include <fcntl.h> |
4 | |
5 | int push(char *text) { |
6 | char foo[1024]; |
7 | sprintf(foo, "echo '%s' >> /tmp/test.log", text); |
8 | system(foo); |
9 | return 0; |
10 | }
|
11 | |
12 | int pop(char *text) { |
13 | int n; |
14 | FILE *foo; |
15 | foo = popen("head -n 1 /tmp/test.log", "r"); |
16 | system("sed '1d' /tmp/test.log > /tmp/tmp.log"); |
17 | system("cp /tmp/tmp.log /tmp/test.log"); |
18 | n=fread(text, 1, 1024, foo); |
19 | text[n]=0; |
20 | fclose(foo); |
21 | return 0; |
22 | }
|
23 | int main() { |
24 | char buffer[1025]; |
25 | push("hello world"); |
26 | push("hello world 1"); |
27 | push("hello world 2"); |
28 | push("hello world 3"); |
29 | pop(buffer); |
30 | printf("%s", buffer); |
31 | pop(buffer); |
32 | printf("%s", buffer); |
33 | pop(buffer); |
34 | printf("%s", buffer); |
35 | pop(buffer); |
36 | printf("%s", buffer); |
37 | return 0; |
38 | }
|
aber da gibt's noch viel elegantere Lösungen. Ausserdem darf sich der Prof nicht beschweren, alles ist in C geschrieben.
:
Bearbeitet durch User
Meine Güte! Ihr seid ja eine Truppe. Var a. : er ist ein Donnerstag Troll (meine Vermutung) Var b. : google nach linked list und gut ist. Es Grüsst, René
Eine Beispielimplementierung eines Stacks. Könnte hilfreich sein, beschränkt sich aber nicht auf double Werte.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.