第3个版本用浮点数计算平均值,并且添加了小数位固定和强制类型转换
3个文件
GradeBook.h
// GradeBook.h
// Definition of class GradeBook that determines a class average.
// Member functions are defined in GradeBook.cpp#ifndef GRADEBOOK_H
#define GRADEBOOK_H#include<string> // program uses C++ standard string class
using std::string;// GradeBook class definition
class GradeBook
{
public:
GradeBook( string ); // constructor initialize course name
void setCourseName( string ); // function to set the course name
string getCourseName(); // function to retrieve the course name
void displayMessage(); // display a welcome message
void determineClassAverage(); // averages grades entered by the userprivate:
string courseName; // course name for this GradeBook
}; // end class GradeBook#endif // GRADEBOOK_H
GradeBook.cpp
// GradeBook.cpp
// Member-function definitions for class GradeBook that solves the
// class average program with sentinel-controlled repetition
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
using std::fixed; // ensures that decimal point is displayed#include<iomanip> // parameterized stream manipulators
using std::setprecision; // sets numeric output precision// include definition of class GradeBook from GradeBook.h
#include "GradeBook.h"// constructor initialize course name with string supplied as argument
GradeBook::GradeBook( string name )
{
setCourseName( name ); // validate and store courseName
} // end GradeBook constructor// function to set the course name
// ensures that the course name has at most 25 characters
void GradeBook::setCourseName( string name )
{
if( name.length() <= 25 ) // if name has 25 or fewer characters
courseName = name;
if( name.length() > 25 ) // if name has more than 25 characters
{
courseName = name.substr( 0, 25 ); // select first 25 characterscout << "Name \"" << name << "\" exceeds maximum length(25).\n"
<< "Limiting courseName to first 25 characters.\n" << endl;
} // end if...else
} // end function setCourseName// function to retrieve the course name
string GradeBook::getCourseName()
{
return courseName;
} // end function getCourseName// display a welcome message to the GradeBook user
void GradeBook::displayMessage()
{
cout << "Welcome to the grade book for\n" << getCourseName()
<< "!\n" << endl;
} // end function displayMessage// determine class average of grades entered by the user
void GradeBook::determineClassAverage()
{
int total; // sum of the grades entered by user
int gradeCounter; // number of grades entered
int grade; // grade value
double average; // number with decimal point for average// initialization phase
total = 0; // initialize total
gradeCounter = 0; // initialize loop counter// processing phase
// prompt for input and read grade from user
cout << "Enter grade or -1 to quit:";
cin >> grade; // input grade or sentinel value// loop until sentinel value read from user
while( grade != -1 )
{
total += grade; // add grade to total
gradeCounter++; // increment counter// prompt for input and read next grade from user
cout << "Enter grade or -1 to quit:";
cin >> grade; // input grade or sentinel value
} // end while// termination phase
if( gradeCounter != 0 ) // if user entered at least one grade
{
// calculate average of all grades entered
average = static_cast< double >( total ) / gradeCounter;// display total and average ( with 2 digits of precision )
cout << "\nTotal of all " << gradeCounter << " grades entered is "
<< total << endl;cout << "\nClass average is " << setprecision( 2 ) << fixed << average
<< endl;
} // end if
else // no grades were entered, so output appropriate message
cout << "No grades were entered" << endl;
} // end function determineClassAverage
测试文件 main.cpp
// Create GradeBook object and invoke its determineClassAverage function// include definition of class GradeBook from GradeBook.h
#include "GradeBook.h"int main()
{
// Create GradeBook object myGradeBook and
// pass course name to constructor
GradeBook myGradeBook( "CS101 C++ Programming!" );myGradeBook.displayMessage(); // display welcome message
myGradeBook.determineClassAverage(); // find average of grades
return 0; // indicate successful termination
} // end main
常见的编程错误
- 忽略了定义一个块的花括号对会导致一个逻辑错误
- 把浮点数当做准确值来用(比较两个浮点数是否相等),很可能导致错误的结果,浮点数在大多数计算机中只表示近似值
- 强制类型转换运算符可以用于基本数据类型之间的转换,如果进行非法的转换,可能产生变异错误或运行时错误
良好的编程习惯
- 在每次用户输入之前最好给出相应的提示,指出输入数据的形式和所有的特殊输入值(如标记值-1)