首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言練習專案:四則運算題目生成器 v1.0(含缺失分析與重構建議)

     編輯:關於C語言

C語言練習專案:四則運算題目生成器 v1.0(含缺失分析與重構建議)

本專案為課堂限時練習產出,功能為選單選擇運算類型,隨機生成一道題目並可選擇看答案或下一題。程式碼雖能跑通,但存在 goto 濫用、隨機種子缺失、範圍未控、結構混亂等問題。本文提供原始碼、問題分析與重構版本。

原始碼 (v1.0)

#include <stdio.h>
#include <stdlib.h>

int main() {
    int a,b,op,os;
    printf("[每課一練 媽媽再也不用擔心我的學習]\n");
aq1: printf("選擇您想挑戰的運算法則\n");
    printf("1.加法 2.減法 3.乘法 4.除法\n");
    scanf("%d",&op);
    switch(op) {
    aq: case 1:
        a=rand(); b=rand();
        printf("題目:%d + %d = ?\n\n",a,b);
        printf("1.看答案 2.下一題\n");
        scanf("%d",&os);
        if(os==1) { printf("%d + %d =%d\n\n\n",a,b,a+b); goto aq1; }
        else goto aq;
        break;
    at: case 2:
        a=rand(); b=rand();
        printf("題目:%d - %d = ?\n\n",a,b);
        printf("1.看答案 2.下一題\n");
        scanf("%d",&os);
        if(os==1) { printf("%d - %d =%d\n\n\n",a,b,a-b); goto aq1; }
        else goto at;
        break;
    aq2: case 3:
        a=rand(); b=rand();
        printf("題目:%d * %d = ?\n\n",a,b);
        printf("1.看答案 2.下一題\n");
        scanf("%d",&os);
        if(os==1) { printf("%d * %d =%d\n\n\n",a,b,a*b); goto aq1; }
        else goto aq2;
        break;
    aq3: case 4:
        a=rand(); b=rand();
        printf("題目:%d / %d = ?\n\n",a,b);
        printf("1.看答案 2.下一題\n");
        scanf("%d",&os);
        if(os==1) { printf("%d / %d =%d\n\n\n",a,b,a/b); goto aq1; }
        else goto aq3;
        break;
    }
    return 0;
}

嚴重問題清單

問題影響修正方案
缺 srand()每次執行產生相同題目開頭加 srand(time(NULL))
rand() 無範圍數值過大 (0~32767),不適合國小rand()%100+1 限制 1~100
大量 goto程式結構混亂,難維護改用 do-while 迴圈 + 函式
除法無整除保護產生非整數答案調整被除數為除數倍數
減法無序保護可能出現負數答案確保被減數 ≥ 減數
無退出機制選單無 0 選項,只能強制結束加入 case 0: break 並外層迴圈

重構版 v2.0 (模組化、無 goto、完整流程)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void show_menu() {
    printf("\n=== 四則運算練習 ===\n");
    printf("1.加法  2.減法  3.乘法  4.除法  0.結束\n選擇:");
}

int generate_question(int op, int *a, int *b, char *symbol) {
    *a = rand()%100+1; *b = rand()%100+1;
    switch(op) {
        case 1: *symbol='+'; break;
        case 2: *symbol='-'; if(*a<*b){int t=*a;*a=*b;*b=t;} break;
        case 3: *symbol='*'; break;
        case 4: *symbol='/'; if(*b==0)*b=1; *a=*a**b; break;
        default: return 0;
    }
    return 1;
}

int main() {
    srand((unsigned)time(NULL));
    int choice, a, b, ans, correct;
    char sym;
    do {
        show_menu();
        if(scanf("%d",&choice)!=1) break;
        if(choice==0) break;
        if(choice<1 || choice>4) continue;
        generate_question(choice, &a, &b, &sym);
        printf("%d %c %d = ", a, sym, b);
        scanf("%d", &ans);
        switch(choice) {
            case 1: correct=a+b; break;
            case 2: correct=a-b; break;
            case 3: correct=a*b; break;
            case 4: correct=a/b; break;
        }
        if(ans==correct) printf("正確!\n");
        else printf("錯誤,正確答案:%d\n", correct);
    } while(choice!=0);
    printf("再見!\n");
    return 0;
}

重構亮點

  • 單一職責:選單、出題、主迴圈分離
  • 消除 goto,使用 do-while 控制流程
  • 統一題目生成邏輯,集中處理邊界條件
  • 即時判對錯,提升互動體驗

從 v1.0 到 v2.0 的演進,展示了「先跑通、再重構」的務實開發態度,也是從初學者邁向工程師的關鍵一步。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved