goto

goto 是所有流程控制指令的鼻祖。 在低階程式語言裡面,只有一個 goto 可以用來控制流程。 現今的程式語言教科書,把 goto 視為洪水猛獸, 一再勸戒學生不要使用 goto,原因是難以偵錯,不容易理解程式的邏輯結構。 但是,我還是認為 goto 是一個丟掉太可惜的工具。 對於大的程式,或許 goto 真的是弊多於利,但是對於不太複雜的程式, 只要頭腦清楚,應該不至於因為用了 goto 就昏頭轉向吧。

配合 goto 使用的,就是標籤。C 的標籤,就是一個合法的字。 這個字的規則,就和變數名、符號常數名、函式名的命名規則一樣。 標籤的名字不需宣告,只要在字的後面接一個冒號 :, 就使它成了標籤。而,在程式的任何地方,只要出現了

    goto label
C 就立刻跳到
    label:
然後開始執行它的下一個指令。 由此可見,一個函式內的標籤只應該定義一次,否則 C 就不知道要 goto 哪裡去。

goto 經常用來結束層層相套的迴圈。break; 只能解除一層迴圈。 如果有超過一層的迴圈要一口氣解除,用 goto 比較方便。 這裡,我們應用 goto,再寫一遍 vsearch()


int vsearch(int u[], unsigned int m, int v[], unsigned int n) {
    int i, j;
    for (i=0; i < m; ++i)
        for (j=0; j < n; ++j)
            if (u[i] == v[j])
                goto found;
    return -1;
    found:
    return i;
}

很明顯地,跟第一版的 vsearch() 相比, 這個程式的邏輯簡單一些,也不見得有多難讀懂。

以下我們示範第二版的 prime.c 程式,它也是產生前 1000 個質數, 請與第一版的 prime.c 比較。 我們不再需要 isprime 這個旗標性質的變數。


#include <stdio.h>
#define SIZE 1000

/* Calculate the first SIZE primes.  Let the first prime be 2. (prime.c) */
main() {
    int p[SIZE], q, n, i, j;
    p[j=0] = n = 2;
    while (j < SIZE) {
        ++n;
        q = p[i=0];
        while (q*q <= n)
            if (!(n%q))
                goto next;
            else
                q = p[++i];
	p[++j] = n;
    next:
    }
    for (j=0; j<SIZE; ++j)
        printf("%4d:%5d\n", j+1, p[j]);
}

習題

[ 前一節 ]‧[ 後一節 ]‧[ 回目錄 ]



注意:此處所有文件均為原著,個別的版權宣告日後會一一公布, 整體版面設計亦尚未完成。但仍請勿抄襲文字與圖片,以免觸犯著作權法。

Created: May 21, 2000
Last Revised: Feb 22, 2001
© Copyright 2001 Wei-Chang Shann 單維彰

shann@math.ncu.edu.tw