ubuntuusers.de

C Funktionsdeklaration mit optionalen Parametern

Status: Ungelöst | Ubuntu-Version: Ubuntu 10.10 (Maverick Meerkat)
Antworten |

Kerberos

Anmeldungsdatum:
18. Juni 2007

Beiträge: 330

Ich würde gerne in C eine Funktion deklarieren die normal ein Parameter hat und optional zwei. Nur wie macht man das?

Bsp:

1
int *meineFunktion(int einParameter, int optionalesParameter);

Könnt ihr mir da weiterhelfen?

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Vorab, ich bin kein C-Experte, aber meines Wissens kennt C weder das Konzept von Default-Werten für Argumente, noch vom Überladen von Funktionen. Du wirst den Anwender deiner API vermutlich dazu nötigen müssen, ggf NULL-Argumente zu übergeben. So ist das in der Praxis ja eigentlich auch üblich, auch wenn's hässlich ist. Oder du gehst halt den Weg, dass du zwei verschiedene Funktionen machst, die einem die jeweils passende Signatur anbieten, intern aber nur das Argument / die Argumente an eine Funktion weiterreichen, welche die eigentliche Arbeit übernimmt und die dann eben die besagte hässliche Signatur hat.

Kerberos

(Themenstarter)

Anmeldungsdatum:
18. Juni 2007

Beiträge: 330

Ich hab nochmal gegoogled und es scheint doch zu gehen.

http://pronix.linuxdelta.de/C/standard_C/c_programmierung_21.shtml

Ich brauch jetzt aber erstmal eine Pause bevor ich da durchsteige. ☺

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Kann man natürlich auch so machen. Dann muss man aber auch das Zählen der Argumente und die Typprüfungen übernehmen, was sonst Aufgabe des Compilers ist. Ob es noch weitere Nachteile mit sich bringt, weiß ich nicht.

EDIT: Ah, va_arg() nimmt glücklicherweise auch den erwarteten Typen als Argument an. Das ist ja schon Mal gut.

Systemkritiker

Anmeldungsdatum:
2. Januar 2011

Beiträge: 110

Wohnort: Schweiz

Spar dir die Mühe; das mit der Argumentliste geht nicht. Du brauchst dazu immer noch die Information, wie viele Argumente übergeben wurden und die hast du (mit zwei Parametern) nicht.

Dass C bewusst auf optionale Parameter verzichtet, muss dir zu denken geben. Es gibt gute Gründe dafür und darum unterstützen nicht alle Sprachen dieses Feature. In C++ bringt das viele Probleme mit sich (z.B. wenn eine Bibliothek einen Standardwert ändert, müssen alle Benutzer neu kompillieren, sonst haben sie noch den alten Wert).

Halte es so wie wie es die GLib auch macht: zwei Funktionen. Das führt zu sprechenden Namen, einfacherer Benutzung, kurz: einem besseren Interface.

1
2
3
4
5
6
7
// Variante 1: Einparametrig als für die Funktion typischer
int * my_function (int a);
int * my_function_with_factor (int a, int b);

// Variante 2: Einparametrig als Abkürzung
int * my_function_with_defaults (int a);
int * my_function (int a, int b);

Zweiteres ist übrigens gebräuchlicher.

Beste Grüsse, Systemkritiker

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17625

Wohnort: Berlin

Systemkritiker schrieb:

Dass C bewusst auf optionale Parameter verzichtet, muss dir zu denken geben. Es gibt gute Gründe dafür und darum unterstützen nicht alle Sprachen dieses Feature. In C++ bringt das viele Probleme mit sich (z.B. wenn eine Bibliothek einen Standardwert ändert, müssen alle Benutzer neu kompillieren, sonst haben sie noch den alten Wert).

Die Logik der Argumentation erschließt sich mir nicht.

Dass C++ *bewusst nicht* auf optionale Parameter verzichtet, muss uns nicht zu denken geben? Obwohl doch C++ jünger ist als C, also auf mehr Erfahrungen zurückschauen kann als es C konnte?

z.B. wenn eine Bibliothek einen Standardwert ändert, müssen alle Benutzer neu kompillieren, sonst haben sie noch den alten Wert

Wenn die alten Benutzer mit dem Wert unzufrieden wären, dann hätten sie ja einen anderen Wert explizit gewählt. Wäre es nicht eher überraschend, ein Defaultwert würde sich stillschweigend ändern?

Systemkritiker

Anmeldungsdatum:
2. Januar 2011

Beiträge: 110

Wohnort: Schweiz

Dass C++ *bewusst nicht* auf optionale Parameter verzichtet, muss uns nicht zu denken geben? Obwohl doch C++ jünger ist als C, also auf mehr Erfahrungen zurückschauen kann als es C konnte?

Das Feature hätte problemlos in C98 oder C1x aufgenommen werden. C++ schleppt es als „Altlast“ mit und kann es nicht entfernen (ergo?). Es kommt oft vor, dass Dinge aus C++ in C eingeführt werden. Hier ist es nicht der Fall, auch wenn es wohl mehr am Sprachstil liegt als an der grundsätzlichen Idee.

z.B. wenn eine Bibliothek einen Standardwert ändert, müssen alle Benutzer neu kompillieren, sonst haben sie noch den alten Wert

Wenn die alten Benutzer mit dem Wert unzufrieden wären, dann hätten sie ja einen anderen Wert explizit gewählt. Wäre es nicht eher überraschend, ein Defaultwert würde sich stillschweigend ändern?

Da gebe ich dir Recht, aber das Problem tritt auf. Daher darf man einen Defaultwert praktisch nicht mehr ändern, was eine Einschränkung darstellt. Bei dem Workaround mit den zwei Funktionen geht das.

Ich habe keine vollständige Liste der Argumente aufgestellt, natürlich gibt es da viele; Pro und Kontra.

Fakt ist jedoch, dass sich jeder C-Programmierer damit abfinden muss, dass es nun mal keine gibt.

Beste Grüsse, Systemkritiker

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6518

Wohnort: Hamburg

Ich würde gerne in C eine Funktion deklarieren die normal ein Parameter hat und optional zwei.

Ich kenne zwar die eigentliche Aufgabenstellung nicht, aber der einfachste Weg wäre, für den zweiten Parameter bei nichtgebrauch einfach einen Dummy zu übergeben.

Du kannst es aber auch im Stile von printf() machen. Ich habe sowas jetzt lange nicht mehr gemacht, aber ich denke die Funktionen va_start(), va_arg() und va_end() könnten da weiterhelfen.

Giesi35

Anmeldungsdatum:
30. Januar 2011

Beiträge: 164

Gibt mehrere Optionen:

1
2
3
4
5
6
int *pMyFunction(int Zahl, int Startwert = 0);
...

/** Aufruf der Funktion */
pMyFunction(2);  /** Startwert = 0 */
pMyFunction(2,2);/** Startwert = 2 */

Andere Option wäre (wie bei printf) eine Argumentenliste:

1
2
3
4
5
void MyOutputFunction(const char *Str, ...)
{
    va_list list; /** Argumentenliste */
    ...
}

Google bringt einige nützliche Beispiele dafür!

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Giesi35 schrieb:

Gibt mehrere Optionen:

1
2
3
4
5
6
int *pMyFunction(int Zahl, int Startwert = 0);
...

/** Aufruf der Funktion */
pMyFunction(2);  /** Startwert = 0 */
pMyFunction(2,2);/** Startwert = 2 */

Hast Du das mal versucht zu kompilieren? 😉

Google bringt einige nützliche Beispiele dafür!

Ja, aber erstens kann man nicht jeder Quelle trauen und zweitens muss man auch mal genauer hingucken. Ich habe nur Hinweise zu C++ gefunden in diesem Kontext - aber ich kenne ja Deinen Suchstring nicht; würde mich aber mal interessieren.

Da in diesem Thread bereits mehrfach geschrieben wurde, dass C solche default-Werte nicht kennt, empfinde ich das schon ein wenig dreist, einfach einen Code-Schnipsel hinzuklatschen, ohne auf die bisherigen Kommentare einzugehen. Spätestens dann nämlich hättest Du der Sache ja wohl tiefer auf den Grund gehen müssen und wärst vermutlich selber drauf gekommen, dass das so nicht funzt - z.B.. durch einen einfachen Compilierversuch 😉

Giesi35

Anmeldungsdatum:
30. Januar 2011

Beiträge: 164

Lysander schrieb:

Giesi35 schrieb:

Gibt mehrere Optionen:

1
2
3
4
5
6
int *pMyFunction(int Zahl, int Startwert = 0);
...

/** Aufruf der Funktion */
pMyFunction(2);  /** Startwert = 0 */
pMyFunction(2,2);/** Startwert = 2 */

Hast Du das mal versucht zu kompilieren? 😉

Google bringt einige nützliche Beispiele dafür!

Ja, aber erstens kann man nicht jeder Quelle trauen und zweitens muss man auch mal genauer hingucken. Ich habe nur Hinweise zu C++ gefunden in diesem Kontext - aber ich kenne ja Deinen Suchstring nicht; würde mich aber mal interessieren.

Das war zum Thema va_list / va_arg!

Da in diesem Thread bereits mehrfach geschrieben wurde, dass C solche default-Werte nicht kennt, empfinde ich das schon ein wenig dreist, einfach einen Code-Schnipsel hinzuklatschen, ohne auf die bisherigen Kommentare einzugehen. Spätestens dann nämlich hättest Du der Sache ja wohl tiefer auf den Grund gehen müssen und wärst vermutlich selber drauf gekommen, dass das so nicht funzt - z.B.. durch einen einfachen Compilierversuch 😉

Schuldig! Ich habe mir wirklich nicht viel davor durchgelesen! Das gebe ich zu und entschuldige mich auch dafür!

Aber wegen Quellen: Es gibt ne Art default-Werte mit Makros: http://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99/

Systemkritiker

Anmeldungsdatum:
2. Januar 2011

Beiträge: 110

Wohnort: Schweiz

Giesi35 schrieb:

Aber wegen Quellen: Es gibt ne Art default-Werte mit Makros: http://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99/

Stimmt, so könnte das gehen, Makros habe ich bis jetzt nicht in Betracht gezogen. Die sind unglaublich mächtig. Aber wie gesagt: Solche Hacks stiften mehr Verwirrung als sie bringen.

Beste Grüsse, Systemkritiker

Antworten |