Hallo zusammen
Ich programmiere zwar auf einem uC, aber da dies eher eine allgemeine
Programmierfrage ist, habe ich dieses Unterforum gewählt. Wenn falsch,
bitte verschieben.
Ich habe mehrere Integerarrays mit verschiedenen Datentypen, die aber
alle auf die gleiche Weise verarbeitet werden müssen. Ist es nun
sinvoll, eine allgemeine Funktion zu schreiben, der ein void Zeiger
übergeben wird, anstatt für jeden Datentyp eine eigene Funktion zu
schreiben? Wie wird dies allgemein gehandhabt?
Hier ein Beispiel, wie ich mir den Funktionsprototyp in etwa vorstelle:
1
voidfoo(
2
void*result,
3
intresulttype,
4
void*source,
5
intsourcetype,
6
intsourcesize);
Dass die Sache funktioniert weiss ich, habs selbst versucht. Die Frage
ist nur, wie fehleranflällig das Ganze ist und ob es evt. bessere
Lösungen gibt.
Der Sinn dahinter ist es, Speicherplatz zu sparen und nicht für jeden
Datentyp eine Funktion mit identischem Code schreiben zu müssen.
Hallo,
naja, es kommt darauf an was du mit den Daten machen möchtest. Problem
ist, dass du mit (void*) nicht rechnen kannst. Also z.B.
1
voidfoo(void*in,void*out,intn)
2
{
3
inti;
4
for(i=0;i<n;i++)
5
*out++=(*in++)*(*in++);
6
}
wird nicht gehen, da der Compiler nicht weiß wie er die Zahl
interpretieren muss. Du müsstest jetzt abhängig von deinem Parameter
resulttype die Ein- und Ausgangsvariable casten und dann damit rechnen.
Ob sich der Aufwand lohnt hängt vom Umfang der Funktion ab...
Grüße,
Florian
be stucki schrieb:> Ich habe mehrere Integerarrays mit verschiedenen Datentypen
Hm, was denn nun? Alles Integers, oder verschiedene Datentypen?
Und da nirgends etwas über die Programiersprache steht, würde ich in C++
einfach eine Template-Funktion dafür schreiben ;)
Oliver
be stucki schrieb:> Dass die Sache funktioniert weiss ich, habs selbst versucht. Die Frage> ist nur, wie fehleranflällig das Ganze ist und ob es evt. bessere> Lösungen gibt.
kann ich mir nicht vorstellen.
wenn dein array aus uint8_t besteht, dann kannst du keinen array zugriff
machen.
uint8_t x[10];
foo( x );
void foo( void* a ) {
a[9] = 1;
};
wird einfach nicht funktionieren.
Der Aufruf ist Fehleranfällig, da deine Typnummer immer zum
tatsächlichen Typ passen muss.
Wenn deine Funktion funktioniert überlade sie mit Funktionen, die einen
definierten Typ haben, damit sinkt die Chance später Fehler zu machen
und der Codebedarf bleibt gering.
Vielen Dank für die schnellen Antworten!
Programmiersprache ist C, steht im Titel.
Es sind alles Arrays mit Integer-Datentypen, also char, short, int,
long, long long oder die aus stdint.h
Dass ich keine direkten Arrayzugriffe machen kann und casten muss, ist
mir bewusst. Wie ich nun immer den richtigen Datentyp caste, hatte ich
mir noch nicht überlegt. Nach kurzem Nachdenken hab ich jedoch keine
sinnvolle Lösung gefunden, Ideen? Wahrscheinlich wird daran die Sache
scheitern.
Dass die Sache fehleranfällig wird, hab ich schon vermutet. C kennt
leider keine Überlagerungen.
So wie ich das sehe, hinkt mein Vorhaben gewaltig...
be stucki schrieb:> Dass ich keine direkten Arrayzugriffe machen kann und casten muss, ist> mir bewusst. Wie ich nun immer den richtigen Datentyp caste, hatte ich> mir noch nicht überlegt. Nach kurzem Nachdenken hab ich jedoch keine> sinnvolle Lösung gefunden, Ideen? Wahrscheinlich wird daran die Sache> scheitern.
In C geht da eigentlich nur:
zb ein uint8_t als Typkennung zusammen mit einer Handvoll #define oder
einem enum, der die möglichen Werte dafür festlegt.
Oder aber du fasst den Funktionspointer samt einem Pointer zu den
Daten-Arrays in einer Struktur zusammen.
Aber eines ist klar:
Fehleranfällig ist das eine wie das andere. Du lieferst dich immer dem
Programmierer aus, dass der keine Fehler macht.
Genau da beginnt ja auch eine der Geburtsstunden der OOP: Der
Zusammenschluss von Daten samt Bearbeitungsfunktionen zu einer Einheit.
Karl Heinz Buchegger schrieb:> In C geht da eigentlich nur:> zb ein uint8_t als Typkennung zusammen mit einer Handvoll #define oder> einem enum, der die möglichen Werte dafür festlegt.
Mein Problem dabei ist, dass ich dem Compiler nicht sagen kann, auf
welchen Datentyp mein void Zeiger zeigt. Ich kann den void Zeiger in
einen int Zeiger kopieren und es funktioniert auch alles wunderbar. Soll
es aber, abhängig von einem Übergabewert, ein anderer sein, funktioniert
die Sache schon nicht mehr. Ich müsste in einem switch den richtigen
Datentyp auswählen. Weil dann die entsprechenden Zeiger einen anderen
Namen haben müssen, muss ich somit auch für jeden Datentyp einen anderen
Code schreiben, den dann den richtigen Zeiger verwendet. Dann schreibe
ich besser gleich von Anfang an für jeden Datentyp eine eigene Funktion.