2010-10-27 205 views

回答

18
#include <cstdlib> 
... 
exit(exit_code); 
+4

使用退出並不好。它打破了我們花時間正確構建的所有RAII對象。返回主體更好。如果另一方面程序被破壞,你應該真的調用std :: terminate() – 2010-10-27 23:28:06

+0

@Martin,'std :: terminate()'只是默認調用'abort()',而'abort()'終止程序任何析構函數被調用。 – 2010-10-28 04:23:35

+2

@ Whisty:是的std :: terminate()基本上是abort()的C++版本(不同之處在於你可以重載並因此做一些清理工作(我強調** TINY **))。這是最後一個手段(如abort())。但是在數據被破壞的地方,解開堆棧沒有什麼意義。損壞的數據意味着什麼都不可信(甚至沒有堆棧展開)。 std :: terminate()就是你刻意不希望堆棧放鬆(因爲你不能相信它)而你想要一個核心轉儲來進行轉儲的情況。 – 2010-10-28 05:54:54

3

是的! exit()。它在<cstdlib>

+3

好吧,'std :: exit'真的:) – ephemient 2010-10-27 22:46:40

+0

Downvote for missing disclaimer about this circumversvents the happy world of RAII。 – 2010-11-29 13:36:24

+0

你真的在2秒內回覆downvote事件嗎?因爲在你已經哭泣的時候,我仍然在說明原因「Downvoter:爲什麼?」。 /好的。你再次刪除了你的哭泣,使我浪費了一些時間無效。 – 2010-11-29 13:37:48

-4

exit(0); //在主函數結束時關閉大括號

+1

爲什麼?從main()返回與調用exit()具有相同的效果,同時還有一個好處,即main()中的任何局部變量都被銷燬。 – 2010-10-27 22:57:57

25

之前雖然你可以呼叫exit()(可能需要這樣做,如果您的應用程序遇到一些致命錯誤),退出程序最乾淨的方法是從返回main()

int main() 
{ 
    // do whatever your program does 

} // function returns and exits program 

當你調用exit(),具有自動存儲時間(局部變量)的對象不會在程序結束之前被銷燬,所以你沒有得到正確的清除。這些對象可能需要清理它們擁有的任何資源,保持所有未決的狀態更改,終止任何正在運行的線程或執行其他操作以便程序完全終止。

+7

如果您需要從程序內部深處退出,'main'中的try/catch塊可能比'exit()'更可取。這實際上是C的保留。 – 2010-10-27 23:01:04

+0

請記住,如果異常在未被捕獲的情況下逃脫主程序,那麼它就是實現定義的天氣,堆棧被解開。因此最安全的方法是捕獲主體中的所有異常,然後重新拋出。我說重新拋出,因爲有些操作系統(Windows)會捕獲未捕獲的異常,併爲開發人員做很好的事情(我不確定這是否僅適用於調試)。 – 2010-10-27 23:26:49

+0

@Mark Ransom:[我不確定我是否正確理解你]我想我真的需要什麼,當我濫用try-catch-block來控制流程時,就是要重構。 – 2010-11-29 13:35:34

0

在main(),還有:

return 0; 
+2

只是'返回0;'?那麼,如果我調用'f()',這會退出程序? 'int f(){return 0; }' – 2010-10-27 23:10:24

+1

否 - 僅從main返回0。 exit()從任何地方工作 – pm100 2010-10-27 23:47:48

2

如果你是主,你可以這樣做:

return 0; 

exit(exit_code); 

退出代碼依賴的你的代碼的語義。 1是錯誤0是正常退出。

在你的程序中的一些功能:

exit(exit_code) 

將退出程序。

6

有幾種方法可以導致程序終止。哪一個是合適的取決於你希望程序終止的原因。絕大多數情況下,它應該通過在主函數中執行return語句來實現。如下所示。

int main() 
{ 
    f(); 
    return 0; 
} 

正如其他已經確定這可以讓你的所有的堆棧變量得到適當的破壞,以便正確地清理。這個非常重要。

如果你已經在你的代碼檢測到錯誤的地方深,你需要退出了,你應該拋出一個異常,返回的主要功能。如下所示。

struct stop_now_t { }; 
void f() 
{ 
     // ... 
     if (some_condition()) 
      throw stop_now_t(); 
     // ... 
} 

int main() 
{ 
    try { 
      f(); 
    } catch (stop_now_t& stop) { 
      return 1; 
    } 
    return 0; 
} 

這會導致堆棧被解開所有堆棧變量被破壞。仍然非常重要。請注意,用非零返回值指示故障是合適的。

如果你的程序檢測表明它不再是安全執行任何更多的語句,那麼你應該使用std ::中止()的情況不太可能的情況下。這會使您的程序突然停止,無需進一步處理。 std :: exit()是相似的,但可能會調用atexit處理程序,如果程序充分borked,這可能會很糟糕。

+0

注意:應該使用'std :: abort()'來立即終止。當異常處理失敗時,'std :: terminate()'應該只能被C++異常處理設施使用;你不應該直接調用它。 – 2010-10-28 04:23:26

+0

在我看來,'stop_now_t'異常類型是濫用異常系統。它的使用將表明您正在使用正常控制流的異常(通常很糟糕)。函數不會拋出一個異常,因爲它只會被'main()'捕獲;它應該拋出一個異常,假設它可能被任何可以處理異常的調用者捕獲。 – 2010-10-28 04:26:48

+0

James,你在std :: terminate()上找到了我。是的,std :: abort是一個更好的選擇。像stop_now_t這樣的異常是否合適取決於你如何構建算法。在一個簡單的例子中,這可能是一個不好的方法。但我只是想說明如何使用例外。 – 2010-10-28 04:39:04

3

允許執行流程離開mainreturning a value or allowing execution to reach the end of the function是程序應該終止的方式,除非在不可恢復的情況下。在C++中返回一個值是可選的,但我通常更願意返回在cstdlib中找到的EXIT_SUCCESS(指示程序成功執行的平臺特定值)。

#include <cstdlib> 

int main(int argc, char *argv[]) { 
    ... 
    return EXIT_SUCCESS; 
} 

但是,如果您的程序達到不可恢復狀態,則應該拋出異常。然而,意識到這樣做的意義是很重要的。沒有廣泛接受的最佳實踐來決定什麼應該或不應該是例外,但是您需要了解一些常規規則。

例如,從析構函數拋出異常幾乎總是一個可怕的想法,因爲被銷燬的對象可能已經被銷燬,因爲已經拋出了異常。如果拋出第二個異常,terminate被調用,您的程序將暫停而未進行任何進一步清理。你可以使用uncaught_exception來確定它是否安全,但通常更好的做法是永遠不允許異常離開析構函數。

雖然通常總是可以調用但不寫入的函數來拋出異常(例如,如果new不能分配足夠的內存,將拋出std::bad_alloc),但初學者程序員通常很難追蹤或甚至瞭解C++中關於異常的所有特殊規則。出於這個原因,我建議只在沒有明智的方式讓程序繼續執行的情況下使用它們。

#include <stdexcept> 
#include <cstdlib> 
#include <iostream> 

int foo(int i) { 
    if (i != 5) { 
    throw std::runtime_error("foo: i is not 5!"); 
    } 
    return i * 2; 
} 

int main(int argc, char *argv[]) { 
    try { 
    foo(3); 
    } 
    catch (const std::exception &e) { 
    std::cout << e.what() << std::endl; 
    return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

exit是選自C的保持,並可能導致在具有自動存儲對象不被正確地清理。 abortterminate有效地導致程序自殺,絕對不會清理資源。

無論你做什麼,不要使用例外,exitabort/terminate作爲一個柺杖來解決寫一個正確的結構化程序。將它們保存爲特殊情況。

0
#include <cstdlib> 
... 
/*wherever you want it to end, e.g. in an if-statement:*/ 
if (T == 0) 
{ 
exit(0); 
} 
-3

足夠簡單..

出口(0); } //函數結束

確保0的兩邊都有空格。沒有空格,程序不會停止。

+3

空格與此無關。 – 2013-01-22 20:35:21

-1
else if(Decision >= 3) 
    { 
exit(0); 
    } 
+1

正如在其他答案的評論中指出的那樣,使用'exit'實際上是一個結束程序的非常糟糕的方式 - 我認爲最糟糕的方式(在很多可能的情況下)。 – 2015-02-25 12:41:34

相關問題