C语言程序设计第五次作业——循环结构(1)
(一)改错题
输出华氏摄氏温度转换表:输入两个整数lower和upper,输出一张华氏摄氏温度转换表,华氏温度的取值范围是{lower,upper},每次增加2℉。计算公式如下:
c = 5×(f-32)/9
其中,c表示摄氏温度,f表示华氏温度。
输入输出样例1:
Enter lower:32
Enter upper:35
fahr celsius
32 0.0
34 1.1
输入输出样例2:
Enter lower:40
Enter upper:30
fahr celsius
源程序(有错误的程序)
#include <stdio.h>
int main(void)
{
int fahr , lower, upper; /* fahr表示华氏度 */
double celsius; /* celsius表示摄氏度 */
printf("Enter lower:");
scanf("%d",&lower);
printf("Enter upper:");
scanf("%d",&upper);
printf("fahr celsius\n"); /* 显示表头 */
/* 温度转换 */
for (fahr = lower , fahr <= upper, fahr ++) ;
celsius = 5 /9 * (fahr - 32.0);
printf("%3.0f %6.1f\n", fahr, celsius);
return 0;
}
对源程序进行编译,结果如下:
错误信息1:
错误原因:
for语句后面加了分号。
改正方法:
将分号去掉。
错误信息2:
错误原因:
for语句下没有加“{}“
改正方法:
在for语句下加上“{}”
错误信息3:
错误原因:
发现for语句内语句用逗号隔开了。
改正方法:
将逗号改为分号。
编译正确:
运行结果:
发现得不到先要的结果,继续修改程序。
错误信息4:
错误原因:
题目要求是每次fahr的值加2,而源程序是加1.
改正方法:
把fahr++改为fahr=fahr+2。
运行结果:
发现运行结果还是不对,继续检查并修改程序。
错误信息5:
错误原因:
与题目中给出的摄氏度与华氏摄氏度的转换不一致。
改正方法:
将celsius = 5 /9 * (fahr - 32.0)改为celsius = 5*(fahr-32.0)/9。
运行结果:
发现运行结果依然不正确,继续寻找错误。
错误信息6:
错误原因:
在定义变量时,fahr被定义为整型变量,所以在输出时不能写%3.0f。
改正方法:
将%3.0f改为%3d。
运行结果1:
运行结果2:
满足题目要求。
(二)学习总结
1.有如下程序:
#include <stdio.h>
int main()
{
int i,num,odd,even;
odd = 0;
even = 0;
for(i = 1; i <= 10;i++)
{
scanf("%d",&num);
if(num % 2 == 0)
{
even++;
}
else
{
odd++;
}
}
printf("%d %d",even,odd);
return 0;
}
详细描述程序的执行过程,即说明程序的每一步是执行的哪条代码,执行顺序如何。循环需描述前两次循环和最后一次循环的详细执行过程。最后说明程序实现的功能是什么。
1.首先先定义三个整型常量,num,even,odd,分别表示输入的值,偶数,奇数。
2.将奇数偶数赋初值为0。
3.开始执行循环体,i=1为真,进入循环。
4.输入一个数,判断该数和2求余是否为0。
5.若为0,则继续执行even++,此时even=1。
6.若不为0,则执行odd++,则odd=1。
7.继续执行循环体,此时i=2。
8.继续输入第二个数。
9.若第二个数和2求余等于0,则又执行even++。若第一个数和2求余也等于0,则此时的even=2,若不等于0,则even=1。
10.若第二个数和2求余不等于0,则执行odd++,若第一个数和2求余也不等于0,则此时odd=2,若等于0,则odd=1。
11.继续执行,直到i=11时,不满足i<=10。循环结束,输出even和odd。
程序实现的功能是,在输入的十个数中,判断是奇数还是偶数,并且奇数有几个,偶数有几个。
2.增量运算符
(1)运行下面程序,结果是什么?增量运算符在单独使用时,前缀和后缀形式有区别吗?
#include <stdio.h>
int main()
{
int i,j;
i = 2;
j = 2;
i++;
++j;
printf("i = %d\n",i);
printf("j = %d\n",j);
return 0;
}
运行结果:
增量运算符在单独使用时,前缀和后缀形式没有区别。但实际上增量运算符的前缀和后缀形式对计算还是有影响的。
(2)运行下面的程序,结果是什么?两条输出语句的执行过程是怎样的?说明什么问题?这两条输出语句执行完后,i和j的值分别是多少?
#include <stdio.h>
int main()
{
int i,j;
i = 2;
j = 2;
printf("%d\n",i++);
printf("%d\n",++j);
return 0;
}
运行结果:
增量运算符作为表达式的一部分时,前缀形式和后缀形式执行过程是不一样的。在该程序中,i=2,在输出时,输出i++,执行过程是,先输出i的值,在执行i+1。而j=2,在输出时,输出++j,执行过程是,先执行j+1,在输出赋值后j的值。所以在该程序中输出结果是i=2,j=3。但实际上这两条输出语句执行完后i和j的值都是3。
3.有些循环语句后面有{},有些没有,有些语句有缩进,运行下面的四个小程序,运行结果有什么不同?循环体的认定与缩格形式是否有关?与{}是否有关?那么,应该如何正确判断一个循环语句中的循环体?下面的程序中,哪几种格式是正确的缩进格式。
(1)
#include <stdio.h>
int main()
{
int i;
for(i = 1;i <= 5;i++)
printf("*");
printf("\n");
return 0;
}
运行结果:
(2)
#include <stdio.h>
int main()
{
int i;
for(i = 1;i <= 5;i++)
printf("*");
printf("\n");
return 0;
}
运行结果:
(3)
#include <stdio.h>
int main()
{
int i;
for(i = 1;i <= 5;i++)
{
printf("*");
printf("\n");
}
return 0;
}
运行结果:
(4)
#include <stdio.h>
int main()
{
int i;
for(i = 1;i <= 5;i++)
{
printf("*");
}
printf("\n");
return 0;
}
运行结果:
在这四个程序中,前两个程序是在证明在循环体的认定与缩格形式是否有关,由运行结果可知,两个运行结果的格式完全相同,所以可知,循环体的认定与缩格形式没有关系。
后两个是在证明循环体的认定与“{}”是否有关,由运行结果可知,第三个程序,运行结果的格式是一排竖着的星号,而第四个程序,运行结果的格式是一排横着的星号,二者产生区别的原因是,(3)程序中的换行语句也包括在了循环语句中,即在i<=5的范围内,输出一个星号就换一次行,直到循环结束。而(4)程序中换行语句在循环语句外面,即在i<=5的范围内,输出星号直到循环结束再换行。所以循环体的认定与“{}”是有关系的。
要正确判断一个循环语句的循环体,要把想要循环的语句用“{}”括起来,在执行循环体时要分清输出语句是在循环体内还是在循环体外。
在这四个程序中,第三个和第四个是正确的缩进格式。
4.对其他你认为需要进行总结的内容进行总结。
(1)for语句里的三个语句应该用分号隔开,而不是用逗号隔开。
(2)for语句下必须加大括号。
(3)循环结构比较复杂,总是写着写着代码思绪就乱了,这就应该课下做好复习工作。
(三)实验总结
本次实验总结,学号末位数是单数的同学完成循环结构(1)中的1、3、5、7题,学号末位数是双数的同学完成循环结构(1)中的2、4、6、8题。
-
求奇数分之一序列前N项和
(1)题目
本题要求编写程序,计算序列 1 + 1/3 + 1/5 + ... 的前N项之和。
(2)流程图
(3)源代码include <stdio.h>
int main (void)
{
int N,i;
double sum;
scanf("%d",&N);
for(i=1,sum=0;i<=N;i++)
{
sum=sum+1.0/(2*i-1);
}
printf("sum = %.6f",sum);return 0;
}
(4)实验分析
问题1:
在写程序时,for语句里的i++写成了i=i++。
原因:
没有真正理解i++就代表了i=i+1。
解决办法:
向同学询问,改正错误。
(5)本题PTA提交列表
2.奇偶分家
(1)题目
给定N个正整数,请统计奇数和偶数各有多少个?
(2)流程图
(3)源代码
# include <stdio.h>
int main(void)
{
int i,N,number,j,o;
j=0;
o=0;
scanf("%d\n",&N);
for(i=1;i<=N;i++)
{
scanf("%d",&number);
if(number%2==0)
o++;
else
j++;
}
printf("%d %d",j,o);
return 0;
}
(4)实验分析
问题1:
编译正确,但是运行错误。
原因:
没有给j,o赋初值。
解决办法:
将j,o赋初值,让j=0,o=0。
(5)本题PTA提交列表
3.统计字符
(1)题目
本题要求编写程序,输入10个字符,统计其中英文字母、空格或回车、数字字符和其他字符的个数。
(2)流程图
(3)源代码
# include <stdio.h>
int main(void)
{
int letter = 0,blank = 0,digit = 0,other = 0,i;
char a;
for(i = 1;i <= 10;i++)
{
scanf("%c",&a);
if((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'))
{
letter = letter + 1;
}
else if(a == '\n' || a == ' ')
{
blank = blank + 1;
}
else if(a >= '0' && a <= '9')
{
digit = digit + 1;
}
else
{
other = other + 1;
}
}
printf("letter = %d, blank = %d, digit = %d, other = %d",letter,blank,digit,other);
return 0;
}
(4)实验分析
问题:
因为该程序中a定义的是char类型的,不知道怎么表示字母,数字,空格还有回车。
原因:
对字符型数据应用不熟练。
解决办法:
听老师讲解,修改程序。
(5)本题PTA提交列表
4.求交错序列前N项和
(1)题目
本题要求编写程序,计算交错序列 1-2/3+3/5-4/7+5/9-6/11+... 的前N项之和。
(2)流程图
(3)源代码
# include <stdio.h>
# include <math.h>
int main()
{
int N,i;
double sum;
sum=0;
scanf("%d",&N);
for(i=1;i<=N;i++)
{
sum=sum+(i/(2.0*i-1))*pow(-1,i-1);
}
printf("%.3f",sum);
return 0;
}
(4)实验分析
问题1:
输不出想要的值。
原因:
因为该程序求的和是一加一减的,所以在计算过程中不会算。
解决办法:
向同学询问,并听老师讲解,修改程序。
(5)本题PTA提交列表
(四)博客互评
每个同学至少评论三篇其他同学的博客作业,依次列出你所评论的博客地址。对于同学对你的博客作业提出的问题,应积极进行回答,存在的错误应及时改正。希望大家能够在互评的过程中取长补短,共同进步。
1.http://www.cnblogs.com/wlm312/p/7812154.html
王丽敏同学,在改错题中,哪里错了,还做出了标记,让人一目了然。提交列表中犯的错也比较少,整体值得学习。
2.http://www.cnblogs.com/myg123/p/7802056.html
整体上,马阳光同学作业内容整齐,给人很清晰的感觉。然后在改错题中,错误的部分也做出了标记,让人知道错在哪。
但是,她的代码没有用正确的markdown格式写,希望能够改正。
在第三大题实验总结部分,如果源代码也用markdown格式写会更好。
整体还是值得学习的。
3.http://www.cnblogs.com/tengwenqing/p/7811860.html
滕文清同学,在做的流程图下边还给出了运行结果,给人清晰的感觉,这一点是值得我学习的。她的PTA提交列表错误也很少,纵观整个作业是值得我学习的。