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.两种语句所表达的无限循环模式并没有太大的区别,若要保证两种程序正常执行,需要在循环中加入一些适当的选择和判断,在无限循环的条件下加入某种限制条件,让循环能够完全的为我们所用,最后需要注意的就是无限循环的跳出问题,可以用break
或goto
结束循环,或者在结束循环后用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的第一题中,我们并不知道具体的循环次数,而是知道item
与eps
之间的联系,故用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);