Arrays typecasten
-
Hallo zusammen!
Angenommen ich habe folgende Funktion gebaut, die rationale Zahlen addiert:
void addiere(int ergebnis[2], const int summanden[][2], const int anzahl);
wobei bei der letzten Dimension des Arrays Element [0] für Zähler und Element [1] für Nenner steht.
Nun habe ich aber ein mehrdimensionales Feld von Werten, die ich alle addieren möchte:
int erg[2];
int feld[10][10][10][2];// ... Feld mit irgendwas füllen
addiere(erg,feld,1000);
Das geht so nicht, der Compiler meckert natürlich rum. Was kann ich tun, um das zum Laufen zu bringen?
Ich möchte dabei nicht Element für Element in ein neues Array mit den richtigen Dimensionen kopieren, da dies unnötig ist. Im Speicher steht ja schon alles in der richtigen Reihenfolge, es soll einfach das [10][10][10][2]-Array als [1000][2]-Array interpretiert werden. Ich hätte gedacht, mit reinterpret_cast kann man das machen:
addiere(erg,reinterpret_cast<int [1000][2]>(feld),1000);
Das passt dem feinen Herrn Compiler aber auch nicht.
Was kann ich tun?
Ich möchte übrigens nicht wissen, wie hässlich und stillos mein Code ist und dass ich lieber mit structs arbeiten soll. Das hier ist ein konstruiertes Beispiel, um den Kern meines Problems einfachst möglich darzustellen. Ich würde mich freuen, wenn ich zur Lösung nur den Funktionsaufruf entsprechend aufkäsen muss.
Danke im Voraus!
Grüße,
Mirko
-
Dein Problem ist die Funktionssignatur. Die ist einfach Schrott. Das macht man in C mit Zeigern und nicht Arrays - dann hast du kein Problem mehr mit den Casts.
Ein dirty Hack wäre uU:
typedef int type[][2]; //damit wir keine gehirnverdrehungen bekommen int feld[10][10][10][2]; addiere(erg, *(type*)&feld, 1000);Aber der Code ist einfach kein gutes C. (und c++ ist es sowieso nicht).
-
Was ist denn so schlecht an der Signatur?
Ich bin nicht so 110%ig bewandert in C und C++, vor allem was Stil angeht. Ich benutze es immer nur aus Performance-Gründen, normal programmiere ich in Matlab.
Was ich jetzt aus der Kritik ziehe ist, dass ich es so machen sollte:
void addiere(int* ergebnis, int* summanden, int anzahl);
Dann kann ich aber innerhalb der Funktion nicht bequem auf summanden[i][j] zugreifen sondern muss die indizierung manuell ausmultiplizieren. Ist zwar jetzt nicht soo schlimm aber macht die Sache noch hässlicher, wie ich finde.
Oder hab ich was falsch verstanden?
-
Mirkompiler schrieb:
Dann kann ich aber innerhalb der Funktion nicht bequem auf summanden[i][j] zugreifen sondern muss die indizierung manuell ausmultiplizieren. Ist zwar jetzt nicht soo schlimm aber macht die Sache noch hässlicher, wie ich finde.
Jop. In C++ kann man das natürlich abstrahieren, indem man ein Objekt mit dem Speicher und den Dimensionen initialisiert, das dann entsprechende Operatorüberladungen anbietet. Wurde hier auch schon oft genug gezeigt, meistens im Zusammenhang mit Matrizen. (operator () (std::size_t i, std::size_t j))
Edit: Und jetzt wo ich dein Problem lese muss ich sagen, dass dein Code ziemlich hässlich und stillos ist und du mit struct/class arbeiten solltest. Dann hättest du die Probleme nämlich nicht.
-
Mirkompiler schrieb:
Was ist denn so schlecht an der Signatur?
Arrays. Arrays in C sind böse. Naja, zumindest in Interfaces.
Wenn du einen int** statt einem int[][2] nehmen würdest, wäre das Problem garnicht aufgetreten
Wenn dein Code C++ wäre, würde ich einfach korrekte Datentypen nehmen, dann ist das Problem auch automatisch gelöst. Ein Array für rationale Zahlen ist unpraktisch. Warum ihnen nicht Namen und Typen geben.
Das Problem mit deiner Schnittstelle ist, dass man damit zwangsläufig Fehler machen wird. Wenn der Code etwas komplexer wird, dann hast du irgendwann zB das Problem dass die Zahlen plötzlich leicht anders im Speicher liegen und schon schleichen sich Fehler ein die Niemand je finden wird.
In C++ würde man für die jeweiligen Datentypen (zB Rational, Matrix,...) eine Klasse schreiben und dann kann man ganz natürlich arbeiten. zB wäre eine Matrix multiplikation dann zB so:
Matrix m1; Matrix m2; int i; Matrix erg=m1*m2*i;