一、改错题
题目
序列求和:输入一个正实数eps,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精确到最后一项的绝对值小于eps(保留6位小数)。
源程序(有错误的程序)
#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:

错误原因:第17行的while( item < eps)的后面没有加“;”
改正方法:在while( item < eps)的后面加上一个“;”
错误信息2:

错误原因:回到源程序检查发现第八行输入格式有问题
改正方法:将scanf("%f",&eps)里的“%f”改成“%lf”
错误信息3:改正错误2后继续运行,结果并没有发生改变,如下图所示:

错误原因:继续检查源程序发现第13行中的运算为整型运算,并不能出现实数
改正方法:将“item = 1/ n”中的“1”改成“1.0”,使运算结果为实数
错误信息4:改正错误3后运行程序,结果仍未发生改变,如下图所示:

错误原因:回头检查发现第17行中while()语句的括号里的表达式错误,与题目不符
改正方法:将“while( item > eps)”里的“<”改成“>”
错误信息5:改正错误4后运行程序结果正确,如下图所示:

错误原因:运行正确后再一次检查程序发现最后输出时格式符并不正确,题目要求保留6位小数,但是输出格式符并没有保留6位小数
改正方法:将“printf( "s = %f\n",s)”中的“%f”改成“%.6f”
改正完毕后输入样例“1E-4”,结果如下图:

符合期望。
与样例一样,输入临界值数据“1”与其他数据检验,如图:


符合期望,认为改正完毕。
附上改正后的源代码:
#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(;;)没有判断条件,视为空语句,所以for(;;)也是无限循环
③如果想要这种循环正常执行就必须保证其判断条件为“1”,也就是真
2.针对上面三种情况,分别采用什么循环语句实现比较好?对每种情况,用我们完成的两次循环结构作业中的题目加以说明。
(1)循环次数已知:使用for语句,比如我们PTA作业循环结构(1)中的7-7题,因为循环次数已知,所以用for循环,源程序如:
#include <stdio.h>
#include <math.h>
int main()
{
int N,i,a;
double sum = 0;
scanf("%d",&N);
for(i = 1;i <= N;i++)
{
sum = sum - i * pow(-1,i) / (2 * i - 1);
}
printf("%.3f",sum);
return 0;
}
(2)循环次数未知,但循环条件在进入循环时明确:使用while语句,比如我们PTA作业循环结构(2)中的7-1题,源程序如下:
#include <stdio.h>
#include <math.h>
int main()
{
double eps,item,S = 0;
int denominator = 1,flag = 1;
item = 1.0;
scanf("%lf",&eps);
if(eps >= item)
{
S = 1.0;
}
while(fabs(item) > eps)
{
item = flag *1.0 / denominator;
S = S + item;
flag = -flag;
denominator = denominator + 3;
}
printf("sum = %.6f",S);
return 0;
}
(3)循环次数未知,且循环条件在进入循环时未知,需要在循环体中明确:使用do...while语句,比如我们PTA作业循环结构(2)中的7-7题,源程序如下:
#include <stdio.h>
int main()
{
int num,i = 0,a = 0;
do
{
scanf("%d",&num);
if(num == 250)
{
i = a + 1;
printf("%d",i);
break;
}
a++;
}
while(1);
return 0;
}
3.有如下问题:输入一批学生成绩,以-1作为结束,计算学生的平均成绩。要求分别用for语句、while语句、do while语句三种循环语句实现,并说明你认为哪种形式更合适?
我认为while语句更合适一些,因为这个程序是循环次数未知,但循环条件在进入循环时明确,如果用for语句或者是do...while语句来写的话会比while麻烦一点需要加判断语句
4.运行下面程序,输入1到10,结果分别是什么?为什么?
运行程序(1)结果如下图:

原因:程序if语句后面的内容是break,表示跳出循环,当n = 1时不符合if语句条件执行s = s + n,s的值为1,然后再次执行循环体,此时n=2,符合if语句的条件则跳出循环体,此时s的值仍为1
运行程序(2)结果如下图:

原因:程序if语句后面的内容是continue,它的作用就是结束当前循环,开始下一轮循环,同理符合if语句的条件时开始执行新一轮循环,而不是执行s = s + n,不符合时执行s = s + n,所以s得输出值为25
三、实验总结
1.求给定精度的简单交错序列部分和
(1)题目
本题要求编写程序,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... 直到最后一项的绝对值不大于给定精度eps。
(2)流程图

(3)源代码
#include <stdio.h>
#include <math.h>
int main()
{
double eps,item,S = 0;
int denominator = 1,flag = 1;
item = 1.0;
scanf("%lf",&eps);
if(eps >= item)
{
S = 1.0;
}
while(fabs(item) > eps)
{
item = flag *1.0 / denominator;
S = S + item;
flag = -flag;
denominator = denominator + 3;
}
printf("sum = %.6f",S);
return 0;
}
(4)实验分析
问题1:写完程序编译无错误,但是输出结果错误,如下图:

原因:题目要求item的绝对值不大于给定精度eps,而源程序的while判断条件却是while(item > eps)
解决办法:将while(item > eps)改成while(fabs(item) > eps)
问题2:当改成错误1后运行程序,结果无错误,但是提交pta时出现如下错误:

原因:回到源程序检查发现,没有判断最后一项的绝对值大于等于给定精度eps时的情况
解决办法:在“scanf("%lf",&eps);”后面9至12行添加if判断语句,如下图:

(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 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;
}
(4)实验分析
问题1:开始写程序时题目理解错误,导致程序无论修改多少次,仍是提交错误
原因:以为游戏机产生的随机数、以及猜测的最大次数N是程序自己随机生成的,所以用了随机函数,而没有让用户自己输入数据
解决办法:回头检查程序并且仔细读题目,将随机函数删除,换成用户自己输入数据的格式,使用scanf语句
问题2:当输入负数时仍然可以继续输入其他数据,如下图所示:

原因:没在if判断语句后的内容加上跳出循环的语句break
解决办法:在第13行加入“break;”
问题3:

原因:没有进行换行
解决办法:在Too big和Too small后面分别写入“\n”进行换行
(5)本题PTA提交列表

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

(3)源代码
#include <stdio.h>
int main()
{
int n,sum = 0;
do
{
scanf("%d",&n);
if (n % 2 == 1)
{
sum += n;
}
}
while (n > 0);
printf("%d\n", sum);
return 0;
}
(4)实验分析
问题1:

原因:if语句的括号应该是运算符,不是赋值
解决办法:将括号里的一个等于号写成两个等于号
(5)本题PTA提交列表

博客互评
我的评论同学的博客链接
郭玉霖
http://www.cnblogs.com/HBQ521/p/7826030.html
评论内容:
①修改完错误程序后最好再输入两组其他数据测试程序的正确性;
②实验分析应该再具体一点,不是笼统概述,而是具体操作步骤;
③老铁,不客气!
许天笑
http://www.cnblogs.com/snxtx/p/7824427.html
评论内容:
①修改完错误程序后最好再输入两组其他数据测试程序的正确性;
②老铁,其他的很好,不客气!
侯冠达
http://www.cnblogs.com/HGD980425/p/7837319.html
评论内容:
①老铁,你的改错改的太少了,还有错误没改出来,比如保留6位小数的要求;
②修改完错误程序后最好再输入两组其他数据测试程序的正确性并且附上改正后的源代码,让人一看便知;
③老铁,不客气!
这是我此次的博客作业
祝评论我博客的人所有的难过都被风吹走




