查看完整版本: 新手發問C語言Goto指令
頁: 1 [2] 3

titanping 發表於 2018-7-9 11:55 AM

別聽網路說大話 ,該用就用 ,但別用太多 程式會亂七八糟.<div></div>

affkame 發表於 2018-7-12 12:34 PM

Goto沒有問題,但當你run的專案大,要互相review時,你就會發現怎麼自己的code最髒,再過三個月後回來看,你會發現這到底是哪個阿呆在亂寫

MY0613 發表於 2018-7-12 01:49 PM

本帖最後由 MY0613 於 2018-7-12 01:53 PM 編輯

「未悟道以前,見山是山,見水是水;見道以後,見山不是山,見水不是水;最後大徹大悟以後,見山還是山,見水還是水。」

初學者就先記著這個潛規則,
程式碼看多了…if (do_something() != ERR) {
    if (do_something2() != ERR) {
        if (do_something3() != ERR) {
            if (do_something4() != ERR) {
                ...這種東西就覺得用 gotoif (do_something() == ERR)  // Straight line
    goto error;             // |
if (do_something2() == ERR) // |
    goto error;             // |
if (do_something3() == ERR) // |
    goto error;             // V
if (do_something4() == ERR) // emphasizes normal control flow
    goto error;感覺就典雅很多
但是,看了一陣子…發現程式碼還是人寫的…程度不夠的人看了這段碼,為了修bug 毀了這典雅…
那還是回到原點…

總之,工具本身沒有"對錯"、"好壞"…但是用的人不同,才會顯示出差異…
參考看看。
Why do some kernel programmers use goto instead of simple while loops?
Linux Kernel source code 也存在著許多goto…但那又如何呢?

...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

cockroachrun 發表於 2018-7-13 10:22 AM

還有別的情況下也可以用goto
很多層的loop 最內層有錯發生. 外層也不要執行了. 直接用goto 離開.
example
while( exp )
{
   while( exp2 )
   {
      while( exp3 )
      {
             ....
             if( fail )
                goto exitAll;
             ....
  
      }
   }
}
exitAll:;

love88131496 發表於 2018-7-13 05:43 PM

GOTO最大的問題是在"可讀性"。
但所謂可讀性,是在程式碼需要"被讀"的時候才重要。
10~20行內,作GOTO,限制跨原始碼檔作GOTO呼叫,有什麼不可?
ASM,遠程呼叫常見(也只能用JUMP)

如果一個函式,寫到了幾千行,那用所謂的"結構性的迴圈"也不會比用"GOTO"好到哪裡去

try...catch...finally也是典型類似GOTO的"結構性"寫法。但try...catch中間,或者catch..finally中間區塊幾千行,那也好不到哪裡去

該用就用吧。註解寫好就好。最後補充一個GOTO和結構性語法要注意的點:
注意程式流程,在特定的語言中,記憶體釋放這種"收尾"工作,常常會因為GOTO作了"兩次以上"(反而不是忘了呼叫)...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>

ash1326 發表於 2018-8-8 09:28 PM

指令本身是沒有問題的,但你的同事問題會很多

advantise 發表於 2018-8-17 12:14 AM

沒有不能使用goto, 我認為語言的設計出來的東西都有其必要性, 很多公司都限制programmer不能使用marco, 我認為這些限制是不合理的, 而且你去看linux kernal, marco/goto 用一堆, 誰說有什麼東西不能用。

advantise 發表於 2018-8-18 01:44 PM

advantise 發表於 2018-8-17 12:14 AM static/image/common/back.gif
沒有不能使用goto, 我認為語言的設計出來的東西都有其必要性, 很多公司都限制programmer不能使用marco, 我 ...

每個公司都不太一樣, 但是大部份的公司都認為不好維護, 這些公司有上市公司, 也有大的美商公司

chevylin0802 發表於 2018-9-8 09:11 PM

其實避免使用goto是1980年代結構化程式語言教科書上的指示。當時為了強調結構化的重要性,因此提出這樣子的觀念。
但事實上,在Linux kernel卻是很常見的做法。原因出在Linux kernel採用的是物件化的觀念,由於純C的程式並沒有try catch 的語法,因此goto成為替代選項。事實上,這樣子的語法反而比結構化寫法更容易理解,同時也更不容易出錯。因為過多巢狀的if else 反而更容易出錯,尤其是程式又臭又長的情況下。試想看看,當程式裡if else裡有個五層的if else語法包覆時的情況,可讀性能好到哪去。還遠不及採用goto的方式來解決問題。
所以不要以為結構化是萬能的寫法,畢竟盡可能保持乾淨易懂的程式碼,以及盡可能減少使用巢狀式的設計,才是最重要的事情。起碼不要讓程式出現一堆{{{}}}之類的事情發生,才是最要緊的事情,因為這種巢狀結構一個不小心就更容易出錯。...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

hunter00101 發表於 2018-9-10 09:04 AM

goto最好不要用,因為在後續除錯上,增加困難度。<br><br><br><br><br><div></div>

whyend1119 發表於 2018-9-30 01:29 PM

本帖最後由 whyend1119 於 2018-9-30 01:35 PM 編輯

樓上有很多舉出用GOTO的例子,其實都可以用try, throw和catch來完美的呈現,這也是寫程式在做error handling的標準做法,當然,這要用到C++的語法。

很多時候錯誤發生在巢狀迴圈或是判斷式中,要每個地方跳出來個別做錯誤處理,用GOTO似乎是無奈但卻很合理的選擇,正是因為這樣,才有try, throw和catch的語法出現

例如:


if (do_something() == ERR)  // Straight line
    goto error;             // |
if (do_something2() == ERR) // |
    goto error;             // |
if (do_something3() == ERR) // |
    goto error;             // V
if (do_something4() == ERR) // emphasizes normal control flow
    goto error;

就可以用下面來完成

try
{
if (do_something() == ERR)  // Straight line
    throw ERR1;             // |
if (do_something2() == ERR) // |
    throw ERR2;             // |
if (do_something3() == ERR) // |
    throw ERR3;             // V
if (do_something4() == ERR) // emphasizes normal control flow
    throw ERR4;
.......
}
carch (int error_code)
{
    // error handling here
}...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

affkame 發表於 2018-10-3 12:50 PM

非不能用,而是你寫了之後,三個月後再回來看,你能不能秒懂?
當然如果只需要寫不需要看也不靠這吃飯,就你開心就好

ykshieh 發表於 2018-11-28 07:57 PM

其實現在分兩派,
一派是goto很好用,另一派是不要用goto。

先說兩派主要堅持的地方,
(我是中立派的,工具好用就該用,不好用就別硬用)
不用goto的主要原因,
因為程式"不標準、不夠結構化"(只是什麼是標準...!?)
程式能力不強的人,會讓程式不知道跳到哪、讀程式碼的人不好了解。

用goto的主要原因,
因為程式該跳的時候就跳到想要的地方,
非常有效率,
不用再額外判斷許多變數後才放棄原本要執行的程式碼。

而大多數寫C語言約15年至20年以上的老手,
建議不要用goto,
是因為那個時候力吹"避免用goto,goto是不好的東西",
所以久而久之,就很少在用goto了。
(其實我覺得goto蠻像break或continue,但是又不相同)

當然,結構化的程式很好讀、好懂;
我遇過用goto會有問題(純粹是系統管理記憶體的問題),
是在用遞迴時,遞迴到一半強制跳過某個遞迴時,
系統在處理記憶體上會有問題,
但若是自己把遞迴展開成迴圈執行用goto,
則沒有記憶體的錯誤問題。

所以雖然goto可以治百病,因為可以亂跳,但是用不好也會致命。...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

chevylin0802 發表於 2018-12-10 06:23 PM

ykshieh 發表於 2018-11-28 07:57 PM
其實現在分兩派,
一派是goto很好用,另一派是不要用goto。



這是因為系統堆疊的問題
遞迴之中再跳到另一個遞迴時
就很容易出錯
goto不在於好不好用
而是在於是否能夠避免使用過多的{}夾層
{{}}過多層的時候就不具有可讀性
所以就連Linux 原始碼
goto即使滿天飛
仍然有它一定的使用規則
通常只使用在需要判斷記憶體配置是否成功的地方
包括驅動程式物件的建立是否成功
除此之外
就很少在其他的地方看到
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

幻想的夢境 發表於 2019-4-15 01:41 AM

我也不愛用Goto,這樣做事超難結構化,小程式還可以,大程式丟災系,以前教授就講,Goto只有一個地方可以用,那就是這句語法可能導致整個系統或程式Crash,那這樣就得直接用Goto指向某個地方,不然crash更麻煩,不過到現在,我一次Goto都沒用到,倒是在VBA還用到一些,誰叫VBA沒有跟C一樣有continue(攤手<br><br><br><br><br><div></div>
頁: 1 [2] 3