任务2-1:为大奖赛编制一个计分程序,成绩在0-10之间,输入错误时要能马上重新输入。评委人数在程序中的修改要尽可能方便。
任务2-2:在任务2-1的基础上,输出当前选手的最后得分后,提示“按任意键计算下一位选手的成绩,退出请选择N:”如果输入的不是N或n,可以为下一位选手计算成绩。运行结果如图所示,将此任务写入报告,体会:如果一个大任务难于直接完成,可以先完成核心任务,再逐渐完善。
第一部分是我的解答,第二部分总结同学们的做法。
【第一部分 我的报告】
实验目的:学会使用循环控制语句解决实际问题
实验内容:编写大奖赛用的计分程序
/* 程序头部注释开始(为避免提交博文中遇到的问题,将用于表明注释的斜杠删除了) * 程序的版权和版本声明部分 * Copyright (c) 2011, 烟台大学计算机学院 * All rights reserved. * 文件名称: score.cpp * 作 者: 贺利坚 * 完成日期: 2011 年 11 月 15 日 * 版 本 号: V1.0 * 对任务及求解方法的描述部分 * 输入描述:选手的原始成绩 * 问题描述:各评委打出的成绩介于0-10之间,计分规则为去掉一个最高分和一个最低分后取平均。其他要求:输出错误要能马上重新输入;评委人数在程序中的修改要尽可能方便;计算完一位选手的成绩后可以连续地计算下一位选手的成绩。 * 程序输出:各位选手的最高分、最低分及最终成绩 * 问题分析:用两层的do循环完成,第一层完成每位选手的计分,第二层输入所有评委给出的评分,输入不对时用continue从头开始 * 算法设计:…… * 程序头部的注释结束(此处也删除了斜杠) */ #include <iostream> #include <iomanip> using namespace std; int main( ) { const int n=10; //学会用常变量 int i; double ave, score, sum, max, min; //这几个变量涉及成绩,double是合理的 char choice; //用于接受用户选择,字符型多合适 cout<<setiosflags(ios::fixed)<<setprecision(3); //输出格式,只设一次就管用 do //计算选手的成绩,至少1次,用do很自然,别的循环不用想 { i=1; //i代表评委的编号,其实这个变量名起得不好 max=-1; //这儿有技巧,第1位评委给的成绩一定大于-1,max将变成第1个成绩 min=11; //同样和技巧,要学会这样“设圈套” sum=0; //注意:这4个变量在循环内赋初值是必须的,这意味着计算某一选手成绩的开始 cout<<"请输入选手的成绩(0-10)"<<endl; do //至少有一位评委,再用do循环 { cout<<"第"<<i<<"位评委给分:"; cin>>score; if(score<0||score>10) continue; //输入不对就继续输,continue多合适 sum+=score; if(max<score) max=score; // 联想上一层循环中max的初值,学会技巧 if(min>score) min=score; //有不少同学用函数解决,复杂化了 i++; }while(i<=n); ave = (sum-max-min)/(n-2); cout<<"减去一个最高分:"<<max; cout<<", 减去一个最低分:"<<min<<"。"<<endl; cout<<"当前选手的最后得分是:"<<ave<<endl; cout<<"******************* SUCCESS ***********************"<<endl; cout<<"按 N 退出,其他键继续...."; cin>>choice; //用choice=getchar();也行 cout<<endl; }while(choice!='N' && choice!='n'); //不管输入大小写,全算数 return 0; }
运行结果:
经验积累:
1. 至少执行1次的循环用do-while
2. 赋初值的位置有学问
3. max,min初值的技巧
4. 编写实用程序,一定要实用
【第二部分 同学们做法的点评】
许多同学谈到这道题难了。程序是写得长了,但如果将思维整理好了,不难。关键是学过的内容不熟练。怎么熟练起来,看书、上机,无他法。
有同学程序越写越乱,头脑不清楚了,原因很简单:变量名尽用单个字母的,而不是起有意义的。这叫自找罪受。实际上,好的编程风格最受益的是自己。生活中论人品,编程也要有品格,有品味。
以后,同学们要注意程序能够顺利运行后,运行结果是否正确。不少同学的输出明显错误,例如成绩在0-10之间,但平均成绩却大大高于10,有可能吗?大奖赛就砸在你手里了。
最大的问题是没有用do-while循环。其实三种循环各有特点,做到用最合适的循环,有利于给出好的解决方案。
…… }while(choice!='N' && choice!='n');
处,有同学是这样写的
…… if (choice=='N' && choice=='n') break; }while(1);
显得有些没有必要,直接循环条件就可以了。
有同学给出的用for循环的解决办法输入不在0-10范围内的事,方法倒也巧妙,贴在下面。程序中还有其他毛病,我一并指出,供大家参考。
#include<iostream> using namespace std; int main() { cout << "请输入评委数目:" <<endl; //处理好,增强了程序的适用性,但这一句放在cin前就更好了。 double all =0 , max , min , fen; int ping , i; char a; cin >> ping; do { cout << "请输入选手的成绩(0-10):" << endl; for (i = 1; !(i == ping+1) ;) //!(i == ping+1)写成i!=ping+1或i<=ping更好,注意这儿表达式3是空的,一般这儿应写i++ { cout<< "第" << i << "位评委给分:"; cin >> fen; if (fen >= 0 && fen <= 10) { if (i==1) min = fen; //这么处理不如在循环前给min赋一大值 if (fen > max) max = fen; //max没有像min一样处理,利用了VC++未赋初值的变量默认一个绝对值很大的负数的特点。在其他编译系统中未必这样,所以程序移植时就危险了。进一步,这样处理是错的,因为没有专门赋值,在计算第二位选手的成绩时,max保存的是第一位选手的最高成绩。 if (fen < min) min = fen; all += fen; i++; //这个i++没有放在for中,用得很妙。我先以为错误的,作者解释后,我承认我错了,评价他“别有用心”。看出来了吗?如果(fen >= 0 && fen <= 10)为假,i是不会自增的。同学在这儿是用了脑子的,赞!但程序可读性受影响。 } else cout <<"输入错误,请重新输入:"; cout <<endl; } cout << "减去一个最高分:" << max << ",减去一个最最低分:" << min << "。" << endl; cout <<"当前选手的最后得分是:" << (all - max - min) / ping << endl; //这儿有错,去掉两个成绩后,评委数应该减2才对 cout <<"******************** SUCCESS ********************" << endl; cout << "按 N 退出,其他键继续…………" << endl; getchar(); cin >> a; }while (!(a == 'N' || a == 'n')); return 0; }
时间: 2024-11-01 11:11:38