continue

for, whiledo-while 迴圈中, 如果出現了 continue; 指令,表示不再執行這些迴圈中的其餘指令, 而重頭再開始迴圈。明確地說,如果是

while (COND) {
    ...
    continue;
    ...
}
或是
do {
    ...
    continue;
    ...
} while (COND);
則在遇到 continue; 之後,回到 COND 這個步驟。 如果是
for (PRE ; COND ; POST) {
    ...
    continue;
    ...
}
則在遇到 continue; 之後,回到 POST 這個步驟。

如果在迴圈中必然遇到 continue; 指令, 則它下面的其餘指令不就等於白寫了? 所以,通常 continue; 都是寫在迴圈內的 if-else 結構內。 而且,continue; 只對最內層的 for, whiledo-while 迴圈生效,如果有層層相套的迴圈,要注意這個現象。

以下,我們以一個 mean 程式示範 continue; 的用法。 這個程式,從 stdin 讀入文字資料,假設每一列至多有一個整數。 如果一列中的第一個非空白字元是井字號 (hash, #), 或者有一列是空列,就略過這一列。 然後,輸出總共讀到了幾個數?總和多少?平均多少?


#include <stdio.h>
#define BUFSIZE 80
#define WHITE(c) (c == ' ' || c == '\t')

int s2i(char[]);
int getline(char[], int);

/* Compute the essential count, sum and mean  (mean.c) */
main () {
    int i, nc=0, sum=0;
    char buf[BUFSIZE];

    while (getline(buf, BUFSIZE) > 0) {
        for (i=0; WHITE(buf[i]) ; ++i) ;
        if (buf[i] == '#' || buf[i] == '\n')
	    continue;
        ++nc;
        sum += s2i(buf);
    }
    printf("Count: %-6d  Sum: %-8d  Mean: %-.4g\n", nc, sum, (double) sum/nc);
}

請讀者自己將 s2i()getline() 各別放進檔案, 例如分別是 s2i.cgetline.c。 然後下指令
shell% gcc -c s2i.c getline.c
shell% gcc -o mean mean.c s2i.o getline.o
然後就可以執行了。例如
shell% mean
1
#  2
3
4
Count: 3       Sum: 8         Mean: 2.667
我們還可以將數字寫在純文字檔案裡面,然後用檔案導向 (<)來送給 mean 處理。

以上這個程式,其實並不是非用 continue; 不可。 很明顯地,我們可以將 while 迴圈的內容,改寫成

    while (getline(buf, BUFSIZE) > 0) {
        for (i=0; WHITE(buf[i]) ; ++i) ;
        if (buf[i] != '#' && buf[i] != '\n') {
	    ++nc;
	    sum += s2i(buf);
        }
    }
但是,我們故意要用 continue; 作為練習。 而且,我個人認為,用了 continue; 的程式比較好看。

mean.c 的另一個問題是,稍微浪費了時間。 因為 s2i() 裡面也會做「跳過一列前面的連續空白」這件事, 而我們在 mean.c 裡面已經先將一列前面的連續空白都跳過了。 所以,「跳過一列前面的連續空白」這件事等於被做了兩遍。 這是浪費時間的。 關於這個問題,我們要稍後,學了更多的工具,才能處理。

習題

  1. 寫一個程式,從 stdin 讀入純文字檔案,假設每列至多有一個整數。 如果一列中的第一個字符是 - 號,而且此減號的後面不立即跟著一個數目字, 則略過這一列。最後輸出總共讀到了幾個數?總和多少?平均多少? 例如輸入是
    8
    -
    6
    10
    
    應該總共得到 3 個數、總和 24、平均 8。
  2. x0, x1, ..., xn-1n 個不同的數。定義一個 n-1 階 Lagrange 多項式如下:
    \begin{displaymath}L_i(x) = {\prod_{k=0\atop k\not=i}^n}
\frac{x - x_k}{x_i - x_k}\end{displaymath}
    寫一個符合以下規格的函式
    double lagrange(double node[], int n, double x, int i);
    
    其中 node[k] 就是 xk 的值, 而 lagrange() 的返回值就是 L i (x)。
  3. x0, x1, ..., xn-1n 個給定的常數,以它們為根的 n 階多項式可以寫成
    p (x) = (x - x0 ) (x - x1 ) (x - x2 ) ... (x - xn-1 )
    寫一個符合以下規格的函式,
    double polyval(double x[], unsigned int n, double t, int k)
    
    其中的 x[i],0 <= i <= n-1,就是前述的 x i。 當 k==0 的時候,返回 p (t) 的值, 當 k==1 的時候,返回 p' (t) 的值 (就是 p (x) 在 x=t 處的一次導數)。 對於其他的 k,返回 0。 【提示:應用微分乘法律,導出 p' (x) 的公式】
  4. 寫一個程式,將每一列輸入的文字都做階梯狀排列。例如輸入
    This is a book.
    That is a pen.
    
    就輸出
    This
        is
          a
           book.
    That
        is
          a
           pen.
    
    注意,如果連續出現空格或跳格,要被視為只有一個空格。例如,如果輸入是
    This is a       book.
       That is a  pen.
    
    則輸出也要像上面的階梯一樣。

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



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

Created: May 20, 2000
Last Revised: May 20, 2000
© Copyright 2000 Wei-Chang Shann 單維彰

shann@math.ncu.edu.tw