![]() |
C 教材:序列 array 資料結構 |
以下的程式,要記錄輸入的純文字檔案中, 每個數目字各出現多少次。 我們可以為每個數目字宣告一個變數來計數。 例如宣告 int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9;。 試想,如果這樣做,將會需要寫 10 層相套的 if-else 結構。 這是非常煩瑣的工作。 見以下範例。
#include <stdio.h> /* 錯誤示範,請勿模倣 (digits-ifelse.c)*/ main() { int c, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9; n0 = n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = n9 = 0; while((c = getchar()) != EOF) if (c == '0') ++n0; else if (c == '1') ++n1; else if (c == '2') ++n2; else if (c == '3') ++n3; else if (c == '4') ++n4; else if (c == '5') ++n5; else if (c == '6') ++n6; else if (c == '7') ++n7; else if (c == '8') ++n8; else if (c == '9') ++n9; printf("%d %d %d %d %d %d %d %d %d %d\n", n0,n1,n2,n3,n4,n5,n6,n7,n8,n9); }
現在我們介紹序列 (array) 資料型態。 其實,序列本身不是一個獨立的資料型態, 它是從基本的資料型態:包括 char、int、 float、double 衍生出來的資料結構。 看以下例子。
#include <stdio.h> /* 計算 0 -- 9 每個數目字出現幾次 (digits.c) */ main() { int c, i, ndigit[10]; for (i=0; i<10; ++i) ndigit[i] = 0; while((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c-'0']; for (i=0; i<10; ++i) printf("%d ", ndigit[i]); putchar('\n'); }
注意,我們故意寫 ndigit[]。 這是書寫 C 語言的習慣。 在 ndigit 之後寫一對 [] 表示它是個序列變數。 如果只寫 ndigit 容易被誤解為普通變數。
同理,如果宣告了
char st[1024];則 st[] 是個維度為 1024 的 char 序列, v[] 是個維度為 256 的 double 序列。
double v[256];
由於 '0' 到 '9' 的字碼是連號, 所以讀進來的數目字字元 c-'0' 就獲得了那個數目字所代表的整數。 這是初學者常常混淆的事。 當您在螢幕上看到 3 的時候, 計算機的內部記錄的是 3 的字碼, 按 C 語法寫,就是 '3';它的字碼是 51。 而 '3'-'0' 才真?得到了整數資料型態的 3。
以上那個程式,分別用 ndigit[i] 來記錄數目字 i 的出現次數。第一個 for-loop 是在定義 ndigit[] 所代表的 10 個整數值。 序列變數,就像所有變數一樣,都是要經過宣告和定義的手續, 才能開始使用的。 第二個 for-loop 是將 ndigit[] 的值依序輸出。 從這個例子,我們看到,定義和輸出序列, 都不能只說變數名字,而是要使用迭代結構來一一執行。 這也是初學者經常忘記的細節,請注意。
最後,看看 ++ndigit[c-'0']; 這個指令。 我們發現,在 [ ] 內的序列編號,可以是任何產生整數結果的 C 語句。 例如 ndigit[9/5+2] 也是可以的。 其次,我們看到,ndigit[i] 就像一個普通變數一樣,可以將它寫在任何 C 語句中容許變數出現的位置。 最後,我們要提醒讀者,若當初一個序列的宣告維度是 N, 則它的標號必須是從 0 到 N-1。 C 語言的編譯程式不會替您看守: 如果您不慎使用到超過 N-1 的序列編號, 它不會警告您,而可能會發生不可預期的錯誤結果。
習題
![]() |
![]() |
單維彰 (2000/03/31) --- |