C语言程序设计第六次作业

C语言程序设计第六次作业

(一)改错题。

(1)序列求和:输入一个正实数eps,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精确到最后一项的绝对值小于eps(保留6位小数)。

1.源程序。

#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;
    }

2.错误及改正。

  • 错误信息1:
  • 错误原因:printf前少了一个;,不熟悉do..while的构成
  • 改正方法:在while语句后加一个分号。

改正后运行,出现以下结果。

  • 编译没有问题,经输入验证,结果如下图:
  • 未达到预期结果,继续检查。
  • 错误信息2:do..while语句中的运算中对item的运算犯了数型错误
  • 错误原因:n被定义为了int型数据,但对n进行了除法运算。
  • 改正方法:将本行代码改为item = 1.0/n

改正后运行:

  • 未达到预期结果,继续检查。
  • 错误信息3:经检查,输入语句中的%f应该改为%lf.
  • 错误原因:单精度的%f应该改为双精度的%lf.
  • 改正方法: 已经定义为double的变量在输入的时候应该用%lf.

改正后运行:

  • 未达到预期结果,继续检查。
  • 错误信息4:检查过程中发现while中的判断语句存在问题。
  • 错误原因:对do...while语句中
  • 改正方法:据题意可得应该在item >= eps时结束循环,不应该在判断为小于时结束循环。

改正后运行,出现以下结果:

  • 结果符合期望,继续检查,发现有一点不准确。
  • 错误信息5:最终输出语句中应该保留六位有效数字,故最终的%f并不准确。
  • 改正方法,出现如下结果:将最后的输出语句改为("%.6f\n",s);

结果符合期望,给出最终修改后的程序。

#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 = %.6f\n",s);
    
        return 0;
    }

(二)学习总结

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

1.对于while()来说,括号内的内容即为判断内容,判断括号内的内容是否为真,就目前情况来说,只要括号内内容不为1,程序就会无限循环;后者判断方式为先确定变量的的值并赋初值,然后分别用两个分号后的语句限制循环条件,目前情况来说,for中的限制条件为空,即为任何条件下都可无限循环。
2.两种语句所表达的无限循环模式并没有太大的区别,若要保证两种程序正常执行,需要在循环中加入一些适当的选择和判断,在无限循环的条件下加入某种限制条件,让循环能够完全的为我们所用,最后需要注意的就是无限循环的跳出问题,可以用breakgoto结束循环,或者在结束循环后用continue继续某项程序。

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

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

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

  • (1).循环次数已知:在循环次数已知的情况下,相比do...while语句与while语句,for语句更能直观的给出循环的限制条件,而前面两种语句更倾向于给出循环结束或继续的某项条件。
  • 例:循环结构1第一题,在输入语句中明确给出了循环次数,这样用for语句就很简便了。
  • 源代码:
#include <stdio.h>

int main()
{
  int i,N;
  double S;
  scanf("%d",&N);
  for(i=1,S=0;i<=N;i++)
  {
    S=S+1.0/(i*2-1);
  }
  printf("sum = %.6lf",S);
  return 0;
  
}
  • (2)循环次数未知,但循环条件在进入循环时明确:在这种条件下,我们不知道循环的具体次数,需要在循环中给出答案,这时用while语句比较妥当,我们虽然不知道具体的循环次数,但应该知道一些循环的条件,以及结束的标准,比如在循环结构2的第一题中,我们并不知道具体的循环次数,而是知道itemeps之间的联系,故用while语句较为适合,括号中的循环条件为最后一项绝对值与给定精度eps之间的联系。
  • 源代码:
#include<stdio.h>
#include<math.h>
    int main()
    {
       int denominator,flag;
       double item,eps,S;
       flag=1;
       denominator=1;
       S=0;
       item=1.0;
       scanf("%lf",&eps);
       if(eps>=1.0)
       S=1.0;
         while(fabs(item)>eps)
       {
       	item=flag*1.0/denominator;
       	S=S+item;
       	flag=-flag;
       	denominator=denominator+3;
       }
       printf("sum = %.6f",S);
   }
  • (3)循环次数未知,且循环条件在进入循环时未知,需要在循环体中明确:do...while语句与while的最大的区别就是while语句在开始会进行一个判断,然后再进行循环;而do...while语句是直接进行循环然后再进行条件判断,但这种情况下,while语句的第一步判断就可能否定输入内容而直接跳出循环,但do...while语句就不存在这种问题,例如循环结构2中的求奇数和。
  • 源程序:
#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语句三种循环语句实现,并说明你认为哪种形式更合适?

  • 分别给出三种情况下的源程序:
  • 1.for循环
#include <stdio.h>

int main()
{
	int i,x,sum;
    double average;
    x=0;
    average=0;
    sum=0;
    i=0;
    for( ; ; )              /* 此处未知条件,故以空白代替 */ 
    {
        scanf("%lf", &x);
        if (x==-1)
        {
            break;
        }

        sum += x;
        i++;
    }
    average=sum / i;
    printf("%f", average);

    return 0;
}
  • 2.while语句
#include <stdio.h>

int main()
{
	int i,sum,x,
    double average;
    x=0;
    average=0;
    sum = 0;
    i = 0;
   while ()              /*  限制条件未知  */ 
    {
        scanf("%lf", &x);
        if (x == -1)
        {
            break;
        }
        sum += x;
        i++;
    }
    average=sum / i;
    printf("%f", average);
    return 0;
}
  • 3.do...while语句
#include <stdio.h>

int main()
{
	int i,sum,x,
    double average;
    x=0;
    average=0;
    sum = 0;
    i = 0;
    do {
            scanf("%lf", &x);
            if (x == -1)
            {
                break;
            }
            sum += x;
            i++;
        } while ();
    average = sum / i;
    printf("%f", average);

    return 0;
}

小结:我认为while语句更加好,因为在循环次数未知,以及诸多条件不明的情况下while语句更能更好的体现计算过程,并且不会出现像do...while语句那样少循环一次的情况。

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

  • 1.运行结果:
  • 原因:在if语句中进行判断时,当进行到第二个值2时符合条件于是程序进行了break操作,跳出了循环,所以最终结束时输出了s=s+n的第一个值1.
  • 2.运行结果:
  • 原因:程序进行了continue操作,即为符合条件后会继续进行循环操作。

(三)实验总结

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

1.源程序:

#include<stdio.h>
#include<math.h>
    int main()
    {
       int denominator,flag;
       double item,eps,S;
       flag=1;
       denominator=1;
       S=0;
       item=1.0;
       scanf("%lf",&eps);
       if(eps>=1.0)
       S=1.0;
         while(fabs(item)>eps)
       {
       	item=flag*1.0/denominator;
       	S=S+item;
       	flag=-flag;
       	denominator=denominator+3;
       }
       printf("sum = %.6f",S);
   }

2.流程图


3.错误及改正

  • 错误信息1:最初未考虑eps>=1.0的情况
  • 错误原因:考虑不周到,忽略了若eps与首项相等或大于的情况,这种情况下S=1.
  • 改正方法:加入以下内容
if(eps>=1.0)
       S=1.0;

提交列表:

2. 猜数字游戏

1.源代码

#include <stdio.h>
int main()
{
    int num,N,i,a;
    i = 1;
    scanf("%d %d",&num,&N);
    do
    {
        scanf("%d",&a);
        if(a < 0)
        {
            printf("Game Over");
            break;
        }
        else if(a == num && i <= N)
        {
            if(i == 1)
            {
              printf("Bingo!");
                break;
            }
            else if(i <= 3)
            {
                printf("Lucky You!");
                break;
            }
            else if(i > 3 && i <= N)
            {
                printf("Good Guess!");
                break;
            }
        }
        else if(i > N)
        {
            printf("Game Over");
            break;
        }
        else if(a > num)
        {
            printf("Too big\n");
        }
        else if(a < num)
        {
            printf("Too small\n");  
        }
        i++;
    }
    while(num != a);
    return 0;
}

2.流程图



3.错误及改正

  • 本题并没有出现编程上的问题,但有一个点需要注意,break语句的应用,在本题中不能将break放于大括号外,否则程序会无法输出。

提交列表:

3.求奇数和

1.源程序:

#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;
}

2.流程图:


3.错误及改正

  • 错误信息1:输入语句中忘记了地址符&
  • 错误原因:思维不严谨,忘记了基本操作。
  • 改正方法:scanf("%d", &n);

提交列表:

博客互评

posted on 2017-11-19 19:35  吉炎臣  阅读(667)  评论(4编辑  收藏  举报

导航