▌第一次閱讀本系列的,可以先看:


goto、標記:

goto 格式: goto [標記];
標記 格式: [標記]:
用於無條件跳躍到標記語句,基礎用法:
printf("Hello");
goto label;
printf(" World!!!");
label:
輸出: Hello
跳過了 printf(" World!!!"); 語句。

  • goto 陳述式 不能夠在函數間跳躍
    跳躍範圍局限於同一個函數內。

  • [標記] 這個識別項擁有自己的命名空間
    故此不會與一般變數名稱衝突,但依然不能設定為關鍵字/保留字。
    .
    正因為擁有自己的命名空間
    所以不能夠用變數作為 [標記] 或者 goto 目標。

  • [標記] 的視野範圍(scope)不會受 forwhile 等區域局限,
    直接擁有整個函數內的視野範圍

  • goto 可以多個,
    但是 [標記] 是唯一的。

▌爭議:

goto 一直以來充滿爭議,被不建議使用,
一些程式風格禁止使用 goto 陳述式。
主要原因是 goto 陳述式 容易大幅降低可讀性
甚至成為不可維護的「麵條程式碼」,
使程式事情的難以追蹤和理解,以及修改
有一些為 goto 陳述式辯護的人認為,
加以限制地使用GOTO陳述式不會導致低質素的程式碼,
並且聲稱一些任務如果不使用一條或多條GOTO陳述式是無法被直接實現的。
如有限狀態自動機的實現、跳出巢狀迴圈以及例外處理。

▌限制不使用 goto 的實現方式:

先嘗試一個用 goto + 標記 做例外處理的例子:
/*陳述式*/
if(/*錯誤檢測*/){
    goto ex_catch;
}
back_to_call:
/*陳述式*/

ex_catch:
/*錯誤處理*/
goto back_to_call;
可讀性已經很差,不過下面那個更加離譜......。
當錯誤檢測成立跳轉到錯誤處理,
最後返回錯誤檢測的位置。
上式與 try-catch(例外處理) 的跳轉類似,
返回發生錯誤的位置。

若果強制限制不使用 goto 的實現方式,

實現方式會變成如何?
int error_is_not_happened = 1;
do{
    do{
        if(error_is_not_happened){
            /*陳述式*/
            if(/*錯誤檢測*/){
                error_is_not_happened = 0
                break;
            }
        }
        error_is_not_happened = 1
        /*陳述式*/
    while(0);
/*錯誤處理*/
while(!error_is_not_happened);
可能有更簡單的實現方法,不過我隨便/暫時想到的是這樣。
宣告了變數標記 error_is_not_happened ,非零為真
利用 do{}while(0) 加上錯誤檢測成立後的 break; ,
快速跳離整個陳述式,到達函式的最底部分,進行錯誤處理
再利用 while(!error_is_not_happened) 判斷,
判斷到達這裏(最底部分)的原因是否因為發生了錯誤
,返回最頂部分
,即是以正常運行步驟到達最底部分,允許離開
返回最頂部分後,利用 if(error_is_not_happened){} ,
快速返回錯誤檢測後的位置,
再把 error_is_not_happened 標記賦值為一(true),允許從最底部分離開。
【其實我是覺得上面這一大堆文字已經沒有什麼人想讀了。】

所以:

這樣的可讀性絕對不高吧......這還是只有一個例外處理的情況。
更多例外處理需要使用 更多的 變數標記,
更多的 do{}while()break ,以及更多的標記判斷。
所以在某些情況下使用 goto 的確會比較方便,
甚至比較可讀。

▌參考資料: