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

分數加減法初學者代碼深度評析與重構(續)

     編輯:關於C語言

原始代碼問題總覽

#include <stdio.h>
#include <string.h> // 無用
int abs(int a) { return a>0?a:-a; } // 衝突標準庫
int gcd(int a,int b) {
    if(a

嚴重問題逐項解析

  1. #include <string.h> 無用:違反「無必要不增實體」原則。
  2. 自訂 abs 衝突標準庫:標準庫 <stdlib.h> 已有 abs,重定義屬未定義行為。
  3. a^=b^=a^=b 交換屬 UB:同一序列點多次修改 a、b,編譯器可任意行為。正確交換用暫存變數。
  4. gcd 排序多餘:輾轉相除法不要求 a>=b,gcd(3,5) → gcd(5,3) 自然處理。
  5. scanf("%d/%d%c%d/%d") 不容空白:輸入 1 / 2 + 3 / 4 會失敗。應用 "%d / %d %c %d / %d"。
  6. 變數命名 temp,temp0,temp1 無語意:應命名為 lcm, numerator, denominator。
  7. 未檢查分母為零:b*d/gcd 若 b 或 d 為零會除零崩潰。
  8. 輸出邏輯錯誤:if(temp0&&temp1==1) 應為 if(temp1==1),否則分子為 0 時誤判。
  9. return 1 非標準退出碼:成功應 return 0。

重構版(模組化、安全、可讀)

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

typedef struct { long num, den; } Frac;

long ggcd(long a, long b) { return b ? ggcd(b, a%b) : a; }
long llcm(long a, long b) { return a / ggcd(a,b) * b; }

void reduce(Frac *f) {
    long g = ggcd(llabs(f->num), llabs(f->den));
    f->num /= g; f->den /= g;
    if (f->den < 0) { f->num = -f->num; f->den = -f->den; }
}

void print_frac(Frac f) {
    if (f.num == 0) { puts("0"); return; }
    if (f.num < 0) { putchar('-'); f.num = -f.num; }
    if (f.den == 1) printf("%ld\n", f.num);
    else printf("%ld/%ld\n", f.num, f.den);
}

int main() {
    Frac f1, f2; char op;
    while (scanf("%ld / %ld %c %ld / %ld", &f1.num, &f1.den, &op, &f2.num, &f2.den) == 5) {
        if (f1.den == 0 || f2.den == 0) { puts("分母不可為零"); continue; }
        if (op == '-') f2.num = -f2.num;
        else if (op != '+') continue;
        long L = llcm(llabs(f1.den), llabs(f2.den));
        f1.num = f1.num * (L / f1.den) + f2.num * (L / f2.den);
        f1.den = L;
        reduce(&f1);
        print_frac(f1);
    }
    return 0;
}

教學重點總結

  • 「能用標準庫別手寫」(abs、gcd 邏輯可封裝但名稱勿衝突)。
  • 「交換兩數請用暫存變數」,位運算技巧在現代編譯器下無優勢且有風險。
  • 「scanf 格式字串留空白」是讀取彈性輸入的關鍵。
  • 「變數命名即文件」,temp0 這類命名在 Code Review 直接打回。
  • 「錯誤輸入要能優雅處理」,非零退出碼、除零保護、格式錯誤跳過皆是專業素養體現。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved