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 8DEFSORT(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!