You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

10 KiB

实验目的要求

  1. 使用 C++ 语言编写简单的计算机程序,掌握 C++ 程序从编辑、编译到运行的全过程,初步了解 C++ 程序的特点。
  2. 掌握 C++ 语言的数据类型(包括对各种数据类型变量的定义、初始化、赋值等)、运算符和表达式的使用。
  3. 掌握数据的输入输出方法。
  4. 理解基本的解题技巧,掌握用自顶向下、逐步求精的过程设计算法。
  5. 熟练掌握 if/else 语句和 switch 语句的使用。
  6. 熟练掌握 while 语句、do/while 语句和 for 语句的使用以及区别。
  7. 掌握 breakcontinue 程序控制语句的使用。
  8. 理解并掌握如何模块化的用函数来构建程序。
  9. 掌握定义函数的方法,了解函数的重载方法,了解内联函数的机制。
  10. 掌握函数间传递信息的机制。
  11. 掌握函数的嵌套调用(和递归调用)的方法。

实验设备

  • 联想小新 Pro 13 2020 锐龙版笔记本电脑一台
  • CPU: AMD Ryzen 7 4800U with Radeon Graphics 1.80 GHz
  • RAM: 16 GB

实验内容

(一)、

  1. <1> 该程序的功能是将输入的大写字符转换为小写、将输入的小写字符转换为大写

  2. <2> 测试:

    输入 输出
    100 40 0, 1
    2000 3000 1, 0
    1000 1000 0, 1
    2000 300 1, 1
    100 4000 0, 0

    分析:

    输出的第一个数表示输入的第一个数是否大于 1000

    输出的第二个数表示输入的第二个数是否小于第一个数

    当输入为 1000 1000 时,输出为 0, 1,这是因为 float 类型存在精度损失

  3. <3> 测试:

    输出为输入加一

    分析:

    由于大于等于 10 时输出时所使用的为后缀自减,故输出为原数字加一,这与小于 10 时的输出相同。

  4. <4> 使用的为 辗转相减法(更相减损术)

  5. <5> 测试:

    输出:22---10

    分析:

    该程序的功能为对 mn 做整除和取余运算;输出中的 k 是进行除法运算的整除结果,m 是余数

  6. <6>

    i 为奇数时输出星号和井号

  7. <7>

    测试:

    输出:a=2, b=8

    分析:

    进行了一次循环;若改为 while,则循环将进行 0

  8. <5>

    hfc() 函数表示求最大公因数

    lcd() 函数表示求最小公倍数

    测试:

    输入:1 10

    输出:hfc=1 lcd=10

  9. <6>

    fib() 函数的功能为求斐波拉契数列的第 n

    斐波拉契数列的每一项都是前两项之和

  10. <7> 测试:

    (2)A
    (3)5,6
    (1)4,6
    

    分析:

    (2) 中输出的是局部变量 k

    (3) 中输出的是全局变量 k

    (1) 中输出的是全局变量 k

  11. <8> 测试:

    subp函数输出
        1    1
        0    0
    main函数输出
        9    3
        6   12
    subp函数输出
        2    2
        1    1
    

    分析:

    x y 是静态变量,只会创建一次;所以除了在第一次运行 subp() 函数时,都不再会初始化 x y。若把 static 去除,则运行结果会发生改变。因为此时 x y 不再是静态变量,每一次调用 subp() 函数时 x y 都会重新初始化为 0

(二)、

  1. 第一题(<1>24解题分析

    此题较为简单,调用 math.h 库即可

    #include <math.h>
    #include <stdio.h>
    
    double T2(double x) {
        return sqrt(1 + 1 / (x + 1 / (x + 1)));
    }
    
    double T4(double x, double y) {
        return exp(x + y) + exp(x - y);
    }
    
    int main() {
        double x, y;
        scanf("%lf", &x);
        printf("%lf\n", T2(x));
        scanf("%lf%lf", &x, &y);
        printf("%lf\n", T3(x, y));
    }
    

    测试:

    输入:
    1
    1 2
    输出:
    1.290994
    20.453416
    
  2. 第二题(<2>)解题分析:

    此题较为简单,考虑读取的是字符,将字符逆向输出即可

    #include <stdio.h>
    
    int main() {
        char sep[4] = {'\n', ',', ',', ','};
        char theNumber[4];
        fread(theNumber, sizeof(char), 4, stdin);
        for (int i = 3; i >= 0; --i)
            printf("%c%c ", theNumber[i], sep[i]);
    }
    

    测试:

    输入:
    1234
    输出:
    4, 3, 2, 1
    
  3. 第三题(<3>)解题分析:

    此题较为简单,调用 math.h 库即可

    #include <math.h>
    #include <stdio.h>
    
    double theZ(double x, double y) {
        if (x < 0 && y < 0)
            return exp(x + y);
        else if (1 <= x + y && x + y < 10)
            return log(x + y);
        else
            return log10(fabs(x + y));
    }
    
    int main() {
        double x, y;
        scanf("%lf%lf", &x, &y);
        printf("%lf\n", theZ(x, y));
    }
    

    测试:

    输入1 10
    输出1.041393
    
  4. 第五题(<5>13解题分析

    此题较为简单,可以使用 for 循环,这里使用递归进行求解

    int T1(int i) {
        return i == 1 ? i : i + T1(i - 1);
    }
    
    long T3(long i) {
        return i == 2 ? i * (i - 1) : i * (i - 1) + T3(i - 2);
    }
    
    int main() {
        printf("%d\n", T1(100));
        printf("%ld\n", T3(40));
    }
    

    测试:

    5050
    11060
    

    分析:

    程序如期运行,结果正确

  5. 第六题(<6>)解题分析:

    比较简单的一道题

    #include <stdio.h>
    
    #define MAGIC_NUMBER 21
    
    void print_left(int i) {
        for (int j = 1; j <= i; j += 2)
            printf(" %d ", j);
    }
    
    void print_right(int i) {
        for (int j = i - 2; j >= 1; j -= 2)
            printf(" %d ", j);
    }
    
    void print_space(int i) {
        for (int j = 1; j <= MAGIC_NUMBER - i - 1; j += 2) {
            printf("   ");
        }
    }
    
    int main() {
        for (int i = 1; i <= MAGIC_NUMBER; i += 2) {
            print_space(i);
            print_left(i);
            print_right(i);
            printf("\n");
        }
    }
    

    测试

                                   1 
                                1  3  1 
                             1  3  5  3  1 
                          1  3  5  7  5  3  1 
                       1  3  5  7  9  7  5  3  1 
                    1  3  5  7  9  11  9  7  5  3  1 
                 1  3  5  7  9  11  13  11  9  7  5  3  1 
              1  3  5  7  9  11  13  15  13  11  9  7  5  3  1 
           1  3  5  7  9  11  13  15  17  15  13  11  9  7  5  3  1 
        1  3  5  7  9  11  13  15  17  19  17  15  13  11  9  7  5  3  1 
     1  3  5  7  9  11  13  15  17  19  21  19  17  15  13  11  9  7  5  3  1
    
  6. 第七题(<7>)题目解析:

    遍历即可

    #include <stdio.h>
    
    int main() {
        for (int i = 1; i <= 10; ++i)
            for (int j = 1; j < i; ++j)
                printf("<%d, %d>\n", i, j);
    }
    

    测试

    <2, 1>
    <3, 1>
    <3, 2>
    ...
    <10, 7>
    <10, 8>
    <10, 9>
    
  7. 第八题(<8>)题目解析:

    暴力输出即可

    #include <stdio.h>
    
    int main() {
        for (int i = 2; i < 10; ++i)
            for (int j = 1; j < i; ++j)
                printf("%d\n", j * 10 + i);
        for (int i = 3; i < 10; ++i)
            for (int j = 2; j < i; ++j)
                for (int k = 1; k < j; ++k)
                    printf("%d\n", k * 100 + j * 10 + i);
        for (int i = 4; i < 10; ++i)
            for (int j = 3; j < i; ++j)
                for (int k = 2; k < j; ++k)
                    for (int l = 1; l < k; ++l)
                        printf("%04d\n", l * 1000 + k * 100 + j * 10 + i);
    }
    

    测试:

    12
    13
    23
    ...
    4789
    5789
    6789
    
  8. 第九题(<9>)题目解析:

    使用递归进行求解较为简单

    #include <stdio.h>
    
    void find_fact(int n) {
        int is_fact = 1;
        for (int i = 2; i < n; ++i) {
            if (n % i == 0) {
                printf("%d*", i);
                find_fact(n / i);
                is_fact = 0;
                break;
            }
        }
        if (is_fact) {
            printf("%d", n);
        }
    }
    
    int main() {
        int n;
        scanf("%d", &n);
        find_fact(n);
    }
    

    测试:

    输入16
    输出2*2*2*2
    输入15
    输出3*5
    输入200
    输出2*2*2*5*5
    

(三)、

  1. 第一题解题分析:

    需要注意重复使用的数字

    #include <stdio.h>
    
    #define LEN 12
    
    int main() {
        int nums[LEN] = {1, 20, 20, 12, 3, 5, 7, 4, 6, 100, 11, 8};
        int comp, t;
        comp = nums[1] > nums[0] ? 1 : nums[1] < nums[0] ? -1 : 0;
        printf("(");
        for (int i = 1; i < LEN; ++i) {
            t = nums[i] > nums[i - 1] ? 1 : nums[i] < nums[i - 1] ? -1 : 0;
            if (t)
                if (t == comp)
                    printf("%d ", nums[i - 1]);
                else {
                    printf("%d), (%d ", nums[i - 1], nums[i - 1]);
                    comp = nums[i] > nums[i - 1]   ? 1
                           : nums[i] < nums[i - 1] ? -1
                                                   : 0;
                }
            else
                comp = nums[i] > nums[i - 1] ? 1 : nums[i] < nums[i - 1] ? -1 : 0;
        }
        printf("%d)", nums[LEN - 1]);
    }
    

    测试:

    (1 20), (20 12 3), (3 5 7), (7 4), (4 6 100), (100 11 8)
    
  2. 第二题解题分析:

    只需反复求出后三位乘以 12 的结果即可

    #include <stdio.h>
    
    int main() {
        int n = 12;
        for (int i = 0; i < 100; ++i)
            n = n % 1000 * 12;
        printf("%d\n", n % 1000);
    }
    

    测试:

    512
    

实验总结

此次实验让我更加深入的了解了 C++ 语言的特性,学习了许多 C++ 语言更深入的用法及技巧,对于函数和递归有了更深一步的认识,也对编程有了新的体会。

在完成 T10 时,本地编译出现了错误;经排错发现为报告代码出现问题。将代码中 int fun(int) 的声明修改为 void fun(int) 后编译通过。通过此测试了解到了 C++ 语言中声明应与实现一致。

参考资料

  1. 参考了 C17 标准
  2. C Plus Plus Reference