Brauche dringend Hilfe bei einem Programm in C



  • Hi Jungs.

    Hoffe ihr könnt mir helfen.
    Ich muss bis heute abend um 23.30 folgende Aufgabe bei meinem Dozenten hochladen.
    Eigentlich dachte ich, ich schaffe das mit Hilfe von paar Kumpels aber geschafft haben wirs leider niciht so ganz.
    Für die Prüfung muss ich das Zeugs mit den Zeigern und der Interpolation noch nachlernen, allerdings ist das blöde Zeitlimit (eben bis heute Nacht) bei der Aufgabe da, die wir gestern bekommen haben.

    Hier erstmal die Aufgabenstellung:

    Vereinfachen Sie die positive Halbwelle einer Sinusfunktion (also sin x für 0<=x<=180° (<= soll kleiner gleich sein)) durch eine Kennlinie mit:

    a)3 b)4 c)5 d)6

    Stützstellen.
    Die Abweichung zwischen Ihrer Kennlinie und der Sinusfunktion soll im gesamten Bereich möglichst klein sein.

    Schreiben Sie ein C-Programm, dass
    - zwischen den punkten linear interpoliert
    - den Betrag der Abweichung automatisch für alle x (1-Grad Schritte) ermittelt und
    - die maximale Abweichung speichert und ausgibt.

    Lassen sie den Anwender entscheiden, ob er 3,4,5 oder 6 Stützstellen eingeben möchte. Reservieren Sie anschließend dynamisch Speicherplatz für die Felder der x- und y-Werte und lassen Sie den Anwender die Stützstellen eingeben.

    Die Interpolation muss in einer Funktion interpol() mit folgendem Prototypen durchgeführt werden

    void interpol(double *kl_x, double *kl_y, int stuetz, double *abw,);

    weobei der Zeiger kl_x das Feld mit den x-Werten, kl_y das Feld mit den y-Werten der Stützstellen und stuetz die Anzahl der Stützstellen aufnehmen, sowie der Zeiger abw die maximale Abweichung ans Hauptprogramm zurückgeben soll.

    Arbeiten Sie ohne globale Variablen.

    Und hier mein bisheriger Quelltext.

    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    
    void interpol(double *kl_x, double *kl_y, int stuetz, double *abw);
    
    int main()
    {
    
    	int stuetz;
    	double * kl_x;	//
        double * kl_y;	//kann später wieder in eine zeile
        double abweichung = 0;  //das nicht
    
    	while( 1 ) //endlosschleife
    	{
    		printf("Bitte geben sie die Anzahl der Stützstellen ein (3,4,5 oder 6 Stützstellen);\n ");
    		scanf("%d", &stuetz);
    		if( 2 < stuetz && stuetz <7 ) //gültige Eingabe für stuetz
    			break; //Schleife beenden
    	}
    
    	//sizeof gibt die anzahl der bytes zurück die der angegebene Variablentyp benötigt
    	// stuetz enthält die anzahl der benötigten Felder
    	// Speicher für alle Felder reservieren
        kl_x = (double *) malloc( stuetz * sizeof( double ) );
    	if( kl_x ==NULL )     //Fehler falls kein Speicher reserviert werden konnte
        {
    	   printf( "FEHLER!!!!!!!111" );
    	   return 0;  //Programm beenden
        }
    
        kl_y = (double *) malloc( stuetz * sizeof( double ) );
        if( kl_y == NULL )      //Fehler falls kein Speicher reserviert werden konnte
        {
    		free( kl_x );		// bereits reservierten Speicher freigeben
     	    printf( "FEHLER!!!!!!!111" );
    	    return 0;  //Programm beenden
        }
    
       // einlesen von Werten
       for( int i = 0; i < stuetz; i++ )
       {
    		printf( "\n\nbitte Werte für Stützstelle %d eingeben\nx=", i+1 ); 
    	 	scanf( "%lf", &kl_x[i] );// [i]  <- Stichwort displacement
    	    printf( "\ny=" );				// pointer[i] gibt steht für eine variable die um i*größe der variable versetzt ist.
    	    scanf( "%lf", &kl_y[i] ); 	// &variable steht für den pointer der variable
    	}
    
       //testausgabe
    /*   for( int i = 0; i < stuetz; i++ )
       {
    		printf( "\n\nbitte Werte für Stützstelle %d eingeben\nx=", i+1 );
    	 	printf( "%lf", kl_x[i] );
    	    printf( "\ny=" );
    	    printf( "%lf", kl_y[i] );
    	} */
    
    	//interpol( kl_x, kl_y, stuetz, &abweichung ); //TODO: implementieren
    	abweichung = sin(90*M_PI/180);
    	//Ausgabe der maximalen Abweichung
    	printf( "\ndie maximale Abweichung ist %lf.", abweichung );
    
    	//Freigeben des Speichers
    	free( kl_x );
    	free( kl_y );
    
        return 0;
    }
    
    void interpol( double *kl_x, double *kl_y, int stuetz, double *abw )
    {
    
    	for( int i = 0; i<=180; i++ ){
    		double x =	i * M_PI /180; //x im Gradmaß
    		double y = sin( x );
    		for( int j = 0; j < stuetz; j++ )	//einzelne Teillinien durchgehen
    		{
    			double dx,dy,d;
    
    			dx = kl_x[i+1] - kl_x[i];
    			dy = kl_y[i+1] - kl_y[i];
    			if( dx > 0 )
    			{
    				if( kl_x[j] <= x && x <= kl_x[j+1] )
    					d = kl_y[j] + ( x - kl_x[j] ) * dy / dx - y;  //Abweichung an der Stelle x
    			}
    			else
    			{
    				if( kl_x[j+1] <= x && x <= kl_x[j] )
    					d = kl_y[j] + ( x - kl_x[j] ) * dy / dx - y;  //Abweichung an der Stelle x
    					//  ( x - kl_x[j] ) * dy / dx = y der kennlinie an der stelle x
    		}
    				d = d* (-1);
    			*abw = ( d > *abw ) ? d : *abw;
    		}
    	}
    
    }
    

    Hoffe das ihr mir helfen könnt.

    Hab leider keine Spoiler gefunden, hoffe aber es ist übersichtlich...



  • Toll.
    Und was funktioniert denn nicht? Gibt es Compiler-Fehler, Laufzeit-Fehler?
    Hier ist ein Programmier(sprachen)-Forum, also bitte auch konkrete Fragen diesbezüglich einstellen, falls ihr Hilfe braucht. Für anderes gibt es Mathe-Foren.

    So, Fussball ist vorbei:

    for( int i=0;...
    

    ist KEIN C sondern C++.

    Die u.g. Funktion verlangt nach x aufsteigend sortierte x,y-Wertelisten mit ZUSÄTZLICHEM Endewert 180 bzw. 0.
    Entweder stellt dies über die Eingabe sicher oder sortiert selbst.
    Wenn mich meine 30 Jahre alten Trigonometriekenntnisse nicht täuschen, sollte
    die u.g. Funktion das erwartete Ergebnis liefern.

    void interpol( double *kl_x, double *kl_y, int stuetz, double *abw )
    {
    	int i,j;
        for( i = 0; i<=180; i++ ){
            double x =    i * M_PI /180; //x im Gradmaß
            double y = sin( x );
            for( j = 0; j <= stuetz; j++ )    //einzelne Teillinien durchgehen
               if( kl_x[j] <= x && x <= kl_x[j+1] )
    								{
    									double fktwert,a;
    									if( kl_y[j]<kl_y[j+1] )
                        fktwert = (kl_y[j+1] * ( x - kl_x[j] ) / (kl_x[j+1]-kl_x[j]));
    									else
    										fktwert = (kl_y[j] * ( kl_x[j+1]-x ) / (kl_x[j+1]-kl_x[j]));
    									a=fabs(fktwert)-fabs(y);
    										if( fabs(a)>fabs(*abw) )
    											*abw=a;
    								}
    		}
    }
    


  • Naja... Prinzipiell sind hier schon Fragen erlaubt, die ueber blosse Syntax- oder Compilerprobleme hinausgehen.

    Aber mal abgesehen davon, dass casten von malloc immer noch sowas wie ein Sakrileg ist und du deinen Ansatz fuer die "interpol"-Funktion nochmal ueberdenken solltest, kann ich dir so auch nicht viel sagen. Wo hakt es denn konkret?
    Bin ansonsten zumindest nicht so motiviert, deine Hausaufgaben zu machen...



  • Nobuo T schrieb:

    Wo hakt es denn konkret?
    Bin ansonsten zumindest nicht so motiviert, deine Hausaufgaben zu machen...

    Kann ich nachvollziehen. Wüde es ja am liebsten selber können, nur leider kriege ich das mit dem interpolieren nicht hin 😞



  • Hallo Leute, bin neu hier und auch relativ neu im C -Millieu.könntet ihr mir vllt sagen, wie ich hierraus

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    int wahl;
    int betrag = 0;
    int zahlenr;
    int summe;
    printf("\n\tplease make your treat selection\n");
    printf ("\n\n1 Kaufen \n2 Zahlenreihe \n3 Zeilen_Spalten\n");
    printf("\n\n Ihre Wahl"": ");
    
    scanf("%i",&wahl);
    
    if (wahl==1)
    printf ("\n4 Kondensator \n5 Widerstand \n6 Spule \n7 Trafo \n8 zur Kasse");
    printf("\n\n Ihre Wahl"": ");
    
    do{
    scanf("%i",&wahl);
    
    if (wahl ==4){
    printf("\n Kondesator 8 $\n");
    betrag=betrag+8;
    }
    if (wahl==5){
    printf("\n Widerstand 5 $\n");
    betrag=betrag+5;
    }
    if (wahl==6){
    printf("\n Spule 9 $\n");
    betrag=betrag+9;
    }
    if (wahl==7){
    printf("\n Trafo 40 $\n");
    betrag=betrag+40;
    }
    if (wahl==8){
    printf("\nloehne so viel %.2i Euro",betrag);
    }
    }
    while(wahl!=8);
    
    if (wahl==2){
       printf("\n\tZahlenreihe\n");
       printf("\n\tEine Zahl groesser 10 eingeben\n");
       scanf("%i",&zahlenr);
       printf("\n1,2,3,4,5,6,7,8,9 ist kleiner als %i ", zahlenr);
    }
    
    if (wahl ==3){
     printf("\n\tZeilen und Spalten\n");
     printf("\n 1-A\t2-B\t3-C\t4-D\t5-E\n");
    }
    
    else
    printf("\nUngueltige Wahl");
    return 0;
    }
    

    das hier hinkriege??

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    int wahl;
        int main()
    {
    	printf("\nplease make your treat selection!!!:\n\n\n");
    		printf("1 - Kaufen.\n");
                printf("2 - Zahlenreihe.\n");
    				printf("3 - Zeilen_Spalten.\n");
    
    scanf("%i",&wahl);
    	getchar();
    
        switch(wahl)
    {
                case 1:
                    kaufen();
                        break;
    
    case 2:
        zahlen();
            break;
    
    case 3:
        zeilen();
            break;
    
    default:
        printf("\nUngueltige Auswahl\n");
    
    }
    
        return 0;
    }
    
        int Kaufen ()
    {
    
        char a;
            float b = 0;
                printf("Kaufen\n");
                    printf("Ihre Auswahl:\n");
                        printf("1 - Kondensator\n");
                            printf("2 - Widerstand\n");
                    printf("3 - Spule\n");
            printf("4 - Trafo\n");
        printf("= - Ende\n");
    printf("\nSie haben gekauft:\n");
    
    do
    {
        printf("\n");
            scanf("%c",&a);
                getchar();
    
    switch (a)
    {
    case '1':
        printf ("Kondensator\t $8.00");
            b = b + 8;
                break;
    
    case '2':
        printf("Widerstand\t $5.50");
            b= b + 5.5;
                break;
    
    case '3':
        printf("Spule\t\t $10.00");
            b= b + 10;
                break;
    
    case '4':
        printf("Trafo\t\t $7.50");
            b= b + 7.5;
                break;
    
    case '=':
        break;
    
    default:
        printf("Falsche Wahl!");
            break;
    }
    
    }
    while (a != '=');
    
        printf("\n= Alles Zusammen: $%.2f\n",b);
            printf("Loehnen Sie: \n");
                return 0;
    }
    
    int Zahlen()
    {
    int zahl,c, d;
    
        printf("\nZahlenreihe\n");
            printf("Bitte eine Zahl eingeben:\n");
    
                scanf("%i",&zahl);
                    getchar();
    
    for(c=1; c!=zahl+1; c=c+1)
    {
        printf("%i, ",c);
    }
    d=zahl;
        zahl= zahl +1;
            printf("%i is greater than %i!\n",zahl, d);
    
    return 0;
    }
    
    int zeilen()
    {
    char e=65;
        int f=1;
    
            printf("Zeilen_Spalten\n");
                printf("Zeilen und Spalten...\n\n");
    do
    {
    
    for (e=65; e<=74; e=e+1)
    {
        printf("%i-%c ",f,e);
    }
        printf("\n");
            f=f + 1;
    }
    while(f<=9);
    
    return 0;
    }
    

    das erste ist aus meiner klausur und das zweite ist mein Verbessertes und mit ganz anderen schleifen versehen Programm.
    Mein Pauker will aber wissen wie ich mein erstes Programm trotzdem hinbiegen kann.
    Komme nicht aus der While schleife und irgendwie hackt es an der Auswahl..HEEEELP 😕 😕



  • Der untere Quelltext läuft nicht wie du dir das vorstellst?

    Wenn das so, ist versuche Infos zu folgender Zeile zu erarbeiten:

    scanf("%c",&a);
    


  • Wutz schrieb:

    for( int i=0;...
    

    ist KEIN C sondern C++.

    Dachte das wäre im C99 enthalten?



  • Das ist in C99 enthalten, ja. Jetzt begibt man sich mit C99 zwar insofern auf etwas dünnes Eis, als dass mindestens ein gängiger Compiler (MSVC) bis heute kein C99 beherrscht, aber diesen speziellen Teil kennt der auch.



  • seldon schrieb:

    Das ist in C99 enthalten, ja. Jetzt begibt man sich mit C99 zwar insofern auf etwas dünnes Eis, als dass mindestens ein gängiger Compiler (MSVC) bis heute kein C99 beherrscht, aber diesen speziellen Teil kennt der auch.

    Echt? Ich bin mir relativ sicher, dass der MSVC im C-Modus strikt C89 ist.



  • seldon schrieb:

    Das ist in C99 enthalten, ja. Jetzt begibt man sich mit C99 zwar insofern auf etwas dünnes Eis, als dass mindestens ein gängiger Compiler (MSVC) bis heute kein C99 beherrscht, aber diesen speziellen Teil kennt der auch.

    Kennt er nicht.



  • Vielleicht einfach mal nach "MSDN + c99" suchen?

    Einige Compiler kommen nah an "c-was auch immer" heran - meisst fehlt jedoch die eine oder andere Funktion, oder es sind mehr Möglichkeiten an Bord.


Log in to reply