Ist das schon generisch?



  • Hab mal ein bisschen mit Makros herumgespielt,
    Fragen dazu im Anschluss:

    /* Header myGenC.h */
    #ifndef MY_GEN_C
    #define MY_GEN_C
    /* Makro, das fuer diverse Skalare Datentypen eine Sortier-Funktion 'generiert' */
    #define DEFSORT(T,OP) void X##T##SortA(T* arr, unsigned sz){\
    	T swp;\
    	unsigned i, iMin;\
    	while(sz){ iMin = 0u;\
    	 for(i = 1u; i < sz; ++i) if(arr OP arr[iMin]) iMin = i;\
    		swp = arr[iMin]; arr[iMin] = arr[0]; arr[0] = swp; ++arr; --sz;}}
    
    /* Aufrufsyntax der mit DEFSORT generierten Sortierfunktionen */
    #define CALLSORT(T,arr,sz) X##T##SortA(arr,sz)
    #endif
    

    ```
    /
    TestMain.c */
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include "myGenC.h"

    /* Hier entsprechend die 'Parameter' des Programms einstellen (quasi 'Modding') */
    #define TYPE int
    #define FMT "%d"
    #define ARR_SIZE 8

    DEFSORT(TYPE,<) /* <-- 'Generiert' die Definition einer Sortierfunktion
    fuer <TYPE>. Auf-(<) oder ab-(>) steigend. */

    /* Testprogramm */
    int main(){
    int nmb;
    TYPE inp[ARR_SIZE];

    printf("Bitte 1-%d Zahlen eingeben,\n"
    			 "oder einen Buchstaben zum Beenden\n"
    			 "der Eingabe >> ", ARR_SIZE);
    for(nmb = 0; nmb < ARR_SIZE; ++nmb)
    	if(scanf(FMT, inp + nmb) != 1)
    		break;
    while(getchar() != '\n');
    
    if(nmb && nmb <= ARR_SIZE){
    	CALLSORT(TYPE, inp, nmb); /* <-- Ruft die 'generische' Sortierfunktion auf, die oben
    																mit dem DEFSORT Makro definiert wurde. */
    	printf("Sortiert: ");{
    		int i;
    		for(i = 0; i < nmb; ++i)
    			printf(FMT " ", inp[i]);
    	}
    }
    else
    	printf("Falsche Eingabe");
    printf("\nProgramm-Ende");
    getchar();
    return 0;
    

    }

    
    Mehrere Bemerkungen dazu:  
    Die String-Verkettungs-Makros scheinen potentiell dazu geeignet,  
    zumindest Funktions-Templates zu simulieren, wenn auch die Handhabung  
    etwas 'gewöhnungsbedürftig' ist.  
    Von dem Programm lassen sich je nachdem, wie man die 3 #defines in TestMain.c  
    sinngemaess waehlt, auch double, __int64 sowie ab- und aufsteigende  
    'Exemplare' kompilieren. Also in bescheidenem Umfang: generisch.  
    
    Jedenfalls hätte ich dazu noch mehrere FRAGEN:  
    \- Ließe sich so ein Makro/'Pseudo-'Template theoretisch nicht nur für  
    elementare 'Skalare' Datentypen basteln, sondern womöglich auch für  
    x-beliebige Strukturen, wo der Schlüsselwert, nach dem sortiert werden soll,  
    irgend ein Member sein darf? Womöglich sogar ein Zeiger oder String?  
    Wenn ja: Wie müsste man so ein Sortier-Makro für x-beliebige Strukturen  
    basteln (jedenfalls irgendwie mit ##, soviel ist klar!)  
    
    \- Wie groß darf eine [i]logische* Zeile (inklusive \ Erweiterungen)  
    bei solchen Makro-Definitionen maximal werden, z.B. laut C-Standard, oder  
    wie lang darf so eine Zeile bei VisualC sein? Könnte man so auch mehrere  
    Seiten lange Template-Bibliotheken mit einem einzigen Makro basteln?  
    
    \- WIE schriebe man eigentlich eine äquivalente 'Template'-Sortier-Funktion  
    wie in dem obigen Beispiel in C++? (kenne mich mit C++ Templates  
    leider überhaupt nicht aus, aber das könnte sich ändern wenn hier jemand  
    ein Beispiel für eine C++ Version für das obige Mini-Programm zur Demonstration  
    angeben würde _ wär auch super mit erläuternden Kommentaren!)  
    
    \- Ein bisschen ungeschickt find ich, dass man leider so ausdrucksstarke  
    Symbole wie < oder > nicht in den Funktionsnamen hinein-verketten kann.  
    Dann ließen sich in einem Programm sowohl < als auch > Versionen für den  
    selben Datentyp definieren. Vielleicht ist das Makro in seiner  
    momentanen Gestalt auch einfach nur zu ungeschickt implementiert.  
    Wie könnte man es so umschreiben, dass sogar die verwendete Vergleichs-  
    operation (also das Symbol <,>) generisch wird?  
    
    mfg  
    und Danke für jederlei Tipps!

Anmelden zum Antworten