实验3
task1
代码
#include <stdio.h> char score_to_grade(int score); // 函数声明 int main() { int score; char grade; while(scanf("%d", &score) != EOF) { grade = score_to_grade(score); // 函数调用 printf("分数: %d, 等级: %c\n\n", score, grade); } return 0; } // 函数定义 char score_to_grade(int score) { char ans; switch(score/10) { case 10: case 9: ans = 'A'; break; case 8: ans = 'B'; break; case 7: ans = 'C'; break; case 6: ans = 'D'; break; default: ans = 'E'; } return ans; }
问题1: 功能:函数 score_to_grade 的功能是根据输入的整数分数 score ,通过对 score/10 的判断,将分数转换为对应的等级字符(如 'A' 、 'B' 等)并返回。形参类型: int (接收整数分数)。
返回值类型: char (返回表示等级的字符)。
问题2:1. 字符常量表示错误:
原代码使用单引号 'A' 表示字符常量,修改后用双引号 "A" (字符串),而 ans 是 char 类型,不能赋值字符串,会导致编译错误。
2. 缺少 break 语句:
每个 case 分支后未添加 break ,会引发“穿透”现象。例如输入 95 ( score/10 为 9 ),执行完 case 9 后会继续执行 case 8 等后续代码,最终结果错误。
3. case 10 逻辑错误:
修改后的代码中, case 10 分支未处理(无赋值语句),且未添加 break ,会穿透到 case 9 ,导致逻辑混乱。
task2
代码
#include <stdio.h> int sum_digits(int n); // 函数声明 int main() { int n; int ans; while(printf("Enter n: "), scanf("%d", &n) != EOF) { ans = sum_digits(n); // 函数调用 printf("n = %d, ans = %d\n\n", n, ans); } return 0; } // 函数定义 int sum_digits(int n) { int ans = 0; while(n != 0) { ans += n % 10; n /= 10; } return ans; }
问题1:函数`sum_digits`的功能是计算输入整数`n`的各位数字之和。
问题2:原因:新定义的递归版本中,若 n < 10 直接返回 n (处理个位);否则通过 sum_digits(n/10) + n%10 递归分解 n ,先处理高位再累加当前位,与原循环逐位分解累加的逻辑一致。
算法思维区别:原实现是迭代循环,通过循环逐次处理每一位;新实现是递归,利用函数自身调用分解问题,二者本质都是逐位提取数字并求和,仅实现方式(迭代 vs 递归)不同。
task3
代码:
#include <stdio.h> int power(int x, int n); // 函数声明 int main() { int x, n; int ans; while(printf("Enter x and n: "), scanf("%d%d", &x, &n) != EOF) { ans = power(x, n); // 函数调用 printf("n = %d, ans = %d\n\n", n, ans); } return 0; } // 函数定义 int power(int x, int n) { int t; if(n == 0) return 1; else if(n % 2) return x * power(x, n-1); else { t = power(x, n/2); return t*t; } }
问题1:函数 power 的功能是计算并返回参数 x 的 n 次幂(即 x^n )。通过递归方式,根据 n 的不同取值(0、奇数、偶数),采用不同的计算逻辑实现幂运算。
问题2:
函数 power 是递归函数,因为其在函数体内调用了自身。递归模式对应的数学公式模型如下:
- 当 n = 0 时: x^n = 1
- 当 n 为奇数时: x^n = x \times x^{n-1}
- 当 n 为偶数时: x^n = \left( x^{n/2} \right)^2
task4
代码:
#include <stdio.h> #include <math.h> // 判断素数函数 int is_prime(int n) { if (n <= 1) return 0; for (int i = 2; i <= sqrt(n); i++) { if (n % i == 0) { return 0; } } return 1; } int main() { int count = 0; printf("100以内的孪生素数:\n"); for (int n = 3; n <= 97; n += 2) { // 遍历可能的n值,步长2(偶数无需判断) if (is_prime(n) && is_prime(n + 2)) { printf("%d %d\n", n, n + 2); count++; } } printf("100以内的孪生素数共有%d个.\n", count); return 0; }
结果:
task5
代码:
#include <stdio.h> #include <stdlib.h> #define MAX_MOVES 10000 char move_records[MAX_MOVES][50]; // 存储移动步骤 int move_count = 0; // 记录移动总次数 // 汉诺塔递归函数 void hanoi(int n, char from_peg, char to_peg, char aux_peg) { if (n == 1) { snprintf(move_records[move_count], sizeof(move_records[move_count]), "%d: %c --> %c", n, from_peg, to_peg); move_count++; return; } hanoi(n - 1, from_peg, aux_peg, to_peg); snprintf(move_records[move_count], sizeof(move_records[move_count]), "%d: %c --> %c", n, from_peg, to_peg); move_count++; hanoi(n - 1, aux_peg, to_peg, from_peg); } int main() { int n; while (scanf("%d", &n) != EOF) { move_count = 0; // 每次输入新n时重置计数和记录 hanoi(n, 'A', 'C', 'B'); // 输出移动步骤 for (int i = 0; i < move_count; i++) { printf("%s\n", move_records[i]); } printf("一共移动了%d次.\n", move_count); } return 0; }
结果:
task6
代码:
#include <stdio.h> int func(int n, int m); // 函数声明 int main() { int n, m; int ans; while(scanf("%d%d", &n, &m) != EOF) { ans = func(n, m); // 函数调用 printf("n = %d, m = %d, ans = %d\n\n", n, m, ans); } return 0; } // 迭代方式实现组合数计算 int func(int n, int m) { if (m == 0 || m == n) { return 1; } if (m > n) { return 0; } int result = 1; for (int i = 0; i < m; i++) { result = result * (n - i) / (i + 1); } return result; }
#include <stdio.h> int func(int n, int m); // 函数声明 int main() { int n, m; int ans; while(scanf("%d%d", &n, &m) != EOF) { ans = func(n, m); // 函数调用 printf("n = %d, m = %d, ans = %d\n\n", n, m, ans); } return 0; } // 递归方式实现组合数计算 int func(int n, int m) { if (m == 0 || m == n) { return 1; } if (m > n) { return 0; } return func(n - 1, m) + func(n - 1, m - 1); }
task7
代码:
#include <stdio.h> // 函数声明 int gcd(int a, int b, int c); int main() { int a, b, c; int ans; while(scanf("%d%d%d", &a, &b, &c) != EOF) { ans = gcd(a, b, c); // 函数调用 printf("最大公约数: %d\n\n", ans); } return 0; } // 函数定义:用穷举法计算三个整数的最大公约数 int gcd(int a, int b, int c) { int min_val = a; // 找出三个数中的最小值 if (b < min_val) { min_val = b; } if (c < min_val) { min_val = c; } // 从最小值开始向下穷举 for (int i = min_val; i >= 1; i--) { if (a % i == 0 && b % i == 0 && c % i == 0) { return i; } } return 1; // 理论上不会执行到这,除非输入全为0(但题目未明确处理,这里作为保底) }