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

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

  之前的博客园图片没处理好,对大家说一声抱歉。希望大家能够多多指出我的错误,我来认真修改 ^ - ^ !。

(1)改错题

序列求和:输入一个正实数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;
    }

错误信息 1:

错误原因 :while后面的括号没有加“;”。

改正方法:在while后面加上分号“;”。

编译正确,继续执行

错误信息 2:

错误原因:答案不正确,输入和输出用了%f

改正方法:在输入和输出的时候把“%f”改成“%lf”和“%.6lf”。

结果发现答案还是不正确:

错误原因:回头发现do while里面的语句运行不下去了就换一种格式来写

改正方法:把第一个程序改成第二个,如下:

do{
            item = 1/ n;
            s = s + flag * item;  
            flag = -flag;
            n = n + 3;
        }while( item < eps);
do 
	{
		item=flag*1.0/(3*n-2);
		s+=item;
		flag=-flag;
		n++;
	}
	while(fabs(item)>eps);

**因为在源代码中出现了数学函数fabs(),所以要用include<math.h>。

运行结果:运行正确!

附上正确的源代码:
 #include<stdio.h>
#include <math.h>
    int main()
    {
        int flag,n;
        double eps,item,s;
    
        printf("Input eps: ");
        scanf("%lf",&eps);
        flag = 1;
        s = 0;
        n = 1;
        do 
	    { 
		item=flag*1.0/(3*n-2);
		s+=item;
		flag=-flag;
		n++;
	    }
	while(fabs(item)>eps);
        printf( "s = %.6lf\n",s);
        return 0;
    }

(二)学习总结

1.语句while(1)和for( ; ; )是什么意思?,如何保证这种循环能正常执行?

while(1)相当于while(ture)里面的循环条件一直为真,一直循环下去。

保证这种循环正常执行在后面加一个判断并且为假,就直接跳出循环;或者加一个break;也可以跳出循环,保证这个循环能够正常运行。

for( ; ; )表示为死循环。

因为for后的圆括号中,第一个分号前的内容是执行第一次循环前执行的,第二个分号前的内容是每次执行前都要判断的(如果该处表达式的值为真,那么执行循环体,如果为假,那么就跳出循环体),第二个分号后的内容是每执行完一次循环体后执行的。

在循环体中使用break跳出循环体。

2.一般情况下,设计循环结构时,使用for、while、do while三种语句都可以,并且三种语句可以相互转换,但是,在某些特定情况下,我们应该优先选择某种语句来快速实现循环设计。如果有如下情况:

(1)循环次数已知

(2)循环次数未知,但循环条件在进入循环时明确

(3)循环次数未知,且循环条件在进入循环时未知,需要在循环体中明确

针对上面三种情况,分别采用什么循环语句实现比较好?对每种情况,用我们完成的两次循环结构作业中的题目加以说明。

①用for的循环结构来写。例如:
循环结构(1)中 7-2 统计学生平均成绩与及格人数, 7-3 奇偶分家 7-8 找出最小值,给出7-3的源程序:

#include <stdio.h>
int main(void)
{
int N,i,n,a = 0,b = 0;
scanf("%d",&n);
for(i = 0;i < n;i++)
{
   scanf("%d",&N); 
   if(N % 2 == 0)
 {
    a++;
 }
   else
 {
    b++;
 }
 
}
  printf("%d %d",b,a);
  return 0; 
}

②可以用while和do while的循环结构来写。例如:循环结构(2)中 7-5爬动的蠕虫,循环结构(1)中 7-4 到底是不是太胖了 给出7-5的源程序:

#include <stdio.h>
int main(void)
{
	int N,U,D,head=1,time=0;
	scanf("%d %d %d",&N,&U,&D);
	while(1) 
	{
		head+=U;
		time++;
		if(head>N)break;
			head-=D;
			time++;
	}
	printf("%d",time);
	return 0;
}

③可以用do while的循环结构来写。例如:循环结构(2)中 7-1 求给定精度的简单交错序列部分和 7-3 求奇数和,给出7-3的源程序:

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

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

循环次数未知,且循环条件在进入循环时未知,需要在循环体中明确,所以我觉得用do while写来比较合适。

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

(1)

#include<stdio.h>
int main()
{
    int n,s,i;
    s = 0;
    for(i = 1; i <= 10; i++)
    {
        scanf("%d",&n);     
        if(n % 2 == 0)
            break;      
        s = s + n;      
    }
    printf("s = %d\n",s);
    return 0;
}

输出结果:

(2)

#include<stdio.h>
int main()
{
    int n,s,i;
    s = 0;
    for(i = 1; i <= 10; i++)
    {
        scanf("%d",&n);     
        if(n % 2 == 0)
            continue;       
        s = s + n;      
    }
    printf("s = %d\n",s);
    return 0;
}

输出结果:

这俩个源程序看上去没什么俩样,但是不同的地方就是第一个用的是break,而第二个用的是continue。结果一个输出1,一个输出25,因为第一个就执行一次s=s+n,而s为0,n为1,当第一次输入1的时候就直接跳出循环就进行s=s+n,所以最后输出1;

而第二个流程图用continue俩控制循环条件,他进行判断后不会跳出而是直接进行下一个,并且把能整除2的数过滤掉,所以最后输出的是25。

(三)实验总结

(1) 题目

7-1 求给定精度的简单交错序列部分和

(2) 流程图



(3) 源代码

#include<stdio.h>
#include<math.h>
int main(void)
{
   	int dom,flog;
	double eps,sum,t;
	flog=1;
	dom=1;
	sum=0;
	scanf("%lf",&eps);
    do 
	{
		t=flog*1.0/(3*dom-2);
		sum+=t;
		flog=-flog; /*让这个值改变*/
		dom++;
	}
	while(fabs(t)>eps);
	printf("sum = %.6lf",sum);
	
	return 0;
 } 

(4) 实验分析:

问题1:

第一次写的时候有while的形式是用一下格式:

 while(fabs(x) > eps)
        {
           t=flog*1.0/(3*dom-2);
		   sum+=t;
		   flog=-flog; /*让这个值改变*/
		   dom++;
        }

但是输出的结果答案错误,这个问题纠结了很长时间。该程序需要先执行一次然后再进行循环,如果用while的形式就不能保证进行一次,所以该格式不能保证。我们要用do while的格式来写。

do 
	{
		t=flog*1.0/(3*dom-2);
		sum+=t;
		flog=-flog; /*让这个值改变*/
		dom++;
	}
	while(fabs(t)>eps);
问题2:答案错误

原因:while括号里面的条件判断错误

解决方法:把"<="改成">"。


答案正确:

(5)本题PTA提交列表

(1) 题目:

7-2 猜数字游戏

(2) 流程图


(3) 源代码

#include<stdio.h>
int main()
 {
   int key, n;
   scanf("%d %d",&key,&n);  /*输入俩个数*/
   int i;
   int m;
   int flag = 0;  /*定义一个数*/
   for (i = 1;i <= n;i ++)
     {
       scanf("%d",&m); /*再次输入一个数*/
       if (m < 0)
       break;
       if (m > key)
         printf("Too big\n");
        if (m < key)
          printf("Too small\n");
        if (m == key)
           {
              if (i == 1)
               {
                  flag = 1;  /*为假,跳出*/
                  printf("Bingo!\n");
                  break;
               }
              if (i == 2 || i == 3)
                {
                  flag = 1; /*为假,跳出*/
                  printf("Lucky You!\n");
                  break;
                }
              if (i > 3)
                {
                  flag = 1; /*为假,跳出*/
                  printf("Good Guess!\n");
                  break;
                }


           }
        }
        if (flag == 0) /*为真,输出*/
        printf("Game Over\n");
     return 0;
 }

(4) 实验分析

错误信息:一开始输入产生随机数,用了数学函数rand(),但是结果输出错误。

原因:理解题意错误,不用函数就可以,直接输入俩个数再进行循环就可以。

需要注意的:循环结束可以用break来实现。在本题需要定义一个量flag=0,如果后面的跟前面所定义的相等就判断为真,如果不相等就判断为假,并且在break的条件下进行跳出进行下一步的运算。

(5)本题PTA提交列表

(1) 题目

7-3 求奇数和

(2) 流程图


(3) 源代码

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

(4) 实验分析

问题 : 用 if--for的形式输入结果总是部分正确,例如下面的错误源程序

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

原因:该程序不能用if for的形式来写,它需要先循环一次,然后再进行循环。给出正确的源程序:

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

(5)本题PTA提交列表

(四)博客互评

针对移动、淫领四妓夜物 的博客园:
(1).实验总结写的很认真,值得我们学习!老铁,没毛病!继续加油
针对郭玉霖的博客园:
(1).在学习总结的第三个题文字与图片应该空一格,这样看起来比较舒服。
(2).在实验分析的时候应该把问题用截图截下来并且圈出来,这样别人才能知道你哪儿多了条件或者哪儿漏了条件。
针对ShizukaRi的博客园
(1).在改错题应该把错误的源程序给出来并且改正给出正确的。
(2).学习总结只能用很认真来形容,向你学习,可以看出你学的很好。
(3).实验总结的第二个流程图看着有点别扭,希望以后尽量截图好一点,大家能够更好的看清楚。

^ - ^欢迎大家来评论我的博客园!
posted @ 2017-11-16 23:41  一只猫の磊☀  阅读(701)  评论(11编辑  收藏  举报