首页 > 编程语言 >实验3_C语言函数应用编程

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

时间:2024-10-29 21:12:58浏览次数:5  
标签:return 函数 power int 编程 C语言 char ans printf

任务一:

#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,将其转换为对应的等级字符并返回。形参类型是int,即接受一个整数参数。返回值类型是char,即返回一个字符。

问题2:有问题。问题在于当score/10的值为 9 或者 10 时,执行完ans = "A"后,没有break语句,程序会继续执行下一个case,同理对于其他的case也存在这个问题。这样会导致最终返回的等级可能不是预期的结果。例如,如果score为 95,理论上应该返回等级A,但由于没有break,程序会继续执行后续的case,直到遇到break或者整个switch语句结束,这样可能会返回B、C、D或E等错误的等级。此外,ans被定义为字符类型变量,而在修改后的代码中,给ans赋值用了双引号括起来的字符串常量,这是不匹配的类型赋值,在 C 语言中会导致编译错误。

任务2:

#include <stdio.h> 
int sum_digits(int n); // 函数声明 
#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:可以实现同等效果。

两种实现方式背后的算法思维区别如下:

(1)第一种实现方式是采用循环的算法思维。通过不断地取n的末位数字累加到ans中,然后将n除以 10 去掉末位数字,重复这个过程直到n变为 0。这种方式是一种迭代的过程,逐步处理整数的每一位数字。

(2)第二种实现方式是采用递归的算法思维。如果输入的整数n小于 10,直接返回n,因为一个一位数的各位数字之和就是它本身。如果n大于等于 10,则先递归地计算n/10的各位数字之和,再加上n的末位数字n%10。这种方式是将问题不断分解为更小的子问题,直到子问题可以直接求解,然后逐步合并子问题的解得到最终结果。

任务3:

#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次方并返回结果。

问题 2:函数power是递归函数。递归模式为:当n为 0 时,返回 1;当n为奇数时,返回x * power(x, n - 1);当n为偶数时,先计算t = power(x, n/2),然后返回t * t。

数学公式模型为

power(x, 0)= 1;

当n为奇数时,power(x, n)= x* power(x, n -1);
当n为偶数时,power(x, n)= power(x, n/2)* power(x, n/2)。

任务4:

#include <stdio.h>

int is_prime(int n) {
    if (n <= 1) return 0;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return 0;
    }
    return 1;
}

int main() {
    int count = 0;
    printf("100 以内的孪生素数:\n");
    for (int i = 1; i < 100; i++) {
        if (is_prime(i) && is_prime(i + 2)) {
            printf("%d %d\n", i, i + 2);
            count++;
        }
    }
    printf("100 以内的孪生素数共有 %d 个\n", count);
    return 0;
}

任务5:

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

void hanoi(unsigned int n, char from, char temp, char to, int *count);
void moveplate(unsigned int n, char from, char to, int *count);

int main() {
    unsigned int n;
    while (scanf("%u", &n)!= EOF) {
        int count = 0;
        hanoi(n, 'A', 'B', 'C', &count);
        printf("一共移动了%d次。\n", count);
    }
    system("pause");
    return 0;
}

void hanoi(unsigned int n, char from, char temp, char to, int *count) {
    if (n == 1) {
        moveplate(n, from, to, count);
    } else {
        hanoi(n - 1, from, to, temp, count);
        moveplate(n, from, to, count);
        hanoi(n - 1, temp, from, to, count);
    }
}

void moveplate(unsigned int n, char from, char to, int *count) {
    printf("%u:%c-->%c\n", n, from, to);
    (*count)++;
}

任务6:

迭代

#include <stdio.h>

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

    int result = 1;
    for (int i = 1; i <= m; i++) {
        result = result * (n - (m - i)) / i;
    }
    return result;
}
int main() {
    int n, m;
    int ans;
    while (scanf("%d%d", &n, &m)!= EOF) {
        ans = func_iterative(n, m);
        printf("n = %d, m = %d, ans = %d\n\n", n, m, ans);
    }
    return 0;
}

递归

#include <stdio.h>

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

int main() {
    int n, m;
    int ans;
    while (scanf("%d%d", &n, &m)!= EOF) {
        ans = func_recursive(n, m);
        printf("n = %d, m = %d, ans = %d\n\n", n, m, ans);
    }
    return 0;
}#include <stdio.h>
#include <stdlib.h>

int print_charman(int n);

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

任务7:

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

实验总结

知识归纳:

1.函数声明与定义:我学会了如何正确地声明和定义函数,明确函数的输入参数类型和返回值类型,确保在主函数中能够正确调用。理解了函数声明是为了让编译器提前知道函数的存在,而函数定义则是具体实现函数功能的代码部分。

2.循环结构:for循环和while循环的灵活运用。在打印字符小人阵列的程序中,使用for循环控制行数和列数,精确地输出特定格式的图形。通过循环的条件判断,如循环变量的起始值、终止值和步长的设置,实现不同的输出效果。

3.递归与迭代:递归方式:理解了递归的概念和实现方法。在计算组合数和汉诺塔问题中,递归函数通过不断调用自身来解决问题,将复杂问题分解为更小的子问题。但也需要注意递归的深度,避免栈溢出。

迭代方式:掌握了迭代的方法,通过循环和变量的更新来逐步计算结果。与递归相比,迭代通常更高效,尤其是在处理大规模数据时。

体会感受:

 

       在解决不同问题时,需要根据问题的特点选择合适的算法。例如,计算组合数可以使用递归或迭代方式,两种方法各有优缺点。递归方式代码简洁,但可能会导致栈溢出;迭代方式效率高,但代码相对复杂一些。在打印字符小人阵列的问题中,通过分析图形的规律,选择合适的循环结构和条件判断来实现输出。通过递归方式解决问题,让我深刻体会到了程序设计的简洁之美。递归函数能够将复杂问题分解为简单的子问题,使代码更加清晰易懂。但同时也意识到递归的局限性,如栈空间的限制和性能问题。

 

标签:return,函数,power,int,编程,C语言,char,ans,printf
From: https://www.cnblogs.com/guxieyao/p/18514473

相关文章

  • 并发编程(1)——线程
    目录一、day11.线程的建立1.1线程如何发起1.1.1普通函数1.1.2仿函数1.1.3lambda函数1.1.4类的成员函数1.1.5move1.2子线程需要被等待1.3detach1.4.异常处理1.5慎重使用隐式转换1.6如何在线程中使用引用2.thread参数传递和调用原理2.1数据成员2.......
  • 实验2 类和对象_基础编程1
    实验任务1代码t.h1#pragmaonce2#include<string>34classT{5public:6T(intx=0,inty=0);7T(constT&t);8T(T&&t);9~T();1011voidadjust(intratio);12voi......
  • 第六章 FreeRTOS 任务相关 API 函数
    6.1任务创建和删除API函数FreeRTOS的任务创建和删除API函数如表:函数xTaxkCreate()此函数用来创建一个任务,任务需要RAM来保存与任务有关的状态信息(任务控制块),任务也需要一定的RAM来作为任务堆栈。如果使用函数xTaskCreate()来创建任务的话那么这些所需的RAM......
  • 少儿编程学习中的家庭支持:家长角色如何从监督到参与?
    随着少儿编程教育的普及,越来越多的家庭开始意识到编程对孩子未来发展的重要性。编程不仅仅是一项技术技能,更是培养逻辑思维、解决问题能力和创新意识的有效途径。然而,如何在家庭中正确支持孩子的编程学习,对家长而言是一个新的挑战。从过去的“监督学习”到如今的“积极参与和......
  • 少儿编程进入义务教育课程:培养信息科技素养的新政策解读
    近年来,随着数字化进程的推进和人工智能技术的普及,编程教育逐渐走入中小学课堂。教育部在《义务教育课程方案和课程标准(2022年版)》中正式将编程与信息科技教育纳入小学和初中的课程体系中,强调培养学生的计算思维、编程能力和科技素养。这一政策的出台,标志着编程教育已成为义务......
  • JavaScript基本内容续集之函数和对象
    书接上篇,我们讲到了JavaScript的基本内容,这篇讲到JavaScript的函数和对象。目录一、函数(一)概述(二)函数的定义(三)函数的使用1、在程序中调用(分为有返回值和无返回值调用)①无返回值的调用②有返回值的调用2、常见事件①在超链接被点击时调用(监听点击事件)②在按钮被点击......
  • 函数调用寄存器及栈帧结构
    函数调用X86下,遵循被调用者使用规则,函数在调用子函数之前,保存相关寄存器的内容。函数调用时,参数先入栈,接着为返回地址入栈,BP寄存器入栈、再接着就是子函数的局部变量之类的了。常用寄存器栈帧结构函数调用时栈帧结构......
  • C语言中实现一个包含开卡、查询内容、存钱、取钱、转账和修改密码的银行服务系统
       大家好,我是带我去滑雪,每天教你一个小技巧!   本次在C语言中实现一个包含开卡、查询内容、存钱、取钱、转账和修改密码的银行服务系统,下面开始代码实战。目录一、功能模块设计(1)开卡功能(2)查询内容(3)存钱功能(4)取钱功能(5)转账功能(6)修改密码功能二、数据结构......
  • Python 编程的最好搭档—VSCode 详细指南
     刚学Python的同学可能会觉得每次写Python的时候都得打开Cmd有点烦躁,直接上手Pycharm的同学可能会觉得这软件太笨重了,晦涩难用。那么有没有省去打开CMD的步骤,又能弥补Pycharm笨重的特点的软件呢?当然有,答案是VSCode.诞生于2015年的VSCode编辑器,现在可以说是目前最强的编辑......
  • 实验2 类和对象_基础编程1
    实验1task1.cppt.h:#pragmaonce#include<string>//类T:声明classT{//对象属性、方法public:T(intx=0,inty=0);//普通构造函数T(constT&t);//复制构造函数T(T&&t);//移动构造函数~T();//析构函数......