2013-10-06 5 views
6

Kürzlich bekam ich eine Frage beim Schreiben eines Programms zum Öffnen von Dateien.Wie kann ich eine Funktion mit optionalen Argumenten in C machen?

Lassen Sie mich meine Frage klar erklären. Hier nehme ich open Anruf als ein Beispiel.

Um eine Datei zu erstellen:

open("file_name", O_CREAT, 0766); //passing 3 parametrs 

Um eine Datei zu öffnen:

open("file_name", O_RDWR); //only 2 arguments. 

Dann diesen Punkt klar beobachtete ich und es funktioniert auch für main() auch.

main(void) //worked 
main(int argc, char **argv); //worked 
main(int argc) //worked and it's doesn't give an error like "too few arguments". 
main() //worked 

Also, wie können wir diese optionalen Argumente erstellen? Wie genau kann der Compiler diese Prototypen validieren? Wenn möglich, schreibe bitte ein Beispielprogramm.

+0

Siehe auch: http: // stackoverflow.com/q/18421735/1870232 – P0W

Antwort

7

Die open Funktion als variadische Funktion deklariert. Es sieht ungefähr so ​​aus:

#include <stdarg.h> 

int open(char const * filename, int flags, ...) 
{ 
    va_list ap; 
    va_start(ap, flags); 

    if (flags & O_CREAT) 
    { 
     int mode = va_arg(ap, int); 
     // ... 
    } 

    // ... 

    va_end(ap); 
} 

Die weiteren Argumente werden nicht verbraucht, es sei denn, Sie haben angegeben, dass sie tatsächlich existieren.

Die gleiche Konstruktion ist für printf verwendet.

Das Handbuch macht dies nicht immer explizit, da die einzigen möglichen zwei Signaturen (char const *, int) und (char const *, int, int) sind. Es macht also wenig Sinn zu enthüllen, dass die Funktion tatsächlich variable Argumente akzeptiert. (Sie können dies testen, indem Sie versuchen, etwas wie open("", 1, 2, 3, 4, 5, 6) zu kompilieren.)

+0

aber wie können sie diese validieren. es gibt kein Argument wie "zu wenig Argumente". – SGG

+0

@SGG: Wie printf kann auch validiert werden, ob Sie die richtige Anzahl und Art von Argumenten übergeben haben. –

+0

@KerrekSB: Entschuldigung, mir fehlt Klarheit. Sehen Sie, es gibt eine Funktion, die ein Argument oder nichts (void) akzeptiert. Ich meine, Funktion sollte validiert werden, wenn ich Funktion() oder Funktion (10) anrufe. Kannst du die Definition für diese Funktion schreiben? – SGG

1

In allen Fällen muss eine Varargs-Funktion in der Lage sein, aus den festen Argumenten irgendwie zu bestimmen, wie viele Variablenargumente es gibt. Die Funktionsfamilie printf() verwendet beispielsweise die Formatzeichenfolge, um Anzahl und Typen der Argumente zu bestimmen. Die execl()-Funktion verwendet einen Sentinel (Nullzeiger), um das Ende der Argumentliste zu markieren. Es wäre möglich, einen Zählwert anstelle eines Sentinels zu verwenden (aber wenn Sie das tun, besteht die Möglichkeit, dass ein Zählwert und ein Array in einer Nicht-Varargs-Funktion genauso gut funktionieren, wenn nicht besser als ein zählen und eine Liste von Argumenten). Die open()-Funktion verwendet eines der Flag-Bits, um festzustellen, ob der Modus vorhanden sein sollte - siehe answer.

Die main() Funktion ist ein Sonderfall. Die Umsetzung (Compiler) aus Vereinbarkeit eines Prototyps für verboten sind, und müssen zumindest zwei Formen annehmen:

int main(int argc, char **argv); 
int main(void); 

oder deren Äquivalente. Es kann auch andere Formen annehmen; siehe What's the use of the third environment variable in the C main()? für eine gemeinsame Form. In C, aber nicht in C++, kann ein Standardcompiler andere Rückgabetypen dokumentieren - und Microsoft hat void als gültigen Rückgabetyp ab VS 2008 dokumentiert.

Da keine Implementierung vorausgesetzt, es ist Prototyp für main(), kann der Compiler nicht offiziell keine Erklärungen/Definitionen von main() ablehnen, obwohl es kommentieren Formen passieren könnte es nicht erkennt (GCC tut Kommentar über main() Funktionen, die tun Geben Sie zum Beispiel keinen int Typ zurück).

+1

Eigentlich kann ein Compiler * Formen von 'main' ablehnen, die er nicht akzeptiert. Alternative Formulare sind implementierungsdefiniert, was bedeutet, dass der Compiler von einem Dokument begleitet sein muss, das sie auflistet. Ein Programm mit einer Definition, die weder eine der beiden Standardformen noch eine implementierungsdefinierte Form für den aktuellen Compiler ist, hat undefiniertes Verhalten (durch Auslassung, da der Standard das Verhalten nicht definiert) (5.1.2.2.1). Die Ablehnung einer Übersetzungseinheit ist eine akzeptable Antwort auf undefiniertes Verhalten (3.4.3). –