我已經在C++編程了幾個月了,當我經歷論壇時,我發現了一個趨勢。看來goto
聲明通常被認爲是完全錯誤的使用,或者應該只在非常特定的情況下使用。什麼是goto
陳述,使他們從根本上錯誤?爲什麼goto語句在C++中被視爲禁忌?
回答
最大的原因是它使代碼難以遵循。 goto
並不是不好的;使用它編寫難以編寫的代碼很容易。
例如,您寧願閱讀哪一個?這:
int factorial(int n) {
int result;
if(n==0 || n==1)
result = 1;
else
result = n*factorial(n-1);
return result;
}
或者這樣:
int factorial(int n) {
int result;
if(n > 1)
goto big;
result = 1;
goto end;
big:
result = n*factorial(n-1);
end:
return result;
}
的兩種實現方式是一樣的機器,但首先是更清楚我們的人的眼睛。雖然有時候goto
是更清晰。例如,在C考慮這個(或C++沒有例外):
void process_big_file(FILE* foo) {
if(possible_failure_1(foo))
goto cleanup;
// Do some work
if(possible_failure_2(foo))
goto cleanup;
// Do some more work
cleanup:
fclose(foo);
}
在這裏,用goto
是有道理的,因爲它可以讓你把所有的清理代碼在一個地方,和goto
5事實上創建的邏輯流程執行。特別是在閱讀代碼時,很明顯,您總是(a)達到清理代碼,並且(b)總是達到清理代碼,這是重要的。在沒有例外情況下,我實際上認爲goto
在嘗試組織(例如)清理代碼時是正確的。
最後一個例子不應該在C++中使用。即使沒有例外,您也始終擁有與錯誤代碼/早期退貨一起工作的RAII。 – Pubby 2013-04-28 18:42:45
作爲一項規則,我同意,但有時RAII不適合。在這種情況下,你需要一個好的舊指針(甚至不需要'auto_ptr',它會爲你實現RAII),然後你必須手動進行清理。一個很好的例子是帶有循環引用的對象圖,因爲RAII類型對象和'auto_ptr'都使用(a)對象生命週期或(b)引用計數(分別)來執行清理。當然,有時候你會插入傳統的C代碼,然後所有的地獄都會崩潰。 :) – sigpwned 2013-04-28 18:48:12
@sigpwned最後一個例子是設計不佳的代碼的一個完美例子,其中一個函數做得太多。 – 2013-04-28 19:00:50
主要原因是goto
使代碼的推理非常困難,如果不是不可能的話。 (請注意,對於隱藏的goto也是如此,就像使用break
從循環中間退出一樣。)通常,如果您想要推理代碼的正確性,則需要輸入每個塊在頂部,並將其留在底部。如果沒有能夠推斷代碼的正確性,則無法確定它是否正確。
關於我所看到的主題的最佳解釋。 – SChepurin 2013-04-29 05:28:43
- 1. 爲什麼全局變量被認爲是「禁忌」語法?
- 2. 什麼被認爲是C++語句?
- 3. C#.NET中的GOTO語句
- 4. 爲什麼print語句不被執行?
- 5. 爲什麼if語句被忽略?
- 6. 爲什麼Visual C#中的if語句未被正確評估?
- 7. 爲什麼我的if語句中的條件被忽略? C#
- 8. Netezza GOTO語句
- 9. sql-goto語句
- 10. C#中的goto語句慢了嗎?
- 11. 爲什麼bool在C++中不被視爲boost :: true_type?
- 12. 爲什麼&在這個if語句中?
- 13. 爲什麼return語句不能在else語句中工作
- 14. 在try塊java中返回語句。什麼會被方法返回,爲什麼?
- 15. 爲什麼在Android Studio中使用import語句被指定爲「unused import statement」?
- 16. 爲什麼在C++中的return語句後停止執行?
- 17. 在Java中替代goto語句
- 18. 爲什麼開關語句在案例
- 19. 爲什麼JavaScript有時會被視爲低級語言?
- 20. 數學 - 爲什麼PHP中的微分微積分(MVP)是禁忌?
- 21. C++中的goto語句在堆棧中的效果
- 22. 爲什麼WebFrameLoadDelegate被視爲未聲明?
- 23. Javascript,爲什麼被視爲八進制
- 24. 爲什麼*不被視爲MathSymbol?
- 25. 爲什麼「strcat」被視爲「不安全」?
- 26. 爲什麼if語句中的print語句沒有運行?
- 27. 即將使用goto語句
- 28. 爲什麼C++被稱爲面向對象的編程語言?
- 29. 爲什麼我可以在C#中編寫一個通用的catch語句,該語句什麼都不做?
- 30. 爲什麼推送隊列被禁用
您可能想從[這裏]開始(http://en.wikipedia.org/wiki/Considered_harmful) – 2013-04-28 18:28:39
* goto *語句不是「根本錯誤」 - 優化的彙編代碼充滿了跳轉目的。但是* goto *使代碼難以被人讀取 - 對於一臺機器來說什麼是好的對於人來說通常不是那麼好。 – SChepurin 2013-04-28 18:48:14
自20世紀60年代以來,Goto一直失寵。然而,一些着名作家,如Knuth,仍在使用它們。 – 2013-04-28 19:03:39