C语言课堂上的题目解答2

C语言课堂上的题目解答2

_

C++的内容还有一些,C语言课堂上的题目其实都不算简单,故作以下题解

1.输出素数

编程实现输出1000以内自然数中的素数(除其本身以外不能被其它任意整数整除)

本题按照素数的定义实现一个函数,该函数传入一个整数,判断其是否为素数,题目很简单

#include <stdio.h>
#include <stdbool.h>

bool isPrime(int num){
    if (num <= 1){
        return false;
    }else if (num == 2){
        return true;
    }else{
        for (int i = 2; i < num;i++){
            if (num % i == 0){
                return false;
            }
        }
        return true;
    }

}

int main(){
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++){
        if (isPrime(i)){
            printf("%d ", i);
        }
    }
}

这道题唯一要注意的就是bool 类型要导入stdbool.h 头文件(什么鬼,bool居然不是关键字)

2.输出回文数

编程实现输出1000以内自然数中的素数(除其本身以外不能被其它任意整数整除)

这道题的难点依旧是反转数字,方法在题解1里面也有所提及,故不再赘述

#include <stdio.h>
#include <stdbool.h>

bool IsPalindrome(int num){
    int reversed = 0;
    int original = num;
    while (num!=0){
        reversed = reversed * 10 + num % 10;
        num /= 10;
    }
    return original == reversed;
}

int main(){
    int n;
    scanf("%d", &n);
    for (int i = 10; i <= n;++i){
        if (IsPalindrome(i)){
            printf("%d ", i);
        }
    }
    return 0;
}

3.成绩计算

编程实现小学生四则运算测试题并根据答题情况给出成绩

emm,有两种实现效果,第一种是每输出一个等式就立马输入答案,第二种是输出全部等式后再输出答案,如果采用第二种,我们就需要储存每一个等式,由于等式中含有符号和运算数,所以我们不可避免的要用结构体来实现,但由于这堂课离结构体比较远,所以还是实现第一种,我们主要维护2个函数,其中一个用来检查答案是否正确,我们将等式的三个元素(两个运算数和操作符)以及答案传入,根据传入的操作符匹配运算,再与答案比较,最后返回一个布尔值。第二个函数用来生成题目,接受输入然后判断答案是否正确并计算分数,我们在函数内部维护一个包含加减乘除符号的数组,然后利用stdlib.h 内的rand() 函数生成随机数,然后将随机数的范围限定在要求内(如生成小于4的随机数,只需要将生成的随机数对4取余即可),利用随机数选择符号以及生成两个运算数(注意使用rand()前需要使用srand() 函数设置种子,具体设置方法见代码),生成算式后,我们接受答案的输入,调用前一个函数判断是否正确并计算最终分数

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

bool examine(double a, double b, char sym, double answer){
    switch (sym){
        case '+':
            if (a + b == answer){
                return true;
            }
            else{
                return false;
            }
        case '-':
            if (a - b == answer){
                return true;
            }
            else{
                return false;
            }
        case '*':
            if (a * b == answer){
                return true;
            }
            else{
                return false;
            }
        case '/':
           if ((a/b - answer)<1e-6){
               return true;
           }
           else{
               return false;
           }
    }
}

int test(){
    int score = 0;
    int n = 10;
    char sym[4] = {'+', '-', '*', '/'};
    while(n--){
        srand((unsigned)time(NULL));
        int a = rand() % 100;
        int b = rand() % 100;
        int op = rand() % 4;
        char rsym = sym[op];
        double answer;
        printf("%d %c %d =  ", a, rsym, b);
        scanf("%lf", &answer);
        if (examine((double)a, (double)b, rsym, answer)){
            score += 10;
        }
    }
    return score;
}

int main(){
    int i;
    long id;
    printf("请输入学号:");
    scanf("%ld", &id);
    printf("请回答测试题目,直接输入答案\n");
    printf("学号为%ld的同学,你的成绩为:%d\n", id,test());
}

有一些值得注意的点:

1.要注意数据类型,因为整数除以整数不一定为整数

2.在比较小数大小时应当用差值是否小于一个给定的误差的方法,不可直接用相等运算符,因为浮点数都是有误差的

4.求解非线性方程2

使用二分法求解方程:f(x)=x^3+2x^2+10x-20=0 [0,2] 上的根

这道题指明了让我们使用二分法,故我们使用二分法。首先我们可以先实现一个计算f(x_0) 的函数便于简化代码,二分法的步骤主要有两个:

1.求出区间的中点并代入方程

2.更新区间

我实现的二分法函数传入的区间的两个端点,由于我们要判断方程是否已经到达了题目所要求精度,所以我们要将中点作为返回值,但是我们还要更新区间,所以我们只能使用函数址传递的方式,具体实现如下

#include <stdio.h>
#include <math.h>
#define EPSILON 1e-6

double func(double x){
    return (pow(x,3)+2*pow(x,2)+10*x-20);
}

double duifenfa(double* a, double* b){
    double c = (*a + *b) / 2.0;
    if (func(*a) * func(c) <= 0){
        *b = c;          
    } else {
        *a = c;          
    }
    return c;
}

int main(){
    double x = 1.5;
    double a = 1.0;
    double b = 2.0;
    while(!((fabs(func(x)))<EPSILON)){
        x = duifenfa(&a,&b);
    }
    printf("%.6lf\n", x);
}

该程序的输出结果为

1.368808

使用desmos得出的解

另外提一嘴,由于这个函数是单调的,我们同样可以用题解1里面的牛顿迭代法实现,这个任务交给读者

5.插入排序算法的实现

对数组实现插入排序

先给出插入排序的算法思路

插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。

我们直接性的给出代码

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

void insert_sort(int *arr, int n){
    int temp;
    for (int i = 1; i < n; ++i){
        if (arr[i] < arr[i - 1]){
            temp = arr[i];
            int j = i - 1;
            for (; j >= 0 && arr[j] > temp; --j){
                arr[j + 1] = arr[j];
            }
            arr[j + 1] = temp;
        }
    } 
}

int main(){
    int n;
    scanf("%d", &n);
    int *arr = malloc(n);
    for (int i = 0; i < n; i++){
        scanf("%d", &arr[i]);
    }
    insert_sort(arr, n);
    for (int i = 0; i < n; i++){
        printf("%d ", arr[i]);
    }
    free(arr);
    arr = NULL;
    return 0;
}

注意内存使用完后要释放并置空(网上关于插入排序的讲解有很多也很详细,这里不再啰嗦)

C语言课堂上的题目解答3 2025-12-07
兔子生育问题 2025-11-12

评论区