ETJava Beta | Java    注册   登录
  • 搜索:
  • 2个月搞定计算机二级C语言——真题(5)解析

    发表于      阅读(1)     博客类别:Crawler     转自:https://www.cnblogs.com/main-studio/p/18511838
    如有侵权 请联系我们删除  (页面底部联系我们)  

    1. 前言

    本篇我们讲解2个月搞定计算机二级C语言——真题 5

    真题5-程序评分

    2. 程序填空题

    2.1 题目要求

    真题5-程序填空

    2.2 提供的代码

    #include <stdio.h>
    
    double fun(int n) {
        int    i;
        double s, t;
        /**********found**********/
        s = __1__;
        /**********found**********/
        for (i = 1; i <= __2__; i++) {
            t = 2.0 * i;
            /**********found**********/
            s = s + (2.0 * i - 1) * (2.0 * i + 1) / __3__;
        }
        return s;
    }
    
    main() {
        int n = -1;
        while (n < 0) {
            printf("Please input(n>0): ");
            scanf("%d", &n);
        }
        printf("\nThe result is: %f\n", fun(n));
        getchar();
    }
    

    2.3 解题思路

    这道题就是典型的纸老虎题,它作为编程的第一题定会在考场上压力你一下,在题目上做做文章,搞得这道题好像很难的样子,其实主要的代码都写完了,而且也给出了式子的规律,那么我们只需略微出手,便可拿下此题。

    (1) 处填空:

    此处是给变量 s 赋值,可以看到在 fun() 函数的末尾是 return s; 将其作为函数返回值返回,由此可以得出 s 是保存前 n 项和的变量,所以这里我们给它赋值为 0,做一个变量初始化,防止程序开始运行时 s 存储的是垃圾值

    s = 0;  // 初始化为 0
    

    (2) 处填空:

    这里缺一个循环的条件,在题目所给的式子中是从 1 计算到 n 的,循环中 i 做的就是这件事情,所以 i小于等于形参 n 时符合条件,此处填 n

    for (i = 1; i <= n; i++) {  // 1 ~ n
    

    (3) 处填空:

    我们单独看这个式子 (2.0 * i - 1) * (2.0 * i + 1) / __3__,此处可以和题目最后的式子规律一一对应,空缺的第 3 处对应着式子的分母部分 (2*n)²。变量 t 在循环开始时通过 t = 2.0 * i; 已经完成了分母括号里的计算,我们只需使用 t * t 计算平方即可。

    s = s + (2.0 * i - 1) * (2.0 * i + 1) / (t * t);  // 计算 t 乘 t,即 t 的平方
    

    当然计算平方也可以使用 C 语言标准库里的函数——pow 函数,它可以用于计算幂次,定义在 math.h 头文件中,使用需要包含头文件。

    // C 库函数 double pow(double x, double y) 返回 x 的 y 次幂,即 x ^ y
    #include <math.h> // 使用 pow 函数时需要包含 math.h 头文件
    
    s = s + (2.0 * i - 1) * (2.0 * i + 1) / pow(t, 2); // 计算 t 的 2 次幂,即 t 的平方
    

    题目要求不要改动其他函数,不得增行或删行,所以这里我继续使用 t * t 计算平方,平时编程时可以直接用 pow 函数。

    2.4 代码实现

    填写完整的代码:

    #include <stdio.h>
    
    double fun(int n) {
        int    i;
        double s, t;
        /**********found**********/
        s = 0;  // 初始化为 0
        /**********found**********/
        for (i = 1; i <= n; i++) {  // 1 ~ n
            t = 2.0 * i;
            /**********found**********/
            s = s + (2.0 * i - 1) * (2.0 * i + 1) / (t * t);  // 计算 t 乘 t,即 t 的平方
        }
        return s;
    }
    
    int main() {
        int n = -1;
        while (n < 0) {
            printf("Please input(n>0): ");
            scanf("%d", &n);
        }
        printf("\nThe result is: %f\n", fun(n));
        getchar();
    }
    

    提示:为确保代码正常运行,请在题库编程环境的对应题目中进行测试和运行。

    3. 程序修改题

    3.1 题目要求

    真题5-程序修改

    3.2 提供的代码

    #include <stdio.h>
    #pragma warning(disable : 4996)
    
    int my_isalpha(char c) {
        if (c >= 'A' && c <= 'Z')
            return 1;
        else if (c >= 'a' && c <= 'z')
            return -1;
        else
            return 0;
    }
    
    void a() {
        char ch;
        int  sort;
        printf("本程序判断你从键盘上键入字符的种类,请输入字符(串):\n");
        do {
            ch = getchar();
            if (ch != '\n') {
                sort = my_isalpha(ch);
                /**********************found***********************/
                switch (-1 <= sort && sort <= 1) {
                    case 1:
                        printf("%c", '*');
                        break;
                        /**********************found***********************/
                    case -1:
                        printf("%c", '#');
                    case 0:
                        printf("%c", '?');
                }
            }
            /**********************found***********************/
        } while (ch == '\n');
        printf("%c", '\n');
    }
    
    void main() {
        a();
    }
    

    3.3 解题思路

    这道题主要考察 switch 语句的用法。

    (1) 处修改:

    switch 括号中的表达式(即控制表达式)必须是整型或能转换为整型的类型。case 标签也必须是常量表达式,并且必须与 switch 的控制表达式类型兼容。

    所以不需要那一堆的关系、逻辑运算,只需放入 sort 就好,它存储着 my_isalpha 函数的返回值。

    switch (sort) {
    

    (2) 处修改:

    switch 语句中,break 语句用于终止当前 case 分支的执行,并跳出 switch 语句,避免程序继续执行后续的 case 分支。

    在改好第一处后,运行程序输入一个小写字母,返回的是 #?,这是因为此处的 case -1: 的分支没有加 break 语句,导致不能跳出 switch 语句,在执行完 case -1: 分支后又执行了 case -1: 分支,显然我们程序没有按照我们的想法运行。

    这时我们需要将两个分支分别加上 break 语句即可。

    我们在后续的程序开发中可以再加上 default 分支,用来执行不在条件内的操作,从而增强程序的健壮性。

    case -1:
        printf("%c", '#');
        break;
    case 0:
        printf("%c", '?');
        break;
    

    (3) 处修改:

    do while 语句会先执行一遍循环中的程序,再判断循环条件是否为真,真则继续循环,否则执行循环后面的程序。

    ch 存储的是键盘输入的单个字符,'\n' 是一个转义序列,用于表示换行符,对应键盘上的回车键(Enter)。

    这里我没找出什么错误,提供的代码是 while (ch == '\n');,改的话只能改成 while (ch != '\n');,这两个代码我分别提交后都可以得满分。

    分别运行这两个程序,如果按照要求先输入字符再敲回车这两个程序是没有任何区别的。

    但是没有先输入字符直接敲回车,那么区别就来了:while (ch == '\n'); 不论你敲多少次回车,这个循环都不停止,因为符合ch == '\n'这个条件,它会一直循环到你输入不是回车的字符。

    do {
        ch = getchar();
        if (ch != '\n') {
            // ……
        }
        /**********************found***********************/
    } while (ch == '\n');
    

    while (ch != '\n');呢?如果你第一次敲回车此时ch存储的是回车的转义字符'\n',循环条件是ch != '\n',由于循环条件不符合,所以不会进行下一次循环,而是执行while下面的语句了。

    do {
        ch = getchar();
        if (ch != '\n') {
            // ……
        }
        /**********************found***********************/
    } while (ch != '\n');
    

    这就是它俩的区别所在,大家以后编程时需要注意循环/判断的条件哦。

    3.4 代码实现

    修改后的代码:

    #include <stdio.h>
    #pragma warning(disable : 4996)
    int my_isalpha(char c) {
        if (c >= 'A' && c <= 'Z')
            return 1;
        else if (c >= 'a' && c <= 'z')
            return -1;
        else
            return 0;
    }
    void a() {
        char ch;
        int  sort;
        printf("本程序判断你从键盘上键入字符的种类,请输入字符(串):\n");
        do {
            ch = getchar();
            if (ch != '\n') {
                sort = my_isalpha(ch);
                /**********************found***********************/
                switch (sort) {
                    case 1:
                        printf("%c", '*');
                        break;
                        /**********************found***********************/
                    case -1:
                        printf("%c", '#');
                        break;
                    case 0:
                        printf("%c", '?');
                        break;
                }
            }
            /**********************found***********************/
        } while (ch != '\n');
        printf("%c", '\n');
    }
    void main() {
        a();
    }
    

    提示:为确保代码正常运行,请在题库编程环境的对应题目中进行测试和运行。

    4. 程序设计题

    4.1 题目要求

    真题5-程序设计

    4.2 提供的代码

    #include <stdio.h>
    #pragma warning(disable : 4996)
    double fun(int n) {
    }
    main() {
        int    n;
        double s;
        void   NONO();
        printf("Input n:  ");
        scanf("%d", &n);
        getchar();
        s = fun(n);
        printf("s=%f\n", s);
        NONO();
        getchar();
    }
    void NONO() { /* 请在此函数内打开文件,输入测试数据,调用 fun 函数,输出数据,关闭文件。 */
        FILE * rf, *wf;
        int    n, i;
        double s;
        rf = fopen("in.dat", "r");
        wf = fopen("out.dat", "w");
        for (i = 0; i < 10; i++) {
            fscanf(rf, "%d", &n);
            s = fun(n);
            fprintf(wf, "%lf\n", s);
        }
        fclose(rf);
        fclose(wf);
    }
    

    4.3 解题思路

    题目要求计算多项式的值,给定多项式的第一项为 1,第二项到第 n 项是计算阶乘倒数的和。

    我们可以用Sn作为存储累加和的变量,之后通过循环累乘得到阶乘的值,最后计算每一项阶乘的倒数并累加至Sn

    在提交时出现了一点小问题,程序可以正常运行,但提交时判为 0 分。经过测试只要把 main 函数里的NONO();语句注释再提交就好了。

    4.4 代码实现

    填写完整的代码:

    #include <stdio.h>
    #pragma warning(disable : 4996)
    double fun(int n) {
        int           i         = 0;
        double        Sn        = 1.0;  // 存储累加和,多项式的第一项为 1
        unsigned long factorial = 1;
    
        for (i = 1; i <= n; i++) {  // 遍历 1~n,注意 i 从 1 开始
            factorial *= i;         // 分别计算从 1~n 的阶乘
            Sn += 1.0 / factorial;  // 计算阶乘的倒数,并加到累加和变量中
        }
    
        return Sn;
    }
    main() {
        int    n;
        double s;
        void   NONO();
        printf("Input n:  ");
        scanf("%d", &n);
        getchar();
        s = fun(n);
        printf("s=%f\n", s);
        NONO();	// 如果评分没过,把这句注释了再提交就可以了
        getchar();
    }
    void NONO() { /* 请在此函数内打开文件,输入测试数据,调用 fun 函数,输出数据,关闭文件。 */
        FILE * rf, *wf;
        int    n, i;
        double s;
        rf = fopen("in.dat", "r");
        wf = fopen("out.dat", "w");
        for (i = 0; i < 10; i++) {
            fscanf(rf, "%d", &n);
            s = fun(n);
            fprintf(wf, "%lf\n", s);
        }
        fclose(rf);
        fclose(wf);
    }
    

    提示:为确保代码正常运行,请在题库编程环境的对应题目中进行测试和运行。

    5. 后记

    本篇博客到这就结束了,如果您有疑问或建议欢迎您在留言区留言。