实验3

任务1

+源代码task1.c:

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

+测试截图:image

+问题回答
问题1:函数score_to_grade的功能是将整数分数,按照除法计算后比较数字大小后将分数转换为对应的等级并返回。形参类型是int整型,返回值类型是char字符型。
问题2:①双引号 "A" 是字符串,不能赋值给ans。ans 是单个字符变量,要用单引号 ''。
②每个switch后面缺少 break,使得不能及时跳出。如若执行了case 10 ,case 9 后,会继续往下顺序执行 case 8、case7…… 后面的代码。

任务2

+源代码task2.c:

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

+测试截图:image

+问题回答
问题1:函数sum_digits的作用是计算输入的每个数的各个位置数字之和,返回累加结果。
问题2:能。区别:原代码是迭代写法,一位位循环累加。用 while 循环反复取出个位,直到为0停止。
第二种代码是递归写法,把大问题拆为子问题。整数各位之和为当前最后一位数字和去掉最后一位剩下数字的各位数字的和,
直到n<10,返回小于10的数字本身。

任务3

+源代码task3.c:

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

+测试截图:image

+问题回答
问题1:函数power的功能是计算整数底数 x的非负整数次幂。 当x是奇数时,xx的n-1次,当x是偶数时,x的幂直接对半折再平方求取。
问题2:是递归函数。数学模型:
power(x,n)-->1,当n=0;
-->x
power(x,n-1),当n是奇数时;
-->[power(x,n/2)]**2,当n是偶数时。
插入图片:

qq_pic_merged_1794493821108

问题3:①逻辑仍然正确,都是当幂为一半时直接平方。算出的结果完全等价。
②性能不同:原写法只执行一次 power(x,n/2),接着t*t自乘。调用power次数少。改后的代码power(x,n/2)多乘了一个,会多调用函数power,产生大量冗余重复计算,同一个子问题会被独立求解两遍;每一层偶数分支都会让递归数量翻倍。
原代码会调用6次,(16.8.4.2.1.0)新代码调用47次,(16两次,8四次,4八次,2十六次,1十六次,0一次)

任务4

+源代码task4.c:

#include <stdio.h>
int classify_triangle(int a,int b,int c);
int main()
{
	int a,b,c;
	int ans;
	while(scanf("%d %d %d",&a,&b,&c)!=EOF)
	{
		ans=classify_triangle(a,b,c); 
		switch(ans)
		{
		case 0:printf("不能构成三角形\n");break;
		case 1:printf("普通三角形\n");break;
		case 2:printf("等边三角形\n");break;
		case 3:printf("等腰三角形\n");break;
		case 4:printf("直角三角形\n");break;
		}
	}	
	return 0;
}
int classify_triangle(int a,int b,int c)
{
	if(a<=0||b<=0||c<=0)
	return 0;
	
	else if(!(a+b>c&&a+c>b&&b+c>a))
	return 0;
	else if(a==b && b==c)
	return 	2;
	else if(a==b || a==c || b==c)
	return 3;
	else if(a*a+b*b==c*c ||b*b+c*c==a*a||a*a+c*c==b*b)
	return 4;
	else
	return 1;	
}

+测试截图:image

任务5

+迭代源代码task5_1.c:

#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, m, ans);
    }
    return 0;
}
int func(int n, int m)
{
    if(m > n)
        return 0;
    if(m == 0 || m == n)
        return 1;
    int ans1 = 1;
    for(int i = 2; i <= n; i++)
        ans1 *= i;
    int ans2 = 1;
    for(int i = 2; i <= m; i++)
        ans2 *= i;
    int fnm = 1;
    int k = n - m;
    for(int i = 2; i <= k; i++)
        fnm *= i;

    return ans1 / (ans2 * fnm);
}

+测试截图:
20261113154031821

+递归源代码task5_2.c:

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

+测试截图:
20261113154031821

任务6

+源代码task6.c:

#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 j;
	int i=a;
	if(b<i)
	{
		i=b;
	}
	if(c<i)
	{
		i=c;
	}
	for(j=i;j>=1;j--)
	{
		if(a%j==0 && b%j==0 && c%j==0)
			return j;
	}
	return 1;
}

+测试截图:
22

任务7

+源代码task7.c:

#include <stdio.h>
#include <stdlib.h>

void print_charman(int n);

int main() {
    int n;

    printf("Enter n: ");
    scanf("%d", &n);
    print_charman(n);

    return 0;
}

void print_charman(int n)
{
    int i, j;

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

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

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

        if (i > 1)
            printf("\n");
    }
}


+测试截图:image
image
image

​

posted @ 2026-11-14 08:55  剑平天下又逢君  阅读(0)  评论(0)    收藏  举报