Co powinno zwracać main() w C i C++?

Jaki jest prawidłowy (najbardziej efektywny) sposób definiowania funkcji main() W C i C++ - int main() lub void main() - i dlaczego? If int main() then return 1 or return 0?


istnieje wiele duplikatów tego pytania, w tym:

Powiązane:

Author: Community, 2008-10-15

18 answers

Wartość zwracana dla {[3] } powinna wskazywać sposób zakończenia programu. Normalne wyjście jest zazwyczaj reprezentowane przez wartość zwracaną 0 z main. Anormalne zakończenie jest zwykle sygnalizowane niezerowym zwrotem, ale nie ma standardu interpretowania niezerowych kodów. Również jak zauważyli inni, {[5] } jest wyraźnie zabronione przez standard C++ i nie powinno być używane. Poprawne podpisy C++ main to:

int main()

I

int main(int argc, char* argv[])

Co jest równoważne

int main(int argc, char** argv)

To warto również zauważyć, że w C++, int main() może być pozostawiony bez zwracanej wartości, w którym momencie domyślnie zwraca 0. Dotyczy to również programu C99. Kwestia, czy return 0 powinien być pominięty, czy nie, podlega dyskusji. Zakres ważnych sygnatur głównych programu C jest znacznie większy.

Również wydajność nie jest problemem z funkcją main. Można go wprowadzić i pozostawić tylko raz (oznaczanie rozpoczęcia i zakończenia programu) zgodnie ze standardem C++. Dla C sprawa jest inna i ponowne wejście main() jest dozwolone, ale prawdopodobnie powinno być unikane.

 478
Author: workmad3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-22 13:49:38

Przyjęta odpowiedź wydaje się być skierowana do C++, więc pomyślałem, że dodam odpowiedź, która odnosi się do C, a to różni się na kilka sposobów.

ISO/IEC 9899:1989 (C90):

main() należy zadeklarować jako:

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

Lub równoważne. Na przykład int main(int argc, char *argv[]) jest odpowiednikiem drugiego. Co więcej, typ zwracany int może zostać pominięty, ponieważ jest to wartość domyślna.

Jeśli implementacja na to pozwala, main() Można zadeklarować w inny sposób, ale to sprawia, że program implementacja zdefiniowana, a nie ściśle zgodna.

Standard definiuje 3 wartości dla zwracania, które są ściśle zgodne (tzn. nie zależą od zachowania zdefiniowanego w implementacji): 0 i EXIT_SUCCESS dla pomyślnego zakończenia i EXIT_FAILURE dla nieudanego zakończenia. Wszelkie inne wartości są niestandardowe i zdefiniowane w implementacji. main() musi mieć wyraźne return oświadczenie na końcu, aby uniknąć niezdefiniowanego zachowania.

Wreszcie, nie ma nic złego z standardowy punkt widzenia z wywołaniem main() z programu.

ISO/IEC 9899:1999 (C99):

Dla C99 wszystko jest takie samo jak wyżej z wyjątkiem:

  • typ int return nie może być pominięty.
  • możesz pominąć deklarację powrotu z main(). Jeśli to zrobisz i main() skończysz, istnieje implicit return 0.
 140
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-05 17:45:56

Standard C-Hosted Environment

W przypadku środowiska hostowanego standard C11 (ISO/IEC 9899:2011) mówi:]}

5.1.2.2.1 uruchamianie programu

Funkcja wywoływana przy starcie programu nosi nazwę main. Realizacja deklaruje nie prototyp dla tej funkcji. Definiuje się go za pomocą typu zwrotu int i bez parametry:

int main(void) { /* ... */ }

Lub z dwoma parametrami (zwanymi tutaj argc i argv, choć wszelkie nazwy mogą być w związku z tym, że są one lokalne do funkcji, w której są deklarowane):

int main(int argc, char *argv[]) { /* ... */ }

Lub równoważny;10) lub w inny sposób określony w implementacji.

Jeśli są zadeklarowane, parametry funkcji głównej są następujące ograniczenia:

  • wartość argc jest nonnegatywna.
  • argv[argc] jest wskaźnikiem zerowym.
  • jeśli wartość argc jest większa niż zero, członkowie tablicy argv[0] przez argv[argc-1] inclusive zawiera wskaźniki do łańcuchów, które są podane implementacja - zdefiniowane wartości przez środowisko hosta przed uruchomieniem programu. Na intencją jest dostarczenie do programu informacji określonych przed uruchomieniem programu z innego miejsca w środowisku hostowanym. Jeśli środowisko hosta nie jest w stanie dostarczanie ciągów z literami zarówno wielkimi, jak i małymi literami, implementacja zapewnia, że ciągi są odbierane w małe litery.
  • jeśli wartość {[13] } jest większa od zera, łańcuch wskazywany przez argv[0] reprezentuje nazwę programu; argv[0][0] jest znakiem null, jeśli nazwa programu nie jest dostępna w środowisku hosta. Jeśli wartość argc jest więcej niż jeden, ciągi wskazywane przez argv[1] przez argv[argc-1] reprezentują parametry programu.
  • parametry argc i argv oraz łańcuchy wskazywane przez tablicę argv powinny być modyfikowane przez programu, i zachowują swoje ostatnio zapisane wartości pomiędzy programem uruchomienie i zakończenie programu.

10) Tak więc, int można zastąpić nazwą typedef zdefiniowaną jako int, lub typ argv można zapisać jako char **argv, i tak dalej.

Zakończenie programu w C99 lub C11

Wartość zwrócona z {[33] } jest przekazywana do 'środowiska' w sposób zdefiniowany przez implementację.

5.1.2.2.3 Program wypowiedzenie

1 Jeśli typ zwracanej funkcji main jest typem zgodnym z int, zwraca się z początkowe wywołanie funkcji main jest równoważne wywołaniu funkcji exit o wartości zwracana przez funkcję main jako jej argument;11) dotarcie do }, które kończy main funkcja zwraca wartość 0. Jeśli Typ powrotu nie jest zgodny z int, status zakończenia zwrócony do środowiska hosta to nieokreślone.

11) zgodnie z 6.2.4, żywotność obiektów z automatycznym czasem przechowywania zadeklarowanym w main skończy się w pierwszym przypadku, nawet jeśli nie byłoby ich w drugim.

Zauważ, że 0 jest wymagane jako "sukces". Możesz użyć EXIT_FAILURE i EXIT_SUCCESS z <stdlib.h>, jeśli wolisz, ale 0 jest dobrze ugruntowane, podobnie jak 1. Zobacz także kody wyjścia większe niż 255 - możliwe?.

W C89 (a więc w Microsoft C), nie ma instrukcji o tym, co się stanie, jeśli funkcja main() zwróci, ale nie określa wartości zwracanej; dlatego prowadzi do niezdefiniowanego zachowania.

7.22.4.4 funkcja exit

¶5 na koniec kontrola jest zwracana do środowiska hosta. Jeśli wartość status wynosi zero lub EXIT_SUCCESS, zwracana jest zdefiniowana w implementacji forma statusu pomyślne zakończenie. Jeśli wartość status wynosi EXIT_FAILURE, postać zdefiniowana w implementacji zwracany jest status nieudane zakończenie. W przeciwnym razie zwracany status jest zdefiniowany w implementacji.

Standardowe Środowisko C++ - Hostowane

[[115]} standard C++11 (ISO/IEC 14882:2011) mówi:

3.6.1 funkcja główna [basic.zaczynaj.main]

¶1 program zawiera globalną funkcję o nazwie main, która jest wyznaczonym startem programu. [...]

¶2 implementacja nie powinna predefiniować główna funkcja. Funkcja ta nie może być przeciążona. On ma typ zwracany typu int, ale poza tym jego typ jest zdefiniowany w implementacji. Wszystkie wdrożenia dopuszcza obie z następujących definicji main:

int main() { /* ... */ }

I

int main(int argc, char* argv[]) { /* ... */ }

W tej ostatniej formie argc jest liczbą argumentów przekazywanych programowi ze środowiska w którym program jest uruchamiany. Jeśli argc jest niezerowe, argumenty te należy podać w argv[0] przez argv[argc-1] jako wskaźniki do początkowych znaków zakończonych znakiem null łańcuchów wielobajtowych (ntmbss) (17.5.2.1.4.2) i argv[0] jest wskaźnikiem do początkowego znaku NTMBS, który reprezentuje nazwa używana do wywołania programu lub "". Wartość argc jest nieujemna. Wartość argv[argc] wynosi 0. [Uwaga: zaleca się dodanie dodatkowych (opcjonalnych) parametrów po argv. - end Uwaga]

¶3 funkcja main nie może być używana w programie. Na linkage (3.5) of main is implementation-defined. [...]

¶5 polecenie return W main powoduje opuszczenie funkcji main (zniszczenie dowolnych obiektów za pomocą automatycznego storage duration) i wywołanie std::exit z wartością zwracaną jako argumentem. Jeśli kontrola dotrze do końca z main bez napotkania instrukcji return, efektem jest wykonanie

return 0;

Standard C++ jawnie mówi " It [the main function] shall have a return type of type int, ale poza tym jego typ jest zdefiniowany jako implementacja " i wymaga tych samych dwóch podpisów, co standard C, aby były obsługiwane jako opcje. Tak więc 'void main ()' nie jest bezpośrednio dozwolony przez standard C++, choć nie ma nic, co może zrobić, aby zatrzymać niestandardową implementację pozwalającą na alternatywy. Zauważ, że C++ zabrania użytkownikowi wywoływania main (ale standard C tego nie robi).

Jest paragraf §18.5 Start i zakończenie w standardzie C++11, który jest identyczna z paragrafem z §7.22.4.4 funkcja exit w standardzie C11 (przytoczonym powyżej), z wyjątkiem przypisu (który po prostu dokumentuje, że EXIT_SUCCESS i EXIT_FAILURE są zdefiniowane w <cstdlib>).

Standardowe Rozszerzenie C-Wspólne

Klasycznie Systemy Unix wspierają trzeci wariant:

int main(int argc, char **argv, char **envp) { ... }

Trzeci argument jest zakończoną znakiem null listą wskaźników do łańcuchów znaków, z których każdy jest zmienną środowiskową, która ma nazwę, znak równości i wartość (ewentualnie pusty). Jeśli nie użyjesz tego, nadal możesz dostać się do środowiska za pomocą " extern char **environ;". Przez długi czas nie miał nagłówka, który ją zadeklarował, ale standard POSIX 2008 wymaga teraz, aby została zadeklarowana w <unistd.h>.

Jest to uznawane przez standard C jako wspólne rozszerzenie, udokumentowane w załączniku J:

J. 5. 1 argumenty środowiskowe

¶1 w środowisku hostowanym, główna funkcja otrzymuje trzeci argument, char *envp[], że wskazuje na zakończoną znakiem NUL tablicę wskaźników do char, z których każdy wskazuje na ciąg znaków który dostarcza informacji o środowisku dla tego wykonania programu (5.1.2.2.1).

Microsoft C

Kompilator Microsoft VS 2010 jest interesujący. Strona mówi:

Składnia deklaracji dla main to

 int main();

Lub, opcjonalnie,

int main(int argc, char *argv[], char *envp[]);

Alternatywnie, funkcje main i wmain mogą być zadeklarowana jako zwracająca void (brak wartości zwracanej). Jeśli zadeklarujesz main lub wmain jako zwracający void, nie możesz zwrócić kodu zakończenia procesowi nadrzędnemu lub systemowi operacyjnemu za pomocą instrukcji return. Aby zwrócić kod wyjścia, gdy main lub wmain jest zadeklarowane jako void, musisz użyć funkcji exit.

Nie jest dla mnie jasne, co się dzieje (jaki kod wyjścia jest zwracany do rodzica lub systemu operacyjnego), gdy program z void main() kończy pracę - a strona MS milczy też.

Co ciekawe, MS nie przepisuje dwuargumentowej wersji main(), której wymagają standardy C i C++. Poleca tylko formę trzech argumentów, gdzie trzecim argumentem jest char **envp, wskaźnik do listy zmiennych środowiskowych.

Strona Microsoftu wymienia również inne alternatywy - wmain(), która przyjmuje szerokie ciągi znaków i kilka innych.

Microsoft Visual Studio 2005 wersja ta strona nie zawiera void main() jako alternatywa. Wersje od Microsoftu Visual Studio 2008

Standard C-Środowisko Wolnostojące

Jak już wspomniano, powyższe wymagania dotyczą środowisk hostowanych. Jeśli pracujesz ze środowiskiem wolnostojącym (które jest alternatywą dla środowiska hostowanego), standard ma znacznie mniej do powiedzenia. Dla środowiska wolnostojącego funkcja wywoływana przy starcie programu nie musi być wywoływana main i nie ma ograniczeń co do jego typu zwrotu. Standard mówi:

5.1.2 środowiska wykonawcze

Zdefiniowano dwa środowiska wykonawcze: wolnostojące i hostowane. W obu przypadkach, uruchomienie programu następuje, gdy określona funkcja C jest wywoływana przez wykonanie środowisko. Wszystkie obiekty o statycznym czasie przechowywania powinny być zainicjalizowane (ustawione na ich początkowe wartości) przed uruchomieniem programu. Sposób i czas takiej inicjalizacji są inaczej nieokreślone. Zakończenie programu zwraca kontrolę do środowiska wykonawczego.

5.1.2.1 środowisko wolnostojące

W środowisku wolnostojącym (w którym wykonywanie programu C może odbywać się bez żadnych korzyści z systemu operacyjnego), nazwa i typ funkcji wywoływanej przy starcie programu są zdefiniowane jako implementacja. Wszelkie urządzenia biblioteczne dostępne dla programu wolnostojącego, inne niż minimalny zestaw wymagany w punkcie 4, są implementacja-zdefiniowana.

Efekt zakończenia programu w środowisku wolnostojącym jest zdefiniowany przez implementację.

Odsyłacz do klauzuli 4 odnosi się do tego:

¶5 a ściśle zgodny program powinien używać tylko tych cech języka i biblioteki określonych w niniejszym międzynarodowym standardzie.3) nie może wytwarzać produkcji zależnej od jakichkolwiek nieokreślonych, nieokreślonych lub zachowanie zdefiniowane w implementacji i nie może przekraczać żadnego minimalnego limitu implementacji.

¶6 dwie formy zgodnej implementacji to hostowane i wolnostojące . zgodna hostowana implementacja akceptuje każdy ściśle zgodny program. zgodna implementacja wolnostojąca akceptuje każdy ściśle zgodny program, w którym korzystanie z funkcji określonych w klauzuli bibliotecznej (klauzula 7) ogranicza się do zawartość standardowych nagłówków <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, oraz <stdnoreturn.h>. Zgodna implementacja może mieć rozszerzenia (w tym dodatkowe funkcje biblioteczne), pod warunkiem, że nie zmieniają zachowania żadnego ściśle zgodnego programu.4)

¶7 a zgodny program jest programem akceptowalnym dla zgodnej implementacji.5)

3) ściśle zgodny program może korzystać z funkcji warunkowych (zob. 6.10.8.3) pod warunkiem, że stosowanie jest chronione przez odpowiednią dyrektywę wstępnego przetwarzania warunkowego włączenia przy użyciu odpowiedniego makra. Na przykład:

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
    /* ... */
    fesetround(FE_UPWARD);
    /* ... */
#endif

4) oznacza to, że zgodne wdrożenie nie rezerwuje identyfikatorów innych niż te wyraźnie zastrzeżone w niniejszym standardzie międzynarodowym.

5) programy ściśle zgodne są przeznaczone do maksymalnej przenośności wśród zgodnych implementacji. Programy zgodne mogą zależeć od nie przenośnych cech zgodnej implementacji.

Zauważalne jest, że jedynym nagłówkiem wymaganym w środowisku wolnostojącym, które definiuje dowolne funkcje, jest <stdarg.h> (a nawet te mogą być - i często są-tylko makrami).

Standard C++ - Środowisko Wolnostojące

Tak jak standard C rozpoznaje zarówno środowisko hostowane, jak i wolnostojące, tak samo jak standard C++. (Cytaty z ISO / IEC 14882:2011.)

1.4 zgodność z implementacją [intro.zgodność]

¶7 zdefiniowano dwa rodzaje implementacji: implementację hostowaną oraz implementację wolnostojącą. Dla implementacji hostowanej ten międzynarodowy Standard definiuje zestaw dostępnych bibliotek. Wolnostojący implementacja to taka, w której wykonanie może odbywać się bez korzyści systemu operacyjnego i ma zdefiniowany przez implementację zestaw biblioteki zawierające niektóre biblioteki obsługujące język (17.6.1.3).

¶8 zgodna implementacja może mieć rozszerzenia (w tym dodatkowe funkcje biblioteczne), pod warunkiem, że nie zmieniają zachowania żadnego dobrze uformowanego programu. Wdrożenia są wymagane do diagnozowania programów, które używaj takich rozszerzeń, które są źle uformowane zgodnie z tym międzynarodowym standardem. Po wykonaniu tych czynności mogą jednak kompilować i uruchamiać takie programy.

¶9 implementacja powinna zawierać dokumentację, która identyfikuje wszystkie konstrukcje wspierane warunkowo, których nie obsługuje, oraz określa wszystkie charakterystyczne cechy lokalne.3

3) dokumentacja ta definiuje również zachowanie zdefiniowane przez implementację; patrz 1.9.

17.6.1.3 implementacje wolnostojące [zgodność]

Definiuje się dwa rodzaje implementacji: hostowaną i wolnostojącą (1.4). Dla hostowanej implementacji, to Międzynarodowy Standard opisuje zestaw dostępnych nagłówków.

Implementacja wolnostojąca ma zdefiniowany przez implementację zestaw nagłówków. Zestaw ten obejmuje co najmniej nagłówki przedstawione w tabeli 16.

Dostarczona wersja nagłówka {[70] } deklaruje co najmniej funkcje abort, atexit, at_quick_exit, exit, i quick_exit (18.5). Pozostałe nagłówki wymienione w niniejszej tabeli muszą spełniać te same wymagania co w przypadku implementacji hostowanej.

Tabela 16-nagłówki C++ dla implementacji wolnostojących

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>

A co z użyciem int main() W C?

Norma §5.1.2.2.1 normy C11 pokazuje preferowaną notację - int main(void) - ale są też dwa przykłady w normie, które pokazują int main(): §6.5.3.4 ¶8 oraz §6.7.6.3 ¶20. Teraz należy zauważyć, że przykłady nie są "normatywne", są jedynie ilustracyjne. Jeśli w przykładach są błędy, to nie bezpośrednio wpływa na główny tekst standardu. To powiedziawszy, są one silnie wskazujące na oczekiwane zachowanie, więc jeśli standard zawiera int main() w przykładzie, sugeruje to, że int main() nie jest zabronione, nawet jeśli nie jest to preferowana notacja.

6.5.3.4 operatory sizeof i _Alignof

¶8 przykład 3 w tym przykładzie rozmiar tablicy o zmiennej długości jest obliczany i zwracany z funkcji:

#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;
}
 102
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 00:43:05

Uważam, że main() powinien zwrócić EXIT_SUCCESS lub EXIT_FAILURE. Są one zdefiniowane w stdlib.h

 57
Author: dmityugov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-28 03:31:37

Zauważ, że standardy C i C++ definiują dwa rodzaje implementacji: wolnostojące i hostowane.

  • C90 hosted environment

    Dozwolone formularze 1:

    int main (void)
    int main (int argc, char *argv[])
    
    main (void)
    main (int argc, char *argv[])
    /*... etc, similar forms with implicit int */
    

    Komentarze:

    Dwie pierwsze są jawnie określone jako dozwolone formy, pozostałe są niejawnie dozwolone, ponieważ C90 zezwala na "implicit int" dla zwracanego typu i parametrów funkcji. Żadna inna forma nie jest dozwolona.

  • C90 wolnostojący środowisko

    Każda forma lub nazwa main jest dozwolona 2.

  • C99 hosted environment

    Dozwolone formularze 3:

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    

    Komentarze:

    C99 usunięto "implicit int" więc {[13] } nie jest już ważne.

    Wprowadzono dziwne, niejednoznaczne zdanie "lub w jakiś inny sposób określony w implementacji". Może to być interpretowane jako "parametry int main() mogą się różnić "lub jako" main może mieć dowolne formularz wdrożeniowy".

    Niektóre Kompilatory zdecydowały się zinterpretować standard w ten drugi sposób. Prawdopodobnie nie można łatwo stwierdzić, że nie są one ściśle zgodne, powołując się na normę samą w sobie, ponieważ jest ona niejednoznaczna.

    Jednak, aby umożliwić całkowicie Dzikie formy main() było prawdopodobnie (?) nie intencją tego nowego zdania. Logika C99 (nie normatywna) zakłada, że zdanie odnosi się do dodatkowych parametrów int main 4.

    Jednak sekcja dla programu hosted environment kończy się, a następnie kłóci się o przypadek, w którym main nie zwraca int 5. Chociaż ta sekcja nie jest normatywna dla tego, jak Main powinien być zadeklarowany, to zdecydowanie oznacza to, że main może być zadeklarowany w całkowicie zdefiniowany sposób implementacji, nawet na systemach hostowanych.

  • C99 środowisko wolnostojące

    Każda forma lub nazwa main jest dozwolona 6.

  • C11 hosted environment

    Dozwolone formularze 7:

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    
  • C11 środowisko wolnostojące

    Każda forma lub nazwa main jest dozwolona 8.


Zauważ, że int main() nigdy nie została wymieniona jako poprawna forma dla żadnej hostowanej implementacji C w żadnej z powyższych wersji. W C, w przeciwieństwie do C++, () i (void) mają różne znaczenia. Ten pierwszy jest przestarzały funkcja, która może zostać usunięta z języka. Zobacz C11 przyszłe kierunki językowe:

6.11.6 deklaratory funkcji

Używanie deklaratorów funkcji z pustymi nawiasami (nie deklaratorów typu parametru prototype-format) jest funkcją przestarzałą.


  • C++03 hosted environment

    Dozwolone formularze 9:

    int main ()
    int main (int argc, char *argv[])
    

    Komentarze:

    Zwróć uwagę na pusty nawias w pierwszej formie. C++ i C są w tym przypadku różne, ponieważ w C++ oznacza to, że funkcja nie pobiera żadnych parametrów. Ale w C oznacza to, że może przyjmować dowolny parametr.

  • C++03 środowisko wolnostojące

    Nazwa funkcji wywoływanej przy starcie jest zdefiniowana w implementacji. Jeśli ma nazwę main() musi spełniać podane formularze 10:

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    
  • C++11 hosted environment

    Dozwolone formularze 11:

    int main ()
    int main (int argc, char *argv[])
    

    Komentarze:

    Tekst normy został zmieniony, ale ma to samo znaczenie.

  • Środowisko wolnostojące C++11

    Nazwa funkcji wywoływanej przy starcie jest zdefiniowana w implementacji. Jeśli ma nazwę main() musi spełniać podane formularze 12:

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    

Referencje

  1. ANSI X3.159-1989 2.1.2.2 Hosted environment. "Program startup "

    Funkcja wywoływana przy starcie programu nosi nazwę main. Na implementacja nie deklaruje prototypu dla tej funkcji. Należy zdefiniowany z typem zwrotnym int i bez parametrów:

    int main(void) { /* ... */ } 
    

    Lub z dwoma parametrami (określanymi tutaj jako argc i argv, choć można używać dowolnych nazw, ponieważ są one lokalne do funkcja, w której są zadeklarowane):

    int main(int argc, char *argv[]) { /* ... */ }
    
  2. ANSI X3. 159-1989 2.1.2.1 wolnostojący środowisko:

    W środowisku wolnostojącym (w którym wykonanie programu C może miejsce bez żadnych korzyści z systemu operacyjnego), nazwę i typ funkcji wywoływanych przy starcie programu są zdefiniowane w implementacji.

  3. ISO 9899: 1999 5.1.2.2 środowisko hostowane -> 5.1.2.2.1 uruchamianie programu

    Funkcja wywoływana przy starcie programu nosi nazwę main. Na implementacja nie deklaruje prototypu dla tej funkcji. Informatyka będzie zdefiniowany z typem zwrotnym int i bez parametrów:

    int main(void) { /* ... */ } 
    

    Lub z dwoma parametrami (określanymi tutaj jako argc i argv, choć można używać dowolnych nazw, ponieważ są one lokalne do funkcja, w której są zadeklarowane):

    int main(int argc, char *argv[]) { /* ... */ }
    

    Lub równoważne; 9) lub w jakiejś innej implementacji-zdefiniowanej sposób.

  4. Uzasadnienie dla międzynarodowych standardów-języki programowania-C, Wersja 5.10. 5.1.2.2 Środowisko hostowane -- > 5.1.2.2.1 uruchamianie programu

    Zachowanie argumentów do main i interakcja exit, main i atexit (zob. §7.20.4.2) został skodyfikowany w celu ograniczenia niepożądanej odmiany w reprezentacji argv łańcuchów, a w znaczeniu wartości zwracanych przez main.

    Specyfikacja argc i argv jako argumentów do main rozpoznaje rozległą wcześniejszą praktykę. argv [argc] musi być wskaźnikiem null, aby zapewnić kontrolę nadmiarową na koniec listy, również w oparciu o powszechną praktykę.

    Main jest jedyną funkcją, która może być zadeklarowana z zero lub dwoma argumentami. (Liczba argumentów innych funkcji musi być dokładnie zgodna pomiędzy wywołaniem i definicją.) Ten szczególny przypadek po prostu rozpoznaje powszechną praktykę pomijania argumentów na main, gdy program nie ma dostępu do łańcuchów argumentów programu. Podczas gdy wiele implementacji wspiera więcej niż dwa argumenty do main, taka praktyka nie jest ani błogosławiona, ani zabroniona przez Standard; program, który definiuje main z trzema argumentami, nie jest ściśle zgodny (patrz §J. 5. 1.).

  5. ISO 9899: 1999 5.1.2.2 środowisko hostowane --> 5.1.2.2.3 zakończenie programu

    Jeśli zwracany typ funkcji głównej jest typem zgodnym z int, to powrót z początkowego wywołania do funkcji głównej jest równoważny wywołaniu funkcji exit z wartością zwracaną przez funkcję główną jako jej argument; 11) dotarcie do }, które kończy główną funkcję Zwraca wartość 0. Jeśli typ zwracany nie jest zgodny z int, status zakończenia zwracany do środowiska hosta jest nieokreślony.

  6. ISO 9899: 1999 5.1.2.1 środowisko wolnostojące

    W środowisku wolnostojącym (w którym wykonywanie programu C może odbywać się bez żadnych korzyści z systemu operacyjnego), nazwa i typ funkcji wywoływanej przy starcie programu są zdefiniowane w implementacji.

  7. ISO 9899: 2011 5.1.2.2 środowisko hostowane -> 5.1.2.2.1 uruchamianie programu

    Ta sekcja jest identyczna z cytowaną powyżej C99.

  8. ISO 9899: 1999 5.1.2.1 środowisko wolnostojące

    Ta sekcja jest identyczna z cytowaną powyżej C99.

  9. ISO 14882: 2003 3.6.1 funkcja główna

    Implementacja nie predefiniuje funkcji głównej. Funkcja ta nie może być przeciążony. Ma typ zwracany typu int, ale poza tym jego typ jest zdefiniowany w implementacji. Wszystkie implementacje dopuszczają obie z następujących definicji main:

    int main() { /* ... */ }
    

    I

    int main(int argc, char* argv[]) { /* ... */ }
    
  10. ISO 14882: 2003 3.6.1 funkcja główna

    Definiuje się, czy program w środowisku wolnostojącym jest wymagany do zdefiniowania głównej funkcji.

  11. ISO 14882:2011 3.6.1 funkcja główna

    Implementacja nie predefiniuje funkcji głównej. Funkcja ta nie może być przeciążona. Ma typ zwracany typu int, ale poza tym jego typ jest zdefiniowany w implementacji. Wszystkie wdrożenia Zezwól na oba

    - funkcja () zwracająca int i

    - funkcja (int, pointer to pointer to char) zwracająca int

    Jako typ main (8.3.5).

  12. ISO 14882:2011 3.6.1 funkcja główna

    Ta sekcja jest identyczna z cytowanym wyżej C++03.

 29
Author: Lundin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 07:08:17

Zwraca 0 W przypadku sukcesu i niezerowy w przypadku błędu. Jest to standard używany przez skrypty UNIX i DOS, aby dowiedzieć się, co stało się z Twoim programem.

 27
Author: Lou Franco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 12:16:51

Pamiętaj, że nawet jeśli zwracasz int, niektóre systemy operacyjne (Windows) obcinają zwracaną wartość do pojedynczego bajtu (0-255).

 7
Author: Ferruccio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 15:22:13

main() w C89 i K&R nieokreślone typy zwracane Domyślnie to 'int'.

return 1? return 0?
  1. Jeśli nie napiszesz instrukcji return w int main(), zamknięcie { domyślnie zwróci 0.

  2. return 0 lub return 1 zostaną odebrane przez proces macierzysty. W powłoce przechodzi ona do zmiennej powłoki, a jeśli uruchamiasz swój program tworząc powłokę i nie używasz tej zmiennej, to nie musisz się martwić o wartość zwracaną main().

Zobacz Jak można Dostaję to, co moja główna funkcja powróciła?.

$ ./a.out
$ echo $?

W ten sposób można zobaczyć, że to zmienna $? otrzymuje najmniej znaczący bajt zwracanej wartości main().

W skryptach uniksowych i DOS-owych, return 0 W przypadku sukcesu i niezerowych błędów są zwykle zwracane. Jest to standard używany przez skrypty Unix i DOS, aby dowiedzieć się, co stało się z programem i kontrolować cały przepływ.

 7
Author: Jeegar Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 00:14:24

Wartość zwracana może być użyta przez system operacyjny do sprawdzenia, jak program został zamknięty.

Wartość zwracana 0 zwykle oznacza OK w większości systemów operacyjnych(te, o których i tak myślę).

Można to również sprawdzić, gdy sam wywołujesz proces i sprawdzasz, czy program zakończył działanie i zakończył się poprawnie.

To nie tylko konwencja programowania.

 4
Author: Yochai Timmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-13 15:14:22

Wartość zwracana main() pokazuje sposób zakończenia programu. Jeśli zwracana wartość to zero, oznacza to, że wykonanie zakończyło się sukcesem, podczas gdy każda niezerowa wartość będzie oznaczać, że coś poszło źle w wykonaniu.

 3
Author: Fahad Uddin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-13 15:14:52

Byłem pod wrażeniem, że standard określa, że main nie potrzebuje zwracanej wartości, ponieważ pomyślny zwrot był oparty na systemie operacyjnym (zero W Jednym może być sukcesem lub porażką w innym), dlatego brak zwrotu był sygnałem dla kompilatora do wstawienia pomyślnego zwrotu.

Jednak zwykle zwracam 0.

 2
Author: graham.reeds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 12:42:47

Zwrócenie 0 powinno informować programistę o pomyślnym zakończeniu zadania.

 2
Author: Vamsi Pavan Mahesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-13 15:18:42

To, co zwrócić, zależy od tego, co chcesz zrobić z plikiem wykonywalnym. Na przykład, jeśli używasz programu z powłoką wiersza poleceń, musisz zwrócić 0 dla sukcesu i niezerową dla niepowodzenia. Wtedy byĹ 'oby moĹźliwoĹ" Ä ‡ uĹźycia programu w powĺ 'okach z warunkowym przetwarzaniem w zaleĹźnoĹ" ci od wyniku kodu. Możesz również przypisać dowolną wartość niezerową zgodnie z Twoją interpretacją, na przykład w przypadku błędów krytycznych różne punkty wyjścia programu mogą zakończyć program z różnymi wartość ta jest dostępna dla wywołującej powłoki, która może zdecydować, co zrobić, sprawdzając zwróconą wartość. JeĹ "li kod nie jest przeznaczony do uĹźycia z powĺ' okami i zwracana wartoĹ " Ä ‡ nikomu nie przeszkadza, moĹźe zostaÄ ‡ pominiÄ ™ ty. Osobiście używam podpisu int main (void) { .. return 0; .. }

 1
Author: phoxis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-28 03:32:13

Jeśli naprawdę masz problemy związane z efektywnością zwracania liczby całkowitej z procesu, prawdopodobnie powinieneś unikać wywoływania tego procesu tyle razy, że ta zwracana wartość staje się problemem.

Jeśli to robisz (wywołujesz proces tak wiele razy), powinieneś znaleźć sposób, aby umieścić swoją logikę bezpośrednio w wywołującym lub w pliku DLL, bez przydzielania określonego procesu dla każdego połączenia; wiele alokacji procesów przynosi odpowiedni problem wydajności w tym case.

W szczegółach, jeśli chcesz wiedzieć tylko, czy zwracanie 0 jest mniej lub bardziej efektywne niż zwracanie 1, w niektórych przypadkach może zależeć od kompilatora, ale ogólnie, zakładając, że są one odczytywane z tego samego źródła (lokalnego, pola, stałej, osadzonego w kodzie, wyniku funkcji, itp.) wymaga dokładnie takiej samej liczby cykli zegara.

 1
Author: Luca C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-13 15:12:55

Jaki jest poprawny (najbardziej efektywny) sposób definiowania funkcji main() w C i C++ - int main() lub void main() - i dlaczego?

Te słowa "(najskuteczniejszy) " nie zmieniają pytania. Jeśli nie jesteś w środowisku wolnostojącym, istnieje jeden powszechnie poprawny sposób deklarowania main(), a to jako zwracanie int.

Co powinno main() zwracać w C i C++?

It 's not what should main() return, it' s what does main() return. main() jest oczywiście funkcją, którą ktoś inny wywołuje. Nie masz żadnej kontroli nad kodem, który wywołuje main(). Dlatego musisz zadeklarować main() z podpisem poprawnym do typu, aby pasował do jego wywołującego. Po prostu nie masz wyboru w tej sprawie. Nie musisz zadawać sobie pytania, co jest mniej lub bardziej efektywne, co jest lepsze lub gorsze, czy coś w tym stylu, ponieważ odpowiedź jest już dla ciebie doskonale zdefiniowana przez standardy C i C+. Just follow oni.

If int main () then return 1 or return 0?

0 za sukces, nonzero za porażkę. Ponownie, nie coś, co musisz (lub dostać się) wybrać: to jest zdefiniowane przez interfejs, który powinieneś być zgodny z.

 1
Author: Steve Summit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-03 21:56:28

W C++ funkcja main powinna być zadeklarowana jako int main (), a nie void main (), ponieważ kompilator wyrzuca błąd w przypadku void main. Funkcja main może przyjmować dowolną liczbę argumentów, takich jak int main(int K, Int l, int arr []) lub int main (void).

#include <iostream>
using namespace std;

int main(void) {
    // your code goes here
    cout<<"a";
    return 0;
}

Wyjście:

Success #stdin #stdout 0s 4416KB
a

Przechodząc do części return powinien zwrócić tylko 0, w przeciwnym razie kompilator wyrzuca błąd. na przykład, jeśli zwrócisz 1, otrzymasz żądane wyjście, ale również rzuca runtime błąd.

Przykład

#include <iostream>
using namespace std;

int main(int k,float m,char g, int arr[]) {
    // your code goes here
    k=0;
    cout<<k;
    g='a';
    cout<<g;
    cout<<"a";
    return 1;
}

Wyjście:

Runtime error   #stdin #stdout 0s 4448KB
0aa
 1
Author: Somit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-23 05:26:23

Oto mała demonstracja użycia kodów zwrotnych...

Podczas korzystania z różnych narzędzi, które dostarcza Terminal Linuksa, można użyć kodu zwrotnego, na przykład do obsługi błędów po zakończeniu procesu. Wyobraź sobie, że obecny jest następujący plik tekstowy myfile:

Jest to przykład, aby sprawdzić, jak działa grep.

Podczas wykonywania polecenia grep tworzony jest proces. Po przejściu (i nie złamaniu) zwraca jakieś Kod od 0 do 255. Na przykład:

$ grep order myfile

If you do

$ echo $?
$ 0

Dostaniesz 0. Dlaczego? Ponieważ grep znalazł dopasowanie i zwrócił kod wyjścia 0, który jest zwykłą wartością dla wyjścia z sukcesem. Sprawdźmy to jeszcze raz, ale z czymś, co nie znajduje się w naszym pliku tekstowym i tym samym nie zostanie znalezione dopasowanie:

$ grep foo myfile
$ echo $?
$ 1

Ponieważ grep nie udało się dopasować tokena " foo " do zawartości naszego pliku, kod powrotu wynosi 1 (jest to zwykle przypadek, gdy wystąpi awaria, ale jak wspomniano powyżej masz wiele wartości do wyboru).

Teraz następujący skrypt bash (po prostu wpisz go w terminalu Linuksa), chociaż bardzo podstawowy powinien dać jakiś pomysł na obsługę błędów:

$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'
$ [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found

Po drugiej linii nic nie jest drukowane do terminala, ponieważ " foo " sprawiło, że grep zwraca 1 i sprawdzamy, czy kod powrotu grepa był równy 0. Druga Instrukcja warunkowa powtarza swoją wiadomość w ostatniej linii, ponieważ jest prawdziwa z powodu CHECK = = 1.

As you can see if you wywołanie tego i tamtego procesu jest czasami konieczne, aby zobaczyć, co zwrócił (przez wartość zwracaną przez main ()).

 0
Author: rbaleksandar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-13 15:36:48

Omit return 0

Gdy program C lub c++ osiągnie koniec main, kompilator automatycznie wygeneruje kod zwracający 0, więc nie ma potrzeby umieszczania return 0; jawnie na końcu main.

Uwaga: kiedy przedstawiam tę sugestię, prawie zawsze następuje jeden z dwóch rodzajów komentarzy: "nie wiedziałem o tym."lub" to zła rada!"Moim uzasadnieniem jest to, że bezpieczne i użyteczne jest poleganie na zachowaniu kompilatora wyraźnie wspieranym przez standard. Dla C, od C99; zob. ISO / IEC 9899: 1999 sekcja 5.1.2.2.3:

[...] powrót z początkowego wywołania funkcji main jest równoważny wywołaniu funkcji exit z wartością zwracaną przez funkcję main jako jej argument; osiągnięcie }, które kończy funkcję main, Zwraca wartość 0.

[13]}dla C++, Od pierwszego standardu w 1998 roku; patrz ISO / IEC 14882: 1998 sekcja 3.6.1:

Jeśli Kontrola dotrze do końca main bez napotkania a Return, efektem jest wykonanie return 0;

Od tego czasu wszystkie wersje obu standardów (C99 i C++98) utrzymywały ten sam pomysł. Opieramy się na automatycznie generowanych funkcjach składowych w C++ i niewiele osób pisze jawne return; wypowiedzi na końcu void funkcji. Powody przeciw pominięciu wydają się sprowadzać do "to wygląda dziwnie" . Jeśli, podobnie jak ja, jesteś ciekawy przesłanek zmiany standardu C przeczytaj to pytanie . Zauważ również, że na początku lat 90. było to uważane za "niechlujną praktykę", ponieważ było to nieokreślone zachowanie (chociaż szeroko wspierane) w tym czasie. ([13]}więc opowiadam się za pominięciem tego; inni się nie zgadzają (często gwałtownie!) W każdym razie, jeśli napotkasz kod, który go pomija, będziesz wiedział, że jest on jawnie obsługiwany przez standard i będziesz wiedział, co on oznacza.
 0
Author: Edward,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:46