因為我們還不會輸入資料,所以下面這個範例,我們將一個序列的值寫在程式裡面。 注意,在宣告序列的時候,可以順便定義它的值。這些數值是某班學生的某科成績。 以下的程式示範一些敘述統計的計算,包括總和、平均、標準差、最大、最小、 列出超過「平均 + 標準差」的值、列出不到「平均 - 標準差」的值。
#include <stdio.h> #include <math.h> #define N 58 /* Do some descriptive statistics on an array. (demo-stats.c) */ main() { int i, x[N]={61,99,67,80,65,61,60,70,66,61,15,64,74,94,61,60,77, 64,71,83,17,70,72,48,45,81,88,86,83,82,71,61,98,93, 47,60,78,69,81,99,72,70,73,44,69,99,89,82,99,14,15, 47,60,80,82,68,98,43}; int sum, max, min; float mean, var, cut; /* 計算總和、最大、最小、平均 */ sum = max = 0; min = 100; for (i=0; i<N; ++i) { sum = sum + x[i]; if (x[i] > max) max = x[i]; if (x[i] < min) min = x[i]; } mean = (sum*1.0)/N; printf("Sum = %4d\n", sum); printf("MAX = %4d\n", max); printf("MIN = %4d\n", min); printf("MEAN = %7.2f\n", mean); /* 計算標準差 */ var = 0; for (i=0; i<N; ++i) var = var + (x[i] - mean)*(x[i] - mean); var = sqrt(var / (N-1)); printf("VAR = %7.2f\n", var); /* 列出盈與不足 */ printf("HIGH = "); cut = mean + var; for (i=0; i<N; ++i) if (x[i] > cut) printf("%3d", x[i]); putchar('\n'); printf("LOW = "); cut = mean - var; for (i=0; i<N; ++i) if (x[i] < cut) printf("%3d", x[i]); putchar('\n'); }
注意 mean = (sum*1.0)/N; 的語法,這是因為 sum 和 N 都是整數型態,但 mean 需要算出小數。這是解決的方法之一, 以後還會知道其他的解法。因為計算標準差的時候要開根號, 所以 #include <math.h>, 記得在編譯的時候要用 -lm 這個參數。
以上程式當然還有許多改進的空間,但是此處我們只是示範序列的計算而已。 其他不在此處多談。
其次,我們再觀察一個程式,它會列出前 1000 個質數 (從 2 開始)。
#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, isprime; p[j=0] = n = 2; while (j < SIZE) { ++n; isprime = 1; q = p[i=0]; while (isprime && q*q <= n) if (n%q == 0) isprime = 0; else q = p[++i]; if (isprime) p[++j] = n; } for (j=0; j<SIZE; ++j) printf("%4d:%5d\n", j+1, p[j]); }
這個程式,讓 p[0] 和 n 都從 2 開始,逐一增加 n, 檢查它是否為質數。如果是,就儲存到 p[] 裡面。 所以,如果 SIZE 過大,有可能產生錯誤。 (C 的內建資料型態無法產生非常大的整數來檢查是否為質數)。 所謂質數,就是不能用比它自己的平方根還要小之質數所整除。 這就是 prime.c 的工作原則。
程式的設計,使用到一個旗標 (flag) 性質的變數 isprime。 它用來記錄 n 是一個質數 (isprime == 1) 或不是質數 (isprime == 0)。 q*q <= n 就是在檢查測試用的質數 q 不超過根號 n, 但是這樣寫可以省去呼叫 sqrt() 的麻煩。 而 if(n%q == 0) 就是說「若 n 被 q 整除的意思」。 其實這句話可以簡寫成 if(!(n%q))。 n%q 就是 q 除 n 的餘數。 如果整除,就是 0,也就是邏輯的 False;反之若不整除,就是一個正數, 也就是邏輯的 True (只要不是 0 就是 True)。 因此,if(!(n%q)) 在邏輯上和 if(n%q == 0) 是等價的。 if(n%q == 0) 那一整句話的意思就是說 「若 n 被 q 整除的意思,知道 n 不是質數,否則令 q 是下一個已知的質數。」
習題
1: 3 2: 7 3: 11 4: 19 ...
1: (3,5) 2: (5,7) 3: (11,13) ...