I've started learning C++, coming from a PHP/JS background. I've got a copy of the Accelerated C++ book and I'm working through it, doing each chapter and exercise. Having done a few, I'd like to get some feedback to make sure I'm not doing anything too wrong.
The chapter is introduced with the premise of
Imagine a course in which each student's final exam counts for 40% of the final grade, the midterm exam counts for 20%, and the average homework grade makes up the remaining 40%.
The particular exercise I'm doing then says
Write a program that will keep track of grades for several students at once. The program could keep two
vector
s in sync: the first should hold the students' names and the second the final grades that can be computed as input is read. For now, you should assume a fixed number of homework grades.
They suggest using two vectors for this; one of student names and one of grades, although I expanded slightly on that to take into account the different grades (midterms, finals and homework). I've also opted to calculate the grades after receiving all input in order to separate the code that gets and stores input from the code that performs calculations.
Here's a full copy of the program as it stands (110 lines). I'm looking for any feedback on style, correctness, language traps I may have accidentally fallen into, and really anything in general that you think may be of use.
#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;
}
using namespace std;
\$\endgroup\$include
andusing
statements, so I don't know aboutnamespace std;
:P I'll look it up for reference of what not to do, though :-) \$\endgroup\$