You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化找零C程序的硬币模块,实现高复用、低耦合与高内聚?

C找零程序优化实现方案

核心优化思路

  • 用常量结构体统一封装每种货币的核心配置(硬币面值、校验规则等)
  • 实现通用找零计算函数,依赖配置完成逻辑,彻底消除重复代码
  • 主交互逻辑通过选择不同配置实现多货币支持,模块间耦合度极低

1. 定义货币配置常量

通过结构体存储三种货币的所有专属配置,包括面值数组、校验规则:

#include <stdio.h>
#include <stdbool.h>

// 货币配置结构体:封装每种货币的专属属性
typedef struct {
    const char* name;
    const int denominations[6]; // 预留空间适配最多面值数量(Euro有6种)
    const int denom_count;
    bool (*validate_amount)(int); // 金额校验函数指针
} CurrencyConfig;

// AUD专属金额校验:必须是5的倍数且在1-95之间
bool validate_aud(int amount) {
    return (amount >= 1 && amount <= 95) && (amount % 5 == 0);
}

// USD/Euro通用金额校验:仅需在1-95之间
bool validate_general(int amount) {
    return amount >= 1 && amount <= 95;
}

// 定义各货币的常量配置(只读,避免意外修改)
const CurrencyConfig USD_CONFIG = {
    .name = "USD",
    .denominations = {25, 10, 5, 1},
    .denom_count = 4,
    .validate_amount = validate_general
};

const CurrencyConfig AUD_CONFIG = {
    .name = "AUD",
    .denominations = {50, 20, 10, 5},
    .denom_count = 4,
    .validate_amount = validate_aud
};

const CurrencyConfig EURO_CONFIG = {
    .name = "Euro",
    .denominations = {50, 20, 10, 5, 2, 1},
    .denom_count = 6,
    .validate_amount = validate_general
};

2. 实现通用找零计算函数

这是核心复用逻辑,所有货币共享同一套计算代码,仅依赖传入的配置:

// 通用找零计算:根据货币配置返回最少硬币数,非法金额返回-1
int calculate_min_coins(const CurrencyConfig* config, int amount) {
    if (!config->validate_amount(amount)) {
        return -1;
    }

    int coin_count = 0;
    int remaining = amount;

    // 从大面值到小面值遍历,保证最少硬币数
    for (int i = 0; i < config->denom_count; i++) {
        while (remaining >= config->denominations[i]) {
            remaining -= config->denominations[i];
            coin_count++;
        }
        if (remaining == 0) break;
    }

    return coin_count;
}

3. 重构主交互逻辑

主流程只负责用户交互、选择配置、调用通用函数,逻辑清晰:

void run_change_program() {
    char continue_choice;
    do {
        // 选择货币类型
        printf("请选择货币类型:\n");
        printf("1. USD\n2. AUD\n3. Euro\n");
        int currency_choice;
        scanf("%d", &currency_choice);

        const CurrencyConfig* selected_config = NULL;
        switch (currency_choice) {
            case 1: selected_config = &USD_CONFIG; break;
            case 2: selected_config = &AUD_CONFIG; break;
            case 3: selected_config = &EURO_CONFIG; break;
            default:
                printf("无效的货币选择,请重新输入\n");
                continue;
        }

        // 输入金额
        printf("请输入金额(1-95分,AUD需为5的倍数):");
        int amount;
        scanf("%d", &amount);

        // 计算并输出结果
        int result = calculate_min_coins(selected_config, amount);
        if (result == -1) {
            printf("输入的金额不符合%s的要求\n", selected_config->name);
        } else {
            printf("%s找零最少需要%d枚硬币\n", selected_config->name, result);
        }

        // 询问是否继续
        printf("是否继续操作?(y/n):");
        scanf(" %c", &continue_choice); // 空格处理输入缓冲区的换行符

    } while (continue_choice == 'y' || continue_choice == 'Y');
}

int main() {
    run_change_program();
    return 0;
}

优化后的核心优势

  • 代码复用:找零计算逻辑仅实现一次,三种货币完全共享,避免重复代码维护
  • 低耦合:新增/修改货币只需添加/修改对应的CurrencyConfig常量,无需改动核心计算函数
  • 高内聚:货币配置、金额校验、找零计算各自封装,职责单一清晰

内容的提问来源于stack exchange,提问作者Dragon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 01:07:48