Dynamische Datenstrukturen
-
Ich habe hier ein Programm, ich bin ein ziemlicher Neuling im Bereich Programmieren. Ich habe hier jetzt ein Programm das ich nicht selber geschrieben habe.
Ich möchte es aber gerne verstehen. Ich habe schon versucht mich durch google zu schlagen und die einzelnen Befehle seperat zu suchen aber das war leider ohne Erfolg. Jetzt wende ich mich mal an euch.Die main:
#include <stdio.h> #include <stdlib.h> #include "pointstack.h" POINT readPoint() { POINT pt; printf("Bitte geben Sie die X-Koordinate ein: "); scanf(" %f", &pt.x); printf("Bitte geben Sie die Y-Koordinate ein: "); scanf(" %f", &pt.y); printf("Bitte geben Sie die Z-Koordinate ein: "); scanf(" %f", &pt.z); return pt; } int main() { char choice; POINT currentlyPoint; while (1) { printf("\n'Q' druecken um das Programm zu beenden\n"); printf("'P' druecken um der Liste einen Punkt hinzuzufuegen\n"); printf("'A' druecken um alle Punkte in der Liste auszugeben\n\n"); scanf(" %c", &choice); switch(choice) { case 'q': case 'Q': exit (1); break; case 'p': case 'P': currentlyPoint = readPoint(); push(currentlyPoint); break; case 'a': case 'A': while (!isEmpty()) { currentlyPoint = pop(); printStackElement (currentlyPoint); } break; default: printf(" ACHTUNG ungültige eingabe \n\n"); break; } } return 0; }
pointstack.c (Funktionen):
#include <stdio.h> #include <stdlib.h> #include "pointstack.h" struct stackPoint { POINT Punkt; struct stackPoint *next; }; typedef struct stackPoint STACK_POINT; typedef STACK_POINT *STACK_POINT_PTR; STACK_POINT *stackTop = NULL; // erhält POINT, speichert ihn in in STACK_POINT // next zeigt auf jetztigen stackTop // fals kein neues element generiert werden kann fehlermeldung // stackTop wird auf neustes Element gesetzt void push(POINT point) { STACK_POINT_PTR cachePtr = NULL; cachePtr = (STACK_POINT_PTR)malloc(sizeof(STACK_POINT)); if (cachePtr == NULL) { printf(" FEHLER nicht genuegend RAM\n"); exit (1); } cachePtr->next = stackTop; stackTop = cachePtr; stackTop->Punkt = point; return; } //True wenn gesamte STACK_POINT lehr, False wenn STACK_POINT benützt int isEmpty() { return stackTop==NULL; } //sichert POINT, legt neues stacktop fest, löst sturktur auf, gibt point wieder POINT pop () { if (isEmpty() != 1) { STACK_POINT *cachePtr = NULL; POINT cachePoint; cachePtr = stackTop; cachePoint = stackTop->Punkt; stackTop = stackTop->next; free (cachePtr); return (cachePoint); } printf("FEHLER Keine Elemente im Stack"); exit (2); } //gibt alle punkte im Stack aus void printStackElement (POINT aPoint) { printf(" x = %f", aPoint.x); printf(" y = %f", aPoint.y); printf(" z = %f\n", aPoint.z); return; }
pointstack.h (Header)
struct point { float x; float y; float z; }; typedef struct point POINT; void push(POINT); //erhält POINT, speichert ihn in in STACK_POINT POINT pop(); //gewinnt letzten punkt aus STACK_POINT, löscht letztes Kettenglied int isEmpty(); //True wenn gesamte STACK_POINT lehr, False wenn STACK_POINT benützt void printStackElement(); //gibt alle Punkte in STACK_POINT aus ohne sie zu verändern
Die Datenstruktur ist im Header definiert. Dann gleich darunter im Header das "typedef struct point POINT;" Was bedeutet denn das typedef? Bedeutet es zufällig das es eine Unterstruktur von point gibt? Das wäre dann das POINT?
Ja dann fangen wir im main() an.
warum wird POINT currentlyPoint; nochmals deklariert?Mit while(1) gibt es eine Dauerschleife solange 1 erfüllt ist.
Danach wird mit printf was ausgegeben und mit scanf wird die choice eingescannt.
Bei switch wird die choise ausgewählt und danach ausgewählt.
Eingabe Q: Das Programm schließt durch exit (1);
Eingabe P: Jetzt wird die Funktion readPoint(); geöffnet. Dort wird mit Hilfe der Datenstruktur die x,y und z eingegeben. Kurze Frage, warum steht denn vor dem x,y und z ein "pt."? Wegen dem POINT pt; davor? Wenn ich aber das weglassen würde, könnte ich dann nicht einfach nur x,y und z schreiben? Ok was das return pt; dann heißt weiß ich nicht.
Jetzt sind wir wieder in der Switch Funktion und zwar bei push(currentlyPoint);
Dabei gelangen wir in die push Funktion in pointstack.c mit dem currentlyPoint, also wahrscheinlich den Wert den wir eingegeben haben in der Struktur.
So, nun jetzt weiß ich garnicht mehr weiter.
was macht er bei dieser Funktion? Es steht zwar was beschrieben im Programm aber ich kann mit dem leider nichts anfangen. Was bedeutet STACK_POINT_PTR = NULL;?
oder was ist malloc?STACK_POINT_PTR cachePtr = NULL;
cachePtr = (STACK_POINT_PTR)malloc(sizeof(STACK_POINT));
if (cachePtr == NULL)
{
printf(" FEHLER nicht genuegend RAM\n");
exit (1);
}
cachePtr->next = stackTop;
stackTop = cachePtr;
stackTop->Punkt = point;
return;Dann wäre P auch fertig. Dann würde noch A kommen als Eingabe aber das lass ich jetzt mal erstmal.
-
HansMaeyer schrieb:
Ich habe hier ein Programm, ich bin ein ziemlicher Neuling im Bereich Programmieren. Ich habe hier jetzt ein Programm das ich nicht selber geschrieben habe.
Ja, das glaube ich auch: https://www.c-plusplus.net/forum/333042
HansMaeyer schrieb:
Ich möchte es aber gerne verstehen. Ich habe schon versucht mich durch google zu schlagen und die einzelnen Befehle seperat zu suchen aber das war leider ohne Erfolg.
Ohne Buch/Tutorial wird das gar nichts. Ohne Buch ist das schon schlecht.
Das sind Grundlagen, die wir dir hier nicht so vermitteln können.HansMaeyer schrieb:
Die Datenstruktur ist im Header definiert. Dann gleich darunter im Header das "typedef struct point POINT;" Was bedeutet denn das typedef? Bedeutet es zufällig das es eine Unterstruktur von point gibt? Das wäre dann das POINT?
Nein. Du definierst einen neuen Variablentyp.
Du kannst jetzt statt struct point kurz POINT schreiben.HansMaeyer schrieb:
Ja dann fangen wir im main() an.
warum wird POINT currentlyPoint; nochmals deklariert?Wieso nochmal? Das ist die erste und einzige Definition der Variable.
HansMaeyer schrieb:
Mit while(1) gibt es eine Dauerschleife solange 1 erfüllt ist.
Ist es immer.
HansMaeyer schrieb:
....
Eingabe P: Jetzt wird die Funktion readPoint(); geöffnet. Dort wird mit Hilfe der Datenstruktur die x,y und z eingegeben. Kurze Frage, warum steht denn vor dem x,y und z ein "pt."? Wegen dem POINT pt; davor?Hört sich sinnvoll an.
HansMaeyer schrieb:
Wenn ich aber das weglassen würde, könnte ich dann nicht einfach nur x,y und z schreiben?
Hast du denn x, y oder z definiert?
Nicht, dann dann kannst du sie auch nicht benutzen.HansMaeyer schrieb:
Ok was das return pt; dann heißt weiß ich nicht.
Das ist aber eine absolute Grundlage.
Ein English-Wörterbuch könnte auch helfen.HansMaeyer schrieb:
... Was bedeutet STACK_POINT_PTR = NULL;?
Das steht so nicht im Programm.
HansMaeyer schrieb:
oder was ist malloc?
Guckst du: http://www.cplusplus.com/reference/cstdlib/malloc/
-
Ich meinte wenn ich das "Point pt;" in "Point;" ändern würde, würde es nicht funktionierten wenn ich dann auch nur x, y und z schreibe anstatt pt.x, pt.y und pt.z?
Ja das mit der Datenstruktur muss ich aufjedenfall nochmal anschauen. Ich versteh da manchmal nicht wie man richtig definiert oder deklariert.
Ja das stimmt es heißt "STACK_POINT_PTR cachePtr = NULL;" Was hat es mit dem auf sich?
-
HansMaeyer schrieb:
Ich meinte wenn ich das "Point pt;" in "Point;" ändern würde, würde es nicht funktionierten wenn ich dann auch nur x, y und z schreibe anstatt pt.x, pt.y und pt.z?
Du solltest bei der richtigen Schreibweise bleiben. Einen Typ Point gibt es nicht bei dir. POINT sehr wohl.
Mit Point pt; definierst du eine Variable vom Typ POINT mit Namen pt.
Ist so wie beiint j;
Wenn du da jetzt nurint;
schreibst, ist der ganze Ausdruck sinnfrei.HansMaeyer schrieb:
Ja das mit der Datenstruktur muss ich aufjedenfall nochmal anschauen. Ich versteh da manchmal nicht wie man richtig definiert oder deklariert.
Dann schau mal bei Wikipedia nach.
Eine Deklaration ist eine Bekanntmachung. "Es gibt da was."
Die Definition belegt Speicher. "Du hast was."
Dasint j;
ist eine Definition und eine Deklaration.Die Zeilen 8 ff in pointstack.h sind Funktionsdeklarationen. Die Funktionsdefinitionen stehen dann in pointstack.c
HansMaeyer schrieb:
Ja das stimmt es heißt "STACK_POINT_PTR cachePtr = NULL;" Was hat es mit dem auf sich?
Das ist eine Variablendeklaration mit gleichzeitiger Initialisierung.
Du legst eine Variable mit Namen cachePtr vom Typ STACK_POINT_PTR an und weist ihr gleich den Wert
NULL
zu.
STACK_POINT_PTR ist ein Zeiger und wurde vorher mit einemtypedef
bekannt gemacht.
-
Okay, warum man das typedef verwenden habe ich jetzt auch verstanden.
Die Funktion void push(POINT point) habe ich jetzt auch fast verstanden. Das malloc reserviert meinen Speicher mit hilfe von "STACK_POINT". Weil STACK_POINT hat ja meine Punkt-eingabe durch meine POINT Struktur. Das ganze wird mit cachPtr gleichgesetzt. Wenn cachePtr == 0 ist dann konnte malloc mir keinen Speicherplatz reservieren. Der Ram ist voll.
Also bis hier hin kein Problem mehr, zum Glück.
Das "cachePtr->next = stackTop;" bedeutet wenn mir malloc durch STACK_POINT 6 Bytes reserviert hat dann geht der StackTop auf 6 Plätze weiter?
Und mit "stackTop->Punkt = point;" Werden die Punkte eingelsen? Beim letzten hier (stackTop->Punkt = point;) bin ich mir noch unsicher was es macht.
-
malloc
liefert dir die Anfangsadresse von einem Speicherbereich der gewümschten Größe. Der kann irgendwo im Speicher in deinem Rechner liegen.
Damit du die Übersicht nicht verlierst, schreibst du in jeden neuen Speicherbereich noch mit rein, wo der vorhergehende Speicherbereich zu finden ist: cachePtr->next = stackTopIn stackTop merkst du dir die Stelle: stackTop = cachePtr;
stackTop->Punkt = point; schreibt die eigentlichen Nutzdaten in deinen angeforderten Speicher.
Das ist eine Zuweisung wie x = y;--
Nimm einen Stapel Post-It, schreib auf einen eine 3D-Koordinate und klebe sie irgendwo hin. Stelle merken.
Da gehst du woanders hin und machst das wieder. Diesmal schreibst du noch drauf, wo der vorhergende Zettel klebt.
Das kannst du eine Weile machen.Wenn du jetzt weißt wo der letzte Zettel ist, findest du alle Anderen in umgekehrter Reihenfolge wieder.