当前位置:首页 > 技术 > 正文内容

基于函数与递归的C语言编程实践

访客 技术 2026年6月21日 12

任务一:分数转等级函数实现

编写一个函数将百分制成绩转换为五级制等级(A-E)。主程序持续读取输入分数,调用函数进行转换并输出结果。

#include <stdio.h>

char convert_score(int score);

int main() {
    int score;
    char grade;

    while (scanf("%d", &score) != EOF) {
        grade = convert_score(score);
        printf("分数: %d, 等级: %c\n\n", score, grade);
    }

    return 0;
}

char convert_score(int score) {
    char result;

    switch (score / 10) {
        case 10:
        case 9: result = 'A'; break;
        case 8: result = 'B'; break;
        case 7: result = 'C'; break;
        case 6: result = 'D'; break;
        default: result = 'E';
    }

    return result;
}

功能说明:函数接收整型参数表示分数,依据十位数值通过switch语句映射到对应字符等级。注意每个分支必须包含break防止穿透执行。

任务二:数字各位求和

设计函数计算正整数各位数字之和,采用循环方式逐位提取并累加。

#include <stdio.h>

int digit_sum(int num);

int main() {
    int n, total;

    while (printf("Enter n: "), scanf("%d", &n) == 1) {
        total = digit_sum(n);
        printf("n = %d, ans = %d\n\n", n, total);
    }

    return 0;
}

int digit_sum(int num) {
    int sum = 0;

    while (num != 0) {
        sum += num % 10;
        num /= 10;
    }

    return sum;
}

算法解析:利用取模运算获取个位数,除法缩小原数,重复直至处理完所有位。此迭代方法逻辑清晰且效率较高。

任务三:幂运算的递归实现

使用递归策略高效计算x的n次方,结合分治思想优化偶数指数情况。

#include <stdio.h>

long power(int base, int exp);

int main() {
    int x, n;
    long result;

    while (printf("Enter x and n: "), scanf("%d%d", &x, &n) == 2) {
        result = power(x, n);
        printf("x^%d = %ld\n\n", n, result);
    }

    return 0;
}

long power(int base, int exp) {
    if (exp == 0)
        return 1;
    else if (exp % 2 == 1)
        return base * power(base, exp - 1);
    else {
        long half = power(base, exp / 2);
        return half * half;
    }
}

递归逻辑:当指数为偶数时,分解为两个相同子问题;奇数时转化为偶数情形处理,显著减少递归深度。

任务四:查找孪生素数对

在100以内找出所有相差2的素数对,并统计总数。

#include <stdio.h>

int is_prime(int val);

int main() {
    printf("100以内的孪生素数:\n");
    int count = 0;

    for (int i = 2; i <= 98; i++) {
        if (is_prime(i) && is_prime(i + 2)) {
            printf("%d 和 %d\n", i, i + 2);
            count++;
        }
    }

    printf("共找到 %d 对孪生素数\n", count);
    return 0;
}

int is_prime(int val) {
    if (val < 2) return 0;
    if (val == 2) return 1;

    for (int j = 2; j * j <= val; j++) {
        if (val % j == 0)
            return 0;
    }
    return 1;
}

优化点:判断素数时只需检测到√n即可,提升整体性能。

任务五:汉诺塔移动模拟

实现经典递归问题——汉诺塔,打印每一步移动过程并统计总步数。

#include <stdio.h>

void hanoi(int disks, char source, char auxiliary, char target);
void move_disk(int disk, char from_peg, char to_peg);
int step_count = 0;

int main() {
    int num_disks;

    while (scanf("%d", &num_disks) != EOF) {
        step_count = 0;
        hanoi(num_disks, 'A', 'B', 'C');
        printf("总共移动了 %d 步\n\n", step_count);
    }

    return 0;
}

void hanoi(int disks, char source, char auxiliary, char target) {
    if (disks == 1) {
        move_disk(disks, source, target);
    } else {
        hanoi(disks - 1, source, target, auxiliary);
        move_disk(disks, source, target);
        hanoi(disks - 1, auxiliary, source, target);
    }
}

void move_disk(int disk, char from_peg, char to_peg) {
    printf("第 %d 号盘: %c → %c\n", disk, from_peg, to_peg);
    step_count++;
}

任务六:组合数计算的两种方式

分别用迭代和递归方法实现组合数 C(n,m) 的计算。

迭代版本

int combination_iter(int n, int m) {
    if (m > n || m < 0) return 0;
    if (m == 0 || m == n) return 1;

    long numerator = 1, denominator = 1;

    for (int i = 0; i < m; i++) {
        numerator *= (n - i);
        denominator *= (i + 1);
    }

    return numerator / denominator;
}

递归版本

int combination_recur(int n, int m) {
    if (m == 0 || m == n) return 1;
    if (m > n) return 0;
    return combination_recur(n-1, m) + combination_recur(n-1, m-1);
}

对比分析:迭代法时间复杂度更优,递归法则直观体现组合恒等式原理。

任务七:字符图形打印

根据输入层数n,打印倒金字塔结构的小人图案。

#include <stdio.h>

void draw_figure(int layers);

int main() {
    int level;
    printf("Enter n: ");
    scanf("%d", &level);
    draw_figure(level);
    return 0;
}

void draw_figure(int layers) {
    for (int row = 0; row < layers; row++) {
        // 输出前导制表符
        for (int pad = 0; pad < row; pad++)
            printf("\t");

        // 打印头部 O
        for (int col = 0; col < 2*layers - 2*row - 1; col++)
            printf(" O \t");
        printf("\n");

        // 打印身体 <H>
        for (int pad = 0; pad < row; pad++)
            printf("\t");
        for (int col = 0; col < 2*layers - 2*row - 1; col++)
            printf("<H>\t");
        printf("\n");

        // 打印腿部 I I
        for (int pad = 0; pad < row; pad++)
            printf("\t");
        for (int col = 0; col < 2*layers - 2*row - 1; col++)
            printf("I I\t");
        printf("\n\n");
    }
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。