Stapelspeicher in C

Gast #4020157
Lesenswert?

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.
Angehängte Dateien:
#4020268
Lesenswert?

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
Gast #4020278
Lesenswert?

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.
Gast #4020296
Lesenswert?

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. :)
#4020428
Lesenswert?

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.
Gast #4020454
Lesenswert?

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 ??
#4020468
Lesenswert?

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.
Gast #4020502
Lesenswert?

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 !
#4020519
Lesenswert?

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.
Gast #4020539
Lesenswert?

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
}
#4020541
Lesenswert?

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.
Gast #4020554
Lesenswert?

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
}
Gast #4020580
Lesenswert?

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
}
#4020596
Lesenswert?

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.
Gast #4020608
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren