C语言第六次作业

(一)改错题

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

 ①错误信息:

  错误原因:do.....while后面没有加分号;
  改正方法:

 ②错误信息:

  错误原因:item 顶一顶为double类型,但是1/n 为int类型,格式不对
  改正方法:

③错误信息:

  错误原因:while语句里面是循环结束语句,而题中给出的是循环跳出的语句
  改正方法:

④错误信息:

  错误原因:题中eps定义的是double格式
  改正方法:

附上改完之后正确的代码:

#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 = %f\n",s);

    return 0;
}

(二)学习总结

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

答:while(1)是无限循环,括号里的数字当为0是便不运行,非0即可成功运行。for(;;)表达式1是初值,表达式2是判断,表达式3是步长,先做表达式1,然后做表达式2,接着做循环体,然后再做表达式3,再回到做表达式2,然后做循环体,接着做表达式3,直到表达式2不成立退出。所以for(;;)也为无限循环。这两种循环的意思是等价的。当与语句中没有停止语句时这两种循环会一直循环下去,如果语句中出现类似于break语句的话,那么这个循环就会停止跳出。

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

答: 当循环语句已知时用for语句比较好,先判断后执行,但是当循环次数未知时 ,但是给出了条件控制时,用while语句比较好,也是先判断后执行,当循环体至少要循环一次时便用do while语句,这个和前面的两个不一样,是先执行后判断。
我们以PTA的循环结构(一)中的第一题为例,题目为:求奇数分之一序列前N项和,此题便用for语句比较方便,明确循环的次数,选定一个初值,明确了结束条件,此题便可以得出答案,而像PTA的循环结构(二)中的第三题,题目为: 求奇数和, 此地便用到了while循环语句,这道题让你求你输入的数中的奇数的和,我们来细想一下,你并不知道要循环多少次,所以用到了while(1)这个无限循环,类似的题目还有第七题:寻找250这个数字,做题时并不知道要循环多少次,,这就是典型的先循环在判断,而类似于像PTA的循环结构(二)中的第六题,题目为:掉入陷阱的数字, 当你输入一个自然数时,你要先锁定他的各个位数,然后再求和,他的要求是当输出的这一次的数和上一次和一样便输出,所以你需要先循环一次,再开始进行判断,直到输出为止。像这种都未知 的情况下就用do...while 语句。

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

答:(一)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;
}

(二)while语句的程序如下:

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

(三)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;
}

(四)无限循环的程序如下:

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

关于这四种的程序形式我感觉for语句和无限循环语句的程序比较相似和易懂,而且很方便,对于while语句和do while语句的程序也比较相似,但是这两种程序的有点是简洁,少了for语句和无线循环语句的繁琐的过程,但是while语句的弊端是最后以-1作为结束的时候,程序会算上-1,从而导致程序结果有误,所以我们需要略微在输出的时候做一下改正,如果题目改为输入一个负数跳出循环的话,while语句和do while语句就没有办法运行了。综合而言,我觉得for语句和无线循环语句更加好。

4.运行下面程序,输入1到10,结果分别是什么?为什么?
(1)结果为如图所示:

(2)结果为如图所示:

这两个程序的唯一区别就是第一个语句用的break循环控制语句,而第二个语句用的是continue循环控制语句,这两个循环控制语句的区别就是break是结束循环并且跳出这个循环语句,然后执行循环之外的语句,这个语句当输入2是就跳出循环了,而continue则是结束本次循环,跳出循环体中尚未执行的语句,继续下一次的循环,直到这个正常结束为止,这个语句求得是1-10的奇数的和,所以这两个程序的答案不一样。

(三)实验总结

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

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

(3)源代码

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

(4)实验分析:
问题1:这个程序用while语句的话是错误的
原因:它必须要执行一次循环才能正常进行
解决办法:把while语句换为do....while语句即可
(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 a = 0,N = 0,i = 0,b = 0;
scanf("%d%d",&a,&N);
for(i = 1;i <= N;i++)
{
	scanf("%d",&b);
	if(b < 0 )
	{
		printf("Game Over");
		break;
	}
	else if(b > a)
	{
		printf("Too big\n");
	}
	else if(b < a)
	{
		printf("Too small\n");
	}
	else if(a == b)
	{
		if(i == 1)
		{
			printf("Bingo!");
			break;
		}
		else if(i <= 3 && i > 1)
		{
			printf("Lucky You!");
			break;
		}
		else if(i > 3)
		{
			printf("Good Guess!");
			break;
		}
		break;
	}
if(i >= N)
{
printf("Game Over");
break;
}
}
return 0;
}

(4)实验分析:
问题1:输出的形式与题中要求不符
原因:没看清题
解决办法:在三个语句中加入!
问题2:当你数入的数字超过次数之后才结束程序
原因:在相等得时候没算结束了
解决办法:把i>N改为i>=N即可
(5)本题PTA提交列表

3.求奇数和

(1)题目
本题要求计算给定的一系列正整数中奇数的和
(2)流程图

(3)源代码

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

(4)实验分析:
本道题个人认为没有什么难点,熟悉无限循环即可。
(5)本题PTA提交列表

(四)博客互评

李晓晓http://www.cnblogs.com/Reloaded/p/7825734.html
侯冠达http://www.cnblogs.com/HGD980425/p/7837319.html
郭展旭http://www.cnblogs.com/1234569ss/p/7824423.html

posted @ 2017-11-14 01:16  许天笑!  阅读(772)  评论(11编辑  收藏  举报