C++ Edition 4 Textbook Exercise 7 Chapter 4

Exercise 4-0

Compile, execute, and test the programs in this chapter

Solution

Chapter 4 (Organising programs and data) contains a mix of all learnings gained from previous chapters (0 to 3), with the newly added introduction to program partitioning – to break down a large program into multiple .cpp (source) files and .h (header) files to make it more manageable. In this post I will demonstrate my understanding of chapter 4 via presenting the one core project which encompasses the use of program partitioning.

My learning strategy:

  1. Read through chapter 4 – try and understand as much as possible.
  2. Write and execute the chapter 4 project in Code::Block – try and get the partitioned program work.
  3. Read through chapter 4 again and experiment with the project – now that the project is working, I would like to understand why and how it works.
  4. Document core learning outcome – this is what this post is for!

Now that I have spent 2 days completing (and re-iterating) step 1 to 3 above, I believe it is time to execute step 4 above – to document learning outcome via writing this post.

The Project

Purpose of the Chapter 4 project:to read in a flat-file format like input, and produce a summarised output (see diagram below).

Acpp4p0Problem

Chapter 4 requires us to create a partitioned program (or so called project ) that is formed of multiple .cpp source files and .h header files. These files somewhat "know" about each other and can work together in the solving of big problem.

In Code::Block (or probably most of the mainstream IDE), we can create such a project fairly easily to keep these files tidy / organised.

I now document the C++ Source Files and Header Files in the following sections.

C++ Source Files

  • main.cpp – this is the first program that is run during the implementation phase.
  • grade.cpp – contains all functions relating to computing grades.
  • median.cpp – contains all functions relating to computing median.
  • Student_info.cpp – contains all functions relating to handling a Student_info object.

C++ Header Files

  • grade.h – declare the functions as defined in grade.cpp
  • median.h – declare the functions as defined in median.cpp
  • Student_info.h – declare the functions as defined in Student_info.cpp, plus defining the data structure of the Student_info (object) type.

See my post How to add header and source files in Code::Block for additional information.

This diagram below shows what the Code::Block Management Tree look like after successful creation of these files.

Acpp4p0MgntTree

The actual content of the source and header files are documented in the following sections.

Source Files

main.cpp

#include <algorithm> #include <iomanip> #include <ios> #include <iostream> #include <stdexcept> #include <string> #include <vector> #include "grade.h" #include "Student_info.h"  using std::cin; using std::cout; using std::endl; using std::domain_error; using std::max; using std::setprecision; using std::sort; using std::streamsize; using std::string; using std::vector;  int main() {     vector<Student_info> students;     Student_info record;     string::size_type maxlen = 0;   // the length of the longest name      // read and store all the student's data.     // Invariant:   students contain all the student records read so far     //              maxlen contains the length of the longest name in students     while (read(cin, record))     {         // find the length of longest name         maxlen = max(maxlen, record.name.size());         students.push_back(record);     }      // alphabetize the student records     sort(students.begin(), students.end(), compare);      // write the names and grades     for (vector<Student_info>::size_type i = 0;          i != students.size(); ++i)     {         //write the name, padded on teh right to maxlen + 1 characters         cout << students[i].name              << string(maxlen + 1 - students[i].name.size(), ' ');           //compute and write the grade         try         {             double final_grade = grade(students[i]);             streamsize prec = cout.precision();             cout << setprecision(3) << final_grade                  << setprecision(prec);         }         catch (domain_error e)         {             cout << e.what();         }         cout << endl;     }     return 0; }        

grade.cpp

#include <stdexcept> #include <vector> #include "grade.h" #include "median.h" #include "Student_info.h"  using std::domain_error; using std::vector;  // definitions for the grade functions from S4.1/52, S4.1.2/54, S4.2.2/63  // compute a student's overall grade from midterm and final exam // grades and homework grade (S4.1/52) double grade(double midterm, double final, double homework) {     return 0.2 * midterm + 0.4 * final + 0.4 * homework; }  // compute a student's overall grade from midterm and final exam grades // and vector of homework grades. // this function does not copy its argument, because median (function) does it for us. // (S4.1.2/54) double grade(double midterm, double final, const vector<double>& hw) {     if (hw.size() == 0)         throw domain_error("student has done no homework");     return grade(midterm, final, median(hw)); }  // this function computes the final grade for a Student_info object // (S4.2.2/63) double grade(const Student_info& s) {     return grade(s.midterm, s.final, s.homework); }        

median.cpp

// source file for the median function #include <algorithm> #include <stdexcept> #include <vector>  using std::domain_error; using std::sort; using std::vector;  // compute the median of a vector<double> double median(vector<double> vec) {     typedef vector<double>::size_type vec_sz;      vec_sz size = vec.size();     if (size == 0)         throw domain_error("median of an empty vector");      sort(vec.begin(),vec.end());      vec_sz mid = size/2;      return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid]; }        

Student_info.cpp

#include "Student_info.h"  using std::istream; using std::vector;  // we are interested in sorting the Student_info object by the student's name bool compare(const Student_info& x, const Student_info& y) {     return x.name < y.name; }  // read student's name, midterm exam grade, final exam grade, and homework grades // and store into the Student_info object // (as defined in S4.2.2/62) istream& read(istream& is, Student_info& s) {     // read and store the student's name and midterm and final exam grades     is >> s.name >> s.midterm >> s.final;      // read and store all the student's homework grades     read_hw(is, s.homework);     return is; }  // read homework grades from an input stream into a vector<double> // (as defined in S4.1.3/57) istream& read_hw(istream& in, vector<double>& hw) {     if (in)     {         // get rid of previous contents         hw.clear();          // read homework grades         double x;         while (in >> x)             hw.push_back(x);          // clear the stream so that input will work for the next student         in.clear();     }     return in; }        

Header Files

grade.h

#ifndef GUARD_GRADE_H #define GUARD_GRADE_H  //grade.h #include <vector> #include "Student_info.h"  double grade(double, double, double); double grade(double, double, const std::vector<double>&); double grade(const Student_info&);  

0 Response to "C++ Edition 4 Textbook Exercise 7 Chapter 4"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel