Struct in eine Funktion übergeben
-
Hallo Leute!
Bin gerade dabei das Programm "Towers Of Hanoi" zu erstellen.
Bin eigentl. schon sehr weit, nur komme ich momentan nicht mehr weiter, denn:->man darf keine globale Variablen im Programm benutzen.
Also habe ich ein Struct Storage erstellt:--> maxrings ist als 12 deklariert
struct Storage { int iTower; //number of rings @ start on TowerA int iStart; //tell me if user started GAME with SPACE int iCounter; //needed for fLog to get logarithm (start Game) //count till a ring is larger than "-1" --> -1 --> no ring there int iA; int iB; int iC; char iTowerA[maxrings]; //create array for Tower A B C--> char iTowerC[maxrings]; char iTowerB[maxrings]; char cSwitcher; char cModus; // tells program if automatic or manual mode };so, hier dann die main:
int main() { struct Storage S; //get start values fInit(&S); //do till 'q' while(S.cModus!='q') { //presses ESC Button == RESET if(S.cModus=='e') { fInit(&S); } fCalculate(&S); if(S.iStart==1) { fLog(&S); } fMenue(S); fVisual(S); fStatus(S); fGetValues(&S); system("cls"); } }und fLog ist mein Lösungsalgorithmus:
#include "hanoi.h" fLog(struct Storage *S) { /* if (iTower == 1) { printf("Move from %c to %c\n",cA, cC); } else { fLog( iTower-1, cA, cB, cC ); fLog( 1, cA, cC, cB ); fLog( rings-1, cB, cC, cA ); } */ }Okay soweit klappt alles, bi auf fLog:
Ich würde dem fLog eigentl. nur folgendes aus dem Struct übergeben (als pointer):
S->iTower //anzahl der ringe am Start
S->iTowerA //array des 1. turms --> später cA
S->iTowerB //array des 2. turms --> später cB
S->iTowerC //array des 3. turms --> später cCAlso die Variblen (cA,cB,cC) muss ich den Logarithmus noch anpassen, aber wie schaffe ich es, NUR die 4 oben genannten Pointer zu übergeben, damit die Rekursion richtig klappt?!
Vielen Dank schonmal!
Hoffe es war verständlich genug
-
Also die Variblen (cA,cB,cC) muss ich den Logarithmus noch anpassen, aber wie schaffe ich es, NUR die 4 oben genannten Pointer zu übergeben, damit die Rekursion richtig klappt?!
Algorithmus!
Und warum deklarierst du die Funktion nicht einfach mit zusätzlichen Parametern?btw:
Es gibt eine sehr einfache rekursive Lösung des Problems. 3 Zeilen reichen üblicherweise, aber probiers ruhig mal so nach deinem Weg!
-
Mach dir Gedanken um eine bessere Struktur deines Programmes. Eine Superstruktur die einfach alles enthält ist oft ein Designfehler, so auch hier. Fasse deine Variablen zu sinnvollen Objekten zusammen.
-
Vielen Dank für die Antworten.
Okay, das Design passt noch nicht ganz, aber das darf ich mal hinten anstehen lassen, okay?
Okay, ich rufe in der main ja meine Funktion auf:
fLog(&S);dabei übergebe ich doch die Adresse mit &S (mein Storage Struct S).
ich habe mal folgendes mit der fLog probiert:
#include "hanoi.h" fLog(struct Storage *S->iTower, *S->iTowerA, *S->iTowerB, *S->iTowerC) { if (iTower == 1) { printf("Move from %c to %c\n",iTowerA, iTowerC); } else { fLog( iTower-1, iTowerA, iTowerB, iTowerC ); fLog( 1, iTowerA, iTowerC, iTowerB ); fLog( rings-1, iTowerB, iTowerC, iTowerA ); } }Mein Compiler sagt dann bei folgender Zeile:
fLog(struct Storage *S->iTower, *S->iTowerA, *S->iTowerB, *S->iTowerC)syntax before -> token
hm, okay, aber wie schreib ichs dann richtig, hab keine Ahnung was da falsch sein soll, mit:
fLog(struct Storage *S)nimmt er es ja auch, aber halt nur das GANZE Struct

Wo liegt mein Fehler?
-
Warum dereferenzierst du denn bei der Deklaration der Funktion?!
Das struct brauchst du in C++ auch nicht hinschreiben:fLog(Storage& Tower, Storage& TowerA, Storage& TowerB, Storage& TowerC) { if (iTower == 1) { printf("Move from %c to %c\n",TowerA, TowerC); } else { fLog( Tower-1, TowerA, TowerB, TowerC ); fLog( 1, TowerA, TowerC, TowerB ); fLog( rings-1, TowerB, TowerC, TowerA ); } }
-
Hey drakon, vielen Dank für den Rat, aber ich komme immer noch nicht weiter.
Also ich habs so probiert wie du es mir empfohlen hast:
die fLog rufe ich ja so auf: fLog(&S)
das sollte ja passen, denn ich will das Struct Storage S übergebendie Funktion selbst (ist in einer separaten C-Datei):
#include "hanoi.h" fLog(Storage& Tower, Storage& TowerA, Storage& TowerB, Storage& TowerC) { }BTW: Hab mal den Rest der Funktion als Kommentar gemacht um den Fehler einzugrenzen
Mein Compiler (M$ Visual Studio 2008) meckert dann aber bei fLog:
Fehler 1 error C2143: Syntaxfehler: Es fehlt ')' vor '&'
...
Fehler 3 error C2059: Syntaxfehler: '&'
...BTW: Ich hab ein Struct namens Storage, die Werte Speicher ich aber in Storage S ein. Ich kann doch eine XBeliebige Variable Hinter Storage machen, oder?! Also hab ich es einfach halber S genannt.
Alle Werte Werden nun in Storage S gespeichert?! Also so stell ich mir das mal vor^^
Okay, dann hab ich jetzt mal rumprobiert:
fLog(Storage& S->Tower etc...)Aber es kommt immer noch der gleiche Fehler mit der Klammer und dem UND...
Wieso muss ich eigentl. das & Zeichen in der Funktion nehmen, wenn ich die Funktion fLog(&S) schon so aufrufe?
-
Phu.. dir scheint vieles noch nicht so klar zu sein.

Ich denke du solltest zuerst ein wenig mit den Grundlagen rumspielen, bevor du dich an einen rekursiven Algorithmus machst.

Das -1
fLog( Tower-1, TowerA, TowerB, TowerC );hier macht imo nicht viel Sinn, da Tower den - Operator gar nicht unterstützt..
Das mit den & ist eine Referenz.
int n = 5; int* pn = &n; // pn ist ein Zeiger auf n int& rn = n; // rn ist eine Referenz auf nDer &-Operator hat also 2 Einsatzgebiete (gibt noch mehr Bedeutungen, aber das ist jetzt egal). Zum einen wird er benutzt, um die Adresse einer Variable (oder Funktion) zu bekommen und anderseits wird er bei Variablendeklarationen dazu benutzt um eine Referenz zu markieren. (Eine Referenz ist ja so etwas ähnliches, wie ein Zeiger).
Referenzen kannst du so angeben, als ob eine Kopie erstellt würde. Also kannst du die Funktion ganz normal ohne den &-Operator aufrufen, wie ich das ja im letzten Post bereits gezeigt habe. (alleine aufgrund des -1 kann das so nicht funktionieren, darum solltest du dir das ganze einfach noch ein wenig besser überlegen).
Also ich rate dir jetzt zuerst einmal ein wenig mit Variablen, Funktionen, Referenzen, Funktionsaufrufe usw. rum zu spielen, dann weisst du auch besser, was du hier flasch machst.
-
Wünsch euch allen erstmal n gutes neues Jahr! ^^
So,... bin wieder da, und hab das blööde bööse Towers of Hanoi so gut wie fertig!
Mich hatte das "&" bei "Storage& Tower" irritiert, weil da n Leerzeichen dazwischen war.... Naja egal, habs jetzt ja soweit.Also klappt alles wunderbar, Automatik und Manuellmodus.
Nur bleib ich grad am letzten Schliff hängen:
Und zwar muss man im Automatik modus zu jederzeit mit der ESCAPE Taste den Durchlauf unterbrechen.
Da habe ich mir gedacht ich frag das einfach per getch() ab.
Aber dann würde mein Automatikmodus immer auf eine Eingabe warten.Kann ich getch() so definieren dass es z.b. nur für 20ms abfrägt und wenn nix kommt läuft der Automatikmodus weiter...?!
Vielen Dank schonmal!
-
Ich denke, dass du die Abfrage am ehesten in einem seperten Thread haben möchtest.
Du erstellst eine einen neuen Thread mit z.B boost::thread.
Aber du kannst eigentlich ja auch einfach mit Ctrl+C abbrechen, wenn dus dir da einfach machen willst.

-
Oder anderen Signalen und einem signal handler, was nicht direkt zur Terminierung führen muss.
-
Prüfe erst mit kbhit(), und danach lies erst die Taste ein, s.a. http://www.c-plusplus.net/forum/viewtopic-var-t-is-39320.html