C语言 实验三 任务报告

📝实验三任务报告

✨实验总结

😟遇到的问题:

这次整体上没有遇到什么大问题,就是srand和rand函数研究了一下,详见任务2.

🧐解决方法:

详见任务2.

🤔反思:

详见任务2.

✨实验内容

🕐任务一

📃代码:

代码1(求解实数根):

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
    int a,b,c,delta;
    do{
        printf("求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
        scanf("%d%d%d",&a,&b,&c);
        delta=b*b-4*a*c;
        if (delta<0)
            printf("数据输入错误请重新输入\n");
    }while (delta<0);
    float x1,x2;
    x1=(-b+sqrt(delta))/(2*a);
    x2=(-b-sqrt(delta))/(2*a);
    printf("求解成功,x1=%.2f,x2=%.2f",x1,x2);
    system("pause");
    return 0;
}

代码2(求解任意根):

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
    float a, b, c, delta;
    float x1, x2, i1, i2;
    printf("求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
    while (scanf("%f%f%f", &a, &b, &c) != EOF)
    {
        delta = b * b - 4 * a * c;
        if (a==0)
        {
            printf("二次项系数不能为0,请重新输入。\n\n");
        }
        else if (delta < 0)
        {
            printf("求解虚数根...\n");
            i1 = sqrt(-delta) / 2. / a;
            i2 = -b / 2. / a;
            printf("求解成功,");
            printf("x1=%.2f%+.2fi,", i1, i2);
            printf("x2=%.2f%+.2fi\n\n", i1, -i2);
        }
        else
        {
            printf("求解实数根...\n");
            x1 = (-b + sqrt(delta)) / (2 * a);
            x2 = (-b - sqrt(delta)) / (2 * a);
            printf("求解成功,x1=%.2f,x2=%.2f\n\n", x1, x2);
        }
        printf("求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
    }

    system("pause");
    return 0;
}

🎨截图:

image.png

🤓反思:

这个求解程序在一开时对于虚数很烦恼,后来发现只要能把i直接像字符一样输出就好了。不过和实数不一样的是虚数的结果是带加减号的,如果把+/-号也一起输出的话,遇到虚部为负数的话就会输出x1=0.87+-0.50i,x2=0.87--0.50i这显然不是想要的结果。想了一下,如果让数据带符号,正数前面有个加号不就好了吗。于是搜索了一下使用%+.2fi就可以解决问题了。不过这个+/-号在实验二中并没有涉及,现在学会也行吧。

🕑任务二

代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
    int x,n;
    printf("生成N个10以内的随机数\n请输入所需要的个数:");
    scanf("%d",&n);
    srand(time(NULL));
    for (int i = 0; i < n; ++i)
    {
        x = rand()%10;
        printf("第%d个随机数为:%d\n",i+1,x);
    }
    system("pause");
    return 0;
}

截图:

image4895df38e4aa0e8c.png

反思:

在之前的实验二中已经初步了解到了随机数中srand()rand()的用法,之前是根据时间变化随机变换颜色,并且将srand()加入到了循环中。不过在本次实验中我也尝试着这么做,出乎预料的居然失败了,在循环之中随机数的值没有变化。在上网查阅了很多资料后都没有很直白的介绍,琢磨了一番之后才得出让自己信服的答案。

随机数生成用到的是srand()rand()函数以及常用的time()函数。srand()用于生成随机数种子,说人话就是在计算机中有一个随机数表,就像高中教科书附录里面的那样。比如这里的随机数表是”1 2 3 4 5 6 7 8 9“ ,srand(1)则表示种子是1,rand()函数就会根据这个种子,从第一位开始往后依次取值,假设我要根据这个种子连续输出随机数,得到的结果就是:1,2, 3 ,4....... 并且只要种子不改变,rand()函数就会一直按照这个顺序执行,正是所谓的伪随机。

要想改变种子的值,常用的方法就是把时间作为种子,即srand((unsigned)time(NULL));NULL在头文件里面定义是0,这句函数的含义是取从00:00:00 GMT, January 1, 1970 到现在所持续的秒数,然后将time_t型数据转化为(unsigned)型再传给srand()函数。当srand()的参数值固定的时候,rand()获得的数也是固定的,因此如果把这句话写到循环里面,每次循环的时间很快,根本达不到1秒,并且每次使用srand()之后rand()又会从种子的第一位开始取,这也就是我之前输出的值不变的原因。正确的用法是只需在主程序开始处调srand((unsigned)time(NULL)); 后面直接用rand()。

🕒任务三

📃代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
    long long n,r,f,l,t;
    n = 0;
    l = 8;
    printf("2\t3\t");
    for (int x = 1; x <= 100000000; ++x)
    {
        t=(int)sqrt(x);
        for (int i = 2; i <= t; ++i)
        {
            r = x % i;
            if (r == 0)
            {
                f = 0;
                break;
            }
            else
                f = 1;
        }
        if (f == 1)
        {
            printf("%d\t",x);
            ++n;
        }
        if (n == l)
        {
            printf("\n");
            l=l+10;
        }
    }
    printf("\n1亿以内的素数一共有%d个\n",n+2);
    system("pause");
    return 0;
}

🎨截图:

image.png

🤓反思:

稍微试了一下1亿以内的质数,之前用的是%6d来控制输出,但是如果改成1亿的话得修改数值,不同的要求就要修改一次很麻烦。于是想到\t被称为制表符,一劳永逸。也同时熟悉了\t的用法,\t默认8位左对齐,超过8位就16位再者24位以此类推,最终1亿也可以轻松表示出来。不过如果只是100-200的话%6d还是更方便一点的。

🕓任务四

📃代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
    long on;
    long t,r,s,n;

    on=0;
    printf("请输入一个数字:");
    while (scanf("%ld",&on)!=EOF)
    {
        long i=0,u=-1,s=0;

        //转化数据
        on = fabs(on);
        //判断位数
        do {
            ++u;
            t = on / pow(10, u);

        } while (t != 0);
        //反向输出
        for (int j = 0; j < u; ++j) 
        {
            t = on / pow(10, j);
            r = t % 10;
            n = u - j - 1;
            s = s + r * pow(10, n);
        }
        //取奇数
        on = s;
        printf("新的数为:");
        do {
            t = on / (int) pow(10, i);
            r = t % 10;
            if (r % 2 != 0) 
            {
                printf("%d", r);
            }
            ++i;
        } while (t != 0);
        printf("\n请输入一个数字:");

    }
    system("pause");
    return 0;
}

🎨截图:

image.png

🤓反思:

思路:先把整个数反序,并以数的形式输出,再把奇数给依次输出。

这个程序其实有点难度,首先如果直接输出奇数会倒序,和结果不一样。尝试着构建算法,先找奇数再反向的话,我找奇数是先找奇数再一个一个输出,反向就变得很难。索性直接先反向在找奇数,思路就很开明了。

🕔任务五

📃代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int fac(n)
{
    long s=1;
    for (int i = 1; i <= n; ++i)
    {
        s=s*i;
    }
    return s;
}
int main()
{
    int n,x;

    printf("求解1-1/2!+1/3!+...+(-1)^(n-1)/n!\n");
    printf("请输入n的值:");
    while(scanf("%d",&n)!=EOF)
    {
        double s=0;
        x=0;
        for (int i = 0; i < n; ++i)
        {
            ++x;
            s = s + 1 * pow(-1, i) / fac(x);
        }
        printf("答案为:%f\n", s);
        printf("请输入n的值:");
    }
    system("pause");
    return 0;
}

🎨截图:

image.png

🤓反思:

这个是在课上完成的,边听函数,一边用出来的。刚开始我以为预定义的函数和主函数的变量会起冲突,结果并没有。不过之后调试的时候,n=10的时候我的答案是0.632120,看了很多遍函数之后也觉得没有问题。之后尝试了一番,把s的类型从float改成了double就正确了,应该是精度的问题。

🕕任务六

📃代码:

#include <stdio.h>
#include <stdlib.h>
#include "time.h"
int main()
{
    srand(time(NULL));
    int n,f,s,m;
    m=rand()%12+1;
    s=rand();
    if (m==1||m==3||m==5||m==7||m==8||m==10||m==12)
    {
        for (int i = 0; i < 3; ++i)
        {
            int d = s % 31 + 1;
            printf("\n您还有%d次机会,请尽力尝试吧!\n",3-i);
            printf("你的幸运月份为%d月,该月有31天,请输入你的幸运日期:",m);
            scanf("%d", &n);
            if (n == d)
            {
                printf("恭喜,你就是天选之人,%d月%d日是你的良辰吉日哦!\n", m, d);
                f=1;
                break;
            }
            else if (n < d)
                printf("可惜,还差一点点!不妨下次试试更大的日期?\n");
            else
                printf("可恶,日期过了!不妨下次试试更小的日期?\n");
        }
    }
    else if (m==4||m==6||m==9||m==11)
    {
        for (int i = 0; i < 3; ++i)
        {
            int d = s % 30 + 1;
            printf("\n您还有%d次机会,请尽力尝试吧\n",3-i);
            printf("你的幸运月份为%d月,该月有30天,请输入你的幸运日期:",m);
            scanf("%d", &n);
            if (n == d)
            {
                printf("恭喜,你就是天选之人,%d月%d日是你的良辰吉日哦!\n", m, d);
                f=1;
                break;
            }
            else if (n < d)
                printf("可惜,还差一点点!不妨下次试试更大的日期?\n");
            else
                printf("可恶,日期过了!不妨下次试试更小的日期?\n");
        }
    }
    else
    {
        for (int i = 0; i < 3; ++i)
        {
            int d = s % 28 + 1;
            printf("\n您还有%d次机会,请尽力尝试吧\n",3-i);
            printf("你的幸运月份为2月,该月有28天,请输入你的幸运日期:");
            scanf("%d", &n);
            if (n == d)
            {
                printf("恭喜,你就是天选之人,%d月%d日是你的良辰吉日哦!\n", m, d);
                f=1;
                break;
            }
            else if (n < d)
                printf("可惜,还差一点点!不妨下次试试更大的日期?\n");
            else
                printf("可恶,日期过了!不妨下次试试更小的日期?\n");
        }
    }
    if (f==1)
        printf("找到了自己的好运日,可以试试现在许愿,说不定到时候会有惊喜哟!\n");
    else
        printf("很抱歉你已经用完了所有机会。不要灰心,世界上好运的人只占一小部分,下次再来吧!\n");
    system("pause");
    return 0;
}

🎨截图:

image.png

image.png

🤓反思:

其实这个感觉是实验中比较简单的一个,就是截图不好截,正如上面所说,好运的人只占一小部分。

posted @ 2020-11-18 23:27  李柳星  阅读(174)  评论(0编辑  收藏  举报