Springerproblem
-
Aknayirp schrieb:
ich musste die letzte Zuweisung von der Zahl erst rückgängig machen
Oh, ich hatte das vergessen zu erwähnen.
Aber ehrlich gesagt, weiß ich nicht wieso es das tut, weil ich komme ja nach jeder Lösung zum return und das return beendet die Fkt. doch, also wieso gehts dann weiter.
Es ist genauso wie bei dem anderen return. Im Prinzip ist das kein Unterschied: In dem einen Fall kehrst du zurück, weil du eine Lösung gefunden hast; in dem anderen Fall kehrst du zurück, weil an dieser Stelle keine (weitere) Lösung mehr gefunden werden kann.
-
Danke, für deine Hilfe. Es klappt perfekt. Krass, dass es bei einem 6x6 Brett so viele verschiedene Möglichkeiten gibt.
Ich wußte jetzt nicht direkt, ob ich einen neuen Thread dafür aufmachen soll, weils ja eine andere Frage ist, aber da sie recht kurz ist, frag ich einfach hier.
Also es geht um ein Programm, indem Strings verglichen werden und die Anfangsposition des 1.Strings, wenn er denn ganz enthalten ist im 2.String, soll ausgegeben werden. Natürlich wieder rekursiv. Hab es auch geschaft.
Nur bekomme ich diese Warnungen beim compilieren:Warnung: Vergleich zwischen Zeiger und Ganzzahl [standardmäßig aktiviert]
Bezogen auf diese Zeilen:
1. if(*str1 == NULL)2. else if(*str2 == NULL)
3. else if(*str1 != NULL && *str2 != NULL)
Es geht bei diesen Bedingungen nur darum, zu sehen, ist in dem String ein Inhalt drin oder eher nicht. Also das Programm funktioniert so wie es soll.
Ist es falsch? Oder kann ich die Warnungen ignorieren, oder gibt es vllcht eine bessere Bedingung?MFG
-
Wenn du den Zeiger vergleichen willst, muss der Dereferenzierungsoperator (der
weg.
Wenn du den Inhalt vergleichen willst, schreib 0 (oder '\0') statt NULL.
NULL steht für einen ungültigen Zeiger.
Zeiger prüfen, ob der Zeiger überhaupt gültig ist.
Inhalt prüfen, ob der String zuende ist.
-
Alles klar, hab ich geändert, funktioniert jetzt ohne Warnungen.
Also das mit der NULL hab ich verstanden.
Der Operater "*", muss da nicht stehen, da der Zeiger durch die 0 selbst überprüft, ob Inhalt vorhanden ist. Ist das richtig so?Noch eine kurze andere Frage:
Größter Gemeinsame Teiler Fkt. (rekursiv)Warnung wird ausgegeben: Kontrollfluss erreicht Ende von Nicht-void-Fkt.
Es geht ja darum, dass da ein return fehlt, aber ich weiß nicht welcher Wert am sinvollsten ist, sodass die Fehlermeldung nicht kommt.unsigned int ggt(unsigned int a, unsigned int b) { printf("a = %d\tb = %d\n",a,b); if(b == 0) return a; else if(a > b) ggt(a-b,b); else if(a<b) ggt(a,b-a); }
-
Nochmal zu den Zeigern:
Du musst erstmal überprüfen ob der Zeiger überhaupt gültig ist:
if(str1 == NULL) // ungültiger Zeiger
Bei der verabeitung der Zeichen musst du auch das Ende der Zeichenkette erkennen.
Das Ende wird mit einer '\0' oder 0 gekennzeichnet.
Dazu musst du auf den Inhalt zugreifen.if(*str1 !=0 && *str2 != 0) // Solange str1 und str2 noch nicht zu Ende sind
Zum ggt:
Deine Funktion gibt einen Wert zurück. Auch die Aufrufe von ggt die du in ggt aufrufst. Deren Wert musst du zurück geben.
-
Jap, vielen Dank, hab ich verstanden!
Hab mal jetzt "wieder" eine andere Frage:
Ich weiß nicht direkt, wie man, wenn man eine Rekursionsaufgabe bekommt, da am besten vorgeht. Wenn Angaben vorhanden sind, dann klappt es, wie z.B. die Eingabeparameter und worauf man Achten soll.
Aber z.B. habe ich jetzt eine Aufgabe, in der (klingen tut sie einfach)
vom Benutzer eine Zahl 'n' eingegeben wird und man soll die Buchstaben 'a' und 'b' n-mal aneinanderreihen mit den verschiedensten Variationen.Bsp: n=3, aaa,aab,aba,abb,bbb ,bba ,bab ,bba
Ein Tipp ist gegeben:Hinweis: Bei einer Lösung mittels einer rekursiven Funktion kann es hilfreich sein, einen
String-Parameter zum Zwischenspeichern von Teilwörtern zu verwenden.Also meine Frage erst, wie man Rekursionsaufgaben am besten löst. Vllcht kann man das an der Aufgabe zeigen.
Bitte nicht die Lösung, sondern eher die Gedanken, mit der man so eine Aufgabe lösen kann.
Danke im VorrausMFG
Aknayirp
-
Das Grundgerüst der meisten Rekursionen ist, dass man folgendes braucht:
1. Eine Abbruchbedingung. Hier: Tiefe n erreicht
2. Irgendetwas, um Informationen an tiefere Ebenen weiter zu reichen, damit diese wissen, was sie überhaupt machen sollen. Zu diesen Informationen zählt:
-Das, woraus sich die Abbruchbedingung ergibt (Hier: Ein Zähler für die Tiefe)
-Eventuelle Nutzdaten (Hier: Ein String mit den vorherigen Ergebnissen)
-Informationen darüber, was überhaupt zu tun ist (Hier: 'a' oder 'b' anhängen)
Es kann gut sein, dass ein oder mehr dieser Informationen identisch sind. Aber irgendetwas ist auf jeden Fall da.
3. Eine Funktion, die 1. und 2. verbindet, also die Informationen entgegen nimmt, die Abbruchbedingung prüft, aufgrund der Informationen handelt und dann wieder sich selbst mit den geänderten Parametern aufruft (in der Regel mehrmals, wenn die Rekursion nicht eine unnötig komplizierte Umschreibung einer einfachen Schleife ist).Die Aufgabe hier ist fies, da Strings in C nicht einfach so kopiert werden können. Du musst dir etwas einfallen lassen, wie du an die tieferen Instanzen echte Kopien weitergeben kannst, nicht einfach nur Zeiger auf immer die gleiche Zeichenkette. Das macht die Aufgabe besonders kompliziert. Tipp: Versuch vielleicht erst einmal mit Zahlen zu rechnen, also 111 112 121 122 usw. auszugeben.
-
Hey Seppj,
ich versuche dies mal zu verinnerlichen.
Die Idee es erst mit 1 und 2 zu versuchen, finde ich gut. Werde ich erst so machen. Danke dir.MFG
-
Hallo, da bin ich wieder:D
Hab eine Frage zu einer Aufgabe.
Zahlen von der Kommandozeile sollen addiert werden.
Problem ist, die Zahlen werden bei mir als Zeichen abgespeichert und deshalb kriege ich es einfach nicht hin, sie aufzuaddieren.
Das war halt mein Ergebnis. Klappt, aber leider so nicht.
Wenn ich jetzt 3 4 eingebe kommt da 103 und nicht 7 raus.
Dachte vllcht mit einem Cast oder so gehts, aber auch net.#include<stdio.h> int main(int argc, char *argv[]) { int i,summe = 0; for(i=1; i<argc; i++) { summe = summe + *argv[i]; } printf("Summe: %d\n",summe); return 0; }
MFG
-
Du suchst die Funktion
strtol()
Wenn du nicht weißt wie die aufgerufen wird, kannst du mal bei http://www.cplusplus.com/reference/clibrary/cstdlib/strtol/ schauen.Wenn du wissen willst, warum das bei dir nicht klappt, dann schau mal in der Wikipedia unter ASCII nach.
-
Dankeschön!
Es hat geklappt:Dint main(int argc, char *argv[]) { int i,summe=0,j=0; for(i=1; i<argc; i++) { j = strtol(argv[i],NULL,10); summe = summe + j; } printf("Summe: %d\n",summe); return 0; }
-
Heyho,
arbeite mich gerade in Strukturen und lineare Listen ein.
Ist gerade etwas holprig.Also bearbeite gerade eine Aufgabe dazu:
Gegeben ist folgende Struktur:
struct Spieler { char *vorname; char *nachname; int tore; struct Spieler *next; };
Hier die Frage dazu:
Schreibe ein Funktion, die einen Datensatz am Anfang einer linearen Liste mit obiger Struktur
einfügt. Die Eingabeparameter der Funktion sollen ein Zeiger auf Listenanfang und ein Zeiger
auf das einzufügende Element sein. Die Funktion soll einen Zeiger auf den Listenanfang mit
dem neuen Datensatz zurückgeben.1:
Also in der Struktur, habe ich ja einen struct Spieler *next, der soll ja immer am Ende des jeweiligen Datensatzes stehen, dass sehe ich doch richtig und gleichzeitig am Ende auch = NULL?2:
Was ich nicht direkt verstehe, was mit char *vorname gemeint ist, in der Struktur.
Wenn ich jetzt eine Code schreibe(mit der Struktur), indem nach einem Vorname gefragt wird und dieser dann an die Fkt. "einfuegen" gegeben wird, dann bekomme ich einen Speicherzugriffsfehler.
Mache das immer in kleinen Schritten, sonst stehen da 1000 Fehler und ich hab keine Ahnung woher die kommen.Also hier erst einmal der Code:
#include<stdio.h> #include<stdlib.h> #include<string.h> struct Spieler{ char *vorname; char *nachname; int tore; struct Spieler *next; }; struct Spieler *anfang = NULL; void einfuegen(char *vn) { if(anfang == NULL) { if((anfang = malloc(sizeof(struct Spieler))) == NULL){ printf("Kein Speicherplatz vorhanden!\n"); return; } strcpy(anfang->vorname,vn); // printf("%s\n",anfang->vorname); } } int main() { char vn[20]; printf("Vorname...: "); fgets(vn,20,stdin); einfuegen(vn); return 0; }
Wenn in der Struktur stehen würde "char vorname[zahl]", dann geht es, aber da es ein Pointer ist, kommt halt die Fehlermeldung.
-
ftfy
#include <stdlib.h> #include <malloc.h> #include <stdio.h> #include <string.h> struct player { char *name; char *surname; int goals; struct player *next; }; void append( struct player ** const players, char const * const name) { struct player *end = 0; if( !*players ) { *players = malloc( sizeof( **players ) ); memset( *players, 0, sizeof( **players ) ); end = *players; } else { for( end = *players; end->next; end = end->next ) ; end->next = malloc( sizeof( **players ) ); end = end->next; memset( end, 0, sizeof( **players ) ); } end->name = malloc( strlen( name ) + 1 ); strcpy( end->name, name ); } int main() { struct player *players = 0; struct player *i = 0; char name[ 20 ]; for( ;; ) { printf( "Name: " ); fgets( name, sizeof( name ), stdin ); if( strlen( name ) == 1 ) break; append( &players, name ); } for( i = players; i; i = i->next ) { puts( i->name ); } }
-
Zu 1.:
Nein, der Verweis muss nicht am Ende der struct stehen.
Ich persönlich mache den am Anfang, da ich dann nur einmal eine Listenverwaltung schreiben muss. Die Zeiger stehen immer am Anfang, egal wie groß die struct ist.Zu 2.:
Da es nur ein Pointer ist, fehlt erstmal der Speicher wo du die Daten hin kopieren kannst.
Wenn du da ein Array mit fester Länge hast, verschenkst du Speicher oder er reicht nicht.Das
if(anfang == NULL)
brauchst du auch nicht.
Deine Funktion soll auch "... einen Zeiger auf den Listenanfang mit
dem neuen Datensatz zurückgeben."
Das fehlt völlig.fgets speichert übrigens das '\n' am Ende mit ab.
Kannst du feststellen wenn du sowas machst:printf("<%s>\n",anfang->vorname);
Wenn da dann
<Aknayirp>
steht, ist kein '\n' drin.
Bei<Aknayirp >
steht, ist ein '\n' drin