我已经开始学习C++,来自于PHP背景。我有一本加速C++的书,我正在研究它,做每一章和练习。做了几件事后,我想得到一些反馈,以确保我没有做错任何事情。
本章是在以下前提下介绍的:
想象一下,每个学生的期末考试占期末成绩的40%,期中考试占20%,家庭作业平均分数占其余40%。
我当时正在做的特别练习是
编写一个程序,可以同时记录几个学生的成绩。这个程序可以让两个
vector
s保持同步:第一个应该保存学生的名字,第二个是可以在输入时计算出来的最终成绩。现在,你应该假设一定数量的家庭作业成绩。
他们建议使用两个向量:一个是学生的名字,另一个是年级,虽然我稍微扩展了一下,以考虑到不同的年级(期中、期末考试和家庭作业)。我还选择在收到所有输入后计算分数,以便将获取和存储输入的代码与执行计算的代码分开。
这是一份完整的程序副本(110行)。我正在寻找关于风格、正确性、语言陷阱的任何反馈,我可能意外地掉进了其中,而且实际上是任何你认为可能有用的东西。
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::setprecision;
using std::streamsize;
using std::string;
using std::vector;
/*****
* This program is designed to take a list of students, then ask for their
* midterm, final and homework grades. It then calculates the final grade
* for each student, with the following weights:
* Midterm: 20%
* Final: 40%
* Homework: 40% of average grade
*/
int main()
{
// How many homework grades each student requires
int assignments = 3;
// Get all student names and store them in the first vector
vector<string> students;
{
string student;
cout << "Please enter all students forenames, or an empty line when done."
<< endl
<< "Student name: ";
while (getline(cin, student) && !student.empty()) {
students.push_back(student);
cout << "Student name: ";
}
cout << endl
<< students.size() << " students entered."
<< endl << endl;
}
// Ask for the midterm, final and `assignments` homework grades for students
vector<double> midterms;
vector<double> finals;
vector<double> homework;
{
double grade;
for (int s = 0; s < students.size(); s++) {
// invariant: we've received grades for `s` students
cout << "Grades for " << students[s] << endl;
cout << " - Midterm: ";
cin >> grade;
midterms.push_back(grade);
cout << " - Final: ";
cin >> grade;
finals.push_back(grade);
for (int a = 0; a < assignments; a++) {
// invariant: we've received the grade for `a` assignments
cout << " - Assignment " << a + 1 << ": ";
cin >> grade;
homework.push_back(grade);
}
cout << endl;
}
}
// Calculate and print the overall grades
cout << "Overall Grades:" << endl;
streamsize precision = cout.precision();
{
typedef vector<string>::size_type vec_size;
double overallGrade,
midtermGrade,
finalGrade,
homeworkGrades;
for (vec_size s = 0; s < students.size(); s++) {
midtermGrade = midterms[s];
finalGrade = finals[s];
homeworkGrades = 0;
// Pull out the homework grades
int start = s * assignments,
end = (s + 1) * assignments - 1;
for (vec_size h = 0; h < assignments; h++) {
// invariant: we've summed the grades for
homeworkGrades += homework[start + h];
}
// Calculate the overall grade
overallGrade = 0.2 * midtermGrade
+ 0.4 * finalGrade
+ 0.4 * homeworkGrades / assignments;
cout << " - " << students[s] << ": "
<< setprecision(3) << overallGrade << setprecision(precision)
<< endl;
}
}
return 0;
}
发布于 2017-06-06 14:44:17
总的来说,在我看来,对初学者来说还不错。有些事情要注意:
endl
vs \n
--我相信你的书提到了这一点,但是endl
会刷新缓冲区,而\n
不会。在大多数情况下使用\n
就足够了。cout << "Student name: ";
,这是重复的,如果稍微重构循环,就可以消除它。您还应该尽可能晚地声明变量。所以将student
的声明移到循环的正前方。字符串学生;用于(;;) { cout <<学生名:";getline(cin,学生);if (student.empty()) { break;}students.push_back(学生);}for
循环,您可以使用新的基于范围的for循环,而不是旧的样式循环,例如for (const auto &s : students) {
而不是for (int s = 0; s < students.size(); s++) {
,相应地调整下一行:cout << "Grades for " << s << endl;
assignments
变量永远不变,因此应该声明为常量。using
而不是类型,正如Scott在他的书“有效的现代C++”中所建议的那样,你应该更喜欢新的using
指令而不是类型防御。例如:使用vec_size = vector::size_type;https://codereview.stackexchange.com/questions/165086
复制相似问题