实验3 C语言函数应用编程

实验任务1

1.源代码

#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;
}

2.运行结果

1

3.Q&A

Q1:函数score_to_grade的功能是什么?形参类型、返回值类型是什么?
A1:将输入的数字分数转换为对应的字母等级。其形参类型为int,返回值类型为字符型char。
Q2:如果line21-28以下形式,代码存在哪些问题,请逐一指出。

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

A2:如果将代码改为赋值为"A"、"B",存在数据类型不匹配的问题。"A"是一个字符串字面量,而变量ans被声明为char类型。将字符串的地址赋值给char类型变量会导致编译警告或错误,且运行结果绝对不符合预期。正确的做法必须使用单引号'A'表示字符常量。

实验任务2

1.源代码

#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;
}

2.运行结果

2

3.Q&A

Q1:函数sum_digits的功能是什么?
A1:计算并返回一个整数n各位数字之和。
Q2:如果把函数sum_digits定义成如下实现方式,能实现同样的输出吗?如果能,说明两种实现方式的算法思维区别;如果不能,分析原因。

int sum_digits(int n) {
if(n < 10)
return n;
}
return sum_digits(n/10) + n%10

A2:能够实现相同的输出结果。区别在于原代码采用的是迭代算法,通过while循环不断对数字取余和整除,累加求和。修改后的代码采用的是递归算法,它将原问题分解为求最后一位数字加上剩余位数字之和的子问题,通过函数调用自身来解决,直到当数字小于10时直接返回数字本身。

实验任务3

1.源代码

#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;
    }
}

2.运行结果

3

3.Q&A

Q1:函数power的功能是什么?
A1:计算x的n次幂
Q2:函数power是递归函数吗?如果是,找出递归模式。写出这个递归模式对应的数学公式模型。
A2:是一个递归函数

\[power(x,n) = \begin{cases} 1 & \text{if } n = 0 \\ x \cdot power(x, n - 1) & \text{if } n \text{ 是奇数} \\ power(x, n/2)^2 & \text{if } n \text{ 是偶数} \end{cases} \]

实验任务4

1.源代码

#include <stdio.h>
int classify_triangle(int a, int b, int c);

int main() {
    int a, b, c, type;
    while (scanf("%d %d %d", &a, &b, &c) != EOF) {
        type = classify_triangle(a, b, c);
        switch (type) {
        case 0: printf("不能构成三角形\n\n"); break;
        case 1: printf("普通三角形\n\n"); break;
        case 2: printf("等边三角形\n\n"); break;
        case 3: printf("等腰三角形\n\n"); break;
        case 4: printf("直角三角形\n\n"); break;
        }
    }
    return 0;
}

int classify_triangle(int a, int b, int c) {
    if (a + b <= c || a + c <= b || b + c <= a) {
        return 0;
    }
    if (a == b && b == c) {
        return 2;
    }
    if (a == b || b == c || a == c) {
        return 3;
    }
    if (a * a + b * b == c * c || a * a + c * c == b * b || b * b + c * c == a * a) {
        return 4;
    }
    return 1;
}

2.运行结果

4

实验任务5

1.源代码

迭代
#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 || n == m) return 1;
    long long ans = 1; 
    for (int i = 1; i <= m; i++) {
        ans = ans * (n - i + 1) / i;
    }
    return (int)ans;
}
递归
#include <stdio.h>

int func2(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 func2(int n, int m) {
    if (m == 0 || n == m) {
        return 1;
    }
    if (m > n) {
        return 0; 
    }
    return func(n - 1, m) + func(n - 1, m - 1);
}

2.运行结果

迭代

5_1

递归

5_2

实验任务6

1.源代码

#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 = a;
    if (b < min) min = b;
    if (c < min) min = c;

    for (int i = min; i >= 1; i--) {
        if (a % i == 0 && b % i == 0 && c % i == 0) {
            return i; 
        }
    }
    return 1;
}

2.运行结果

6

实验任务7

1.源代码

#include <stdio.h>
#include <stdlib.h>
void print_charman(int n);
int main() {
    int n;
    printf("Enter n: ");
    while (scanf("%d", &n) != EOF) {
        printf("input n: %d\n", n);
        print_charman(n);  
        printf("\nEnter n: "); 
    }
    return 0;
}

void print_charman(int n) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            printf("\t"); 
        }
        for (int j = 1; j <= 2 * (n - i) + 1; j++) {
            printf("  O  \t"); 
        }
        printf("\n");

        for (int j = 1; j < i; j++) {
            printf("\t");
        }
        for (int j = 1; j <= 2 * (n - i) + 1; j++) {
            printf(" <H> \t"); 
        }
        printf("\n");

        for (int j = 1; j < i; j++) {
            printf("\t");
        }
        for (int j = 1; j <= 2 * (n - i) + 1; j++) {
            printf(" I I \t"); 
        }
        printf("\n");
    }
}

2.运行结果

7

实验感悟

在实验任务4中,限定了三角形边长为整数,若把变量改成double类型来兼容小数,则程序大概率会出错。原因在于计算机的二进制算法在表示诸如0.1这样的小数时为0.000110011001100110011...这样的无限循环二进制数,存在截断的现象。所以为了更贴合实际,可以引入极小误差值来认为它们是在工程中相等的。在三边被判定为能够组成三角形时,可以利用海伦公式计算三角形面积。

#include <stdio.h>
#include <math.h>

#define EPSILON 1e-6

int is_equal(double x, double y) {
    return fabs(x - y) < EPSILON;
}

int is_right_triangle(double a, double b, double c) {
    return is_equal(a*a + b*b, c*c) || 
           is_equal(a*a + c*c, b*b) || 
           is_equal(b*b + c*c, a*a);
}

void analyze_triangle(double a, double b, double c) {
    if (a + b <= c + EPSILON || a + c <= b + EPSILON || b + c <= a + EPSILON) {
        printf("不能构成三角形\n");
        return;
    }

    double p = (a + b + c) / 2.0;
    double area = sqrt(p * (p - a) * (p - b) * (p - c));
    printf("这是一个有效的三角形,面积为: %.2f\n", area);
    if (is_equal(a, b) && is_equal(b, c)) {
        printf("类型: 等边三角形\n");
    } else if (is_equal(a, b) || is_equal(b, c) || is_equal(a, c)) {
        if (is_right_triangle(a, b, c)) {
            printf("类型: 等腰直角三角形\n"); 
        } else {
            printf("类型: 等腰三角形\n");
        }
    } else if (is_right_triangle(a, b, c)) {
        printf("类型: 直角三角形\n");
    } else {
        printf("类型: 普通三角形\n");
    }
}

int main() {
    double a, b, c;

    printf("请输入三角形的三边长\n");
    while (scanf("%lf %lf %lf", &a, &b, &c) == 3) {
        analyze_triangle(a, b, c);
        printf("----------------------------------------\n");
        printf("请输入三角形的三边长:\n");
    }
    printf("输入结束,程序退出。\n");
    return 0;
}

运行结果

8

posted @ 2026-04-15 18:07  Anchorite404  阅读(13)  评论(0)    收藏  举报