Was sollte main () Rückkehr in C und C ++?
-
03-07-2019 - |
Frage
Was ist der korrekte (sehr effizient) Weg, um die main()
Funktion in C und C ++ zu definieren - int main()
oder void main()
- und warum?
Wenn int main()
dann return 1
oder return 0
?
Es gibt zahlreiche Duplikate dieser Frage, einschließlich:
- Was sind die gültigen Unterschriften für C der
main()
Funktion? - Der Rückgabetyp
main()
Funktion - Unterschied zwischen
void main()
undint main()
? -
main()
Unterschrift in C ++ - Was ist die richtige Erklärung von
main()
- Für C ++ mit einer sehr guten Antwort in der Tat. - Styles von
main()
Funktionen in C - Rückgabetyp von
main()
Methode in C -
int main()
vsvoid main()
in C
Siehe auch:
- C ++ -
int main(int argc, char **argv)
- C ++ -
int main(int argc, char *argv[])
- Ist
char *envp[]
als drittes Argument tragbarmain()
? - Muss die
int main()
Funktion einen Wert zurückgeben in allen Compilern? - Warum ist der Typ der
main()
Funktion in C und C ++ dem Anwender überlassen zu definieren? - Warum
int main(){}
kompilieren? - Recht Definitionen von
main()
in C ++ 14?
Lösung
Der Rückgabewert für main
sollte angeben, wie das Programm verlassen. Normaler Ausgang wird durch einen 0 Rückgabewert von main
allgemein dargestellt. Abnormal Ausgang wird in der Regel durch eine Nicht-Null-Rückkehr signalisiert, aber es gibt keinen Standard für wie Nicht-Null-Codes interpretiert. Auch wie von anderen erwähnt, wird void main()
explizit vom C ++ verboten Standard und sollte nicht verwendet werden. Die gültigen C ++ main
Signaturen sind:
int main()
und
int main(int argc, char* argv[])
das ist äquivalent zu
int main(int argc, char** argv)
Es ist auch erwähnenswert, dass in C ++ kann int main()
ohne Rück Aussage gelassen wird, an welcher Stelle es standardmäßig auf 0 zurückkehr Dies gilt auch mit einem C99-Programm. Ob return 0;
weggelassen werden sollte oder nicht, ist eine offene Frage. Der Bereich gültigen C-Programm Haupt-Signaturen ist viel größer.
Auch Effizienz ist nicht ein Problem mit der main
Funktion. Es kann nur einmal eingegeben und verlassen wird (Kennzeichnung des Starts des Programms und Terminierung) nach dem C ++ Standard. Für C ist der Fall anders und Neueingabe main()
ist erlaubt, sollte aber vermieden werden.
Andere Tipps
Die akzeptierte Antwort scheint für C ++ abgezielt werden, so dass ich dachte, dass ich eine Antwort hinzufügen würde, die C betrifft, und dies unterscheidet sich in ein paar Möglichkeiten.
ISO / IEC 9899: 1989 (C90):
main()
sollte deklariert werden entweder:
int main(void)
int main(int argc, char **argv)
oder gleichwertig. Zum Beispiel ist int main(int argc, char *argv[])
auf die zweite ein Äquivalent. Ferner kann die int
Rückgabetyp verzichtet, da es sich um ein Standardwert ist.
Wenn eine Implementierung es erlaubt, main()
kann auf andere Weise erklärt werden, aber das macht die Umsetzung des Programms definiert sind, und nicht mehr streng entspricht.
Der Standard definiert drei Werte für die Rückgabe, die streng konform sind (das heißt, verlässt sich nicht auf die Umsetzung definiert Verhalten): 0
und EXIT_SUCCESS
für eine erfolgreiche Beendigung und EXIT_FAILURE
für eine nicht erfolgreiche Beendigung. Alle anderen Werte sind nicht-Standard und Implementierung definiert. main()
muss eine explizite return
Erklärung am Ende muß nicht definiertes Verhalten zu vermeiden.
Schließlich gibt es nichts falsch von einer Norm Sicht mit main()
aus einem Programm aufgerufen wird.
ISO / IEC 9899: 1999 (C99):
Für C99, alles ist das gleiche wie oben, außer:
- Der
int
Rückgabetyp nicht verzichtet werden kann. - Sie können die return-Anweisung von
main()
weglassen. Wenn Sie das tun, undmain()
fertig sind, gibt es eine implizitereturn 0
.
Standard C - Umwelt
HostedFür eine gehostete Umgebung (das ist die normale), der C11-Standard (ISO / IEC 9899: 2011) sagt:
5.1.2.2.1 Programmstart
Die Funktion beim Programmstart aufgerufen wird
main
benannt. Die Umsetzung erklärt nicht Prototyp für diese Funktion. Sie gilt mit dem Rückgabetypint
definiert werden und mit nicht Parameter:int main(void) { /* ... */ }
oder mit zwei Parametern (hier bezeichnet als
argc
undargv
, obwohl alle Namen sein können, verwendet, da sie auf die Funktion lokal sind, in der sie deklariert sind):int main(int argc, char *argv[]) { /* ... */ }
oder gleichwertig;. 10) oder in einer anderen Implementierung definiert Weise
Wenn sie deklariert sind, werden die Parameter an die Hauptfunktion gehorchen den folgenden Einschränkungen:
- Der Wert von
argc
soll sein nichtnegativ.argv[argc]
wird ein Null-Zeiger sein.- Wenn der Wert von
argc
größer als Null ist,argv[0]
die Array-Mitglieder durchargv[argc-1]
inklusive sind Zeiger auf Zeichenfolgen enthalten, die gegeben sind Implementierung definiert Werte, die von der Host-Umgebung vor dem Programmstart. Das Absicht ist es, die Programminformationen bestimmt vor der Inbetriebnahme zu liefern programmieren von anderswo in der gehosteten Umgebung. Wenn die Host-Umgebung ist nicht in der Lage Zuführen von Strings mit Buchstaben in Groß- und Klein, die Umsetzung sorgt dafür, dass die Strings in Klein empfangen werden.- Wenn der Wert von
argc
größer als Null ist, wies die Zeichenfolge vonargv[0]
stellt der Programmname;argv[0][0]
ist es, die Null-Zeichen, wenn die Programmname ist von der Host-Umgebung nicht zur Verfügung. Wenn der Wert vonargc
ist größer als eins ist, zeigte die Saiten vonargv[1]
durchargv[argc-1]
zu stellen die Programmparameter.- Die Parameter
argc
undargv
und die Saiten auf die durch denargv
Array soll modifizierbar durch das Programm, und behalten ihre zuletzt gespeicherten Werte zwischen Programm Start und Beendigung des Programms.10) Somit kann als
int
int
, oder die Art desargv
definiert durch einen typedef Namen ersetzt werden kann geschrieben werden alschar **argv
, und so weiter.
Programmabbruch in C99 oder C11
Der Wert von main()
zurückgegeben wird, in einer Implementierung definierte Art und Weise auf die ‚Umwelt‘ übertragen werden.
5.1.2.2.3 Programmabbruch
1 Wenn der Rückgabetyp der
main
Funktion eine Art kompatibel mitint
ist, eine Rückkehr von der erster Aufruf der Funktion entsprichtmain
dieexit
Funktion mit dem Wert zu nennen durch diemain
Funktion als Argument zurückgegeben; 11) Erreichen des}
, Das beendet diemain
Funktion gibt einen Wert von 0. Wenn der Rückgabetyp nicht kompatibel mitint
ist, die Beendigungsstatus an den Host-Umgebung zurückgegeben wird, ist nicht spezifiziert.11) Gemäß 6.2.4, die Lebensdauer von Objekten mit automatischer Speicherdauer in
main
erklärt wird im ersten Fall beendet hat, wo auch sie würden nicht in den letzteren haben.
Beachten Sie, dass 0
als ‚Erfolg‘ vorgeschrieben ist. Sie können EXIT_FAILURE
und EXIT_SUCCESS
von <stdlib.h>
verwenden, wenn Sie es vorziehen, aber 0 ist gut etabliert, und so ist 1. Siehe auch Exit-Codes größer als 255 -?. möglich
In C89 (eind daher in Microsoft C), gibt es keine Aussage darüber, was, wenn die main()
Funktion zurückkehrt geschieht aber nicht angibt, einen Rückgabewert; es führt daher zu nicht definiertes Verhalten.
7.22.4.4 Die
exit
Funktion¶5 Schließlich wird die Steuerung an die Host-Umgebung zurück. Wenn der Wert von
status
Null oderEXIT_SUCCESS
ist, eine Implementierung definiert Form des Status erfolgreiche Beendigung zurückgegeben. Wenn der Wert vonstatus
EXIT_FAILURE
ist, eine Implementierung definiert Form des Status erfolglose Beendigung zurückgegeben. Ansonsten kehrte der Status ist die Implementierung definiert.
Standard C ++ - gehosteten Umgebung
Der C ++ 11-Standard (ISO / IEC 14882: 2011) sagt:
3.6.1 Hauptfunktion [basic.start.main]
¶1 Ein Programm soll eine globale Funktion enthält Haupt genannt, die der designierte Start des Programms ist. [...]
¶2 Eine Implementierung ist nicht die Hauptfunktion vordefinieren. Diese Funktion darf nicht überlastet werden. Es sollte hat einen Rückgabetyp vom Typ int, aber sonst seine Art ist Implementierung definiert. Alle Implementierungen werden die beiden folgenden Definitionen von Haupt erlauben:
int main() { /* ... */ }
und
int main(int argc, char* argv[]) { /* ... */ }
In der letzteren Form
argc
soll die Anzahl der Argumente für das Programm aus der Umgebung übergeben werden in dem das Programm ausgeführt werden. Wennargc
ungleich Null ist, soll diese Argumente inargv[0]
geliefert werden durchargv[argc-1]
als Zeiger auf die Anfangszeichen des nullterminierte Multibyte Strings (NTMBSs) (17.5.2.1.4.2) undargv[0]
wird der Zeiger auf den Anfangszeichen eines NTMBS sein, dass die darstellt Namen verwendet, um das Programm oder""
aufzurufen. Der Wert vonargc
wird nicht negativ sein. Der Wert vonargv[argc]
ist 0. [Hinweis sein: Es wird empfohlen, dass alle weiteren (optional) Parameter nachargv
hinzugefügt werden. -Ende Anmerkung]¶3 Die Funktion
main
darf nicht innerhalb eines Programms verwendet werden. Die Verbindung (3.5) vonmain
ist die Implementierung definiert. [...]¶5 Eine return-Anweisung in Haupt die Wirkung hat, die Hauptfunktion verlassen (alle Objekte mit automatischer Zerstörung Speicherdauer) und ruft
std::exit
mit dem Rückgabewert als Argument. Wenn die Steuerung das Ende erreicht, Haupt ohne eine return-Anweisung zu begegnen, ist die Wirkung, dass die Ausführungreturn 0;
Der C ++ Standard ausdrücklich sagt: „Es [die Hauptfunktion] soll einen Rückgabetyp vom Typ int
hat, aber sonst seine Art ist Implementierung definiert“, und erfordert die gleichen zwei Unterschriften wie der C-Standard als Optionen unterstützt werden. So ein ‚void main ()‘ wird direkt erlaubt nicht durch die C ++ Standard, obwohl es nichts dagegen tun kann eine Nicht-Standard-Implementierung zu stoppen Alternativen zu ermöglichen. Beachten Sie, dass C ++ den Benutzer verbietet main
von Aufruf (aber der C-Standard nicht).
Es gibt einen Absatz von §18.5 Start und Beendigung in dem C ++ 11-Standard, der auf den Absatz identisch ist von §7.22.4.4 Der exit
Funktion in dem C11 Standard (oben zitiert), abgesehen von einer Fußnote (die nur Dokumente, die in EXIT_SUCCESS
definiert EXIT_FAILURE
und <cstdlib>
werden).
Standard C - Gemeinsame Erweiterung
Classically, Unix-Systeme unterstützen eine dritte Variante:
int main(int argc, char **argv, char **envp) { ... }
Das dritte Argument ist ein Null-terminierte Liste von Zeigern auf Strings, von denen jede eine Umgebungsvariable, die einen Namen hat, ein Gleichheitszeichen und ein Wert (möglicherweise leer). Wenn Sie nicht über diese, können Sie immer noch auf die Umwelt über ‚extern char **environ;
‘ bekommen. Für eine lange Zeit, die nicht have einen Header, es erklärt, aber die POSIX 2008-Standard erfordert es jetzt in <unistd.h>
deklariert werden.
Dies wird durch den C-Standard als eine gemeinsame Erweiterung erkannt wird, dokumentiert in Anhang J:
J.5.1 Umwelt Argumente
¶1 In einer gehosteten Umgebung, empfängt die Hauptfunktion ein drittes Argument,
char *envp[]
, dass die Punkte auf einen Null-terminierte Array von Zeigern aufchar
, von denen jeder weist auf eine Zeichenfolge dass liefert Informationen über die Umgebung für diese Ausführung des Programms (5.1.2.2.1).
Microsoft C
Die Microsoft VS 2010 Compiler ist interessant. Die Website sagt:
Die Deklarationssyntax für Haupt ist
int main();
oder optional
int main(int argc, char *argv[], char *envp[]);
Alternativ können die
main
undwmain
Funktionen können als Rückkehrvoid
(kein Rückgabewert) deklariert werden. Wenn Siemain
oderwmain
als Rückkehr für nichtig zu erklären, können Sie nicht einen Exit-Code an dem übergeordneten Prozess oder das Betriebssystem zurückkehren, indem eine Rückkehr-Anweisung. Um einen Exit-Code zurück, wennmain
oderwmain
alsvoid
erklärt, müssen Sie dieexit
-Funktion verwenden.
Es ist mir nicht klar, was passiert (was Exit-Code wird an den Eltern oder OS zurückgegeben), wenn ein Programm mit void main()
Ausgang hat -. Und die MS-Website ist zu leise
Interessanterweise MS schreibt nicht vor, die mit zwei Argumenten Version von main()
, dass die C- und C ++ Standards erfordern. Sie schreibt nur drei Argument Formular, in dem das dritte Argument char **envp
, ein Zeiger auf eine Liste der Umgebungsvariablen ist.
Die Microsoft-Seite listet auch einige andere Alternativen - wmain()
die breite Zeichenketten nimmt, und einige mehr
Die Microsoft Visual Studio 2005 Version von diese Seite nicht auflistet void main()
als Alternative. Die Versionen von Microsoft Visual Studio 2008 weiter tun.
Standard C - Freistehend Umwelt
Bereits auf erwähnt, gelten die oben genannten Anforderungen zu gehosteten Umgebungen. Wenn Sie mit einer frei stehenden Umgebung arbeiten (das ist die Alternative zu einer gehosteten Umgebung ist), dann hat der Standard viel weniger zu sagen. Für eine freistehende Umgebung, die Funktion beim Programmstart aufgerufen braucht nicht main
und dort genannt wird, sind keine Einschränkungen für dessen Rückgabetyp. Die Norm sagt:
5.1.2 Ausführungsumgebungen
Zwei Ausführungsumgebungen sind definiert: freistehend und gehostet. In beiden Fällen, Programmstart tritt auf, wenn eine festgelegte C-Funktion durch die Ausführung aufgerufen wird, Umgebung. Alle Objekte mit statischer Speicherdauer wird (auf ihre Anfangswerte) initialisiert werden, bevor Programmstart. Die Art und Weise und den Zeitpunkt der Initialisierung solche sind ansonsten nicht näher bezeichnet. Programmende kehrt die Steuerung an die Ausführungsumgebung.
5.1.2.1 Freistehende Umgebung
In einer frei stehenden Umgebung (in der C Programmausführung erfolgt ohne Nutzen eines Betriebssystems in Anspruch nehmen), den Namen und den Typ der Funktion beim Programmstart aufgerufen sind die Implementierung definiert. Jede Bibliothek Einrichtungen, die dem freistehenden program, andere als die minimale Menge erforderlich nach Satz 4 sind die Implementierung definiert.
Die Wirkung der Beendigung des Programms in einer freistehenden Umgebung ist die Implementierung definiert.
Der Querverweis auf Paragraf 4 Conformance bezieht sich auf diesem:
¶5 A streng konformes Programm ist nur die Funktionen der Sprache und die Bibliothek in dieser Internationalen Norm angegeben verwenden. 3) Es wird nicht ausgegeben abhängig von einer nicht näher bezeichnet produzieren , unbestimmt, oder die Implementierung definiert Verhalten, und übernimmt keine Mindest Umsetzung Grenze nicht überschreiten.
¶6 Die beiden Formen der Implementierung konform sind Gastgeber und freistehend . A konforme gehostete Implementierung ist jedes streng konformes Programm akzeptieren. A konforme freistehende Ausführung ist jedes streng konformes Programm akzeptieren, in der die Verwendung der Funktionen in der Bibliothek Klausel (Klausel 7) spezifizierten die Inhalte der Standard-Header beschränkt
<float.h>
,<iso646.h>
,<limits.h>
,<stdalign.h>
,<stdarg.h>
,<stdbool.h>
,<stddef.h>
,<stdint.h>
und<stdnoreturn.h>
. Eine konforme Implementierung kann Erweiterungen (einschließlich weitere Bibliotheksfunktionen), sofern sie das Verhalten eines streng konformen Programm nicht verändern. 4)¶7 A konformes Programm ist eine, die auf eine konforme Implementierung annehmbar ist. 5)
3) Ein streng konformes Programm kann bedingte Eigenschaften (siehe 6.10.8.3) bereitgestellt, um die Verwendung durch eine entsprechende bedingte Aufnahme Vorverarbeitung Richtlinie geschützt wird, um das zugehörige Makro. Zum Beispiel:
#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */ /* ... */ fesetround(FE_UPWARD); /* ... */ #endif
4) Dies bedeutet, dass eine konforme Implementierung Reserven keine Identifikatoren anderen als den reservierten ausdrücklich in dieser Internationalen Norm.
5) streng konforme Programme sollen unter konformen Implementierungen maximal tragbar sein. Konforme Programme abhängen kann auf nicht tragbare Merkmale einer konforme Implementierung.
Es fällt auf, dass der einzige Header einer frei stehenden Umgebung erforderlich, die alle Funktionen tatsächlich definiert ist <stdarg.h>
(und sogar sein diejenigen können - und ist oft - nur Makros).
Standard C ++ - Freistehend Umwelt
So wie der C-Standard sowohl gehostete und freistehende Umgebung erkennt, tut dies auch den C ++ Standard. (Zitate aus ISO / IEC 14882:. 2011)
1.4 Umsetzung Compliance [intro.compliance]
¶7 Zwei Arten von Implementierungen sind definiert: a Implementierung gehostet und freistehende Implementierung . Für eine gehostete Implementierung dieser Internationalen Norm definiert die Menge der verfügbaren Bibliotheken. Eine freistehende Implementierung ist eine, in der Ausführung Ort ohne den Vorteil eines Betriebssystems in Anspruch nehmen, und hat eine Implementierung definierten Satz von Bibliotheken, die bestimmte Sprachunterstützungsbibliotheken (17.6.1.3) umfasst.
¶8 Eine konforme Implementierung Erweiterungen (einschließlich zusätzlicher Bibliotheksfunktionen) können, sofern sie nicht verändern das Verhalten eines wohlgeformten Programm. Implementationen sind erforderlich, Programme zu diagnostizieren, dass verwenden solche Erweiterungen, die schlecht ausgebildet sind, nach dieser Internationalen Norm. Nachdem dies geschehen ist, können sie jedoch kompilieren und solche Programme auszuführen.
¶9 Jede Implementierung hat Unterlagen zu enthalten, die alle bedingt unterstützten Konstrukte identifiziert, dass sie nicht unterstützt und definiert alle locale-spezifischen Eigenschaften. 3
3) Diese Dokumentation definiert auch die Implementierung definiert Verhalten; siehe 1.9.
17.6.1.3 Freistehende Implementierungen [Compliance]
Zwei Arten von Implementierungen sind definiert: hosted und freistehende (1.4). Für eine gehostete Implementierung dieser Internationalen Norm beschreibt die Menge der zur Verfügung stehenden Header.
Eine freistehende Implementierung hat eine Implementierung definiert Satz von Headern. Dieser Satz soll mindestens die Header in der Tabelle 16.
Die mitgelieferte Version des Headers
<cstdlib>
muss mindestens die Funktionenabort
,atexit
,at_quick_exit
,exit
undquick_exit
(18.5) erklären. Die anderen Überschriften in dieser Tabelle aufgeführt sind, werden die gleichen Anforderungen wie für eine gehostete Anwendung erfüllen.Tabelle 16 - C ++ Header für freistehende Implementierungen
Subclause Header(s) <ciso646> 18.2 Types <cstddef> 18.3 Implementation properties <cfloat> <limits> <climits> 18.4 Integer types <cstdint> 18.5 Start and termination <cstdlib> 18.6 Dynamic memory management <new> 18.7 Type identification <typeinfo> 18.8 Exception handling <exception> 18.9 Initializer lists <initializer_list> 18.10 Other runtime support <cstdalign> <cstdarg> <cstdbool> 20.9 Type traits <type_traits> 29 Atomics <atomic>
Was ist mit int main()
in C?
Der Standard §5.1.2.2.1 des C11-Standard zeigt die bevorzugte Schreibweise - int main(void)
- aber es gibt auch zwei Beispiele in der Norm, die int main()
zeigen: §6.5.3.4 ¶8 und §6.7.6.3 ¶20 . Nun ist es wichtig zu beachten, dass die Beispiele sind nicht ‚normative‘; sie sind nur illustrativ. Wenn es Fehler in den Beispielen, sie nicht direkt den Haupttext des Standards beeinflussen. Das heißt, sie sind ein starkes Indiz für die erwartete Verhalten, so dass, wenn die Standard-int main()
in einem Beispiel enthält, schlägt er vor, int main()
ist nicht verboten, auch wenn es nicht die bevorzugte Schreibweise ist.
6.5.3.4 Die
sizeof
und_Alignof
Operatoren...
¶8 Beispiel 3: In diesem Beispiel ist die Größe eines Arrays mit variabler Länge berechnet wird, und aus einer zurücken Funktion:
#include <stddef.h> size_t fsize3(int n) { char b[n+3]; // variable length array return sizeof b; // execution time sizeof } int main() { size_t size; size = fsize3(10); // fsize3 returns 13 return 0; }
Ich glaube, dass main()
entweder EXIT_SUCCESS
oder EXIT_FAILURE
zurückkehren. Sie sind in stdlib.h
definiert
Beachten Sie, dass die C- und C ++ Standards definieren zwei Arten von Implementierungen. Freistehend und gehostet
-
C90 gehosteten Umgebung
erlaubt Formen 1 :
int main (void) int main (int argc, char *argv[]) main (void) main (int argc, char *argv[]) /*... etc, similar forms with implicit int */
Kommentare:
Die ersten beiden werden als die erlaubten Formen explizit angegeben ist, werden die anderen implizit erlaubt, da C90 „impliziten int“ für Rückgabetyp und Funktionsparameter erlaubt. Keine andere Form ist erlaubt.
-
C90 freistehende Umgebung
Jede Form oder den Namen des Haupt erlaubt ist 2 .
-
C99 gehosteten Umgebung
erlaubt Formen 3 :
int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */
Kommentare:
C99 entfernt "implizites int" so
main()
nicht mehr gültig ist.Ein seltsamer, zweideutiger Satz „oder in einer anderen Implementierung definierte Art und Weise“ eingeführt wurde. Dies kann entweder als „die Parameter
int main()
variieren kann“ interpretiert werden oder als „Haupt jede Implementierung definiert Form haben kann“.Einige Compiler haben sich entschieden, den Standard in der letzteren Art und Weise zu interpretieren. Argumentieren, kann man nicht einfach sagen, dass sie nicht unbedingt mit dem Hinweis auf den Standard in der sich konform sind da sie nicht eindeutig sind.
Um jedoch zu ermöglichen, vollständig Wildformen von
main()
waren wahrscheinlich (?) Nicht die Absicht dieses neuen Satzes. Die C99 Begründung (nicht normativ) bedeutet, dass der Satz, um zusätzliche Parameter bezieht sich aufint main
4 .Doch der Abschnitt für gehostete Umgebung Programmabbruch geht dann über den Fall auf dem Argument, wo Haupt nicht zurück int 5 . Obwohl dieser Abschnitt nicht normativ für ist, wie Haupt erklärt werden soll, bedeutet es auf jeden Fall, dass Haupt könnte in einem völlig Implementierung definierte Art und Weise auch auf gehostete Systemen deklariert werden.
-
C99 freistehende Umgebung
Jede Form oder den Namen des Haupt erlaubt ist 6 .
-
C11 gehosteten Umgebung
erlaubt Formen 7 :
int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */
-
C11 freistehende Umgebung
Jede Form oder den Namen des Haupt erlaubt ist 8 .
Beachten Sie, dass int main()
nie als gültige Form für jeden aufgeführt wurde Implementierung von C in einen der oben genannten Versionen gehostet. In C, im Gegensatz zu C ++, ()
und (void)
unterschiedlichen Bedeutungen haben. Ersteres ist eine obsolescent Funktion, die aus der Sprache entfernt werden. Siehe C11 Zukunft Sprachrichtungen:
6.11.6 Funktionsdeklaratoren
Die Verwendung von Funktionsdeklaratoren mit leeren Klammern (nicht Prototyp-Format Parametertyp Deklaratoren) ist eine veraltete Funktion.
-
C ++ 03 gehosteten Umgebung
erlaubt Formen 9 :
int main () int main (int argc, char *argv[])
Kommentare:
Beachten Sie die leere Klammer in der ersten Form. C ++ und C unterscheiden sich in diesem Fall, da in C ++ bedeutet dies, daß die Funktion keine Parameter annimmt. Aber in C bedeutet dies, dass es jeden Parameter annehmen kann.
-
C ++ 03 freistehende Umgebung
Der Name der Funktion beim Start aufgerufen ist die Implementierung definiert. Wenn es
main()
genannt wird, muss es die genannten Formen folgen 10 :// implementation-defined name, or int main () int main (int argc, char *argv[])
-
C ++ 11 gehosteten Umgebung
erlaubt Formen 11 :
int main () int main (int argc, char *argv[])
Kommentare:
Der Text der Norm geändert wurde, aber es hat die gleiche Bedeutung.
-
C ++ 11 freistehende Umgebung
Der Name der Funktion beim Start aufgerufen ist die Implementierung definiert. Wenn es
main()
genannt wird, muss es die genannten Formen folgen 12 :// implementation-defined name, or int main () int main (int argc, char *argv[])
Referenzen
-
ANSI C3.159-1989 2.1.2.2 gehosteten Umgebung. „Program startup "
Die Funktion beim Programmstart aufgerufen wird, den Name main. Das Implementierung erklärt keinen Prototyp für diese Funktion. Es soll sein definiert mit dem Rückgabetyp int und ohne Parameter:
int main(void) { /* ... */ }
oder mit zwei Parametern (hier bezeichnet als argc und argv, obwohl alle Namen verwendet werden, da sie die örtliche sind Funktion, in der sie deklariert sind):
int main(int argc, char *argv[]) { /* ... */ }
-
ANSI C3.159-1989 2.1.2.1 Freistehende Umgebung:
In einer frei stehenden Umgebung (in der C Programmausführung in Anspruch nehmen Platz ohne Nutzen eines Betriebssystems), dem Namen und den Typ beim Programmstart der Funktion ist aufgerufen die Implementierung definiert.
-
ISO 9899: 1999 5.1.2.2 gehosteten Umgebung -> 5.1.2.2.1 Programmstart
Die Funktion beim Programmstart aufgerufen wird, den Name main. Das Implementierung erklärt keinen Prototyp für diese Funktion. Es soll sein definiert mit dem Rückgabetyp int und ohne Parameter:
int main(void) { /* ... */ }
oder mit zwei Parametern (hier bezeichnet als argc und argv, obwohl alle Namen verwendet werden, da sie die örtliche sind Funktion, in der sie deklariert sind):
int main(int argc, char *argv[]) { /* ... */ }
oder äquivalent; 9) oder in einer anderen Implementierung definiert Art und Weise.
-
Begründung für International Standard - Programmiersprachen - C, Revision 5.10. 5.1.2.2 gehosteten Umgebung -> 5.1.2.2.1 Programmstart
Das Verhalten der Argumente zur Haupt und der Wechselwirkung von Ausgang, Haupt- und atexit (Siehe §7.20.4.2) wurde kodifiziert einige unerwünschte Vielfalt in der Darstellung von argv einzudämmen Streicher und im Sinne der Werte von Haupt zurückgegeben.
Die Angabe von argc und argv als Argumente zur Haupt erkennt umfangreiche Stand der Praxis. argv [argc] ist erforderlich, ein Null-Zeiger sein, um eine redundante Prüfung für das Ende der Liste zu schaffen, auch auf der Grundlage gemeinsamen Praxis.
Haupt ist die einzige Funktion, die portabel entweder mit null oder zwei Argumenten geltend gemacht werden kann. (Die Anzahl der anderen Funktionen Argumente müssen genau zwischen den Aufruf und die Definition entsprechen.) Dieser Sonderfall erkennt lediglich die weit verbreitete Praxis der Weglassen der Argumente zur Haupt, wenn das Programm nicht die Programmargument Strings zugreift. Während viele Implementierungen mehr als zwei Argumente zur Haupt unterstützen, ist eine solche Praxis weder gesegnet noch von der Norm verboten; ein Programm, das mit drei Argumenten Haupt definiert ist nicht streng konform (§J.5.1 sehen.).
-
ISO 9899: 1999 5.1.2.2 gehosteten Umgebung -> 5.1.2.2.3 Programmabbruch
Wenn der Rückgabetyp der Hauptfunktion eine Art kompatibel mit int ist, eine Rückkehr von dem ursprünglichen Aufruf der Hauptfunktion entspricht, die Exit-Funktion mit dem Wert zum Aufruf durch die Hauptfunktion als Argument zurückgegeben; 11) erreicht die
}
, die die Haupt-Funktion gibt einen Wert von 0. Wenn der Rückgabetyp mit int ist nicht kompatibel beendet, kehrte der Beendigungsstatus an den Host-Umgebung ist nicht spezifiziert. -
ISO 9899: 1999 5.1.2.1 Freistehende Umgebung
In einer frei stehenden Umgebung (in der C Programmausführung erfolgt ohne Nutzen eines Betriebssystems in Anspruch nehmen), den Namen und den Typ der Funktion beim Programmstart aufgerufen sind die Implementierung definiert.
-
ISO 9899: 2011 5.1.2.2 gehosteten Umgebung -> 5.1.2.2.1 Programmstart
Dieser Abschnitt ist mit dem C99 eines wie oben zitiert identisch.
-
ISO 9899: 1999 5.1.2.1 Freistehende Umgebung
Dieser Abschnitt ist mit dem C99 eines wie oben zitiert identisch.
-
ISO 14882: 2003 3.6.1 Hauptfunktion
Eine Implementierung wird die Hauptfunktion nicht vordefinieren. Diese Funktion darf nicht überlastet werden. Es wird einen Rückgabetyp vom Typ int hat, aber sonst seine Art ist die Implementierung definiert. Alle Implementierungen müssen die beiden folgenden Definitionen von Haupt erlauben:
int main() { /* ... */ }
und
int main(int argc, char* argv[]) { /* ... */ }
-
ISO 14882: 2003 3.6.1 Hauptfunktion
Es ist die Implementierung definiert, ob ein Programm in einer frei stehenden Umgebung erforderlich, um eine Hauptfunktion zu definieren.
-
ISO 14882: 2011 3.6.1 Hauptfunktion
Eine Implementierung wird die Hauptfunktion nicht vordefinieren. Diese Funktion darf nicht überlastet werden. Es wird einen Rückgabetyp vom Typ int hat, aber sonst seine Art ist die Implementierung definiert. Alle Implementierungen sollen erlauben sowohl
- eine Funktion von () Rückkehr int und
- eine Funktion von (int, Zeiger auf Zeiger auf char) int Rückkehr
als Typ der Haupt (8.3.5).
-
ISO 14882: 2011 3.6.1 Hauptfunktion
Dieser Abschnitt ist identisch mit dem C ++ 03 oben zitiert.
Zurück 0 bei Erfolg und Nicht-Null für Fehler. Dies ist der Standard, die von UNIX und DOS-Scripting, um herauszufinden, was mit Ihrem Programm passiert ist.
main()
in C89 und K & R C nicht spezifiziert Rückgabetypen standardmäßig auf ‚int`.
return 1? return 0?
-
Wenn Sie nicht über eine return-Anweisung in
int main()
schreiben, wird das Schließen{
return 0 standardmäßig aktiviert. -
return 0
oderreturn 1
wird vom übergeordneten Prozess empfangen werden. In einer Schale geht es in ein Shell-Variable, und wenn Sie Ihr Programm ausführen eine Schale bilden und nicht diese Variable verwenden, dann müssen Sie sich nicht über den Rückgabewert vonmain()
sorgen.
Siehe Wie kann ich, was meine Hauptfunktion zurückgekehrt ist? .
$ ./a.out
$ echo $?
Auf diese Weise können Sie sehen, dass es die Variable $?
ist, die das am wenigsten signifikante Byte des Rückgabewert von main()
erhält.
In Unix und DOS-Scripting, return 0
auf Erfolg und Nicht-Null-Fehler werden in der Regel zurückgegeben. Dies ist der Standard, der von Unix und DOS-Scripting verwendet, um herauszufinden, was mit Ihrem Programm passiert ist und die gesamte Strömung zu steuern.
Beachten Sie, dass, auch wenn Sie einen int sind Rückkehr, einige OSes (Windows) gestutzt den zurückgegebenen Wert auf ein Byte (0-255).
Der Rückgabewert kann vom Betriebssystem verwendet werden, um zu überprüfen, wie das Programm geschlossen wurde.
Rückgabewert 0 bedeutet in der Regel OK in den meisten Betriebssystemen (die, die ich sowieso denken kann).
Es kann auch überprüft werden, wenn man sich ein Verfahren nennen, und sehen, ob das Programm verlassen und beendete richtig.
Es ist nicht nur eine Programmierkonvention.
Der Rückgabewert von main()
zeigt, wie das Programm verlassen. Wenn der Wert Rückkehr zero
, bedeutet dies, dass die Ausführung erfolgreich war, während jeder Wert ungleich Null wird vertreten, dass etwas schlecht ging in der Ausführung.
Ich hatte den Eindruck, dass Standard legt fest, dass Haupt keinen Rückgabewert benötigt als eine erfolgreiche Rückkehr wurde OS-basierten (Null in einem entweder ein Erfolg oder ein Fehler in einem anderen sein könnte), damit das Fehlen der Rückkehr war ein Stichwort für den Compiler selbst die erfolgreiche Rückkehr einzufügen.
Ich kehre jedoch in der Regel 0.
0 Rückkehr sollte den Programmierer sagen, dass das Programm erfolgreich die Arbeit beendet hat.
auslassen return 0
Wenn ein C oder C ++ Programm das Ende main
erreicht die Compiler automatisch generieren Code 0 zurück, so gibt es keine Notwendigkeit return 0;
explizit am Ende main
zu setzen.
Hinweis: , wenn ich diesen Vorschlag machen, ist es fast immer durch eine von zwei Arten von Kommentaren gefolgt: „Ich habe das nicht wissen.“ oder „Das ist ein schlechter Rat!“ Meine Begründung ist, dass es sicher ist und nützlich auf Compiler Verhalten verlassen explizit durch den Standard unterstützt. Für C, da C99; siehe ISO / IEC 9899: 1999 Abschnitt 5.1.2.2.3:
[...] eine Rückkehr aus dem ersten Aufruf die
main
Funktion entspricht dieexit
Funktion mit dem Wert Aufruf durch diemain
Funktion als Argument zurückgegeben; die}
erreicht, die diemain
Funktion gibt einen Wert von 0 beendet wird.
Für C ++, seit dem ersten Standard im Jahr 1998; siehe ISO / IEC 14882: 1998 Abschnitt 3.6.1:
Wenn die Steuerung des Ende der Haupt erreicht, ohne eine return-Anweisung zu begegnen, ist der Effekt, dass die Ausführung return 0;
Alle Versionen beiden Standards seitdem (C99 und C ++ 98) haben die gleiche Idee gehalten. Wir setzen auf automatisch Member-Funktionen in C ++ erzeugt, und nur wenige Leute schreiben explizit return;
Aussagen am Ende einer void
Funktion. Gründe gegen Weglassen scheinen " es sieht seltsam ". Wenn, wie ich, du bist über die Gründe für die Änderung der C-Standard neugierig lesen Sie diese Frage . Beachten Sie auch, dass in den frühen 1990er Jahren wurde diese „schlampige Praxis“ betrachtet, weil es nicht definiertes Verhalten war (obwohl weit unterstützt) zu der Zeit.
Zusätzlich kann der C ++ Basisrichtlinien mehrere Instanzen enthält Weglassen return 0;
am Ende main
und keine Fälle, in denen eine explizite Rückkehr geschrieben wird. Obwohl es zu diesem speziellen Thema in diesem Dokument noch nicht eine spezielle Leitlinie ist, dass zumindest eine stillschweigende Billigung der Praxis scheint.
Also ich befürworten Weglassen es; die andere nicht (oft heftig!) Auf jeden Fall, wenn Sie Code auftreten, die es unterlässt, werden Sie wissen, dass es von der Norm ausdrücklich unterstützt wird und Sie wissen, was es bedeutet.
Was zurückzukehren hängt davon ab, was Sie mit der ausführbaren Datei tun mögen. Zum Beispiel, wenn Sie Ihr Programm mit einem Befehlszeilen-Shell verwendet, dann müssen Sie 0 für einen Erfolg und ein nicht Null für das Scheitern zurückzukehren. Dann würden Sie das Programm in Schalen mit bedingter Verarbeitung abhängig vom Ergebnis des Codes verwenden können. Auch können Sie einen beliebigen Wert ungleich Null, wie pro Ihre Interpretation zuordnen, zum Beispiel für kritische Fehler unterschiedliche Programmausstiegspunkte könnte ein Programm mit unterschiedlichen Austrittswerte beenden, und die mit dem Aufruf Shell zur Verfügung, die entscheiden kann, was durch Überprüfen der zurückgegebene Wert zu tun.
Wenn der Code nicht für die Verwendung mit Muscheln und der zurückgegebene Wert der Mühe jemand dann nicht beabsichtigt ist, es könnte weggelassen werden. Ich persönlich die Unterschrift int main (void) { .. return 0; .. }
verwenden
Wenn Sie wirklich Fragen im Zusammenhang mit Effizienz im Zusammenhang haben aus einem Prozess eine ganze Zahl von Rückkehr, sollten Sie wahrscheinlich, dass Prozess so oft anrufen vermeiden, dass dieser Rückgabewert wird zu einem Problem.
Wenn Sie dies tun (nennen sie einen Prozess so oft), sollten Sie einen Weg finden, Ihre Logik zu setzen direkt innerhalb des Anrufers oder in einer DLL-Datei, ohne ein spezielles Verfahren für jeden Anruf zuweisen; die mehrere Prozesszuweisungen bringen Sie die entsprechende Effizienzproblem in diesem Fall.
Im Detail, wenn Sie wissen wollen, ob 0 Rückkehr mehr oder weniger effizient als 1 zurückkehrt, könnte es vom Compiler in einigen Fällen ab, aber allgemein, vorausgesetzt, sie sind aus der gleichen Quelle lesen (lokal, Feld, konstant, im Code, Funktionsergebnis eingebettet, etc.) erfordert genau die gleiche Anzahl von Taktzyklen.
Was ist die richtige (sehr effizient) Art und Weise ist es, die Funktion main () in C und C ++ zu definieren - int main () oder void main () - und warum
Diese Worte „(sehr effizient)“ nicht die Frage ändern. Sofern Sie in einer frei stehenden Umgebung sind, dann gibt es einen universell richtigen Weg main()
zu erklären, und das ist als int zurück.
Was in C und C
main()
Rückkehr sollte ++?
Es ist nicht das, was sollte main()
Rückkehr, es ist, was hat main()
Rückkehr. main()
ist, natürlich, eine Funktion, dass jemand anderes Anrufe. Sie haben keine Kontrolle über den Code, der main()
aufruft. Daher müssen Sie main()
mit einem Typ-korrekte Signatur deklarieren seine Anrufer anzupassen. Sie haben einfach keine andere Wahl in der Angelegenheit. Sie müssen sich nicht fragen, was mehr oder weniger effizient, oder was ist besser oder schlechter Stil, oder so etwas, weil die Antwort schon ganz genau definiert ist, für Sie, die von den C und C + -Standards. Gerade ihnen folgen.
Wenn int main () dann 1 zurückzukehren oder 0 zurück?
0 für den Erfolg, ungleich Null für das Scheitern. Auch hier nicht etwas, müssen Sie (oder erhalten zu) wählen: Es wird von der Schnittstelle definiert ist du sollst werden konformen
.Hier ist eine kleine Demonstration der Verwendung von Rückgabecodes ...
Wenn die verschiedenen Tools, die das Linux-Terminal bietet man den Return-Code beispielsweise für die Fehlerbehandlung verwendet werden kann, nachdem der Prozess abgeschlossen ist. Stellen Sie sich vor, dass die folgende Textdatei Meinedat vorhanden ist:
Dies ist ein Beispiel einer um wie grep Arbeiten zu überprüfen.
Wenn Sie den grep-Befehl ausführen ein Prozess erstellt wird. Sobald es durch (und nicht brechen) es einen Code zwischen 0 zurück und 255. Zum Beispiel:
$ grep order myfile
Wenn Sie das tun
$ echo $?
$ 0
Sie erhalten eine 0 Warum? Da grep gefunden eine Übereinstimmung und ergab einen Exit-Code 0, die zum Verlassen mit einem der üblichen Wert ist Erfolg. Lassen Sie sich wieder, aber mit etwas, das nicht in unserer Textdatei ist und somit wird keine Übereinstimmung gefunden werden:
$ grep foo myfile
$ echo $?
$ 1
Da grep das Token „foo“ mit dem Inhalt unserer Datei der Return-Code übereinstimmen ausgefallen ist 1 (dies ist der Normalfall, wenn ein Fehler auftritt, aber wie oben angegeben Sie genügend Werte zur Auswahl).
Nun ist der folgende Bash-Skript (einfach in einem Terminal Linux Typ), obwohl sehr einfach eine Vorstellung von Fehlerbehandlung geben soll:
$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'
$ [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found
Nach der zweiten Linie nichts mit der Klemme, da „foo“ gemacht grep return 1 gedruckt und wir überprüfen, ob der Return-Code von grep gleich war 0. Die zweite bedingte Anweisung erinnert an seine Botschaft in der letzten Zeile, da es wahr ist, aufgrund PRÜFEN == 1.
Wie Sie sehen können, wenn Sie dies fordern und dieser Prozess ist es manchmal wichtig zu sehen, was es zurückgekehrt ist (durch den Rückgabewert von main ()).