Springerproblem



  • 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 Vorraus

    MFG
    Aknayirp


  • Mod

    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:D

    int 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


Anmelden zum Antworten