?
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!