首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >加速C++,练习3-5:学生成绩计算器

加速C++,练习3-5:学生成绩计算器
EN

Code Review用户
提问于 2017-06-06 13:28:21
回答 1查看 1.9K关注 0票数 8

我已经开始学习C++,来自于PHP背景。我有一本加速C++的书,我正在研究它,做每一章和练习。做了几件事后,我想得到一些反馈,以确保我没有做错任何事情。

本章是在以下前提下介绍的:

想象一下,每个学生的期末考试占期末成绩的40%,期中考试占20%,家庭作业平均分数占其余40%。

我当时正在做的特别练习是

编写一个程序,可以同时记录几个学生的成绩。这个程序可以让两个vectors保持同步:第一个应该保存学生的名字,第二个是可以在输入时计算出来的最终成绩。现在,你应该假设一定数量的家庭作业成绩。

他们建议使用两个向量:一个是学生的名字,另一个是年级,虽然我稍微扩展了一下,以考虑到不同的年级(期中、期末考试和家庭作业)。我还选择在收到所有输入后计算分数,以便将获取和存储输入的代码与执行计算的代码分开。

这是一份完整的程序副本(110行)。我正在寻找关于风格、正确性、语言陷阱的任何反馈,我可能意外地掉进了其中,而且实际上是任何你认为可能有用的东西。

代码语言:javascript
运行
复制
#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;
}
EN

回答 1

Code Review用户

回答已采纳

发布于 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变量永远不变,因此应该声明为常量。
  • 使用您已经在定义代码范围的函数,这是很好的,但是正如@RichN所指出的,您最好还是使用函数。
  • 喜欢using而不是类型,正如Scott在他的书“有效的现代C++”中所建议的那样,你应该更喜欢新的using指令而不是类型防御。例如:使用vec_size = vector::size_type;
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/165086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档