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

C語言實戰:企業利潤分級提成獎金計算程式詳解

     編輯:關於C語言

問題背景

企業依據月利潤 I(萬元)分級提成發放獎金,規則如下:

利潤區間提成比例說明
I ≤ 1010%全額按 10%
10 < I ≤ 207.5%超過 10 萬部分按 7.5%
20 < I ≤ 405%超過 20 萬部分按 5%
40 < I ≤ 603%超過 40 萬部分按 3%
60 < I ≤ 1001.5%超過 60 萬部分按 1.5%
I > 1001%超過 100 萬部分按 1%

演算法設計:數軸分界法

預先計算各區間上界對應的累積獎金基數,主程式僅需判斷利潤落在哪個區間,再加上超出部分的獎金,避免重複乘加運算。

基數預計算

bonus1  = 10 * 0.10  = 1.00      // 10 萬以內
bonus2  = bonus1 + 10 * 0.075 = 1.75   // 20 萬以內
bonus4  = bonus2 + 20 * 0.05  = 2.75   // 40 萬以內
bonus6  = bonus4 + 20 * 0.03  = 3.35   // 60 萬以內
bonus10 = bonus6 + 40 * 0.015 = 3.95   // 100 萬以內

單位:萬元。主邏輯:

if (I <= 10)      bonus = I * 0.10;
else if (I <= 20) bonus = bonus1  + (I - 10) * 0.075;
else if (I <= 40) bonus = bonus2  + (I - 20) * 0.05;
else if (I <= 60) bonus = bonus4  + (I - 40) * 0.03;
else if (I <= 100) bonus = bonus6  + (I - 60) * 0.015;
else              bonus = bonus10 + (I - 100) * 0.01;

完整程式碼(C99 標準)

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

int main(void) {
    long profit;          // 萬元單位
    double bonus;         // 獎金可能含小數

    printf("請輸入當月利潤(萬元):");
    if (scanf("%ld", &profit) != 1 || profit < 0) {
        fprintf(stderr, "輸入錯誤:請輸入非負整數。\n");
        return EXIT_FAILURE;
    }

    const double b1 = 10 * 0.10;
    const double b2 = b1 + 10 * 0.075;
    const double b4 = b2 + 20 * 0.05;
    const double b6 = b4 + 20 * 0.03;
    const double b10 = b6 + 40 * 0.015;

    if (profit <= 10)       bonus = profit * 0.10;
    else if (profit <= 20)  bonus = b1 + (profit - 10) * 0.075;
    else if (profit <= 40)  bonus = b2 + (profit - 20) * 0.05;
    else if (profit <= 60)  bonus = b4 + (profit - 40) * 0.03;
    else if (profit <= 100) bonus = b6 + (profit - 60) * 0.015;
    else                    bonus = b10 + (profit - 100) * 0.01;

    printf("應發放獎金總額:%.2f 萬元\n", bonus);
    return EXIT_SUCCESS;
}

關鍵細節解析

  • 資料型別:利潤用 long 避免 32 位元 int 溢位;獎金用 double 保留小數精度。
  • 輸入驗證:檢查 scanf 回傳值與非負條件,增強健壯性。
  • 常數化:基數宣告為 const double,編譯器可優化且防止誤改。
  • 格式化輸出:%.2f 固定兩位小數,符合財務習慣。

進階擴充:資料驅動重構

若稅制頻繁調整,建議改用結構體陣列:

typedef struct {
    long threshold;   // 區間上限(萬),最後一區間設 LONG_MAX
    double rate;      // 該區間稅率
    double base;      // 該區間起始累積獎金
} Bracket;

Bracket brackets[] = {
    {10,  0.10, 0},
    {20,  0.075, 1.0},
    {40,  0.05,  1.75},
    {60,  0.03,  2.75},
    {100, 0.015, 3.35},
    {LONG_MAX, 0.01, 3.95}
};

double calc_bonus(long profit) {
    for (size_t i = 0; i < sizeof(brackets)/sizeof(brackets[0]); ++i) {
        if (profit <= brackets[i].threshold)
            return brackets[i].base + (profit - (i?brackets[i-1].threshold:0)) * brackets[i].rate;
    }
    return 0; // unreachable
}

新增/修改區間只需調整陣列資料,主邏輯完全不動,符合開放封閉原則。

測試案例

輸入利潤(萬)預期獎金(萬)驗算說明
50.505×0.10
151.3751.0 + 5×0.075
302.251.75 + 10×0.05
553.052.75 + 15×0.03
803.653.35 + 20×0.015
1504.453.95 + 50×0.01

常見錯誤與避坑指南

  1. 整數除法截斷:原碼 100000*0.1 中 0.1 為 double,但若寫成 1/10 會變整數除法得 0。務必使用浮點字面常數 0.1 或 1.0/10。
  2. 區間邊界重疊/遺漏:連續 else if 確保互斥完備,邊界值(10,20,40...)歸屬下一區間,符合「超過部分」語意。
  3. 變數未初始化:所有路徑均賦值 bonus,但加上 double bonus = 0; 更保險。

總結

本程式展示了分段函數建模、預計算優化、輸入驗證與資料驅動重構等實務技巧。從單一 main 邏輯出發,逐步演進為可維護、可擴充的結構,是從「寫出能跑的碼」邁向「工程化思維」的典型範例。

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