首页 > 编程语言 > 详细

C语言程序设计第六次作业——循环结构(2)

时间:2017-11-19 19:25:12      阅读:844      评论:0      收藏:0      [点我收藏+]

标签:分享   void   设计   来看   都是   scanf   里的   数量   正整数   

(一)改错题

序列求和:输入一个正实数eps,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精确到最后一项的绝对值小于eps(保留6位小数)。
  输入输出样例:
  Input eps:1E-4
  s = 0.835699
源程序(有错误的程序)

#include<stdio.h>
int main()
{
    int flag,n;
    double eps,item,s;

    printf("Input eps: ");
    scanf("%f",&eps);
    flag = 1;
    s = 0;
    n = 1;
    do{
        item = 1/ n;
        s = s + flag * item;  
        flag = -flag;
        n = n + 3;
    }while( item < eps)
    printf( "s = %f\n",s);

    return 0;
}

错误一:
错误原因:while语句后面没有分号
技术分享图片
技术分享图片
改正方法:在while( item < eps)的后面加上一个“;”

改正错误后,编译没有错误
技术分享图片

输入数据验证
技术分享图片
程序错误

错误二:
错误原因:第八行输入语句有问题,不应该用%f
技术分享图片
改正方法:将%f改为%lf

错误三
错误原因:第13行中的运算为整型运算,并不能出现实数
技术分享图片
技术分享图片
改正方法:将“item = 1/ n”中的“1”改成“1.0”

改正后,输入数据,程序仍然错误
技术分享图片

错误四
错误原因:输出语句有问题,%f错误
技术分享图片
技术分享图片
改正方法:将%f改为%lf

错误五
错误原因:循环语句有错误,while语句括号里面的语句错误
技术分享图片
改正方法:将“while( item > eps)”里的“<”改成“>”

将改正后的程序输入数据进行验证
技术分享图片

附上改正后的程序:

#include<stdio.h>
int main()
{
    int flag,n;
    double eps,item,s;

    printf("Input eps: ");
    scanf("%lf",&eps);
    flag = 1;
    s = 0;
    n = 1;
    do{
        item = 1.0/ n;
        s = s + flag * item;  
        flag = -flag;
        n = n + 3;
    }while( item >= eps); 
    printf( "s = %lf\n",s);

    return 0;
}

(二)学习总结

1.语句while(1)和for(;;)是什么意思?,如何保证这种循环能正常执行?
答:两个语句都是循环语句,并且都是无限循环,也就是我们说的死循环,这种循环适用于不清楚循环应该运行的次数的循环。while()的括号内的判断方是括号内的条件是否为真,只要括号内为任意非零数值,均判断为真,所以不一定为1,其他的非零数值均可,如:1,-5等均可。 而for循环,其判断依据是根据for(;;)的括号内的三个表达式来判断真假,第二个表达式为循环的条件,若第二个表达式为空,则循环停下来的条件就会缺失,循环语句则会无限循环。
若要保证这种循环正常执行,就必须保证其判断条件为“1”,也就是真,即语句本身不能出现错误,并且不会出现循环控制语句,即不出现break语句等。

2.一般情况下,设计循环结构时,使用for、while、do while三种语句都可以,并且三种语句可以相互转换,但是,在某些特定情况下,我们应该优先选择某种语句来快速实现循环设计。如果有如下情况:
(1)循环次数已知
(2)循环次数未知,但循环条件在进入循环时明确
(3)循环次数未知,且循环条件在进入循环时未知,需要在循环体中明确
针对上面三种情况,分别采用什么循环语句实现比较好?对每种情况,用我们完成的两次循环结构作业中的题目加以说明。

答:(1)循环语句已知的情况下用for语句比较好,因为for语句中含有明确的将循环停止的语句。如pta循环第一次作业中,求奇数分之一序列前N项和这一题,此题便用for语句比较方便,明确循环的次数,选定一个初值,明确结束条件,便可以得出答案。
(2)循环次数未知,但循环条件在进入循环时明确,这种情况使用while语句比较好,由于循环次数未知,但是已知某些条件,便可以利用循环。如怕他循环第二次作业中,韩信点兵问题就是利用while语句,利用先循环在判断的形式,该问题的循环次数为多少我们在不经过计算的情况下并不知道,但是题目所给出的条件可以让我们写出循环停止的语句,所以利用while语句比较好。
(3)循环次数未知,且循环条件在进入循环时未知,需要在循环体中明确,这样的情况我们一般利用do while语句。如pta循环第二次作业中的掉入陷阱的数字的问题,我们对循环执行的次数以及循环停止的条件并不清楚,do while循环的执行方式为先进入循环体执行一次循环体,之后再判断循环条件是否成立,这样利用循环体我们就可以使循环执行下去,来满足题目要求。

3.有如下问题:输入一批学生成绩,以-1作为结束,计算学生的平均成绩。
要求分别用for语句、while语句、do while语句三种循环语句实现,并说明你认为哪种形式更合适?

(1)若使用for语句,程序如下:

#include<stdio.h>
int main(void)
{
int grade=0,sum=0,i=0;
double average=0.0;
for(;;) 
{
scanf("%d",&grade);
if(grade!=-1)
{
sum = sum +grade;
i++;
}
else if(grade==-1)
{
break;
}
}
average = sum / i;
printf("%f",average);
return 0;
}

(2)若使用while语句,程序如下:

#include <stdio.h>
int main()
{
double sum = 0.0, n = 0.0, average = 0.0;
int num = 0;

sum = 0.0;
num = 0;
while (1)
{
    scanf("%lf", &n);
    if (n == -1)
    {
        break;
    }

    sum += n;
    num++;
}
average = sum / num;
printf("%f", average);

return 0;
}

(3)若使用do while语句,程序如下:

#include<stdio.h>
int main(void)
{
int grade=0,sum=0,i=0;
double average=0.0;
i=0;
do
{
scanf("%d",&grade);
sum = sum + grade;
i++;        
}
while(grade!=-1) ;
average = (sum+1) / (double)(i-1);
printf("%f",average);
return 0;
}

(4)无限循环。程序如下:

#include<stdio.h>
int main(void)
{
int n = 0,sum = 0,count = 0;
    for(;;)                           
    {
    scanf("%d",&n);               
    if(n < 0)                    
    {
        break;
    }
    else
    {
        sum += n;
    count++;
    }

    }
if(count == 0)   
{
    count++;
}
printf("average = %.1f\n",(double)sum / count);
return 0;
}

从程序代码上来看,while循环以及do while循环比较简洁,但是for循环和无限循环我认为更加易懂,综合来说我认为while语句更加合适,因为输入时学生数量是未知的,所以for循环不太好,而当我们输入完事,循环条件在进入循环时已经明确,所以比do while循环好,相比无限循环的繁琐,while循环比较简洁,所以while循环比较好。

4.运行下面程序,输入1到10,结果分别是什么?为什么?

运行程序(1)结果如下图:
技术分享图片

运行程序(2)结果如下图:
技术分享图片

原因:两个程序结果输出显然不同,差别就在于一个为break语句跳出循环,另一个为continue。if语句后面的内容是break语句,表示跳出循环,假如为循环嵌套形式的时候,当循环执行完for语句的时候,到达break语句,break语句会直接跳出距离他最近的循环,而不执行下一个循环;但continue语句则不同,当循环执行完for语句的时候,到达continue语句,continue语句会略过continue后面的内容,执行距离他最近的循环的判断。所以这道问题,用break语句显然不能满足要求,应该使用continue语句。

(三)实验总结

1.求给定精度的简单交错序列部分和问题
(1)题目
本题要求编写程序,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... 直到最后一项的绝对值不大于给定精度eps。
(2)流程图
技术分享图片
技术分享图片

(3)源代码

#include<stdio.h>
#include<math.h>
int main()
{
int n = 1;
double eps,a = 1.0,S = 1.0,sum = 0.0;
scanf("%lf",&eps);
do
{
    a = 1.0 / (S* pow(-1,n+1));
    S = S + 3 ;
    sum = sum + a;
    n++;
}
while(fabs(a) > eps);
printf("sum = %lf",sum);
return 0;
 } 

(4)实验分析
问题:输出0.0000000
解决办法:将计算结果强制转化为double型

(5)pta提交列表
技术分享图片

2.猜数字游戏
(1)题目
猜数字游戏是令游戏机随机产生一个100以内的正整数,用户输入一个数对其进行猜测,需要你编写程序自动对其与随机产生的被猜数进行比较,并提示大了(“Too big”),还是小了(“Too small”),相等表示猜到了。如果猜到,则结束程序。程序还要求统计猜的次数,如果1次猜出该数,提示“Bingo!”;如果3次以内猜到该数,则提示“Lucky You!”;如果超过3次但是在N(>3)次以内(包括第N次)猜到该数,则提示“Good Guess!”;如果超过N次都没有猜到,则提示“Game Over”,并结束程序。如果在到达N次之前,用户输入了一个负数,也输出“Game Over”,并结束程序。
(2)流程图

(3)源代码

#include<stdio.h>
int main()
{

int M,N,n = 0,math;
scanf("%d%d",&M,&N);

do
{   
    n++;
    scanf("%d",&math);
    if(math<0)
    {
        printf("Game Over");
        break;
    }
    else if(n>N)
    {
        printf("Game Over");
        break;
    }
    else if(math==M)
    {
        if(n==1)
        {
            printf("Bingo!");
            break;
        }
        else if(n==2||n==3)
        {
            printf("Lucky You!");
            break;
        }
        else
        {
            printf("Good Guess!");
            break;
        }
    }
    else if(math<M)
    {
        printf("Too small\n");
    }
    else if(math>M)
    {
        printf("Too big\n");
    }   
}
while(1);
return 0;
}

(4)实验分析
问题:输入正确答案后,仍然输出gameover
解决办法:在Bilgo加上exit(0)

(5)pta提交列表
技术分享图片

3.求奇数和问题
(1)题目
本题要求计算给定的一系列正整数中奇数的和。
(2)流程图
技术分享图片

(3)源代码

#include <stdio.h>
int main()
{
int N,sum=0;
    while(1)
    {
        scanf("%d",&N);
        if(N%2!=0&&N>0)
        {
            sum+=N;
        }
        if(N<=0)
        {
            break;
        }
    }
printf("%d",sum);
return 0;
}

(4)实验分析
问题:输入-1后,-1也假如计算
解决办法:没有及时退出循环,将循环变量减一次,

(5)pta提交列表
技术分享图片

(四)博客互评

李晓晓http://www.cnblogs.com/Reloaded/p/7825734.html
刘梦醒
滕文清

C语言程序设计第六次作业——循环结构(2)

标签:分享   void   设计   来看   都是   scanf   里的   数量   正整数   

原文:http://www.cnblogs.com/fkh1/p/7845653.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号