設計軟體亦如是,大型程式該怎麼做控制權的移轉,常常也會讓開發者傷透腦筋。程式執行其實可以分成許多情況,就以猜數字遊戲來看,程式最後有五種情況,就是猜對數字、猜大超過 5 、猜大小於 5 、猜小超過 5 、 猜小小於 5 。
因此遊戲到最後的五種情況,也就是處於五種不同的狀態中。我們打算以狀態作為顯示最後結果的依據,這是說,猜數字遊戲會分成兩部份,首先是狀態設定,依三層巢狀的 if-else 陳述設定狀態,再來是依狀態顯示最後遊戲的訊息。
利用狀態操作程式的控制移轉是一種技巧,這個效果在我們目前的猜數字可能並不明顯,對我們往後繼續開發程式卻有莫大的助益。
我們提供利用狀態改寫的版本如下
#include <stdio.h> #include <time.h> #include <math.h> enum STATE {RIGHT = 1, BIG_FOUR, BIG_FIVE, SMALL_FOUR, SMALL_FIVE}; int main(void) { int answer = time(NULL); int guess; int diff; int state = 0; answer %= 25; if (answer == 0) { answer = 25; } printf("請猜一個數字 1 到 25: "); scanf("%d", &guess); diff = guess - answer; diff = (int) fabs(diff); if (guess == answer) { state = RIGHT; } else { if (guess > answer) { if (diff > 5) { state = BIG_FIVE; } else { state = BIG_FOUR; } } else { if (diff > 5) { state = SMALL_FIVE; } else { state = SMALL_FOUR; } } } if (state == RIGHT) { printf("猜對囉!\n"); } else if (state == BIG_FIVE) { printf("猜的數字比答案大....還很遠,再加把勁!\n"); } else if (state == BIG_FOUR) { printf("猜的數字比答案大....不錯喔!很接近了\n"); } else if (state == SMALL_FIVE) { printf("猜的數字比答案小....還很遠,再加把勁!\n"); } else if (state == SMALL_FOUR) { printf("猜的數字比答案小....不錯喔!很接近了\n"); } else { printf("猜錯囉!\n"); } return 0; } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:gn4.c 功能:簡單的猜數字遊戲 作者:張凱慶 時間:西元2010年7月 */
第 5 行,我們利用了 C 語言設計一連串整數常數的關鍵字 enum ,來標示狀態
enum STATE {RIGHT = 1, BIG_FOUR, BIG_FIVE, SMALL_FOUR, SMALL_FIVE};
利用 enum 宣告出的特別的列舉型態,其為有名稱的列舉數,實際上是整數常數。這是說,列舉數中如果用等號設定初值,隨後的值都會逐項遞增 1 ,如果沒有用等號設定初值,第一項列舉數會被設成 0 ,隨後的值也都會逐項遞增 1 。
注意,列舉數的宣告不需要等號,首先是 enum ,然後空格,接上列舉型態的名稱,然後是用大括弧圍起來的列舉數。通常宣告列舉型態會放到引入標頭檔之下,也就是所有函數之外,這樣一來所有函數都可以使用。
所以五種狀態,我們用列舉數分別是 RIGHT 、 BIG_FOUR 、 BIG_FIVE 、 SMALL_FOUR 、 SMALL_FIVE ,程式的第 24 行到第 44 行為設定狀態,第 46 行到第 63 行則是依狀態顯示遊戲結果的訊息。
第 46 行到第 63 行,我們用了種不一樣的寫法
if (state == RIGHT) { printf("猜對囉!\n"); } else if (state == BIG_FIVE) { printf("猜的數字比答案大....還很遠,再加把勁!\n"); } else if (state == BIG_FOUR) { printf("猜的數字比答案大....不錯喔!很接近了\n"); } else if (state == SMALL_FIVE) { printf("猜的數字比答案小....還很遠,再加把勁!\n"); } else if (state == SMALL_FOUR) { printf("猜的數字比答案小....不錯喔!很接近了\n"); } else { printf("猜錯囉!\n"); }
因為對不同條件判斷很常用到,所以 else 後面可以直接加另一個 if 陳述,最後的 else 則是可有可無,加的話程式就會執行以上皆非的情況,不加的話,以上皆非就會直接跳過,程式會繼續執行最後 else 底下大括弧的陳述。
來編譯執行看看吧!
問題與討論
- 為什麼要用狀態控制程式?
- 列舉數還可以有哪些應用?
- C 語言有哪些方式可以做多重選擇?
- 連續的 else if 最後若接 else ,這跟 switch-case 的 default 有什麼相似之處?
沒有留言:
張貼留言