基于函数与递归的C语言编程实践
任务一:分数转等级函数实现
编写一个函数将百分制成绩转换为五级制等级(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");
}
}