Hallo Ich mache gerade den Versuch ein SUDOKU Programm (python) nach #C zu portieren. Ich bin Hobby Programmierer. Es funktioniert schon ein wenig. In der einen for Schleife gibt es Probleme. Manchmal wird die Variable nicht mit dem Startwert 1 belegt, sondern geht z.B mit 11 weiter. Vielen Dank für eure Hilfe Peter
:
Verschoben durch Moderator
Peter W. schrieb: > In der einen for Schleife gibt es Probleme Mag das daran liefgen, dass Du alle Schleifenvariablen global deklarierst, aber die Funktion, in der Du sie benutzt, moch innerhalb der Schleife rekusiv aufrufst. So benutzt Du die gleiche Instanz der Schleifenvariablen gleichzeitig mehrfach Das kann eigentlich nur schiefgehen. hint: for (int i=0; i<9; i++){...} HTH (re)
Peter W. schrieb: > Ich mache gerade den Versuch ein SUDOKU Programm (python) nach #C zu > portieren. 🤦🤦🤦 Wie kommt man auf so eine Idee?
Peter W. schrieb: > Ich mache gerade den Versuch ein SUDOKU Programm (python) nach #C zu > portieren. Das ist falsch. Du musst avaJ nehmen.
#re In der Funktion werden jetzt keine Variablen mehr übergeben, sind ja global. Leider ist die Ausgabe immer noch genau so falsch (Werte bis 14). Peter
Peter W. schrieb: > Leider ist die Ausgabe immer noch genau so falsch Die Schleifenvariablen sind ja auch immer noch global definiert. | #include <stdio.h> | | #define FALSE 0 | #define TRUE !(FALSE) | | char zeile=0, spalte=0, zahl=0, x=0, y=0, xi=0, yi=0, xLO, yLO, xD, yD; Als erstes sollten die lokal definiert sein, so wie oben vorgeschlagen. Dann kann man weitersehen. (re)
Ich weiß nicht wie ich das mit zahl, x und y in der funktion loesung machen soll, damit das nicht kollidiert! x, y lokal klappt so einfach auch nicht. Hat jemand noch einen Tip für mich? Danke Peter
Peter W. schrieb: > Ich weiß nicht wie ich das mit zahl, x und y in der funktion loesung > machen soll ... indem man für die Schleife keine globale Variable nimmt, wie in | #include <stdio.h> | | char zeile=0, spalte=0, zahl=0, x=0, y=0, xi=0, yi=0, xLO, yLO, xD, yD; sondern die schleifenvariable nur innerhalb der Schleife deklariert: | void loesung() | : | for (int x=0;x<9;x++){ | : | for(int y=0;y<9;y++){ | : | for (int zahl=1;zahl<10;zahl++){ | : | loesung(); | } | } | } und außerhalb unzugänglich lässt. Ich hoffe, das ist jetzt klarer. Nebenbei aber noch für unser Verständnis: (a) Welche Sprache wird das nun eigentlich? Weil: * Du schreibst von "#C", aber zu "C#" passt die Syntax nicht so recht, und * die Dateiendung deutet aber auf "C++", aber * der Code selbst ist weder c++/cpp noch C#, sondern eher "Kernigham-Ritchie-C (1978)", wozu die Dateiendung aber nicht passt. Die drei Kandidaten haben bis auf das "C" im Namen nur recht wenig gemeinsam. Könntest Du das aufklären? (b) Die Funktion "loesung ()" wird rekursiv aufgerufen, jedoch jedesmal mit den gleichen Aufrufparametern (nämlich keinen). Das deutet normalerweise auf einen Programmierfelher hin. Ist das so gewollt? (c) Der Rückgabewert von "char loesung()" ist nur für bestimmte Pfade fefiniert ("return 0;"), im allgemeinen Fall jedoch von Zufall abhängig. Das deuet normalerweise auf einen Programmierfehler hin, aber (d) Der Rückgabewert von "char loesung()" wird überhaupt nirgends ausgewertet, auch nicht beim rekursiven Aufruf. Auch das deutet normalerweise auf Programmierfehler hin. Hat diese Konstruktion einen besonderen Hintergrund? HTH; (re)
Bitte nimm int anstatt char, das ist geläufig, char ist sehr ungewöhnlich die Variable in der for Schleife definieren, weniger fehleranfällig und nicht style von vor 30 jahren Also for(int x = ... Nicht immer erst die variable definieren und dann x Zeilen darunter initalisieren, einfach int blub = 32; Und KEINE globalen variablen! Nach der Korrektur können wir über Logikfehler diskutieren
re schrieb: > eher "Kernigham-Ritchie-C (1978)" Ich sehe da kein K&R C, sondern bis auf die Zeilenkommentare C89.
Erst mal vielen Dank für die Antworten Ich habe jetzt alle Variablen als lokal geändert. In der Funktion loesung "return" berichtigt. Jetzt erhalte ich als Ausgabe das ungelöste sudoku! Wie gesagt, ich versuche die datei sudoku.py zu portieren. Ich arbeite mit DevC++. Die Kommentare in sudok12.cpp sind die vom pyhton Programm. mfG Peter
Prima, schon ein wenig Fortschritt. Ich würde in Zeile 99, kurz vor der letzten schließenden Klammer von 'loesung()' mal versuchsweise ein "ausgabe();" plazieren. Nur zum Testen, Erklärung weiter unten. Die Fragen nach dem Hintergrund von (b) und (d) waren übrigens durchaus ernst gemeint. Das Beheben des "seltsamen Aussehens" ist zwar auch schon ein Fortschritt, behebt aber nicht den eventuellen Denkfehler, der einen dazu gebracht hat, dieses Konstrukt so zu formulieren, sondern nur den Hinweis auf den Denkfehler. Aber weiter mit konkreteren Dingen: In Zeile 88 hast Du das Konstrukt | zahlen[x][y] = zahl; | loesung(); | zahlen[x][y] = 0; welches sich mir nicht direkt erschließt. Wo immer in "zahlen[x][y]" eine Zahl eingetragen wird, wird sie direkt nach dem Aufruf wieder auf "0" gesetzt. Deswegen bekommst Du immer wieder die originale Besetzung heraus. Deswegen die Frage (b) nach der Sinnhaftigkeit des rekursiven Aufrufs. Der soll vermutlich dazu dienen, die weiteren fehlenden Zahlen einzusetzen. In Zeile 82 prüft "loesung()" jede Zelle ab, ob sie noch zu besetzen ist. Nun hätte ich erwartet, dass der entweder terminiert oder ein "fertig" ausgibt, wenn er findet, dass alle Zellen besetzt sind - das würde man daran erkennen, dass er bis zur letzten schließenden Klammer von loesung() in Zeile 99 kommt. Da hätte ich jetzt entweder sowas wie ein "return TRUE;" erwartet. Oder ein aufruf von ausgabe(), bevor die Funktion verlassen wird. Die würde dann in jedem Fall ein gelöstes Sudoku ausgeben, bevor es wieder mit Nullen überschrieben wird. Besser würde man es natürlich mit einem Rückgabewert machen, so wie es vorher schon in Fragmenten angefangen war, aber der Rückgabewert muss dann auch 1.) in jedem Zweig zurückgegeben werden und 2.) nach dem Aufruf ausgewertet werden. Funktioniert das bei Dir, mit dem "ausgabe()"? HTH (re)
Im Übrigen @TO: Du hast doch vorher überprüft, ob das ungelöste Sudoku überhaupt mindestens eine Lösung hat, oder? (re)
re schrieb: > Ich würde in Zeile 99, kurz vor der letzten schließenden Klammer von > 'loesung()' mal versuchsweise ein "ausgabe();" plazieren. Nur zum > Testen, Erklärung weiter unten. Das war der richtige Tip - jetzt funktioniert es, aber warum? DevC++ in der Fehlersuche ist total Fehleranfällig, und nervt total! Gibt es ein alternatives einfaches Programm, welches funktioniert? re schrieb: > Aber weiter mit konkreteren Dingen: In Zeile 88 hast Du das Konstrukt > > | zahlen[x][y] = zahl; > | loesung(); > | zahlen[x][y] = 0; > > welches sich mir nicht direkt erschließt. > Wo immer in "zahlen[x][y]" eine Zahl eingetragen wird, wird sie direkt > nach dem Aufruf wieder auf "0" gesetzt. Die Zahlen werden nur gelöscht, wenn zahl = 10 ist. Dann wird aus: for (int zahl= 1; zahl< 10; zahl++) rausgesprungen und durch return gelangt man zur zeile: zahlen[x][y] = 0; Es funktioniert! Vielen Dank für die Unterstützung mfG Peter
Peter W. schrieb: > aber warum? Naja, auf die Gefahr hin, mich zu wiederholen: Die Funktion "loesung()" in Deinem Programm ruft sich selbst rekursiv auf, wenn noch etwas zu tun ist (also ein Feld noch 0 enthält) und sie läuft nur dann (ohne weitere Rekursion) bis zum Ende durch, wenn die Lösung fertig ist, also kein einziges Feld mehr "0" enthält. Davon, dass die Lösung fertig ist und die Funktion bis zum Ende gelangt, merkt aber niemand etwas, wenn dort nicht sowas wie "ausgabe()" oder "return FERTIG" steht, oder sonstwas mit dieser Bedeutung. HTH ;-) Peter W. schrieb: > Die Zahlen werden nur gelöscht, wenn zahl = 10 ist. Dann wird aus: > for (int zahl= 1; zahl< 10; zahl++) rausgesprungen und durch return > gelangt man zur zeile: zahlen[x][y] = 0; Mit Verlaub, da bist Du aber schwer auf dem Holzweg: (a) Die Zahlen werden immer "gelöscht". Ansonsten müsste da ein if oder sowas stehen. Durch "return" gelangt man nicht zu irgendwelchen Zeilen, sondern nur aus dem aktuellen Funktionkontext heraus. (b) Wenn "loesung()" mit "return" verlassen wird, bist du in jedem Fall hinter dem Aufruf von "loesung()" (Zeile 89) und danach geht es in jedem Fall mit "zahlen[x][y]=0;" weiter. (c) Im Übrigen wird "zahl" niemals "10" - schließlich ist es ja nur innerhalb der Schleife sichtbar und dort wird auf "zahl<10" geprüft, bevor der Schleifenkörper durchlaufen wird. Aber egal, es geht ja nun. Peter W. schrieb: > DevC++ in der Fehlersuche ist total Fehleranfällig, und nervt total! > Gibt es ein alternatives einfaches Programm, welches funktioniert? Meinst Du Compiler oder IDE? Und warum benutzt Du es denn, wenn es so nervt? Und ja, gibt es. Tausende. Welches für Dich passt, hängt davon ab, was Du von ihm erwartest. Davon abgesehen, ich denke, bevor man Werkzeuge zum Debugging anwirft, sollte man für sich selbst erstmal klargestellt haben, wie die Funktionsweise des eigenen Programms und seiner Teile sein soll. Wenn das nicht steht, dann bastelt man meist nur an den Symptomen, aber nicht am eigentlichen Problem. my2ct (re)
Also der Test im debugger läuft das so: 1.wenn eine zahl (beginnend von 1 bis 9) an der freien Position paßt, wird sie geschrieben - und wieder rekursiv loesung() aufgerufen. 2. dann wird die nächste freie Position gesucht u.s.w 3. paßt keine zahl 1 bis 9 wird for (int zahl= 1; zahl< 10; zahl++) durch return verlassen und man gelangt zur letzten berechneten Position: nach loesung() zur zeile zahlen[x][y]=0; 4. die zahl der letzte Position wird gelöscht und von der letzten gespeicherten zahl weiter geteste, ob sie geht. Sehe ich das alles falsch? Kannst Du eine "einfache" IDE für C# empfehlen? mfG Peter
Peter W. schrieb: > Kannst Du eine "einfache" IDE für C# empfehlen? Für Windows: VisualStudio (unerreicht im Komfort) Für Linux: MonoDevelop Die sind allerdings beide nicht "einfach" im Sinne von "primitiv", sondern im Sinne von "erstmal relativ einfach zu benutzen". Sie sind aber beide doch recht mächtig und deswegen kommt man bei beiden früher oder später doch an den Punkt, wo man sich auch mit der IDE selber beschäftigen muss. Dein Projekt kann man aber wohl noch völlig problemlos abfackeln, ohne diesen Punkt zu erreichen...
Peter W. schrieb: > Kannst Du eine "einfache" IDE für C# empfehlen? Visual stuio community, frei und der geläufigste compiler+ide unter windows Und du programmierst hier C, das andere wäre C++, aber auf keinen Fall ist das hier gezeigte C#
Du hast C Code in cpp C++ Dateien und sprichst von C# Das letztere ist eine völlig andere Programmiersprache von Microsoft da könntest du auch den Code zeigen und nach einer Java IDE fragen, lös dich von dem c#/C-Sharp begriff - ist hier völlig falsch
Peter W. schrieb: > 3. paßt keine zahl 1 bis 9 wird for (int zahl= 1; zahl< 10; zahl++) > durch return verlassen [...] > > Sehe ich das alles falsch? Nun... sie wird aber auch dann mit return verlassen, wenn doch eine oder mehrere Zahlen passen. Die eingesetzte Zahl wird in jedem Fall früher oder später im Array wieder "gelöscht", bevor loesung() zu einem Ende kommt. Und deswegen ist es wichtig, dass bei irgendeiner Rekursionstiefe einmal signalisiert wird, wenn eine Lösung tatsächlich gefunden wurde, bevor sie letztendlich doch wieder mit '0' überschrieben wird - wie Du ... Peter W. schrieb: > Jetzt erhalte ich als Ausgabe das ungelöste sudoku! ... ja selbst beobachtet hast. HTH (re)
Ich hab hier einiges durcheinander gebracht! Ich programmierst natürlich in C. Visual stuio community wollte ich ausprobieren. Ist mir zu gewaltig und läuft so einfach bei mir nicht - man muß vermutlich einige GB nachinstallieren. mfG Peter
Peter W. schrieb: > Kannst Du eine "einfache" IDE für C# empfehlen? https://www.codeblocks.org/ merciless
Peter W. schrieb: > [MSVS] läuft so einfach bei mir nicht Hm. Um da mal einen Ansatzpunkt zu finden: (a) Welche Kriterien haben denn zur Auswahl des nun schon etwas in die jahre gekommenen DevC++ geführt? (b) Unter welchen Systembedingungen soll das eigentlich laufen? (re)
DevC++ ist einfach zu bedienen und deutsch. Eigendlich bin ich damit zufrieden. Aber beim debuggern funktioniert es oft nicht. Wenn man dann einen Fehler sucht kann man fast verzweifeln! Windows 7 ist mein Freund. mfG Peter
Peter W. schrieb: > Visual stuio community [...] läuft so einfach bei mir nicht > > Windows 7 ist mein Freund. Naja, da sind unsere Freudeskreise wohl etwas disjunkt. Etwas herumfragen in 4ma hat da übrigens einen Rechner zutage gefördert, auf dem MSVS(v15) auch unter Win7(64,SP1) auf einem Prozessorkern, etwa 6GB RAM und insgesamt 60 GB Plattenplatz ganz zufriedenstellend läuft. Sollte also auch bei Dir ohne besondere Klimmzüge gehen. Peter W. schrieb: > Ist mir zu gewaltig Ja, "schlank" geht anders. Aber wenn es der GDB nun nicht sein soll und teuere kommerzielle Produkte auch nicht infrage komen, dann muss man diese Kröte möglicherweise schlucken, wenn man Wert auf komfortables Debugging legt. my2ct (re)
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.