![]() |
C 教材:廣義字,if-else 與 || 算子 |
定義廣義字 (general word) 是 以一個或連續若干多個:空格、tab、LF 字元所隔開的任意一串可見字元 (printable)。例如
while((c = getchar()) != EOF)裡面有 5 個廣義字:while((c、 =、getchar())、!=、EOF)。 這也就是 wc 程式中對所謂「字」 (word) 的定義, 同時也是 vi 程式中用 W、B 和 E 指令所定義的「字」。
以下我們要寫一個程式,列出純文字輸入檔中有幾個廣義字。 這個程式的一個主要觀念上的技巧,就是要知道目前讀到的字元在什麼狀態。 我們用 state 代表狀態。 此處只有兩種狀態:在一個廣義字的裡面或外面。 為了增加程式的可讀性,我們用兩個符號常數 IN 和 OUT 來代表這兩種狀態。 state 原本是 OUT。 當我們從 OUT 狀態首次遇見可見字元時, state 改為 IN。 一直到首次遇見空格、tab 或 LF 字元,才改為 OUT。 每進入 IN 一次,就記錄一次廣義字的個數。
#include <stdio.h> #define IN 1 #define OUT 0 /* 簡化的 UNIX wc -w 程式 (mywc.c) */ main() { int c, nw=0, state=OUT; while((c = getchar()) != EOF) { if (c == ' ' || c == '\t' || c == '\n') state = OUT; else if (state == OUT) { state = IN; ++nw; } } printf("%d\n", nw); }
if (CONDITION) STATEMENTS_1 else STATEMENTS_0若 CONDITION 成立,執行 STATEMENTS_1, 否則執行 STATEMENTS_0。 不論 STATEMENTS_1 或 STATEMENTS_0, 執行結束之後,都直接跳去執行 STATEMENTS_0 的下一個指令。
在前面的程式中,若遇到新輸入的字元是空格、tab 或 LF, 就把 state 設定為 OUT。 若連續出現這些字元也沒關係,反之 state 總是 OUT。 否則就是輸入了可見字元。 但是只有第一次從 OUT 狀態遇到可見字元的時候才算一個字, 而且將 state 變成 IN。 否則不做任何事。
在上面的 if-else 結構中,STATEMENTS_0 只有一個指令,就是
if (state == OUT) { state = IN; ++nw; }這個指令。雖然看起來有很多,但是在結構上,它就是一個 if 結構而已, 算是一個指令。 因為只有一個指令,所以不必放在 { } 裡面。
這個程式的輸出,應該和 wc -w 的結果一樣。
習題
![]() |
![]() |
單維彰 (2000/03/30) --- |