实验三:磕磕碰碰

实验内容

1.实验任务1

#include<math.h>
#include<stdio.h>

int main(){
    float a,b,c,x1,x2;
    float delta,real,image;
    
    printf("Enter a,b,c:  ");
    
    while(scanf("%f,%f,%f",&a,&b,&c)!=EOF){
        if(a==0)
        printf("not quadratic equation.\n\n");
        else{
            delta=b*b-4*a*c;
            if(delta>=0){
                x1=(-b+sqrt(delta))/(2*a);
                x2=(-b-sqrt(delta))/(2*a);
                printf("x1=%.2f,x2=%.2f\n",x1,x2);
                
            }
            else{
                real=-b/(2*a);
                image=sqrt(-delta)/(2*a);
                printf("x1=%.2f+%.2fi,x2=%2f-%2fi\n\n",real,image,real,image);
                
            }
        }
        printf("Enter a,b,c: ");
        
        
    }
    return 0;
} 

运行结果

但是我偶然发现在先输入部分数字之后再按Ctrl+Z会出现无限输出的情况

 后来了解到这是因为......

可能这就是所谓的“漏洞”吧。

Ps:EOF的值一般是-1

在我们进行包括scanf等的输入函数使用时,其实用户在cmd中的输入实际是存放于缓冲区当中,当用户键入回车那一瞬间,之前输入的数据才会被存进去,而这里无论是单个字符还是字符串,我们都知道scanf的返回值呢是表示成功接受到的对象的个数,那这里如果遇到特殊情况,比如缓冲区文件流满等问题,那么scanf将如何处理呢?答案是返回-1 ! 这里不光是scanf,返回值为个数的函数,遇到文件流满大多都会返回-1,所以这个-1用的比较多,那么stdio.h就索性专门定义一个宏来表示,取End Of File(文件末尾的意思)的前三个字母即组成EOF,所以也就有了 #define EOF (-1) 这样的话!

2.实验任务2

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 5

int main(){
    int x,n;
    
    srand(time(0));
    n=0;
    do{
        n++;
        x=rand()%10;
        printf("%3d",x);
        
    }while(n<N);
    
    printf("\n");
    
    return 0;
}

运行结果

PS:

伪随机数:

伪随机数是用确定性的算法计算出来自[0,1]均匀分布的随机数序列。并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪随机数可以用计算机大量生成,在模拟研究中为了提高模拟效率,一般采用伪随机数代替真正的随机数。模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。

so~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

3.实验任务3

#include<stdio.h>
#include<math.h>

int main()
{
    int m,k,n;
    
    k=0;

    for(n=101;n<=200;n++)
    {
        for(m=2;m<=sqrt(n);++m)
         if(n%m==0)break;
        if(m>sqrt(n))
        {
            printf("%d\t",n);
            k++;
            if(k%5==0)
            printf("\n");
            
        }
    }
    printf("101~200");
    
    
    printf("101^200之间共有%d个素数",k);
    
 
    

  return 0;}

运行结果(正常)

而在这之前又出现了一些bug......

and......

 

4.实验任务4

#include<stdio.h>

int main() {

    int a,s,t,m;

    m = 1;

    t = 0;

    

    printf("Enter a number: ");

    while (scanf("%d", &s) != EOF) {



        while (s >= 1)

        {

            a = s % 10;

            s = s / 10;

            if (a % 2 != 0)

            {

                t = t + a * m;

                m = m * 10;

            }

        }

        if (s % 2 == 1)

            t = t + m * s;

        printf("new number is %d\n", t);

        printf("Enter a number: ");

        t = 0;

        m = 1;

    }

    return 0;

}

运行结果(肯定正常了,不用看了啦~~~~~~~~~~~~~~~~~~~~~)

但其实不是,我发现这个程序运行存在异常

其实就是数据类型的范围问题啦~~

PS:算法思路

其实就是先输入一个数,然后用对10取余的循环语句的方式得出各个数位上的数字,再将这些数字对2取余,若为1则判定为奇数,再次用循环语句将这些数据按原来的顺序依次输出,但输出的却是真的数,这依靠于输出的变量乘以相应的位数再加上之前这种循环所得出的结果。

 

5.实验任务5

#include<stdio.h>
int main(){
    int n,k,i;
    float s,x;
    s=0;
    x=1;
    i=1;
    k=1;
    printf("Enter n(0^10):");
    
    while(scanf("%d",&n)!=EOF){
        for(; k<=n; k++)
        {
            i=(-1)*i*k;
            s=s-x/i;}
            printf("n=%d,s=%f\n\n",i,s);
            
            printf("Enter n(0^10):");
    }
        
    
    return 0;
    
    
}

就因为一个引号害我弄了半天还以为电脑该换了(>  )3:<)

 

while(scanf("%d,&n")!=EOF){

emmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

and 来之不易的运行成果:



6.实验任务六
#include<stdlib.h>
#include<time.h>
int main(){
    int n,i,t;
    srand(time(0));
    t=rand()%30+1;
    i=0;
    printf("猜猜2020年哪一天会是你的luck day\n");

    printf ("开始喽,你有三次机会,猜吧(1^31):");
    scanf("%d",&n) ;
    while(i<=3){
        if(n>t){
    
        printf("你猜的日期晚了,luck day悄悄溜到前面啦\n");
        printf("再猜:");
        scanf("%d",&n) ;
        i++;}
        else if(n<t){
        
        printf("你猜的日期早了,luck day还没到呢\n");
        printf("再猜;");
        scanf("%d",&n);
        i++;}
        else
        printf("猜中了,nice!") ;
        i++;
        }
        printf("次数用完啦。偷偷告诉你:12月,你的luck day是%d号",t); 
        return 0; 
         
        
         
    }
    
    

运行结果一切正常

运气真好~
再猜亿遍~~



 实验总结

这次的实验很有难度呢,而且还有很多有新的概念呢~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

比如说:

1.伪随机数rand()和srand()
伪随机数是用确定性的算法计算出来自[0,1]均匀分布的随机数序列。并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪随机数可以用计算机大量生成,在模拟研究中为了提高模拟效率,一般采用伪随机数代替真正的随机数。模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。

在标准的C库中函数rand()可以生成0~RAND_MAX之间的一个随机数,其中RAND_MAX 是stdlib.h 中定义的一个整数,它与系统有关。

rand()函数没有输入参数,直接通过表达式rand()来引用;例如可以用下面的语句来打印两个随机数:

printf("Random numbers are: %i %i\n",rand(),rand());

因为rand()函数是按指定的顺序来产生整数,因此每次执行上面的语句都打印相同的两个值,所以说C语言的随机并不是真正意义上的随机,有时候也叫伪随机数。

为了使程序在每次执行时都能生成一个新序列的随机值,我们通常通过为随机数生成器提供一粒新的随机种子。函数 srand()(来自stdlib.h)可以为随机数生成器播散种子。只要种子不同rand()函数就会产生不同的随机数序列。srand()称为随机数生成器的初始化器。

2.头文件time.h和time(x)

函数名称: localtime

函数原型: struct tm *localtime(const time_t *timer)

函数功能: 返回一个以tm结构表达的机器时间信息

函数返回: 以tm结构表达的时间

timer-使用time()函数获得的机器时间

 

当然还有正确的打开方式!

 

1.循环语句的嵌套使用

*特别注意""和括号的使用!两个看似相同的程序可能因为一个小小的疏忽而天差地别!

2.变量的引入

*不要混淆各个变量!

3.实验之间的迁移与运用

*一个实验可能包含在另一个实验之中,理解运用好基础实验才能handle更复杂的实验!

4.学会简化程序

*尽量使问题简单化!

 

再次谢谢所有看到最后的人!

 

 

 

 

 

 

posted @ 2020-11-14 12:52  怅望灰天的小奇  阅读(156)  评论(3编辑  收藏  举报