Hallo Gemeinde. Ich habe folgenden struct definiert, der Elemente unterschiedlicher Datentypen aufweist: struct sExample { float zahl1_float; float zahl2_float; int zahl3; bool test_1; float zahl4_float; }; Meine main()-Routine legt eine Variable vom Type der Struktur an, initiliasiert diese mit Werten und übergibt die Adresse der Strukur an eine Unterfunktion func1( sExample *strukt ), die einen Pointer vom Typ sExample hat. main() { sExample struktur; struktur.zahl1_float = 1.2345f; struktur.zahl2_float = 2.3456f struktur.zahl3 = 18; struktur.test_1 = true; struktur.zahl4_float = 7.89f; func1( &struktur ); }; Jetzt meine Frage: Die Unterfunktion func1( sExample *strukt ) soll nun die Aufgabe erfüllen, alle Werte der Struktur auf der Konsole auszugeben (via cout() ). Ich möchte nun aber eben nicht nochmal die Elemente mit ihren Namen ansprechen, sondern eleganter die Struktur durchlaufen. Sprich explizites cout << strukt->zahl1_float << endl; soll nicht zur Anwendung kommen. Kann ich die Elemente irgendwie mittels *strukt erreichen, sodass ich irgendwann eine allgemeine Code-Zeile realisieren kann etwa. cout << (float)(*strukt) << endl; // nächstes Element strukt++ cout << (int)(*strukt) << endl; Welche Möglichkeiten gibt es so etwas umzusetzen? Ich meine jedes Element hat doch im Speicher seine eigene Adresse. Hierüber sollte es doch erreichabr sein? Vielen Dank schon einmal im Voraus.
Ich betone: Die Schwierigkeit liegt in der Existenz unterschiedlicher Datentypen innerhalb der Strukur. Wären alle Elemente-Typen gleich z.B. Integer wäre es sehr sicher einfach die Elemente mittels Zeiger zu erreichen. DANKE.
Stefan schrieb: > Die Unterfunktion func1( sExample *strukt ) soll nun die Aufgabe > erfüllen, alle Werte der Struktur auf der Konsole auszugeben (via cout() > ). > Ich möchte nun aber eben nicht nochmal die Elemente mit ihren Namen > ansprechen, sondern eleganter die Struktur durchlaufen. Musst du aber. Weder in C, noch in C++ gibt es das, was in Java oder C# 'Reflection' genannt wird. Oder aber, du verwendest in erster Linie keine Struktur, sondern etwas intelligenteres.
Möglicherweise kann man da was mit einem void* Pointer, dem Makro offsetof() und "Zurechtgecaste" was machen. http://www.cplusplus.com/reference/clibrary/cstddef/offsetof/ Oder man verwendet von vornherein eine andere Datenstruktur und umgeht das Problem :-)
Karl Heinz Buchegger schrieb: > Oder aber, du verwendest in erster Linie keine Struktur, sondern etwas > intelligenteres. Zb einen Container, der polymorphe Typen aufnehmen kann, wobei die einzelnen Objekte dann selbst wissen, wie sie sich auf cout auszugeben haben.
>> Welche Möglichkeiten gibt es so etwas umzusetzen? Ich meine jedes >> Element hat doch im Speicher seine eigene Adresse. Hierüber sollte es >> doch erreichabr sein? char* struct = (char*) parameter; cout << (float)(*((float*)strukt)) << endl; // nächstes Element strukt += sizeof (float) cout << (int)(*((int*)strukt)) << endl; // nächstes Element strukt += sizeof (int) ... aber warum sollte man so etwas tun ???????? Stefan
Stefan schrieb: > Welche Möglichkeiten gibt es so etwas umzusetzen? Ich meine jedes > Element hat doch im Speicher seine eigene Adresse. Hierüber sollte es > doch erreichabr sein? Ja, eine Adresse hat es, aber wie willst du die ermitteln, ohne den Namen des Elements anzugeben? Und woher weißt du den Datentyp? Der ist in der Adresse nicht enthalten.
Betrifft das MACRO offsetof (type, member): Also wenn ich das Makro mit dem Parameter "member" als String aufrufen könnte, dann hätte ich wohl ne Lösung. Speziell für mein Beispiel: offsetof (sExample, "zahl4_float"): Dieser Aufruf würde mir dann den Byte-Offset und damit die Speicheradresse des Elemntes liefern. Ich würde den Datentyp in einer Tabelle vorhalten die geparsed wird. Somit hätte ich Adresse und Datentyp und könnte damit wunderbar arbeiten... Nur wie zwinge ich offsetof() als zweiten Parameter einen String anzuerkennen? Vielen Dank für eure bisherige Unterstützung!
Stefan schrieb: > Betrifft das MACRO offsetof (type, member): > > Also wenn ich das Makro mit dem Parameter "member" als String aufrufen > könnte, dann hätte ich wohl ne Lösung. > > Speziell für mein Beispiel: > > offsetof (sExample, "zahl4_float"): Denk den Gedankengang mal zu Ende. Was bringt es dir wenn du anstelle von cout << pointer->zahl4_float; ein windiges Konstrukt mittels offsetof( sExample, "zahl4_float" ); in die Funktion hinschreiben musst? > Dieser Aufruf würde mir dann den Byte-Offset und damit die > Speicheradresse des Elemntes liefern. Du musst nach wie vor den Namen des Elements, ALLER Elemente, kennen. Und zwar IN der Funktion! > Nur wie zwinge ich offsetof() als zweiten Parameter einen String > anzuerkennen? Gar nicht. Wie die Amerikaner sagen: Du bellst den falschen Baum an.
Stefan schrieb: > Speziell für mein Beispiel: > > offsetof (sExample, "zahl4_float"): Was bringt es dir denn, wenn du da statt zahl4_float jetzt "zahl4_float" schreiben mußt? Oder anders rum: Wo willst du die Namen der Struktur-Elemente herbekommen? > Nur wie zwinge ich offsetof() als zweiten Parameter einen String > anzuerkennen? Das geht nicht. Zur Laufzeit gibt es die Element-Namen nicht mehr, daher kann man auch nicht über einen String mit dem Namen an ein Element drankommen.
offsetof( sExample, "zahl4_float" ) schreibe Ich natürlich nicht in den QuellCode hinein. Der 2. Parameter also der Elementenname wird dynamisch über ein Input-File gesetzt. Es geht jetzt darum, Wertzuordnungen aus dieser Datei auf eine C-Struktur "zu mappen".
Stefan schrieb: > offsetof( sExample, "zahl4_float" ) > > schreibe Ich natürlich nicht in den QuellCode hinein. > Der 2. Parameter also der Elementenname wird dynamisch über ein > Input-File gesetzt. Was willst du wirklich machen? Das wird jetzt alles immer noch konfuser und immer noch fehleranfälliger. Du arbeitest momentan in eine Richtung zu der ich nur sagen kann: You ask for trouble! Und das alles um ein Hinschreiben aller Strukturmember zu vermeiden, was im übrigen in einer OOP Welt nicht von einer eigenständigen Funktion gemacht wird, sondern von einer Memberfunktion der STruktur. Also in räumlicher Nähe zur Struktur bleibt, so dass man bei Änderungen diesen Teil nur schwer zu ändern vergessen kann.
Stefan schrieb: > Der 2. Parameter also der Elementenname wird dynamisch über ein > Input-File gesetzt. Dann mußt du dieses File anlegen und da die ganzen Elementnamen reinschreiben. > Es geht jetzt darum, Wertzuordnungen aus dieser Datei auf eine C- > Struktur "zu mappen". Warum schreibst du in diese Datei dann nicht auch gleich noch Offset und Datentyp jedes Elements mit rein?
Rolf Magnus schrieb: > Stefan schrieb: >> Der 2. Parameter also der Elementenname wird dynamisch über ein >> Input-File gesetzt. > > Dann mußt du dieses File anlegen und da die ganzen Elementnamen > reinschreiben. Theoretisch könnte er auch das Header File mit der Strukturdefinition parsen. Hätte wenigstens den Vorteil, dass man nicht vergessen kann, bei Änderungen die Beschreibung zu ergänzen. Nicht das ich diesen ganzen Ansatz mit externer Beschriebung generell für vernünftig halten würde. Ich finde ihn nach wie vor schlecht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.