Aufgabe mit Pointer auf Funktion



  • Hallo,
    ich habe folgende Aufgabe zu lösen. Hat jemand eine Idee wie das aussehen könnte? Bin echt dankbar für eure Hilfe! Ich bin noch Programmierneuling und mit Pointer auf Funktion etwas überfordert.

    Aufgabe:
    Schreiben Sie ein Programm, welches entweder den Umfang oder Fläche
    eines Kreises berechnet. Der Benutzer soll den Radius eingeben und wählen, ob Umfang oder Fläche berechnet werden soll.
    Je nach Auswahl soll über einen Pointer auf eine Funktion eine Funktion
    zur Berechnung des Umfangs bzw. zur Fläche zugewiesen und
    ausgeführt werden.

    Ausgabe bei Radius 3 und Umfang berechnen:
    Umfang eines Kreises mit Radius 3.000000 ist 18.849556

    Ausgabe bei Radius 3 und Fläche berechnen:
    Fläche eines Kreises mit Radius 3.000000 ist 28.274334

    PI aus Standardbiblithek: M_PI
    math.h muss dafür inkludiert werden

    Danke für eure Hilfe!



  • Was hast Du denn bis jetzt?

    greetz, Swordfish



  • Bis jetzt habe ich es geschaft, das Programm zum Laufen zu bringen. Leider ohne Pointer auf Funktion! Aufgabestellung ist aber Pointer auf Funktionen einzubauen.

    Thanks fath

    #include <stdio.h>
    #include <math.h>

    int main() {
    float radius;
    float umfang;
    float flaeche;
    char x;

    printf ("Bitte geben Sie U für Umfang oder F für Fläche ein: \n");
    scanf ("%c", &x);
    printf ("Bitte geben Sie einen Radius ein: \n");
    scanf ("%f", &radius);

    flaeche = radius * radius * M_PI;
    umfang = 2 * radius * M_PI;

    if (x == 'U'||x == 'u')
    {printf ("\nDer Umfang eines Kreises mit Radius %f ist %f\n", radius, umfang);}

    else if (x == 'F'||x == 'f')
    {printf ("Die Fläche eines Kreises mit Radius %f ist %f\n", radius, flaeche);}

    else
    printf ("\nFalsche Eingabe! U für Umfang und F für Fläche!");

    return 0;
    }



  • Schreib dir 2 Funktionen und lass abhängig von der Eingabe (bei dir x) den Funktionszeiger auf eine der beiden Funktionen zeigen und ruf dann die Funktion (durch Dereferenzierung des Funktionszeigers) auf.
    Wie genau Funktionszeiger funktionieren musste dafür erstmal garnicht wissen, es reicht wenn du dir einfach die Syntax von irgend nem Tutorial kopierst (functionpointer.com etc)



  • Ich würd' eher ein Array aus den Funktionszeigern basteln:

    #include <stdio.h>
    
    #define _USE_MATH_DEFINES /* ISO/IEC 9899/1999 verlangt M_PI nicht
                                 zwingend -> Compilererweiterung */
    #include <math.h>
    
    void flush_stdin( void ) {
    
    	int ch;
    	while( ( ( ch = getc( stdin ) ) != EOF ) && ( ch != '\n' ) );
    }
    
    double get_outline( float radius ) {
    
    	return 2.0f * radius * M_PI;
    }
    
    double get_area( float radius ) {
    
    	return radius * radius * M_PI;
    }
    
    struct function_switch_t {
    
    	const char *name;
    	double ( *function )( float );
    
    } function_switch[ ] = {
    
    	{ "Der Umfang",  get_outline  },
    	{ "Die Flaeche", get_area     }
    };
    
    int main( void ) {
    
    	float  radius  = 0.0f;
    	int    choice  = 0;
    
    	do {
    		puts( "Bitte geben Sie einen Radius ein:" );
    
    		if( !scanf( "%f", &radius ) ) {
    
    			puts( "Eingabefehler!\n" );
    			flush_stdin( );
    			radius = 0;
    		}
    
    	} while( !radius );
    
    	do {
    		puts( "\nBitte waehlen Sie:" );
    		puts( "  1 ... Umfang" );
    		puts( "  2 ... Flaeche" );
    
    		if( !scanf( "%d", &choice ) && ( choice != 1 ) && ( choice != 2 ) ) {
    
    			puts( "Eingabefehler!" );
    			flush_stdin( );
    			choice = 0;
    		}
    
    	} while( !choice );
    
    	printf( "\n%s eines Kreises mit Radius %f ist %lf.\n",
    		function_switch[ choice - 1 ].name, radius, function_switch[ choice - 1 ].function( radius ) );
    }
    

    greetz, Swordfish



  • Gewaltig!! 👍

    Danke für deine Hilfe Swordfish!

    😉 glg fath



  • Hast Du es auch verstanden?

    greetz, Swordfish



  • Nun ja, teilweise.

    Ein paar Sachen werde ich umschreiben müssen.

    Ich habe noch nicht herausgefunden, warum du den ! Operator benutzt (z.B. vor scanf oder radius)

    while( ( ( ch = getc( stdin ) ) != EOF ) && ( ch != '\n' ) ); Die Bedingung in dieser while Schleife ist auch noch nicht ganz klar für mich.

    Auch struct habe ich noch nicht kennen gelernt.

    Vielleicht hast du ja noch ein paar kurze Erklärungen? Sonst muss ich mich noch durch den Tutorials-Jungle kämpfen.

    Danke inzwischen!!

    lg fath



  • Die Funktion flush_stdin ist nur dazu da, ungültige Eingaben aus dem Puffer von stdin zu flushen. Man hätte auch schreiben können:

    void flush_stdin( void ) {
    
        int ch = 0;
    
        do {
    
            ch = getc( stdin );
    
       } while( ( ch != '\n' ) && ( ch != EOF ) );
    
       // oder: while( !( ( ch == '\n' ) || ( ch == EOF ) ) );
    }
    

    Es werden also Zeichen aus stdin gelesen (entfernt), solange (a) der stream nicht leer ist ( EOF ) und das Ende der Zeile ( '\n' ) nicht erreicht ist.

    Ich habe Funktionen und deren Namen in eine struct zusammengefasst. Du kannst sie natürlich auch getrennt lassen:

    // anstatt:
    
    struct function_switch_t {
    
        const char *name;
        double ( *function )( float );
    
    } function_switch[ ] = {
    
        { "Der Umfang",  get_outline  },
        { "Die Flaeche", get_area     }
    };
    
    // definierst du am beginn der main einfach:
    
    double ( *function_switch[ ] )( float ) = { get_outline, get_area };
    const char *name[ ] = { "Der Umfang", "Die Flaeche" };
    
    // und berechnest so:
    
    printf( "\n%s eines Kreises mit Radius %f ist %lf.\n",
        name[ choice - 1 ], radius, function_switch[ choice - 1 ]( radius ) );
    

    fath schrieb:

    Ich habe noch nicht herausgefunden, warum du den ! Operator benutzt (z.B. vor scanf oder radius)

    C nimmt 0 als false und alles andere als true an. Wenn jetzt in radius 0 steht (d.h. keine gültige Eingabe erfolgt ist), sag ich while( !radius ); . Du könntest auch while( radius != 0 ); schreiben.

    Ich hoffe, nun sind alle Klarheiten beseitigt 😉

    greetz, Swordfish



  • Swordfish schrieb:

    Die Funktion flush_stdin ist nur dazu da, ungültige Eingaben aus dem Puffer von stdin zu flushen.

    ja fein, aber 'flush' ist hier nur das falsche wort.
    🙂



  • Warum?

    greetz, Swordfish



  • im zusammenhang mit irgendwelchen buffern heisst flush soviel wie: 'alle gepufferten daten jetzt sofort an den empfänger senden'. die daten gehen dabei nicht verloren, sondern werden für die sofortige weiterverarbeitung aus dem buffer rausgeschoben. was du aber machst ist eher 'auslesen und wegwerfen'. hier wäre vielleicht 'clear' oder sowas das passendere wort.
    🙂



  • to flush = "leeren" Punktum

    greetz, Swordfish



  • Swordfish schrieb:

    to flush = "leeren"

    naja sagen wir's mal so: wenn du das glas bier auf 'ex' austrinkst ist das ein 'flush'. kippst du es in den ausguss, dann nicht.
    🙂



  • Wenn ich ein Bier wegkippe, so ist das a) Verschwendung und b) nicht ich.

    greetz, Swordfish


Anmelden zum Antworten