題目要求
- C 語言
- 遞迴實作
- 隨機產生一個數 (如 1~100)
- 使用者輸入猜測 → 提示「大了/小了/猜對」
- 猜對則結束
完整程式碼 (修正原回答:種子初始化、輸入驗證、尾遞迴)
#include
#include
#include
/**
* 遞迴猜數字主邏輯
* @param target 目標數字
* @param attempt 當前嘗試次數 (可選,用於統計)
*/
void guessNumber(int target, int attempt) {
int guess;
printf("第 %d 次嘗試,請輸入 1-100 整數: ", attempt);
// 輸入驗證:處理非整數輸入
if (scanf("%d", &guess) != 1) {
printf("輸入無效,請輸入整數。\n");
// 清空輸入緩衝區
while (getchar() != '\n');
guessNumber(target, attempt); // 重新嘗試,不計次數
return;
}
if (guess < 1 || guess > 100) {
printf("超出範圍 (1-100),請重新輸入。\n");
guessNumber(target, attempt);
return;
}
if (guess > target) {
printf("大了!\n");
guessNumber(target, attempt + 1);
} else if (guess < target) {
printf("小了!\n");
guessNumber(target, attempt + 1);
} else {
printf("恭喜!你在第 %d 次猜中了!答案是 %d。\n", attempt, target);
// 遞迴自然結束 (返回主函數)
}
}
int main() {
// 1. 初始化隨機種子 (僅執行一次)
srand((unsigned int)time(NULL));
// 2. 產生 1-100 隨機數
int secret = rand() % 100 + 1;
printf("=== 猜數字遊戲 (遞迴版) ===\n");
printf("我已想好一個 1 到 100 之間的數字。\n\n");
// 3. 啟動遞迴猜測
guessNumber(secret, 1);
return 0;
}
執行流程範例
=== 猜數字遊戲 (遞迴版) ===
我已想好一個 1 到 100 之間的數字。
第 1 次嘗試,請輸入 1-100 整數: 50
大了!
第 2 次嘗試,請輸入 1-100 整數: 25
小了!
第 3 次嘗試,請輸入 1-100 整數: 37
大了!
第 4 次嘗試,請輸入 1-100 整數: 31
恭喜!你在第 4 次猜中了!答案是 31。
關鍵點解析
| 項目 | 說明 |
| 隨機種子 | `srand(time(NULL))` 僅在 `main` 呼叫**一次**,避免同秒多次遊戲產生相同數列 |
| 範圍產生 | `rand() % 100 + 1` → 1~100 (含邊界) |
| 遞迴終止 | 猜對時函數直接 `return`,層層返回 `main` |
| 輸入驗證 | `scanf` 回傳值檢查 + 緩衝區清理,防止無限迴圈 |
| 尾遞迴 | 遞迴呼叫為函數最後動作,編譯器 `-O2` 可優化為迴圈 (常數堆疊) |
堆疊溢位風險評估
- 最壞情況:二分法約 log₂(100) ≈ 7 次;隨機猜測期望 ~50 次;極端用戶連續錯誤輸入可達數百次
- 典型堆疊大小 1-8 MB,每幀 ~32 bytes → **安全深度 > 10,000 層**
- **結論**:遊戲場景下遞迴深度極安全,但**教學外請用 `while` 迴圈**
進階延伸:二分法最佳策略提示
// 在提示「大了/小了」後,可顯示建議範圍
int min = 1, max = 100;
// 猜大了:max = guess - 1
// 猜小了:min = guess + 1
printf("建議範圍: %d - %d\n", min, max);
總結
遞迴實作猜數字遊戲邏輯清晰:`輸入 → 比較 → 遞迴或結束`。關鍵在於**隨機種子初始化一次**、**輸入驗證防呆**、**尾遞迴優化友善**。此為經典遞迴教學範例,**實務開發請改用 `while(true)` 迴圈**。
- 上一篇文章: Python 爬取美團外賣商家資料:動態網頁、AJAX 介面分析與反爬應對
- 下一篇文章: Java 內部類作為方法參數:概念解析、實戰範例與設計模式應用
Copyright ©
程式碼之家 All Rights Reserved