Pointer - Berechnungen (Übung)



  • Hallo Leute, bin gerade am üben (mit Pointern). Stecke gerade wieder und brauch mal wieder eure Unterstüzung.
    Habe ein struct, versuche in einer Funktion Werte für den struct zu setzen. Das Klappt auch.
    Habe ein paar Formeln in einer anderen Funktion und versuche dort, etwas auszugeben. Leider stürzt das Programm dort ab.

    Hier der Code.

    struct test
    {
    	double i;
    	double j;
    	double k;
    	double fmin;
    	double fmax;
    	int schritte;
    	double **ue_fkt;
    };
    
    main()
    {
      parameter();
    }
    
    void parameter(void)
    {
            struct test ptr;
    	struct test *start_pointer = &ptr;
    	//bsp werte setzen
    	ptr.i			 = 100.00;
    	ptr.j			 = 0.01500000;
    	ptr.k			 = 0.00000180;
    	ptr.fmin	         = 100.00;
    	ptr.fmax		 = 1000.00;
    	ptr.schritte = 21;
    
           //Unsicher!! Ist das der richtige aufruf??
    	berechnen(start_pointer);
    }
    
    void berechnen(test_t *test)
    {
    for(x=0; x<test->schritte; x++)
    	{
    		//Formeln zur berechnung
    		f = test->fmin + x * (test->fmax - test->fmin) / (test->schritte - 1);
    		w = 2 * PI * f;
    
    		hilf1 = pow(w * test->i * test->k,2);
    		hilf2 = 1 - w * w * test->j * test->k;
    		Re    = hilf1 / (pow(hilf2,2) + hilf1);
    		Im    = w * test->i * test->k * hilf2 / (pow(hilf2,2) + hilf1);
    
    		//Testen ob man was ausgeben kann - ABER STÜRZT HIER AB!!
    		test->ue_fkt[x][0] = f;
    		test->ue_fkt[x][1] = Re;
    		test->ue_fkt[x][2] = Im;
    		test->ue_fkt[x][3] = sqrt(Re*Re / Im*Im);
    		test->ue_fkt[x][4] = 180/PI*atan2(Im,Re);
    		printf("\nWerte fuer F: %lf"); //erstmal nur f ausgeben
    	}
    }
    

    Unsicher bin ich beim Aufruf von berechnen, ob die Funktion die Werte überhaupt mitbekommt! Und ob ich das überhaupt richtig ausgebe?
    Hoffe ihr könnt mir da helfen! (Formeln sind alle richtig!)
    Danke.



  • Dein zweidimensionales Array 'ue_fkt' ist gar nicht initialisiert, d.h. du mußt dafür erst noch Speicher (mit malloc) reservieren.

    Einfacher für den Anfang wäre es, wenn du ein fixes Array benutzt, z.B.

    double ue_fkt[100][10];
    

    Außerdem fehlt bei deinem printf-Aufruf noch der Parameter 'f' zum ausgeben...



  • Ja habe es mit malloc nicht bedacht. Habe nun den Speicher allokieren können.

    test->ue_fkt = (double**)malloc(sizeof(double*) * test->schritte);
    	for(i = 0; i < test->schritte; ++i)
    		test->ue_fkt[i] = (double*)malloc(5 * sizeof(double));
    ...
    //Hier wieder freigeben...
    for(i = 0; i < test->schritte; ++i)
    		free(test->ue_fkt[i]);
    	free(test->ue_fkt);
    

    Kann es jetzt auch tabellarisch ausgeben. Danke für den Hinweis.



  • Entschuldigt meine Ungeduld, aber ich stecke jetzt wohl beim letzten Schritt.
    Undzwar diese einzige Funktion:

    void schwingkreisparameter(FILE *out, schwingkreis_t *schwingkreis)
    {
    	struct schwingkreis ptr;
    	schwingkreis = &ptr;
    	out			 = stdout;
    
    	ptr.r			 = 100.00;
    	ptr.l			 = 0.01500000;
    	ptr.c			 = 0.00000180;
    	ptr.fmin	    = 100.00;
    	ptr.fmax		 = 1000.00;
    	ptr.schritte = 21;
    
    	system("cls");
    	printf("++++++++++++++++++++++++++++++++++++++++++");
    	printf("\nSchwingkreisparameter:\n");
    	printf("++++++++++++++++++++++++++++++++++++++++++\n");
    
    	fprintf(out, "\nWiderstandswert			 : %.2lf  Ohm", ptr.r);
    	fprintf(out, "\nInduktionswert			 : %lf H", ptr.l);
    	fprintf(out, "\nKapazitaetswert			 : %lf F", ptr.c);
    	fprintf(out, "\nFrequenzintervall - untere Grenze: %.2lf   Hz", ptr.fmin);
    	fprintf(out, "\nFrequenzintervall - obere  Grenze: %.2lf  Hz", ptr.fmax);
    	fprintf(out, "\nAnzahl der Schritte		 : %d", ptr.schritte);
    
    	printf("\n++++++++++++++++++++++++++++++++++++++++++");
    
    	out = fopen("schwingkreis.csv", "w");
    	if(out == NULL)
    	{
    		perror("Fehler beim Oeffnen");
    		exit(EXIT_FAILURE);
    	}
    
    	fwrite(schwingkreis, sizeof(schwingkreis_t), 1, out);
    	fclose(out);
    	/*
    	printf("\nWiderstandswert			 : %.2lf   Ohm", ptr.r);
    	printf("\nInduktionswert			 : %lf H", ptr.l);
    	printf("\nKapazitaetswert			 : %lf F", ptr.c);
    	printf("\nFrequenzintervall - untere Grenze: %.2lf   Hz", ptr.fmin);
    	printf("\nFrequenzintervall - obere  Grenze: %.2lf  Hz", ptr.fmax);
    	printf("\nAnzahl der Schritte		 : %d", ptr.schritte);	
    	*/
    	getch();
    //	liste(start_pointer);
    	menu(out, schwingkreis);		
    }
    

    Ich kriege eine Ausgabe und ich kriege auch eine Datei erzeugt. Aber da stehen kryptische Zeichen drin, wenn ich sie als Text - Datei öffne.
    Ich möchte nur die Daten herraus geschrieben haben, die hier stehen. Solangsam geht meine Kraft zu ende 🙄

    Hoffe ihr könnt mir da weiter helfen.
    EDIT: Könnte ich den pointer *out auch wieder zurück ins menü geben? Also, dass er hier alle Daten erstmal "einsammelt", dann in eine andere Funktion geht, dort "einsammelt" und dann erst am Ende alles hintereinander wegschreibt in eine Datei.



  • fprintf würde alles so in die Datei schreiben, wie es printf auf dem Bildschirm zeigt.
    1. Datei öffnen
    2. mit fprintf reinschreiben
    3. Datei schließen
    fwrite schreibt binär - das willst du nicht!
    😉



  • @egon2 - Habe folgendes jetzt versucht:

    fprintf(out, "%lf", schwingkreis->r);
    

    so schreibt er auch alle Werte dann rein. Wenn ich aber noch folgende Zeilen mit drin haben möchte:

    printf("++++++++++++++++++++++++++++++++++++++++++");
        printf("\nSchwingkreisparameter:\n");
        printf("++++++++++++++++++++++++++++++++++++++++++\n");
    

    Könnte ich es nicht auch mit rausschreiben lassen?



  • egon2

    Also ich müsste dein ganzes Programm sehen, um einzelne Dinge korrigieren zu können.
    Fakt ist, falls du

    out = fopen("schwingkreis.csv", "w");
        if(out == NULL)
        {
            perror("Fehler beim Oeffnen");
            exit(EXIT_FAILURE);
        }
    	fprintf("++++++++++++++++++++++++++++++++++++++++++");
        fprintf("\nSchwingkreisparameter:\n");
        fprintf("++++++++++++++++++++++++++++++++++++++++++\n");
    
        fprintf(out, "\nWiderstandswert             : %.2lf  Ohm", ptr.r);
        fprintf(out, "\nInduktionswert             : %lf H", ptr.l);
        fprintf(out, "\nKapazitaetswert             : %lf F", ptr.c);
        fprintf(out, "\nFrequenzintervall - untere Grenze: %.2lf   Hz", ptr.fmin);
        fprintf(out, "\nFrequenzintervall - obere  Grenze: %.2lf  Hz", ptr.fmax);
        fprintf(out, "\nAnzahl der Schritte         : %d", ptr.schritte);
    	fprintf("\n++++++++++++++++++++++++++++++++++++++++++");
    	fclose(out);
    

    schreibst, alles lesbar in schwingkreis.csv geschrieben wird.
    🙂



  • Ok soweit hab ich es verstanden und auch gemacht, er schreibt es auch tatsächlich raus.
    Eine Frage hätte ich noch. Wäre es denn nicht möglich, die ganzen Daten die raus geschrieben werden sollen, man mit dem file pointer "einsammelt", dann an die nächste Funktion übergibt, dort wieder Daten "einsammelt" und ganz zum Schluss eine Funktion schreibt, die alles raus schreibt?
    Bsp.: erst mit dem Filepointer in der Funktion "schwingkreisparameter" (siehe altes posting)alles "einsammelt". Dann übergebe ich es an das Menü. Dort starte ich eine andere Funktion "berechnen"(siehe code)

    void berechnen(FILE *out, schwingkreis_t *schwingkreis)
    {
    for(i=0; i<schwingkreis->schritte; i++)
    	{		
    		count++;
    		f = schwingkreis->fmin + i * (schwingkreis->fmax - schwingkreis->fmin) / (schwingkreis->schritte - 1);
    		w = 2 * PI * f;
    
    		hilf1 = pow(w * schwingkreis->r * schwingkreis->c,2);
    		hilf2 = 1 - w * w * schwingkreis->l * schwingkreis->c;
    		Re    = hilf1 / (pow(hilf2,2) + hilf1);
    		Im    = w * schwingkreis->r * schwingkreis->c * hilf2 / (pow(hilf2,2) + hilf1);
    		Be		= sqrt(Re*Re / Im*Im);
    		Ph		= 180/PI*atan2(Im,Re);
    
    		schwingkreis->ue_fkt[i][0] = f;
    		schwingkreis->ue_fkt[i][1] = Re;
    		schwingkreis->ue_fkt[i][2] = Im;
    		schwingkreis->ue_fkt[i][3] = Be;
    		schwingkreis->ue_fkt[i][4] = Ph;
    		printf("\n");
    		printf("|%d. \t  %.4lf   %.4lf\t%.4lf\t %.4lf\t %.4lf |", count, f, Re, Im, Be, Ph);
    
    	}
    }
    

    Von hier aus wieder zurück ins Menü und dann endgültig die folgende Funktion schreiben:

    void liste(FILE *out, schwingkreis_t *schwingkreis, char tz)
    

    Und genau hier vor stehe ich, dass hinzukriegen. char tz soll als Trennzeichen gelten. Nach dem "berechnen" soll ein komma als Trennzeichen in der Datei erscheinen.

    Hier noch der aufruf aus main()

    switch(tolower(auswahl))
    		{
    		case 'a':
    				system("cls");
    				schwingkreisparameter(out, schwingkreis);
    			break;	
    		case 'b':
    				system("cls");
    				berechnen(out, schwingkreis);
    			break;
    		case 'c':
    				system("cls");
    				intervall(out, schwingkreis);
    			break;
    		case 'd':
    				system("cls");
    				liste(out, schwingkreis, ',');
    			break;
    		}
    

    Nur "liste" ist allerdings nicht fertig. Da weis ich nich, wie ich das realisieren könnte.

    Hoffe ich hab dich nich durch einander gebarcht 🙂



  • MandaJohn schrieb:

    Eine Frage hätte ich noch. Wäre es denn nicht möglich, die ganzen Daten die raus geschrieben werden sollen, man mit dem file pointer "einsammelt", dann an die nächste Funktion übergibt, dort wieder Daten "einsammelt" und ganz zum Schluss eine Funktion schreibt, die alles raus schreibt?

    Der FILE* Zeiger (out) gibt Dir Zugriff auf die Datei (Datei-Handle) intern werden damit
    die Zuigrifsrechte auf die Datei (Lesen, Schreiben, Schreibschutz, Textmodus, Binärmodus, Dateizeiger-Position)verwaltet und der Zugriff entsprechend ermöglicht.
    Mit dem File-Pointer kannst Du folglich nichts einsammeln, sondern immer nur z.B. in die Datei schreiben,
    und zwar ab Dateizeigerposition.
    In deinem Menü wird zwischen verschiedenen Funktionen gewählt. Parameter der Funktionen
    sind jeweils func(FILE* out, schwingkreis_t* schwingkreis)
    func(out, &schwingkeis ); // &schwingkeis !
    Die Instanz der Struktur schwingreis muss sich ausserhalb der Funktion befinden.
    In dieser Struktur kannst du Daten "einsammeln". Ein Zeiger auf diese Struktur ermöglicht dir
    innerhalb der Funktionen zusammen mit dem File-Pointer die Daten wunschgemäss in die Datei zuschreiben.
    Hoffe, ich konnte dir weiterhelfen.



  • Ok Danke. Ich guck mal was sich da so machen lässt.
    Schöne Grüße
    Manda


Anmelden zum Antworten