Unterschiedliche Strukturen als Übergabeparameter für gleiche Funktion?

Wu-mc

Mitglied
Hallo Forum,

ich habe zwei Funktionen, die jeweils eine Struktur und einen Dateinamen übergeben bekommen und die Struktur dann in die Datei speichern. Beide sind exakt gleich aufgebaut, bis auf den Strukturtyp der sich jedes mal unterscheidet. Gibt es eine Möglichkeit ein und derselben Funktion jeweils unterschiedliche Strukturen zu übergeben?

Also aus:

BOOL BackOfficeFileSaveSetup (SETUPBOX_DATA * psbd)

und

BOOL BackOfficeFileSaveSetup (DTAUSCONFIG * pdc)

soetwas wie

BOOL BackOfficeFileSaveSetup (IRGENDEINESTRUKTUR * pointer)

zu machen?
 
Du könntest einen void Zeiger als Funktionsparameter übergeben und zusätzlich den Typ, so dass Du einen Cast durchführen kannst, also eine Funktionssignatur wie etwa:
Code:
bool backOfficeFileSaveSetup(void *ptr, int type)
{
[...]
switch (type) {
        case 1:
                struct SETUPBOX_DATA *psbd = (struct SETUPBOX_DATA *) ptr;
                break;
        case 2:
                struct DTAUSCONFIG *pdc = (struct DTAUSCONFIG *) ptr;
                break;
}
[...]
}
Ansonsten fällt mir dazu nur Funktionsüberladen ein, aber das gibt es nur unter C++ (C99 erlaubt es meines Wissens nach nur für spezielle mathematische Funktionen der Standardbibliothek).

Übrigens noch ein Tipp zu Deiner Namensgebung. Es hat sich eingebürgert, unter C/C++ nur Konstanten großzuschreiben, also weder BOOL noch die beiden Strukturtypen (woher hast Du BOOL?). Wenn Du solche Richtlinien, sofern möglich, berücksichtigst, haben es später andere Programmierer leichter, Deinen Code zu verstehen und umgekehrt.
 
Hi.

Du kannst es natürlich so machen wie rohrbold vergeschlagen hat, allerdings kannst du da lieber gleich für jede Struktur eine Funktion schreiben (anstatt alles in eine Funktion mit einem "magischen" int Paramter zu packen der dann angibt was gemacht werden soll).

Außerdem ist es keine gute Idee eine Struktur einfach als Speicherklumpen in eine Datei zu schreiben. Das ist unportabel und funktioniert auch nicht für Zeiger innerhalb der Struktur.

@rohrbold: Übrigens hat es sich in C/C++ eingebürgert Präprozessorvariablen und -Makros in Grossbuchstaben zu schreiben. BOOL ist eine Präprozessorvariable, die irgendwo in windows.h definiert wird. bool bzw. _Bool gibt es erst in C99. Soweit ich weiß gibt es keine überladenen Funktionen in C99.

Gruß
 
@ Rohrbold

Also das mit dem großschreiben habe ich mir als Programmierstil von Charles Petzold abgeschaut, der das Buch "Windows-Programmierung" geschrieben hat. Außerdem werden alle Strukturen von Windows auch groß geschrieben wie z.B. WNDCLASS. Denke deshalb das das schon ganz richtig so ist.

Aber vielen Dank für deinen Tipp, werde mir das mal anschauen.

@ Deepthroat

Ich denke halt wenn es eine Funktion ist dann tu ich mir beim späteren Ändern leichter, da ich so dann nur eine Funktion bearbeiten muss.

Und wegen dem Speicherklumpen, wie würdest du es lösen? Ich habe halt diverse Einstellungen die ich so recht leicht verwalten kann und Pointer sind in den Strukturen keine vorhanden, werden ja auch in meinem Fall nicht benötigt. Und was meinst du mit unportabel? Wenn ich die Struktur mit dem gleichen Programm auf einem anderen Rechner auslese geht das nicht?
 
Hm scheint leider nicht zu funktionieren, da ich innerhalb der switch - Verzweigung keine Variablen deklarieren darf:

'SETUPBOX_DATA': Ungültige Verwendung dieses Typs als Ausdruck

setze ich es außerhalb der Verzweigung geht es, jedoch fehlt mir dann die Fallunterscheidung.
 
deepthroat hat gesagt.:
@rohrbold: Übrigens hat es sich in C/C++ eingebürgert Präprozessorvariablen und -Makros in Grossbuchstaben zu schreiben. BOOL ist eine Präprozessorvariable, die irgendwo in windows.h definiert wird. bool bzw. _Bool gibt es erst in C99.
Ja, die Präprozessorvariablen und Makros habe ich nicht ausschließen wollen mit meiner Bemerkung zu Konstanten -- war etwas lachs in der Formulierung. Mit Windows habe ich nichts zu tun, danke für die Erklärung. Vielleicht lohnt es sich aber, mit einem standardisierten bool-Typ zu arbeiten (aus bool.h ab C99).

deepthroat hat gesagt.:
Soweit ich weiß gibt es keine überladenen Funktionen in C99.
Naja, im Grunde ist es ja auch so. Durch Makromagie wurde es aber ermöglicht, mittels der tgmath.h auf mathematische Funktionen zurückzugreifen, die den Typ ihrer Parameter selbst ermitteln, so dass man nicht mehr wie bei
float sinf(float), long double sinl(long double), complex csin(complex)
über Suffixe oder Präfixe die entsprechende Funktion auswählen muss. Aber generell muss man wohl feststellen, dass typsichere überladene Funktionen nur in C++ und noch nicht in C möglich sind.
 
Wu-mc hat gesagt.:
Ich denke halt wenn es eine Funktion ist dann tu ich mir beim späteren Ändern leichter, da ich so dann nur eine Funktion bearbeiten muss.
Ich denke da liegst du falsch, dass es nur eine Funktion ist macht die Sache nicht leichter.

Wu-mc hat gesagt.:
Und wegen dem Speicherklumpen, wie würdest du es lösen? Ich habe halt diverse Einstellungen die ich so recht leicht verwalten kann und Pointer sind in den Strukturen keine vorhanden, werden ja auch in meinem Fall nicht benötigt. Und was meinst du mit unportabel? Wenn ich die Struktur mit dem gleichen Programm auf einem anderen Rechner auslese geht das nicht?
Am besten wäre eine Textdatei (bzw. XML Datei) zu benutzen und die einzelnen Eigenschaften der Funktion in einem bestimmten Format (z.B. Schlüssel - Wert - Paare getrennt mit Doppelpunkt) zeilenweise zu speichern.

Erster Vorteil: man kann die Daten einfach mit jedem Texteditor angucken und sogar bearbeiten.

Zweiter Vorteil: Erweiterbarkeit - wenn die Strukturen sich ändern kannst du deine alten Dateien wegschmeißen bzw. mußt ein Konvertierungsprogramm schreiben.

Dritter Vorteil: Portabilität - eine Textdatei kann man nahezu auf jedem beliebigen System mit Hilfe eines Programms was durch irgendeinen Compiler erstellt wurde auch wieder einlesen - deine Dateien kannst du unter Umständen nicht mal mit dem gleichen Programm welches mit dem gleichen Compiler auf dem gleichen System erstellt wurde lesen wenn bestimmte Compiler-Einstellungen geändert wurden.

Also unter der Voraussetzung, das du sowas machst wie
Code:
fwrite(struktur, sizeof(struktur), 1, datei);

Gruß
 
Wu-mc hat gesagt.:
Hm scheint leider nicht zu funktionieren, da ich innerhalb der switch - Verzweigung keine Variablen deklarieren darf
doch, dann muss man noch Extra-Klammern um die case Statements machen, beispielsweise so:
Code:
switch (i) {
        case EINS: {
                struct conf_rfc params; /* Speicher bereitstellen */
                struct conf_rfc *val = &params;
                /* Werte in Struktur schreiben */
                val->mode = 42;
                val->txw = 4711;
                len = 2;
                add_conf_opt(val, i, len);
                break;
        }
        case ZWEI:
                [...]
}
[...]

Also das ist sicherlich nicht das definitiv eleganteste, aber ich kam vor kurzem auch nicht um solch ein Konstrukt herum.
 
deepthroat hat gesagt.:
Am besten wäre eine Textdatei (bzw. XML Datei) zu benutzen und die einzelnen Eigenschaften der Funktion in einem bestimmten Format (z.B. Schlüssel - Wert - Paare getrennt mit Doppelpunkt) zeilenweise zu speichern.

Erster Vorteil: man kann die Daten einfach mit jedem Texteditor angucken und sogar bearbeiten.

Zweiter Vorteil: Erweiterbarkeit - wenn die Strukturen sich ändern kannst du deine alten Dateien wegschmeißen bzw. mußt ein Konvertierungsprogramm schreiben.

Dritter Vorteil: Portabilität - eine Textdatei kann man nahezu auf jedem beliebigen System mit Hilfe eines Programms was durch irgendeinen Compiler erstellt wurde auch wieder einlesen - deine Dateien kannst du unter Umständen nicht mal mit dem gleichen Programm welches mit dem gleichen Compiler auf dem gleichen System erstellt wurde lesen wenn bestimmte Compiler-Einstellungen geändert wurden.

Also unter der Voraussetzung, das du sowas machst wie
Code:
fwrite(struktur, sizeof(struktur), 1, datei);

Gruß

Naja leider kenn ich mich mit XML Dateien noch garnicht aus, kommt aber auf meine To-Do Liste (die immer länger wird). Mit Textdateien könnte ich mich schon anfreunden. Kannst du mir aber sagen wie ich eine Art Schleife mache um jedes Element einer Struktur abzufragen? Weil sonst muss ich ja jedes mal meine Funktion ändern wenn neue Variablen zur Struktur hinzu kommen.
 
Wu-mc hat gesagt.:
Naja leider kenn ich mich mit XML Dateien noch garnicht aus, kommt aber auf meine To-Do Liste (die immer länger wird).
Also für XML würde ich eine Bibliothek empfehlen (z.b. libxml2) - man muß das Rad ja nicht immer neu erfinden.

Auch für andere Arten von Dateien (z.B. ini Dateien) gibt's natürlich Bibliotheken.
Wu-mc hat gesagt.:
Mit Textdateien könnte ich mich schon anfreunden. Kannst du mir aber sagen wie ich eine Art Schleife mache um jedes Element einer Struktur abzufragen? Weil sonst muss ich ja jedes mal meine Funktion ändern wenn neue Variablen zur Struktur hinzu kommen.
Darum wirst du nicht herumkommen (wenn du structs benutzt). Besser wäre da dann eher einen assoziativen Kontainer wie z.B. eine Hashtabelle bzw. Dictionary als Datenstruktur zu verwenden.

Gruß
 
Zurück