home *** CD-ROM | disk | FTP | other *** search
/ C++ for Dummies (3rd Edition) / C_FD.iso / WORKOUT / PART3.TXT < prev    next >
Text File  |  1996-09-06  |  11KB  |  307 lines

  1. 25-Minute Workout
  2. Part III Answer
  3. HereÆs my analysis of the problem. The two classes I chose from the description were Course and Student. 
  4. Armed with these candidate classes, I returned to the problem description to look for verbs to be turned 
  5. into member functions. I found the following:
  6.     *    Students enroll in courses
  7.     *    Students are graded
  8.     *    The program averages all grades in each course
  9.     *    The program returns each studentÆs grade in each course
  10.     *    The program averages each studentÆs grades from all courses in which that student is 
  11. enrolled
  12.     *    The program calculates the average curved grade by the average grade in the class
  13. To enroll a student in a course and perform the necessary averages, I concluded that each Student object 
  14. needed to know what courses it was enrolled in (like a course list) and each Course needed to know what 
  15. students it had (like a student roll). To keep things simple, I used an array and set a maximum number of 
  16. courses per student and a maximum number of students in each course. So that these maximums were not 
  17. exceeded, I also needed noStudents to class Course and noCourses to Student.
  18. I needed also a Student::add(Course&) to add a course to the studentÆs course list and a 
  19. Course::add(Student&) to add the student to the courseÆs student roll. These two functions handled the 
  20. enroll verb mentioned in the preceding list.
  21. It wasnÆt important to me whether the application accessed these two functions through the Student class or 
  22. the Course class; I chose Student. To keep me from forgetting and getting it wrong in use, I made 
  23. Course::add() protected.
  24. The Students are graded item in the preceding list implied the need for a grade function in Student or 
  25. Course. Is the grade a student receives in a course a property of the student or a property of the course? I 
  26. couldnÆt find a good answer to that one, except that historically grades are kept in little books (or little 
  27. computer databases, nowadays) associated with the course. Thus, I decided to add the member function 
  28. Course::grade(Student&, grade). I also added member functions grade(Student&) to return a studentÆs 
  29. grade and grade() to return the average of all students in the course, as stipulated by the requirements.
  30. One final member function in Course, findStudent(), is used in several member functions to find a student 
  31. in the roll. These functions which are needed only internally should be left protected to keep the classÆs 
  32. surface area as small as possible.
  33. Semester hours is obviously a property of Course, requiring a data member and a member function to set it. 
  34. The studentÆs name is a property of Student, requiring a data member and function pair as well.
  35. The following is my solution to the problem along with a description of how it works. Realize that your 
  36. solution may be different; there is no single right solution as long as youÆre trying to think like an object.
  37. //PROB3.CPP  My solution to the Part III Workout
  38.  
  39. #include <iostream.h>
  40. #include <string.h>
  41.  
  42. const int maxStudents = 20;  //max no. of students in one class
  43. const int maxCourses = 6;    //max no. of courses student can take
  44.  
  45. class Student;                         //Note 1
  46.  
  47. class Course
  48. {
  49.    friend class Student;
  50.   public:
  51.    Course( )                            //Note 2
  52.    {
  53.       noStudents = 0;
  54.       semesterHours = 3;   //default is 3
  55.    }
  56.   ~Course( )
  57.    {
  58.       //nothing to do here
  59.    }
  60.  
  61.    //hours - return or set the number of hours in this class
  62.    int hours( )
  63.    {
  64.       return semesterHours;
  65.    }
  66.    int hours(int newValue)
  67.    {                                   //Note 3
  68.       int oldValue = semesterHours;    //itÆs customary to...
  69.       semesterHours = newValue;
  70.       return oldValue;                 //...return old value
  71.    }
  72.  
  73.    //grade - return the average for the class or the grade of a
  74.    //        single student or set the grade of a single student
  75.    float grade( );                      //Note 4
  76.    float grade(Student &s);
  77.    void  grade(Student &s, float grade);
  78.  
  79.   protected:
  80.    //member functions
  81.    //add - add a student to the roll
  82.    int add(Student &s);
  83.    //findStudent - find student in role
  84.    int findStudent(Student &s);
  85.  
  86.    //data members
  87.    Student *pStudents[maxStudents];
  88.    float    classGrade[maxStudents];
  89.    int      semesterHours;
  90.    int      noStudents;
  91. };
  92.  
  93. class Student
  94. {
  95.   public:
  96.    Student( )
  97.    {
  98.       //just zero out everything
  99.       noCourses = 0;
  100.       sName[0] = æ\0Æ;
  101.    }
  102.   ~Student( )
  103.    {
  104.       //nothing to do
  105.    }
  106.  
  107.    //return grade in a given course or average in all courses
  108.    float grade(Course &c)              //Note 5
  109.    {
  110.       return c.grade(*this);
  111.    }
  112.    float grade( );
  113.  
  114.    //return the grade compared to the class average
  115.    float curvedGrade(Course &c);
  116.  
  117.    //add a student to a course
  118.    void add(Course &c);
  119.  
  120.    //name - read and set name
  121.    char *name( )
  122.    {
  123.       return sName;
  124.    }
  125.    void  name(char *pName);
  126.  
  127.   protected:
  128.    char    sName[20];
  129.    Course *pClasses[maxCourses];
  130.    int     noCourses;
  131. };
  132.  
  133. //--------------Course member functions---------------------
  134. //grade - return the average for the class
  135. float Course::grade( )
  136. {
  137.    //if there are no students, forget it now
  138.    if (noStudents == 0)
  139.    {
  140.       return 0.0F;
  141.    }
  142.  
  143.    //add æem all and return the average
  144.    float accumGrade = 0.0F;
  145.    for (int i = 0; i < noStudents; i++)
  146.    {
  147.       accumGrade += classGrade[i];
  148.    }
  149.    return accumGrade / noStudents;
  150. }
  151.  
  152. //grade(Student*) - return the grade of a single student
  153. float Course::grade(Student &s)
  154. {
  155.    //first look the student up in the student roll
  156.    int offset = findStudent(s);
  157.  
  158.    //return studentÆs grade or 0 if the student wasnÆt found
  159.    return (offset >= 0) ? classGrade[offset] : 0.0F;
  160. }
  161.  
  162. //grade(Student, grade) - set the grade of a single student
  163. void Course::grade(Student &s, float grade)
  164. {
  165.    int offset = findStudent(s);
  166.    if (offset >= 0)
  167.    {
  168.       classGrade[offset] = grade;
  169.    }
  170. }
  171.  
  172. //add - add a student to the class roll; return 1 if
  173. //      it works and a zero otherwise
  174. int Course::add(Student &s)
  175. {
  176.    if (noStudents >= maxStudents)
  177.    {
  178.       cout << ôNo more room in class...maybe next semester\nö;
  179.       return 0;
  180.    }
  181.    pStudents[noStudents++] = &s;
  182.    return 1;
  183. }
  184.  
  185. //findStudent - find a student in the look-up table;
  186. //              return offset or -1 if canÆt find
  187. int Course::findStudent(Student &s)
  188. {
  189.    for (int i = 0; i < noStudents; i++)
  190.    {
  191.       if (pStudents[i] == &s)
  192.       {
  193.          return i;
  194.       }
  195.    }
  196.    return -1;
  197.    }
  198. //--------------Student member functions-------------------
  199. //grade( ) - return the average grade for all courses
  200. float Student::grade( )
  201. {
  202.    int hours;
  203.    int noHours = 0;
  204.    float accumGrade = 0.0F;
  205.    for (int i = 0; i < noCourses; i++)
  206.    {
  207.       hours = pClasses[i]->hours( );
  208.       accumGrade += pClasses[i]->grade(*this) * hours;
  209.       noHours += hours;
  210.    }
  211.    return (noHours) ? (accumGrade / noHours): 0.0F;
  212. }
  213.  
  214. //add - add a student to a class
  215. void Student::add(Course &c)
  216. {
  217.    if (noCourses >= maxCourses)
  218.    {
  219.       cout << ôno more room in the inn\nö;
  220.       return;
  221.    }
  222.    if (c.add(*this))
  223.    {
  224.       pClasses[noCourses++] = &c;
  225.    }
  226. }
  227.  
  228. //curvedGrade - return the grade curved by the average
  229. float Student::curvedGrade(Course &c)
  230. {
  231.    //set the average to 3.0
  232.    float g = 3.0F * grade(c) / c.grade( );
  233.  
  234.    //donÆt let it go over 4.0
  235.    if (g > 4.0F)
  236.    {
  237.       g = 4.0F;
  238.    }
  239.    return g;
  240. }
  241.  
  242. //name(char*) - store the name provided
  243. void  Student::name(char *pName)
  244. {
  245.    strncpy(sName, pName, sizeof(sName) - 1);
  246.    sName[sizeof(sName) - 1] = æ\0Æ;
  247. }
  248.  
  249. //--------------------test program-------------------------
  250. int main( )
  251. {
  252.    //declare a course
  253.    Course geo101;
  254.  
  255.    //give it a couple of students
  256.    Student harry, anne;
  257.    harry.name(ôHarryö);
  258.    harry.add(geo101);
  259.    anne.name(ôAnneö);
  260.    anne.add(geo101);
  261.  
  262.    //grade them
  263.    geo101.grade(harry, 3.0F);
  264.    geo101.grade(anne, 2.5F);
  265.  
  266.    //now letÆs look at the ave