Generische Funktionen - Wie umsezten?



  • Hi Community,

    ich beschäftige mich gerade etwas mit generischen Funktionen. Bis jetzt hatte ich noch nicht sehr viel damit zu tun. Ich habe mich versucht etwas einzulesen und rumzuspielen.
    Leider komme ich nicht so richtig weiter.

    Um die ganz Funktionalität zu verstehen, habe ich mir ein kleines Beispiel überlegt. Ich möchte eine Funktion schreiben, die unabhängig vom Datentyp eine Addition zweier übergebener Zahlen macht. Die Funktion sieht folgendermaßen aus:

    void *generic_addition( void *pnum_a, void *pnum_b )
    {
    	/*variables*/
    	void *res = NULL;
    
    	res = malloc( sizeof(T_TYPE) );
    
    	if( res != NULL )
    		/*addition*/
    		*((T_TYPE*)res) = *((T_TYPE*)pnum_a) + *((T_TYPE*)pnum_b);
    
    	return res;
    }
    

    T_TYPE habe ich mit Hilfe von #define so definiert:

    #define T_TYPE int
    

    Meine main() sieht folgendermaßen aus:

    int main( int argc, char *argv[] )
    {
    	/*variables*/
    	int i_a, i_b, *i_res;
    	double d_a, d_b, *d_res;
    	float f_a, f_b, *f_res;
    
    	/*set values*/
    	i_a = 3;
    	i_b = 6;
    	d_a = 2.05;
    	d_b = 4.70;
    	f_a = 15.091987;
    	f_b = 25.041989;
    
    	/*addition*/
    	i_res = (int*) generic_addition( (int*)&i_a, (int*)&i_b );
    	#define T_TYPE double;
    	d_res = (double*) generic_addition( (double*)&d_a, (double*)&d_b );
    	#define T_TYPE float;
    	f_res = (float*) generic_addition( (float*)&f_a, (double*)&f_b );
    
    	fprintf( stdout, "Results (addition)\n" );
    	fprintf( stdout, "int: %d\n", *i_res );
    	fprintf( stdout, "double: %f\n", *d_res );
    	fprintf( stdout, "float: %f\n", *f_res );
    
    	return 0;
    }
    

    Wie ihr seht definiere ich T_TYPE vor jedem Aufruf mit dem entsprechenden Datentyp neu. Dies funktioniert natürlich nicht und liefert dann folgende Ausgabe auf der Shell:

    Results (addition)
    int: 9
    double: 0.000000
    float: -0.000000

    Jetzt ist meine Frage, wie stelle ich soetwas am besten an? Die Frage ist also, wie kann ich eine Funktion so generisch wie möglich machen und was gibt es dabei zu beachten bzw. welches Vorgehen ist hier angebracht?

    Vielen Dank für eure Hilfe.

    Grüße,
    Fabi



  • Das kannst du z.B. über Funktionszeiger erledigen, wichtig ist bloß, dass du erst alle deine möglichen Anwendungsfälle in entsprechenden Funktionen ausformulierst (jeweils mit gleichem Return-Typ).
    Dann sammelst du die definierten Funktionen noch in geeigneter Weise auf und rufst sie dann auch entsprechend deinen Wünschen auf.

    void *i_add( int x,int y )      { int *z=malloc(sizeof*z); *z=x+y; return printf("%i\n",*z),z;}
    void *d_add( double x,double y ){ double *z=malloc(sizeof*z); *z=x+y; return printf("%f\n",*z),z;}
    
    enum{IADD,DADD};
    typedef void *(*Dispatch)();
    
    int main()
    {
      Dispatch dispatch[]={i_add,d_add};
    
      dispatch[IADD](1,2);
      dispatch[DADD](5.,6.); /* hier aufpassen, wegen argument promotion */
    
      return 0;
    }
    

    Und beim nächsten Mal, liebe Kinder, zeigt euch der Onkel dann auch mal, wie man bei solchen Aufgabenstellungen mit ANSI C Polymorphie realisiert.



  • @Wutz: Vielen Dank für das Beispiel :).

    Und beim nächsten Mal, liebe Kinder, zeigt euch der Onkel dann auch mal, wie man bei solchen Aufgabenstellungen mit ANSI C Polymorphie realisiert.

    Immer her damit 😃 .

    Grüße,
    Fabi


Anmelden zum Antworten