Jak zakończyć kod C ++

267

Chciałbym, aby mój kod C ++ przestał działać, jeśli zostanie spełniony określony warunek, ale nie jestem pewien, jak to zrobić. Więc w dowolnym momencie, jeśli ifinstrukcja jest prawdziwa, zakończ kod w następujący sposób:

if (x==1)
{
    kill code;
}
The Nightman
źródło
98
Użyj właściwej logiki. W main()użyciu return, w funkcjach użyj poprawnej wartości zwracanej lub wygeneruj odpowiedni wyjątek. Nie używaj exit()!
kay - SE jest zły
6
@JathanathanLeffler: Po skompilowaniu ze NDEBUGzdefiniowanym, assertprawdopodobnie stanie się brakiem op, więc nie powinieneś polegać na nim więcej niż na wykrywaniu błędów.
MvG
13
@jamesqf: a returnfrom main()jest całkowicie logiczne. Ustawia kod wyjścia zgłaszany przez program do systemu operacyjnego, co może być przydatne w wielu przypadkach (na przykład, jeśli program może być używany jako część większego procesu).
AAT
11
Co ciekawe, to Q jest duplikatem tego sprzed 5 lat, którego zaakceptowana odpowiedź jest zupełnie inna: stackoverflow.com/questions/1116493/how-to-quit-ac-program Wydaje mi się, że społeczność zajęła 5 lat, aby nauczyć się tego na ślepo wywołanie std :: exit może być złe?
Brandin
5
Pytania Dlaczego używanie jest exit()uważane za złe? - SO 25141737 i Jak wyjść z programu C ++? - SO 1116493 są teraz zamknięte jako duplikaty tego. Pierwszy z nich zawiera odniesienie do „oprogramowania tylko do awarii”, które może być warte spojrzenia, choćby po to, aby pobudzić twoje myślenie o tym, jak napisać solidne oprogramowanie.
Jonathan Leffler

Odpowiedzi:

431

Istnieje kilka sposobów, ale najpierw musisz zrozumieć, dlaczego czyszczenie obiektów jest ważne, a zatem powód std::exitjest marginalizowany wśród programistów C ++.

RAII i rozwijanie stosu

C ++ korzysta z idiomu zwanego RAII , co w uproszczeniu oznacza, że ​​obiekty powinny wykonywać inicjalizację w konstruktorze i czyszczenie w destruktorze. Na przykład std::ofstreamklasa [może] otworzyć plik podczas konstruktora, a następnie użytkownik wykonuje na nim operacje wyjściowe, a na końcu pod koniec swojego cyklu życia, zwykle określanego przez jego zakres, wywoływany jest destruktor, który zasadniczo zamyka plik i opróżnia dowolna zapisana zawartość na dysk.

Co się stanie, jeśli nie dojdziesz do destruktora, aby opróżnić i zamknąć plik? Kto wie! Ale możliwe, że nie zapisze wszystkich danych, które miał zapisać w pliku.

Na przykład rozważ ten kod

#include <fstream>
#include <exception>
#include <memory>

void inner_mad()
{
    throw std::exception();
}

void mad()
{
    auto ptr = std::make_unique<int>();
    inner_mad();
}

int main()
{
    std::ofstream os("file.txt");
    os << "Content!!!";

    int possibility = /* either 1, 2, 3 or 4 */;

    if(possibility == 1)
        return 0;
    else if(possibility == 2)
        throw std::exception();
    else if(possibility == 3)
        mad();
    else if(possibility == 4)
        exit(0);
}

W każdej możliwości dzieje się:

  • Możliwość 1: Return zasadniczo opuszcza bieżący zakres funkcji, więc wie o zakończeniu cyklu życia, w osten sposób wywołując swój destruktor i wykonując prawidłowe czyszczenie przez zamknięcie i opróżnienie pliku na dysk.
  • Możliwość 2: Zgłoszenie wyjątku zajmuje się także cyklem życia obiektów w bieżącym zakresie, tym samym wykonując prawidłowe czyszczenie ...
  • Możliwość 3: Tutaj rozwija się rozwijanie stosu! Nawet jeśli zostanie zgłoszony wyjątek inner_mad, odwijak przejdzie przez stos madi mainaby wykonać prawidłowe czyszczenie, wszystkie obiekty zostaną zniszczone poprawnie, w tym ptri os.
  • Możliwość 4: Cóż, tutaj? exitjest funkcją C i nie jest świadomy ani zgodny z idiomami C ++. To nie wykonywać porządki na swoich obiektach, w tym osw tym samym zakresie. Dlatego Twój plik nie zostanie poprawnie zamknięty i z tego powodu treść może nigdy nie zostać w nim zapisana!
  • Inne możliwości: Po prostu opuści główny zakres, wykonując domniemanie, return 0a tym samym dając taki sam efekt jak możliwość 1, tj. Prawidłowe czyszczenie.

Ale nie bądźcie tak pewni tego, co wam powiedziałem (głównie możliwości 2 i 3); kontynuuj czytanie, a dowiemy się, jak przeprowadzić prawidłowe czyszczenie oparte na wyjątkach.

Możliwe sposoby zakończenia

Wróć z głównego!

Powinieneś to zrobić, gdy tylko jest to możliwe; zawsze wolisz wracać ze swojego programu, zwracając odpowiedni status wyjścia z głównego.

Program wywołujący Twój program i być może system operacyjny mogą chcieć wiedzieć, czy to, co program miał zrobić, zostało wykonane pomyślnie, czy nie. Z tego samego powodu powinieneś zwrócić zero lub EXIT_SUCCESSaby zasygnalizować, że program został pomyślnie zakończony i EXIT_FAILUREaby zasygnalizować, że program zakończył się niepowodzeniem, każda inna forma wartości zwracanej jest zdefiniowana w implementacji ( § 18.5 / 8 ).

Jednak możesz być bardzo głęboko w stosie wywołań, a zwracanie wszystkiego może być bolesne ...

[Nie] zgłaszaj wyjątku

Zgłoszenie wyjątku wykona prawidłowe czyszczenie obiektu za pomocą rozwijania stosu, wywołując destruktor każdego obiektu w dowolnym poprzednim zakresie.

Ale oto haczyk ! Jest zdefiniowane w implementacji, czy odwijanie stosu jest wykonywane, gdy zgłoszony wyjątek nie jest obsługiwany (przez klauzulę catch (...)), a nawet jeśli masz noexceptfunkcję w środku stosu wywołań. Jest to określone w §15.5.1 [z wyjątkiem terminów] :

  1. W niektórych sytuacjach należy zrezygnować z obsługi wyjątków dla mniej subtelnych technik obsługi błędów. [Uwaga: Te sytuacje to:

    [...]

    - gdy mechanizm obsługi wyjątków nie może znaleźć procedury obsługi zgłoszonego wyjątku (15.3), lub gdy wyszukiwanie funkcji obsługi (15.3) napotka najbardziej zewnętrzny blok funkcji o parametrze noexcept-specyfikacja , która nie zezwala na wyjątek (15.4), lub [...]

    [...]

  2. W takich przypadkach wywoływana jest funkcja std :: terminate () (18.8.3). W sytuacji, gdy nie znaleziono pasującego modułu obsługi, jest zdefiniowane w implementacji, czy stos jest rozwijany przed wywołaniem std :: terminate () [...]

Więc musimy to złapać!

Rzuć wyjątek i złap go w pozycji głównej!

Ponieważ niewyłapane wyjątki mogą nie powodować rozwijania stosu (a tym samym nie będą wykonywać właściwego czyszczenia) , powinniśmy wychwycić wyjątek w main, a następnie zwrócić status wyjścia ( EXIT_SUCCESSlub EXIT_FAILURE).

Prawdopodobnie dobrym rozwiązaniem byłoby:

int main()
{
    /* ... */
    try
    {
        // Insert code that will return by throwing a exception.
    }
    catch(const std::exception&)  // Consider using a custom exception type for intentional
    {                             // throws. A good idea might be a `return_exception`.
        return EXIT_FAILURE;
    }
    /* ... */
}

[Nie] std :: exit

Nie powoduje to żadnego rozwijania stosu i żaden żywy obiekt na stosie nie wywoła odpowiedniego niszczyciela w celu przeprowadzenia czyszczenia.

Jest to egzekwowane w §3.6.1 / 4 [basic.start.init] :

Zakończenie programu bez opuszczania bieżącego bloku (np. Przez wywołanie funkcji std :: exit (int) (18.5)) nie niszczy żadnych obiektów z automatycznym czasem przechowywania (12.4) . Jeśli std :: exit zostanie wywołane w celu zakończenia programu podczas niszczenia obiektu o czasie przechowywania statycznym lub wątkowym, program ma niezdefiniowane zachowanie.

Pomyśl o tym teraz, dlaczego zrobiłbyś coś takiego? Ile przedmiotów boleśnie uszkodziłeś?

Inne [złe] alternatywy

Istnieją inne sposoby zakończenia programu (inne niż zawieszanie się) , ale nie są zalecane. Dla wyjaśnienia zostaną tutaj przedstawione. Zwróć uwagę, że normalne zakończenie programu nie oznacza rozwijania stosu, ale dobry stan systemu operacyjnego.

  • std::_Exit powoduje normalne zakończenie programu i to wszystko.
  • std::quick_exitpowoduje normalne zakończenie programu i wywołuje std::at_quick_exitprocedury obsługi, żadne inne czyszczenie nie jest wykonywane.
  • std::exitpowoduje normalne zakończenie programu, a następnie wywołuje programy std::atexitobsługi. Przeprowadzane są inne rodzaje porządków, takie jak wywoływanie destrukcyjnych obiektów statycznych.
  • std::abortpowoduje nieprawidłowe zakończenie programu, żadne czyszczenie nie jest wykonywane. Należy to wywołać, jeśli program zakończy się w naprawdę, naprawdę nieoczekiwany sposób. Nie zrobi nic poza zasygnalizowaniem systemu operacyjnego o nienormalnym zakończeniu. W tym przypadku niektóre systemy wykonują zrzut pamięci.
  • std::terminatewywołuje te, std::terminate_handlerktóre std::abortdomyślnie wywołują .
Denilson Amorim
źródło
25
Jest to dość pouczające: przede wszystkim nigdy nie zrozumiał, że rzuca wyjątek, który nie jest obsługiwany w dowolnym miejscu (na przykład: niektóre newrzuca std::bad_alloci program zapomnieli złapać tego nigdzie wyjątku) będzie nie prawidłowo rozwijać stosu przed zakończeniem. Wydaje się to głupie mnie byłoby łatwo zasadniczo zawinąć wywołanie mainw trywialny try{- }catch(...){}bloku, który zapewniłby stos odwijania jest prawidłowo wykonane w takich przypadkach, bez ponoszenia kosztów (przez co rozumiem: programy nie to za pomocą zapłaci nie rzut karny). Czy jest jakiś konkretny powód, dla którego tego nie zrobiono?
Marc van Leeuwen
12
@MarcvanLeeuwen jednym z możliwych powodów jest debugowanie: chcesz włamać się do debuggera, gdy tylko zostanie zgłoszony nieobsługiwany wyjątek. Rozpakowanie stosu i wykonanie czyszczenia spowoduje usunięcie kontekstu tego, co spowodowało awarię, którą chcesz debugować. Jeśli nie ma debugera, lepiej zrzucić rdzeń, aby można było przeprowadzić analizę pośmiertną.
Hugh Allen
11
Czasami moja przeglądarka się psuje (obwiniam flasha) i zużywa kilka gigabajtów pamięci RAM, a mój system operacyjny zrzuca strony na dysk twardy, co spowalnia wszystko. Po zamknięciu przeglądarki następuje właściwe odwijanie stosu, co oznacza, że ​​wszystkie te gigabajty pamięci RAM są odczytywane z dysku twardego i kopiowane do pamięci w celu zwolnienia, co zajmuje około minuty. Żałuję, że nie skorzystali z nich, std::abortaby system operacyjny mógł zwolnić całą pamięć, gniazda i deskryptory plików bez zamiany na minutę.
nwp
2
@ nwp, rozumiem to uczucie. Ale natychmiastowe zabijanie może uszkodzić pliki, nie zapisywać moich najnowszych kart itp. :)
Paul Draper
2
@PaulDraper Na pewno nie uznałbym za dopuszczalne, gdyby przeglądarka nie mogła przywrócić kart, które otworzyłem przed utratą zasilania. Oczywiście, gdybym właśnie otworzył kartę i nie miałbym jeszcze czasu na jej uratowanie, straciłbym ją. Ale poza tym mówię, że nie ma usprawiedliwienia dla jego utraty.
kasperd
61

Jak wspomniał Martin York, wyjście nie wykonuje koniecznego czyszczenia, tak jak robi to return.

Zawsze lepiej jest użyć powrotu w miejscu wyjścia. Jeśli nie jesteś w Main, gdziekolwiek chcesz wyjść z programu, wróć najpierw do Main.

Rozważ poniższy przykład. W następującym programie zostanie utworzony plik z wymienioną zawartością. Ale jeśli komentowany jest return i niekomentowane wyjście (0), kompilator nie zapewnia, że ​​plik będzie zawierał wymagany tekst.

int main()
{
    ofstream os("out.txt");
    os << "Hello, Can you see me!\n";
    return(0);
    //exit(0);
}

Nie tylko to, posiadanie wielu punktów wyjścia w programie utrudni debugowanie. Wyjścia używaj tylko wtedy, gdy jest to uzasadnione.

Narendra N.
źródło
2
Co zalecasz, aby osiągnąć to zachowanie w nieco większym programie? Jak zawsze wracasz do głównego, jeśli gdzieś głębiej w kodzie jest wyzwalany błąd, który powinien wyjść z programu?
Janusz
5
@Janusz, W takim przypadku możesz użyć / wyrzucić wyjątki, jeśli nie, zwróci wcześniej zdefiniowaną wartość, tj. Uzyska wartość zwracaną z funkcji, jak na przykład zwróci 0 po pomyślnym zakończeniu, 1 w przypadku niepowodzenia, ale kontynuuje wykonywanie , -1 w przypadku awarii i wyjdź z programu. Na podstawie wartości zwracanej z funkcji, jeśli jest to awaria, po prostu wróć z głównego po wykonaniu jakichkolwiek czynności czyszczenia. Wreszcie, rozważnie korzystaj z wyjścia, nie chcę tego unikać.
Narendra N
1
@NarendraN, „niezbędne czyszczenie” jest niejasne - system operacyjny zadba (Windows / Linux) o prawidłowe zwolnienie pamięci i uchwytów plików. Jeśli chodzi o „wyjściu” brakującego pliku: Jeśli upierasz się, że to może być prawdziwym problemem, zobacz stackoverflow.com/questions/14105650/how-does-stdflush-work Jeśli stan błędu, prawidłowe rejestrowanie mówi, że program osiągnął stan nieokreślony i można ustawić punkt przerwania tuż przed punktem logowania. W jaki sposób utrudnia to debugowanie?
Markus
2
Zauważ, że ta odpowiedź została połączona z pytaniem Jak wyjść z programu C ++? - SO 1116493 . Ta odpowiedź została napisana około 6 lat przed zadaniem tego pytania.
Jonathan Leffler,
do nowoczesnego użycia C ++ return (EXIT_SUCCESS);zamiast tegoreturn(0)
Jonas Stein
39

Wywołaj std::exitfunkcję.   

Otávio Décio
źródło
2
Które destruktory obiektów są wywoływane, gdy wywołujesz tę funkcję?
Rob Kennedy
37
exit () nie zwraca. Dlatego nie może nastąpić odwijanie stosu. Nawet globalne obiekty nie ulegają zniszczeniu. Ale funkcje zarejestrowane w atexit () zostaną wywołane.
Martin York,
16
Nie dzwoń, exit()gdy kod biblioteki działa w procesie hosta - ten ostatni zakończy działanie w szczerym polu.
sharptooth
5
Zauważ, że ta odpowiedź została połączona z pytaniem Jak wyjść z programu C ++? - SO 1116493 . Ta odpowiedź została napisana około 6 lat przed zadaniem tego pytania.
Jonathan Leffler,
23

Ludzie mówią „call exit (kod powrotu)”, ale to zła forma. W małych programach jest w porządku, ale jest z tym wiele problemów:

  1. W rezultacie będziesz mieć wiele punktów wyjścia z programu
  2. Sprawia, że ​​kod jest bardziej skomplikowany (jak używanie goto)
  3. Nie można zwolnić pamięci przydzielonej w czasie wykonywania

Naprawdę, jedynym wyjściem z problemu jest wyjście z tego wiersza w main.cpp:

return 0;

Jeśli używasz metody exit () do obsługi błędów, powinieneś dowiedzieć się o wyjątkach (i zagnieżdżaniu wyjątków), jako o wiele bardziej eleganckiej i bezpiecznej metodzie.

klucze
źródło
9
W środowisku wielowątkowym wyjątek zgłoszony w innym wątku nie będzie obsługiwany przez main () - przed wygaśnięciem wątku podrzędnego wymagana jest ręczna komunikacja między wątkami.
Steve Gilham
3
1. i 2. zależą od programisty, przy prawidłowym logowaniu nie stanowi to problemu, ponieważ wygaszanie kończy się na zawsze. Jeśli chodzi o 3: to po prostu źle, system operacyjny zwolni pamięć - być może z wyłączeniem urządzeń osadzonych / w czasie rzeczywistym, ale jeśli to robisz, prawdopodobnie znasz swoje rzeczy.
Markus
1
Zauważ, że ta odpowiedź została połączona z pytaniem Jak wyjść z programu C ++? - SO 1116493 . Ta odpowiedź została napisana około 6 lat przed zadaniem tego pytania.
Jonathan Leffler,
1
Jeśli wystąpił błąd, nie powinieneś zwracać 0. Powinieneś zwrócić 1 (lub ewentualnie inną wartość, ale 1 jest zawsze bezpiecznym wyborem).
Kef Schecter,
14

return 0;umieść to w dowolnym miejscu, int main()a program natychmiast się zamknie.

Evan Carslake
źródło
the-nightman, @ evan-carslake i wszyscy inni, dodałbym również, że to SO pytanie nr 36707 zawiera dyskusję na temat tego, czy wyrażenie zwrotne powinno pojawić się gdziekolwiek w ramach rutyny. To jest rozwiązanie; jednak w zależności od konkretnej sytuacji nie powiedziałbym, że to najlepsze rozwiązanie.
localhost
1
OP nic nie powiedział na ten temat, więc myślę, że pochopne jest zakładanie, że kod powinien znajdować się w funkcji main.
Marc van Leeuwen
@localhost Instrukcja return jest całkowicie opcjonalna w każdej sytuacji, w każdych warunkach. Jednak int main()jest inaczej. Program używa int main()do rozpoczynania i kończenia. Nie ma innego sposobu, aby to zrobić. Program będzie działał, dopóki nie zwrócisz true lub false. Niemal przez cały czas zwracana jest wartość 1 lub true, aby wskazać, że program został poprawnie zamknięty (np. Może użyć wartości false, jeśli nie można zwolnić pamięci lub z dowolnego powodu). Pozwolenie na uruchomienie programu jest zawsze złym pomysłem, przykład:int main() { int x = 2; int foo = x*5; std::cout << "blah"; }
Evan Carslake
@EvanCarslake Zrozumiałem, jeśli zauważyłeś komentarz, który zamieściłem gdzie indziej na to pytanie, jestem o tym zaznajomiony int main; jednak nie zawsze dobrym pomysłem jest posiadanie wielu instrukcji return w głównej procedurze. Jednym potencjalnym zastrzeżeniem jest poprawa czytelności kodu; jednak użycie czegoś w rodzaju flagi logicznej, która zmienia stan, aby uniemożliwić działanie niektórych sekcji kodu w tym stanie aplikacji. Osobiście uważam, że wspólne wyrażenie zwrotne sprawia, że ​​większość aplikacji jest bardziej czytelna. Na koniec pytania dotyczące czyszczenia pamięci i prawidłowego zamykania obiektów we / wy przed wyjściem.
localhost
2
@EvanCarslake nie wrócisz truez mainwskazać prawidłowe rozwiązanie. Musisz zwrócić zero lub EXIT_SUCCESS(lub, jeśli chcesz false, które domyślnie zostałyby przekonwertowane na zero), aby wskazać normalne zakończenie. Aby wskazać awarię, możesz wrócić EXIT_FAILURE. Każde inne znaczenie kodu jest zdefiniowane w implementacji (w systemach POSIX oznaczałoby to rzeczywisty kod błędu).
Ruslan
11

Program zakończy się, gdy przepływ wykonania osiągnie koniec głównej funkcji.

Aby go wcześniej zakończyć, możesz użyć funkcji exit (int status), gdzie status jest wartością zwracaną do tego, co uruchomiło program. 0 zwykle oznacza stan bez błędu

chrisbunney
źródło
2
Zauważ, że ta odpowiedź została połączona z pytaniem Jak wyjść z programu C ++? - SO 1116493 . Ta odpowiedź została napisana około 6 lat przed zadaniem tego pytania.
Jonathan Leffler,
11

Albo zwróć wartość z twojego, mainalbo użyj exitfunkcji. Oba przyjmują int. Tak naprawdę nie ma znaczenia, jaką wartość zwracasz, chyba że masz zewnętrzny proces sprawdzający wartość zwracaną.

Goz
źródło
3
Zauważ, że ta odpowiedź została połączona z pytaniem Jak wyjść z programu C ++? - SO 1116493 . Ta odpowiedź została napisana około 6 lat przed zadaniem tego pytania.
Jonathan Leffler,
11

Jeśli masz błąd gdzieś głęboko w kodzie, albo rzuć wyjątek, albo ustaw kod błędu. Zawsze lepiej jest wyrzucić wyjątek niż ustawić kody błędów.

Jagannath
źródło
2
Zauważ, że ta odpowiedź została połączona z pytaniem Jak wyjść z programu C ++? - SO 1116493 . Ta odpowiedź została napisana około 6 lat przed zadaniem tego pytania.
Jonathan Leffler,
9

Zasadniczo użyłbyś tej exit()metody z odpowiednim statusem wyjścia .

Zero oznaczałoby udany bieg. Niezerowy status wskazuje, że wystąpił jakiś problem. Ten kod zakończenia jest używany przez procesy nadrzędne (np. Skrypty powłoki) w celu ustalenia, czy proces został pomyślnie uruchomiony.

Brian Agnew
źródło
1
użycie wyjścia MAY oznacza, że ​​masz problem z projektem. Jeśli program zachowuje się poprawnie, powinien po prostu zakończyć działanie w trybie głównym return 0;. Zakładam, że exit()jest podobny assert(false);i dlatego powinien być używany tylko w fazie rozwojowej do wczesnych problemów połowowych.
CoffeDeveloper
2
Zauważ, że ta odpowiedź została połączona z pytaniem Jak wyjść z programu C ++? - SO 1116493 . Ta odpowiedź została napisana około 6 lat przed zadaniem tego pytania.
Jonathan Leffler,
7

Poza wywoływaniem exit (kod_błędu) - który wywołuje programy obsługi atexit, ale nie destruktory RAII itp. - coraz częściej używam wyjątków.

Coraz bardziej wygląda mój główny program

int main(int argc, char** argv) 
{
    try {
        exit( secondary_main(argc, argv );
    }
    catch(...) {
        // optionally, print something like "unexpected or unknown exception caught by main"
        exit(1);
    }
}

gdzie minor_main w miejscu, gdzie wszystkie rzeczy, które zostały pierwotnie umieszczone - tj. pierwotny main jest przemianowany na wtórny_main i dodawany jest kod główny powyżej. Jest to po prostu drobiazg, aby nie było za dużo kodu między szufladą a połowem w głównym.

Jeśli chcesz, złap inne typy wyjątków.
Bardzo lubię łapać typy błędów łańcucha, takie jak std :: string lub char *, i drukować je w module obsługi catch w main.

Korzystanie z takich wyjątków pozwala przynajmniej wywoływać destruktory RAII, aby mogli wykonać czyszczenie. Co może być przyjemne i przydatne.

Ogólnie rzecz biorąc, obsługa błędów C - wyjście i sygnały - oraz obsługa błędów C ++ - wyjątki try / catch / throw - w najlepszym przypadku grają niespójnie.

Następnie wykrywasz błąd

throw "error message"

lub jakiś bardziej szczegółowy typ wyjątku.

Krazy Glew
źródło
Nawiasem mówiąc: doskonale zdaję sobie sprawę, że użycie typu danych, takiego jak łańcuch znaków, który może wymagać dynamicznej alokacji pamięci, nie jest dobrym pomysłem w procedurze obsługi wyjątków lub w jej pobliżu w przypadku wyjątków, które mogą być związane z brakiem pamięci. Stałe łańcuchowe w stylu C nie stanowią problemu.
Krazy Glew
1
Nie ma sensu dzwonić exitw twoim programie. Skoro jesteś w środku main, możesz po prostu return exitCode;.
Ruslan
-1

Jeśli instrukcja if znajduje się w pętli, możesz jej użyć

 break; 

Jeśli chcesz uciec trochę kodu i kontynuować pętlę Użyj:

kontyntynuj;

Jeśli instrukcja if nie znajduje się w pętli, możesz użyć:

 return 0;

Or 




  exit();
Akshay
źródło
-2

Koleś ... exit()funkcja jest zdefiniowana w stdlib.h

Musisz więc dodać preprocesor.

Umieść include stdlib.hw sekcji nagłówka

Następnie używaj exit();gdziekolwiek chcesz, ale pamiętaj, aby wstawić liczbę interger w nawiasie wyjścia.

na przykład:

exit(0);
rdxxdroid
źródło
-2

Jeśli warunek, który testuję, jest naprawdę złą wiadomością, robię to:

*(int*) NULL= 0;

To daje mi niezły rdzeń, z którego mogę zbadać sytuację.

dront
źródło
4
Można to zoptymalizować, ponieważ powoduje niezdefiniowane zachowanie. W rzeczywistości kompilator może usunąć całą gałąź wykonania z taką instrukcją.
Ruslan
-2

Aby przełamać warunek, użyj return (0);

W twoim przypadku byłoby to:

    if(x==1)
    {
        return 0;
    }
Lawenda
źródło